diff --git a/Controller/AuthorizationController.php b/Controller/AuthorizationController.php index d496db3b..362a7315 100644 --- a/Controller/AuthorizationController.php +++ b/Controller/AuthorizationController.php @@ -48,8 +48,6 @@ public function indexAction(ServerRequestInterface $serverRequest, ResponseFacto return $event->getResponse(); } - $authRequest->setAuthorizationApproved($event->getAuthorizationResolution()); - return $this->server->completeAuthorizationRequest($authRequest, $serverResponse); } catch (OAuthServerException $e) { return $e->generateHttpResponse($serverResponse); diff --git a/Event/AuthorizationRequestResolveEvent.php b/Event/AuthorizationRequestResolveEvent.php index d6febe63..c86d638c 100644 --- a/Event/AuthorizationRequestResolveEvent.php +++ b/Event/AuthorizationRequestResolveEvent.php @@ -27,25 +27,16 @@ final class AuthorizationRequestResolveEvent extends Event */ private $response; - /** - * @var bool - */ - private $authorizationResolution = self::AUTHORIZATION_DENIED; - public function __construct(AuthorizationRequest $authorizationRequest) { $this->authorizationRequest = $authorizationRequest; } - public function getAuthorizationResolution(): bool - { - return $this->authorizationResolution; - } - public function resolveAuthorization(bool $authorizationResolution): void { - $this->authorizationResolution = $authorizationResolution; + $this->authorizationRequest->setAuthorizationApproved($authorizationResolution); $this->response = null; + $this->stopPropagation(); } public function hasResponse(): bool @@ -65,6 +56,7 @@ public function getResponse(): ResponseInterface public function setResponse(ResponseInterface $response): void { $this->response = $response; + $this->stopPropagation(); } public function getGrantTypeId(): string diff --git a/Tests/Acceptance/AuthorizationEndpointTest.php b/Tests/Acceptance/AuthorizationEndpointTest.php index fff4ac0b..56053e14 100644 --- a/Tests/Acceptance/AuthorizationEndpointTest.php +++ b/Tests/Acceptance/AuthorizationEndpointTest.php @@ -99,6 +99,80 @@ public function testCodeRequestRedirectToResolutionUri() $this->assertEquals('/authorize/consent', $redirectUri); } + public function testAuthorizationRequestEventIsStoppedAfterSettingAResponse() + { + $eventDispatcher = $this->client + ->getContainer() + ->get('event_dispatcher'); + $eventDispatcher->addListener(OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, function (AuthorizationRequestResolveEvent $event) { + $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED); + }, 100); + $eventDispatcher->addListener(OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, function (AuthorizationRequestResolveEvent $event) { + $response = (new Response())->withStatus(302)->withHeader('Location', '/authorize/consent'); + $event->setResponse($response); + }, 200); + + timecop_freeze(new DateTime()); + + $this->client->request( + 'GET', + '/authorize', + [ + 'client_id' => FixtureFactory::FIXTURE_CLIENT_FIRST, + 'response_type' => 'code', + 'state' => 'foobar', + ] + ); + + timecop_return(); + + $response = $this->client->getResponse(); + + $this->assertSame(302, $response->getStatusCode()); + $redirectUri = $response->headers->get('Location'); + $this->assertEquals('/authorize/consent', $redirectUri); + } + + public function testAuthorizationRequestEventIsStoppedAfterResolution() + { + $eventDispatcher = $this->client + ->getContainer() + ->get('event_dispatcher'); + $eventDispatcher->addListener(OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, function (AuthorizationRequestResolveEvent $event) { + $event->resolveAuthorization(AuthorizationRequestResolveEvent::AUTHORIZATION_APPROVED); + }, 200); + $eventDispatcher->addListener(OAuth2Events::AUTHORIZATION_REQUEST_RESOLVE, function (AuthorizationRequestResolveEvent $event) { + $response = (new Response())->withStatus(302)->withHeader('Location', '/authorize/consent'); + $event->setResponse($response); + }, 100); + + timecop_freeze(new DateTime()); + + $this->client->request( + 'GET', + '/authorize', + [ + 'client_id' => FixtureFactory::FIXTURE_CLIENT_FIRST, + 'response_type' => 'code', + 'state' => 'foobar', + ] + ); + + timecop_return(); + + $response = $this->client->getResponse(); + + $this->assertSame(302, $response->getStatusCode()); + $redirectUri = $response->headers->get('Location'); + + $this->assertStringStartsWith(FixtureFactory::FIXTURE_CLIENT_FIRST_REDIRECT_URI, $redirectUri); + $query = []; + parse_str(parse_url($redirectUri, PHP_URL_QUERY), $query); + $this->assertArrayHasKey('code', $query); + $this->assertArrayHasKey('state', $query); + $this->assertEquals('foobar', $query['state']); + } + public function testFailedCodeRequestRedirectWithFakedRedirectUri() { $this->client