diff --git a/src/Entities/AccessTokenEntityInterface.php b/src/Entities/AccessTokenEntityInterface.php index 5729c3fc..fd459914 100644 --- a/src/Entities/AccessTokenEntityInterface.php +++ b/src/Entities/AccessTokenEntityInterface.php @@ -14,7 +14,12 @@ use League\OAuth2\Server\CryptKey; interface AccessTokenEntityInterface extends TokenInterface { /** - * Generate a string representation from the access token + * Set a private key used to encrypt the access token. */ - public function convertToAccessToken(CryptKey $privateKey); + public function setPrivateKey(CryptKey $privateKey); + + /** + * Generate a string representation of the access token. + */ + public function __toString(); } diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index c2ee70a6..cbed3122 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -19,6 +19,19 @@ use League\OAuth2\Server\Entities\ScopeEntityInterface; trait AccessTokenTrait { + /** + * @var CryptKey $privateKey + */ + private $privateKey; + + /** + * Set the private key used to encrypt this access token. + */ + public function setPrivateKey(CryptKey $privateKey) + { + $this->privateKey = $privateKey; + } + /** * Generate a JWT from the access token * @@ -26,7 +39,7 @@ trait AccessTokenTrait * * @return Token */ - public function convertToJWT(CryptKey $privateKey) + private function convertToJWT(CryptKey $privateKey) { return (new Builder()) ->setAudience($this->getClient()->getIdentifier()) @@ -43,9 +56,9 @@ trait AccessTokenTrait /** * Generate a string representation from the access token */ - public function convertToAccessToken(CryptKey $privateKey) + public function __toString() { - return (string) $this->convertToJWT($privateKey); + return (string) $this->convertToJWT($this->privateKey); } /** diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 05b73faa..d020c6ad 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -361,6 +361,7 @@ abstract class AbstractGrant implements GrantTypeInterface $accessToken->setClient($client); $accessToken->setUserIdentifier($userIdentifier); $accessToken->setExpiryDateTime((new \DateTime())->add($accessTokenTTL)); + $accessToken->setPrivateKey($this->privateKey); foreach ($scopes as $scope) { $accessToken->addScope($scope); diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 0aedaa55..5d6035e4 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -216,7 +216,7 @@ class ImplicitGrant extends AbstractAuthorizeGrant $this->makeRedirectUri( $finalRedirectUri, [ - 'access_token' => $accessToken->convertToAccessToken($this->privateKey), + 'access_token' => (string) $accessToken, 'token_type' => 'Bearer', 'expires_in' => $accessToken->getExpiryDateTime()->getTimestamp() - (new \DateTime())->getTimestamp(), 'state' => $authorizationRequest->getState(), diff --git a/src/ResponseTypes/BearerTokenResponse.php b/src/ResponseTypes/BearerTokenResponse.php index b630685c..2e658215 100644 --- a/src/ResponseTypes/BearerTokenResponse.php +++ b/src/ResponseTypes/BearerTokenResponse.php @@ -27,7 +27,7 @@ class BearerTokenResponse extends AbstractResponseType $responseParams = [ 'token_type' => 'Bearer', 'expires_in' => $expireDateTime - (new \DateTime())->getTimestamp(), - 'access_token' => $this->accessToken->convertToAccessToken($this->privateKey), + 'access_token' => (string) $this->accessToken, ]; if ($this->refreshToken instanceof RefreshTokenEntityInterface) { diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 5da2776e..a5916de7 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -3,6 +3,7 @@ namespace LeagueTests\Grant; use League\Event\Emitter; +use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\AuthCodeEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; @@ -353,6 +354,7 @@ class AbstractGrantTest extends TestCase /** @var AbstractGrant $grantMock */ $grantMock = $this->getMockForAbstractClass(AbstractGrant::class); + $grantMock->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grantMock->setAccessTokenRepository($accessTokenRepoMock); $abstractGrantReflection = new \ReflectionClass($grantMock); diff --git a/tests/Grant/AuthCodeGrantTest.php b/tests/Grant/AuthCodeGrantTest.php index 6a319234..589e488c 100644 --- a/tests/Grant/AuthCodeGrantTest.php +++ b/tests/Grant/AuthCodeGrantTest.php @@ -2,6 +2,7 @@ namespace LeagueTests\Grant; +use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Exception\OAuthServerException; @@ -40,7 +41,7 @@ class AuthCodeGrantTest extends TestCase public function setUp() { - $this->cryptStub = new CryptTraitStub; + $this->cryptStub = new CryptTraitStub(); } public function testGetIdentifier() @@ -608,6 +609,7 @@ class AuthCodeGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $request = new ServerRequest( [], @@ -676,6 +678,7 @@ class AuthCodeGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $request = new ServerRequest( [], @@ -747,6 +750,7 @@ class AuthCodeGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $request = new ServerRequest( [], @@ -1537,6 +1541,7 @@ class AuthCodeGrantTest extends TestCase new \DateInterval('PT10M') ); $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } @@ -1624,6 +1629,7 @@ class AuthCodeGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $request = new ServerRequest( [], @@ -1695,6 +1701,7 @@ class AuthCodeGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $request = new ServerRequest( [], @@ -1766,6 +1773,7 @@ class AuthCodeGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setRefreshTokenRepository($refreshTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $request = new ServerRequest( [], diff --git a/tests/Grant/ClientCredentialsGrantTest.php b/tests/Grant/ClientCredentialsGrantTest.php index 6c7b5a36..dfd78b41 100644 --- a/tests/Grant/ClientCredentialsGrantTest.php +++ b/tests/Grant/ClientCredentialsGrantTest.php @@ -2,6 +2,7 @@ namespace LeagueTests\Grant; +use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Grant\ClientCredentialsGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; @@ -44,6 +45,7 @@ class ClientCredentialsGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); $grant->setDefaultScope(self::DEFAULT_SCOPE); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $serverRequest = new ServerRequest(); $serverRequest = $serverRequest->withParsedBody( diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index 2ee700f8..c90a83db 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -2,6 +2,7 @@ namespace LeagueTests\Grant; +use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Grant\PasswordGrant; @@ -60,6 +61,7 @@ class PasswordGrantTest extends TestCase $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); $grant->setDefaultScope(self::DEFAULT_SCOPE); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $serverRequest = new ServerRequest(); $serverRequest = $serverRequest->withParsedBody( diff --git a/tests/Middleware/ResourceServerMiddlewareTest.php b/tests/Middleware/ResourceServerMiddlewareTest.php index 0db71cdd..d1a96042 100644 --- a/tests/Middleware/ResourceServerMiddlewareTest.php +++ b/tests/Middleware/ResourceServerMiddlewareTest.php @@ -29,8 +29,9 @@ class ResourceServerMiddlewareTest extends TestCase $accessToken->setUserIdentifier(123); $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); $accessToken->setClient($client); + $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $token = $accessToken->convertToAccessToken(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $token = (string) $accessToken; $request = new ServerRequest(); $request = $request->withHeader('authorization', sprintf('Bearer %s', $token)); @@ -64,8 +65,9 @@ class ResourceServerMiddlewareTest extends TestCase $accessToken->setUserIdentifier(123); $accessToken->setExpiryDateTime((new \DateTime())->sub(new \DateInterval('PT1H'))); $accessToken->setClient($client); + $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); - $token = $accessToken->convertToAccessToken(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $token = (string) $accessToken; $request = new ServerRequest(); $request = $request->withHeader('authorization', sprintf('Bearer %s', $token)); diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 31245b07..2eb87238 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -35,6 +35,7 @@ class BearerResponseTypeTest extends TestCase $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); $accessToken->setClient($client); $accessToken->addScope($scope); + $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $refreshToken = new RefreshTokenEntity(); $refreshToken->setIdentifier('abcdef'); @@ -77,6 +78,7 @@ class BearerResponseTypeTest extends TestCase $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); $accessToken->setClient($client); $accessToken->addScope($scope); + $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $refreshToken = new RefreshTokenEntity(); $refreshToken->setIdentifier('abcdef'); @@ -119,6 +121,7 @@ class BearerResponseTypeTest extends TestCase $accessToken->setUserIdentifier(123); $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); $accessToken->setClient($client); + $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $refreshToken = new RefreshTokenEntity(); $refreshToken->setIdentifier('abcdef'); @@ -164,6 +167,7 @@ class BearerResponseTypeTest extends TestCase $accessToken->setUserIdentifier(123); $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); $accessToken->setClient($client); + $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $refreshToken = new RefreshTokenEntity(); $refreshToken->setIdentifier('abcdef'); @@ -206,6 +210,7 @@ class BearerResponseTypeTest extends TestCase $accessToken->setUserIdentifier(123); $accessToken->setExpiryDateTime((new \DateTime())->add(new \DateInterval('PT1H'))); $accessToken->setClient($client); + $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $refreshToken = new RefreshTokenEntity(); $refreshToken->setIdentifier('abcdef');