diff --git a/.gitignore b/.gitignore index 7ea123c7..71cbd790 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /vendor/* /tests/app/cache /.php_cs.cache +/.phpunit.result.cache diff --git a/src/Client/OAuth2Client.php b/src/Client/OAuth2Client.php index c87be8cd..0daf53b2 100644 --- a/src/Client/OAuth2Client.php +++ b/src/Client/OAuth2Client.php @@ -15,6 +15,7 @@ use League\OAuth2\Client\Provider\AbstractProvider; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; use League\OAuth2\Client\Token\AccessToken; +use phpDocumentor\Reflection\DocBlock\Tags\Param; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Session\SessionInterface; @@ -80,13 +81,15 @@ public function redirect(array $scopes = [], array $options = []) /** * Call this after the user is redirected back to get the access token. * + * @param array $options + * * @return AccessToken|\League\OAuth2\Client\Token\AccessTokenInterface * * @throws InvalidStateException * @throws MissingAuthorizationCodeException * @throws IdentityProviderException If token cannot be fetched */ - public function getAccessToken() + public function getAccessToken(array $options = []) { if (!$this->isStateless) { $expectedState = $this->getSession()->get(self::OAUTH2_SESSION_STATE_KEY); @@ -102,9 +105,10 @@ public function getAccessToken() throw new MissingAuthorizationCodeException('No "code" parameter was found (usually this is a query parameter)!'); } - return $this->provider->getAccessToken('authorization_code', [ - 'code' => $code, - ]); + return $this->provider->getAccessToken( + 'authorization_code', + array_merge(['code' => $code], $options) + ); } /** diff --git a/src/Client/OAuth2ClientInterface.php b/src/Client/OAuth2ClientInterface.php index 348e8171..0aa07575 100644 --- a/src/Client/OAuth2ClientInterface.php +++ b/src/Client/OAuth2ClientInterface.php @@ -33,13 +33,15 @@ public function redirect(array $scopes, array $options); /** * Call this after the user is redirected back to get the access token. * + * @param array $options + * * @return \League\OAuth2\Client\Token\AccessToken * * @throws \KnpU\OAuth2ClientBundle\Exception\InvalidStateException * @throws \KnpU\OAuth2ClientBundle\Exception\MissingAuthorizationCodeException * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException If token cannot be fetched */ - public function getAccessToken(); + public function getAccessToken(array $options = []); /** * Returns the "User" information (called a resource owner). diff --git a/src/Security/Authenticator/SocialAuthenticator.php b/src/Security/Authenticator/SocialAuthenticator.php index be173800..fa418d87 100644 --- a/src/Security/Authenticator/SocialAuthenticator.php +++ b/src/Security/Authenticator/SocialAuthenticator.php @@ -29,10 +29,10 @@ abstract class SocialAuthenticator extends AbstractGuardAuthenticator use PreviousUrlHelper; use SaveAuthFailureMessage; - protected function fetchAccessToken(OAuth2ClientInterface $client) + protected function fetchAccessToken(OAuth2ClientInterface $client, array $options = []) { try { - return $client->getAccessToken(); + return $client->getAccessToken($options); } catch (MissingAuthorizationCodeException $e) { throw new NoAuthCodeAuthenticationException(); } catch (IdentityProviderException $e) { diff --git a/tests/Client/OAuth2ClientTest.php b/tests/Client/OAuth2ClientTest.php index 6809ceb1..5bc8606b 100644 --- a/tests/Client/OAuth2ClientTest.php +++ b/tests/Client/OAuth2ClientTest.php @@ -137,6 +137,26 @@ public function testGetAccessToken() $this->assertSame($expectedToken->reveal(), $actualToken); } + public function testGetAccessTokenWithOptions() + { + $this->request->query->set('state', 'THE_STATE'); + $this->request->query->set('code', 'CODE_ABC'); + + $this->session->get(OAuth2Client::OAUTH2_SESSION_STATE_KEY) + ->willReturn('THE_STATE'); + + $expectedToken = $this->prophesize('League\OAuth2\Client\Token\AccessToken'); + $this->provider->getAccessToken('authorization_code', ['code' => 'CODE_ABC', 'redirect_uri' => 'https://some.url']) + ->willReturn($expectedToken->reveal()); + + $client = new OAuth2Client( + $this->provider->reveal(), + $this->requestStack + ); + $actualToken = $client->getAccessToken(['redirect_uri' => 'https://some.url']); + $this->assertSame($expectedToken->reveal(), $actualToken); + } + public function testGetAccessTokenFromPOST() { $this->request->request->set('code', 'CODE_ABC'); diff --git a/tests/Security/Authenticator/SocialAuthenticatorTest.php b/tests/Security/Authenticator/SocialAuthenticatorTest.php index ce4d252f..d5960e17 100644 --- a/tests/Security/Authenticator/SocialAuthenticatorTest.php +++ b/tests/Security/Authenticator/SocialAuthenticatorTest.php @@ -28,7 +28,7 @@ public function testFetchAccessTokenSimplyReturns() { $authenticator = new StubSocialAuthenticator(); $client = $this->prophesize('KnpU\OAuth2ClientBundle\Client\OAuth2Client'); - $client->getAccessToken() + $client->getAccessToken([]) ->willReturn('expected_access_token'); $actualToken = $authenticator->doFetchAccessToken($client->reveal()); @@ -40,7 +40,7 @@ public function testFetchAccessTokenThrowsAuthenticationException() $this->expectException(NoAuthCodeAuthenticationException::class); $authenticator = new StubSocialAuthenticator(); $client = $this->prophesize('KnpU\OAuth2ClientBundle\Client\OAuth2Client'); - $client->getAccessToken() + $client->getAccessToken([]) ->willThrow(new MissingAuthorizationCodeException()); $authenticator->doFetchAccessToken($client->reveal());