Skip to content

Commit df405a8

Browse files
committed
feature #49 add request token event (jr-k)
This PR was squashed before being merged into the 0.1-dev branch. Discussion ---------- add request token event I've added an event to manipulate the response during /token process. Useful to add some Set-Cookie directives for example. Commits ------- 7be39ea add request token event
2 parents ffbc931 + 7be39ea commit df405a8

File tree

5 files changed

+111
-2
lines changed

5 files changed

+111
-2
lines changed

src/Controller/TokenController.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44

55
namespace League\Bundle\OAuth2ServerBundle\Controller;
66

7+
use League\Bundle\OAuth2ServerBundle\Event\TokenRequestResolveEvent;
8+
use League\Bundle\OAuth2ServerBundle\OAuth2Events;
79
use League\OAuth2\Server\AuthorizationServer;
810
use League\OAuth2\Server\Exception\OAuthServerException;
911
use Psr\Http\Message\ResponseFactoryInterface;
1012
use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
1113
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
1214
use Symfony\Component\HttpFoundation\Request;
1315
use Symfony\Component\HttpFoundation\Response;
16+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
1417

1518
final class TokenController
1619
{
@@ -34,16 +37,23 @@ final class TokenController
3437
*/
3538
private $responseFactory;
3639

40+
/**
41+
* @var EventDispatcherInterface
42+
*/
43+
private $eventDispatcher;
44+
3745
public function __construct(
3846
AuthorizationServer $server,
3947
HttpMessageFactoryInterface $httpMessageFactory,
4048
HttpFoundationFactoryInterface $httpFoundationFactory,
41-
ResponseFactoryInterface $responseFactory
49+
ResponseFactoryInterface $responseFactory,
50+
EventDispatcherInterface $eventDispatcher
4251
) {
4352
$this->server = $server;
4453
$this->httpMessageFactory = $httpMessageFactory;
4554
$this->httpFoundationFactory = $httpFoundationFactory;
4655
$this->responseFactory = $responseFactory;
56+
$this->eventDispatcher = $eventDispatcher;
4757
}
4858

4959
public function indexAction(Request $request): Response
@@ -57,6 +67,14 @@ public function indexAction(Request $request): Response
5767
$response = $e->generateHttpResponse($serverResponse);
5868
}
5969

60-
return $this->httpFoundationFactory->createResponse($response);
70+
$renderedResponse = $this->httpFoundationFactory->createResponse($response);
71+
72+
/** @var TokenRequestResolveEvent $event */
73+
$this->eventDispatcher->dispatch(
74+
new TokenRequestResolveEvent($renderedResponse),
75+
OAuth2Events::TOKEN_REQUEST_RESOLVE
76+
);
77+
78+
return $renderedResponse;
6179
}
6280
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace League\Bundle\OAuth2ServerBundle\Event;
6+
7+
use Symfony\Component\HttpFoundation\Response;
8+
use Symfony\Contracts\EventDispatcher\Event;
9+
10+
final class TokenRequestResolveEvent extends Event
11+
{
12+
/**
13+
* @var Response
14+
*/
15+
private $response;
16+
17+
public function __construct(Response $response)
18+
{
19+
$this->response = $response;
20+
}
21+
22+
public function getResponse(): Response
23+
{
24+
return $this->response;
25+
}
26+
27+
public function setResponse(Response $response): self
28+
{
29+
$this->response = $response;
30+
31+
return $this;
32+
}
33+
}

src/OAuth2Events.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ final class OAuth2Events
3131
*/
3232
public const AUTHORIZATION_REQUEST_RESOLVE = 'league.oauth2_server.event.authorization_request_resolve';
3333

34+
/**
35+
* The REQUEST_TOKEN_RESOLVE event occurs right before the system
36+
* complete token request.
37+
*
38+
* You could manipulate the response.
39+
*/
40+
public const TOKEN_REQUEST_RESOLVE = 'league.oauth2_server.event.token_request_resolve';
41+
3442
/**
3543
* The PRE_SAVE_CLIENT event occurs right before the client is saved
3644
* by a ClientManager.

src/Resources/config/services.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
service('league.oauth2_server.factory.psr_http'),
222222
service('league.oauth2_server.factory.http_foundation'),
223223
service('league.oauth2_server.factory.psr17'),
224+
service('event_dispatcher'),
224225
])
225226
->tag('controller.service_arguments')
226227
->alias(TokenController::class, 'league.oauth2_server.controller.token')

tests/Acceptance/TokenEndpointTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace League\Bundle\OAuth2ServerBundle\Tests\Acceptance;
66

7+
use League\Bundle\OAuth2ServerBundle\Event\TokenRequestResolveEvent;
78
use League\Bundle\OAuth2ServerBundle\Event\UserResolveEvent;
89
use League\Bundle\OAuth2ServerBundle\Manager\AccessTokenManagerInterface;
910
use League\Bundle\OAuth2ServerBundle\Manager\AuthorizationCodeManagerInterface;
@@ -37,6 +38,13 @@ public function testSuccessfulClientCredentialsRequest(): void
3738
'grant_type' => 'client_credentials',
3839
]);
3940

41+
$this->client
42+
->getContainer()
43+
->get('event_dispatcher')
44+
->addListener(OAuth2Events::TOKEN_REQUEST_RESOLVE, static function (TokenRequestResolveEvent $event): void {
45+
$event->getResponse()->headers->set('foo', 'bar');
46+
});
47+
4048
$response = $this->client->getResponse();
4149

4250
$this->assertSame(200, $response->getStatusCode());
@@ -48,6 +56,7 @@ public function testSuccessfulClientCredentialsRequest(): void
4856
$this->assertLessThanOrEqual(3600, $jsonResponse['expires_in']);
4957
$this->assertGreaterThan(0, $jsonResponse['expires_in']);
5058
$this->assertNotEmpty($jsonResponse['access_token']);
59+
$this->assertEmpty($response->headers->get('foo'), 'bar');
5160
}
5261

5362
public function testSuccessfulPasswordRequest(): void
@@ -59,6 +68,13 @@ public function testSuccessfulPasswordRequest(): void
5968
$event->setUser(FixtureFactory::createUser());
6069
});
6170

71+
$this->client
72+
->getContainer()
73+
->get('event_dispatcher')
74+
->addListener(OAuth2Events::TOKEN_REQUEST_RESOLVE, static function (TokenRequestResolveEvent $event): void {
75+
$event->getResponse()->headers->set('foo', 'bar');
76+
});
77+
6278
$this->client->request('POST', '/token', [
6379
'client_id' => 'foo',
6480
'client_secret' => 'secret',
@@ -79,6 +95,7 @@ public function testSuccessfulPasswordRequest(): void
7995
$this->assertGreaterThan(0, $jsonResponse['expires_in']);
8096
$this->assertNotEmpty($jsonResponse['access_token']);
8197
$this->assertNotEmpty($jsonResponse['refresh_token']);
98+
$this->assertSame($response->headers->get('foo'), 'bar');
8299
}
83100

84101
public function testSuccessfulRefreshTokenRequest(): void
@@ -95,6 +112,13 @@ public function testSuccessfulRefreshTokenRequest(): void
95112
'refresh_token' => TestHelper::generateEncryptedPayload($refreshToken),
96113
]);
97114

115+
$this->client
116+
->getContainer()
117+
->get('event_dispatcher')
118+
->addListener(OAuth2Events::TOKEN_REQUEST_RESOLVE, static function (TokenRequestResolveEvent $event): void {
119+
$event->getResponse()->headers->set('foo', 'bar');
120+
});
121+
98122
$response = $this->client->getResponse();
99123

100124
$this->assertSame(200, $response->getStatusCode());
@@ -107,6 +131,7 @@ public function testSuccessfulRefreshTokenRequest(): void
107131
$this->assertGreaterThan(0, $jsonResponse['expires_in']);
108132
$this->assertNotEmpty($jsonResponse['access_token']);
109133
$this->assertNotEmpty($jsonResponse['refresh_token']);
134+
$this->assertEmpty($response->headers->get('foo'), 'bar');
110135
}
111136

112137
public function testSuccessfulAuthorizationCodeRequest(): void
@@ -124,6 +149,13 @@ public function testSuccessfulAuthorizationCodeRequest(): void
124149
'code' => TestHelper::generateEncryptedAuthCodePayload($authCode),
125150
]);
126151

152+
$this->client
153+
->getContainer()
154+
->get('event_dispatcher')
155+
->addListener(OAuth2Events::TOKEN_REQUEST_RESOLVE, static function (TokenRequestResolveEvent $event): void {
156+
$event->getResponse()->headers->set('foo', 'bar');
157+
});
158+
127159
$response = $this->client->getResponse();
128160

129161
$this->assertSame(200, $response->getStatusCode());
@@ -135,6 +167,7 @@ public function testSuccessfulAuthorizationCodeRequest(): void
135167
$this->assertLessThanOrEqual(3600, $jsonResponse['expires_in']);
136168
$this->assertGreaterThan(0, $jsonResponse['expires_in']);
137169
$this->assertNotEmpty($jsonResponse['access_token']);
170+
$this->assertEmpty($response->headers->get('foo'), 'bar');
138171
}
139172

140173
public function testSuccessfulAuthorizationCodeRequestWithPublicClient(): void
@@ -144,6 +177,13 @@ public function testSuccessfulAuthorizationCodeRequestWithPublicClient(): void
144177
->get(AuthorizationCodeManagerInterface::class)
145178
->find(FixtureFactory::FIXTURE_AUTH_CODE_PUBLIC_CLIENT);
146179

180+
$this->client
181+
->getContainer()
182+
->get('event_dispatcher')
183+
->addListener(OAuth2Events::TOKEN_REQUEST_RESOLVE, static function (TokenRequestResolveEvent $event): void {
184+
$event->getResponse()->headers->set('foo', 'bar');
185+
});
186+
147187
$this->client->request('POST', '/token', [
148188
'client_id' => FixtureFactory::FIXTURE_PUBLIC_CLIENT,
149189
'grant_type' => 'authorization_code',
@@ -162,6 +202,7 @@ public function testSuccessfulAuthorizationCodeRequestWithPublicClient(): void
162202
$this->assertLessThanOrEqual(3600, $jsonResponse['expires_in']);
163203
$this->assertGreaterThan(0, $jsonResponse['expires_in']);
164204
$this->assertNotEmpty($jsonResponse['access_token']);
205+
$this->assertSame($response->headers->get('foo'), 'bar');
165206
}
166207

167208
public function testFailedTokenRequest(): void
@@ -188,6 +229,13 @@ public function testFailedClientCredentialsTokenRequest(): void
188229
'grant_type' => 'client_credentials',
189230
]);
190231

232+
$this->client
233+
->getContainer()
234+
->get('event_dispatcher')
235+
->addListener(OAuth2Events::TOKEN_REQUEST_RESOLVE, static function (TokenRequestResolveEvent $event): void {
236+
$event->getResponse()->headers->set('foo', 'bar');
237+
});
238+
191239
$response = $this->client->getResponse();
192240

193241
$this->assertSame(401, $response->getStatusCode());
@@ -197,5 +245,6 @@ public function testFailedClientCredentialsTokenRequest(): void
197245

198246
$this->assertSame('invalid_client', $jsonResponse['error']);
199247
$this->assertSame('Client authentication failed', $jsonResponse['message']);
248+
$this->assertEmpty($response->headers->get('foo'), 'bar');
200249
}
201250
}

0 commit comments

Comments
 (0)