From 517403ba79446e06ff9b558ba1bb0f979396c734 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Wed, 3 Jun 2020 21:47:48 +0200 Subject: [PATCH 01/36] Basic implementation of private claims --- .../Repositories/AccessTokenRepository.php | 11 +++++-- src/Entities/ClaimEntityInterface.php | 29 +++++++++++++++++++ src/Entities/TokenInterface.php | 7 +++++ src/Entities/Traits/AccessTokenTrait.php | 19 ++++++++++-- src/Entities/Traits/TokenEntityTrait.php | 28 ++++++++++++++++++ src/Grant/AbstractGrant.php | 22 ++++++++++++-- src/Grant/AuthCodeGrant.php | 6 +++- src/Grant/ClientCredentialsGrant.php | 7 ++++- src/Grant/GrantTypeInterface.php | 8 +++++ src/Grant/ImplicitGrant.php | 8 ++++- src/Grant/PasswordGrant.php | 13 ++++++++- src/Grant/RefreshTokenGrant.php | 13 ++++++++- .../AccessTokenRepositoryInterface.php | 13 +++++++-- src/Repositories/ClaimRepositoryInterface.php | 26 +++++++++++++++++ 14 files changed, 195 insertions(+), 15 deletions(-) create mode 100644 src/Entities/ClaimEntityInterface.php create mode 100644 src/Repositories/ClaimRepositoryInterface.php diff --git a/examples/src/Repositories/AccessTokenRepository.php b/examples/src/Repositories/AccessTokenRepository.php index d7736c763..4842c448e 100644 --- a/examples/src/Repositories/AccessTokenRepository.php +++ b/examples/src/Repositories/AccessTokenRepository.php @@ -43,10 +43,17 @@ public function isAccessTokenRevoked($tokenId) /** * {@inheritdoc} */ - public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null) - { + public function getNewToken( + ClientEntityInterface $clientEntity, + array $scopes, + $userIdentifier = null, + array $claims = [] + ) { $accessToken = new AccessTokenEntity(); $accessToken->setClient($clientEntity); + foreach ($claims as $claim) { + $accessToken->addClaim($claim); + } foreach ($scopes as $scope) { $accessToken->addScope($scope); } diff --git a/src/Entities/ClaimEntityInterface.php b/src/Entities/ClaimEntityInterface.php new file mode 100644 index 000000000..0fd97440a --- /dev/null +++ b/src/Entities/ClaimEntityInterface.php @@ -0,0 +1,29 @@ + + * @copyright Copyright (c) Sebastian Kroczek + * @license http://mit-license.org/ + * + * @link https://github.com/thephpleague/oauth2-server + */ + +namespace League\OAuth2\Server\Entities; + +use JsonSerializable; + +interface ClaimEntityInterface extends JsonSerializable +{ + /** + * Get the claim's name. + * + * @return string + */ + public function getName(); + + /** + * Get the claim's value + * + * @return mixed + */ + public function getValue(); +} diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index 7b063e138..fca80fdb1 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -82,4 +82,11 @@ public function addScope(ScopeEntityInterface $scope); * @return ScopeEntityInterface[] */ public function getScopes(); + + /** + * Return an array of claims associated with the token. + * + * @return ClaimEntityInterface[] + */ + public function getClaims(); } diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 48e3d1ac4..101d3a782 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -15,6 +15,7 @@ use Lcobucci\JWT\Signer\Rsa\Sha256; use Lcobucci\JWT\Token; use League\OAuth2\Server\CryptKey; +use League\OAuth2\Server\Entities\ClaimEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; @@ -42,13 +43,20 @@ public function setPrivateKey(CryptKey $privateKey) */ private function convertToJWT(CryptKey $privateKey) { - return (new Builder()) - ->permittedFor($this->getClient()->getIdentifier()) + $builder = new Builder(); + $builder->permittedFor($this->getClient()->getIdentifier()) ->identifiedBy($this->getIdentifier()) ->issuedAt(\time()) ->canOnlyBeUsedAfter(\time()) ->expiresAt($this->getExpiryDateTime()->getTimestamp()) - ->relatedTo((string) $this->getUserIdentifier()) + ->relatedTo((string)$this->getUserIdentifier()); + + foreach ($this->getClaims() as $claim){ + $builder->withClaim($claim->getName(), $claim->getValue()); + } + + return $builder + // Set scope claim late to prevent it from being overridden. ->withClaim('scopes', $this->getScopes()) ->getToken(new Sha256(), new Key($privateKey->getKeyPath(), $privateKey->getPassPhrase())); } @@ -81,6 +89,11 @@ abstract public function getUserIdentifier(); */ abstract public function getScopes(); + /** + * @return ClaimEntityInterface[] + */ + abstract public function getClaims(); + /** * @return string */ diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index 83b172322..93c3b8671 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -10,6 +10,7 @@ namespace League\OAuth2\Server\Entities\Traits; use DateTimeImmutable; +use League\OAuth2\Server\Entities\ClaimEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; @@ -20,6 +21,11 @@ trait TokenEntityTrait */ protected $scopes = []; + /** + * @var ClaimEntityInterface[] + */ + protected $claims = []; + /** * @var DateTimeImmutable */ @@ -55,6 +61,28 @@ public function getScopes() return \array_values($this->scopes); } + /** + * Associate a claim with the token. + * + * @param ClaimEntityInterface $claim + */ + public function addClaim(ClaimEntityInterface $claim) + { + $this->claims[] = $claim; + } + + /** + * Return an array of claims associated with the token. + * + * @return ClaimEntityInterface[] + */ + public function getClaims() + { + return $this->claims; + } + + + /** * Get the token's expiry date time. * diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index c4797292a..e2acc0b10 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -19,6 +19,7 @@ use League\OAuth2\Server\CryptTrait; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\AuthCodeEntityInterface; +use League\OAuth2\Server\Entities\ClaimEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; @@ -26,6 +27,7 @@ use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\Repositories\AuthCodeRepositoryInterface; +use League\OAuth2\Server\Repositories\ClaimRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; @@ -62,6 +64,12 @@ abstract class AbstractGrant implements GrantTypeInterface */ protected $scopeRepository; + /** + * @var ClaimRepositoryInterface + */ + protected $claimRepository; + + /** * @var AuthCodeRepositoryInterface */ @@ -116,6 +124,14 @@ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository) $this->scopeRepository = $scopeRepository; } + /** + * @param ClaimRepositoryInterface $claimRepository + */ + public function setClaimRepository(ClaimRepositoryInterface $claimRepository) + { + $this->claimRepository = $claimRepository; + } + /** * @param RefreshTokenRepositoryInterface $refreshTokenRepository */ @@ -418,6 +434,7 @@ protected function getServerParameter($parameter, ServerRequestInterface $reques * @param ClientEntityInterface $client * @param string|null $userIdentifier * @param ScopeEntityInterface[] $scopes + * @param ClaimEntityInterface[] $claims * * @throws OAuthServerException * @throws UniqueTokenIdentifierConstraintViolationException @@ -428,11 +445,12 @@ protected function issueAccessToken( DateInterval $accessTokenTTL, ClientEntityInterface $client, $userIdentifier, - array $scopes = [] + array $scopes = [], + array $claims = [] ) { $maxGenerationAttempts = self::MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS; - $accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier); + $accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier, $claims); $accessToken->setExpiryDateTime((new DateTimeImmutable())->add($accessTokenTTL)); $accessToken->setPrivateKey($this->privateKey); diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 8a30bfc9f..9e6240608 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -159,9 +159,13 @@ public function respondToAccessTokenRequest( } } } + $privateClaims = []; + if($this->claimRepository){ + $privateClaims = $this->claimRepository->getClaims(); + } // Issue and persist new access token - $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $authCodePayload->user_id, $scopes); + $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $authCodePayload->user_id, $scopes, $privateClaims); $this->getEmitter()->emit(new RequestEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request)); $responseType->setAccessToken($accessToken); diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index 691f421bc..87bef2dc2 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -48,8 +48,13 @@ public function respondToAccessTokenRequest( // Finalize the requested scopes $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client); + $privateClaims = []; + if($this->claimRepository){ + $privateClaims = $this->claimRepository->getClaims(); + } + // Issue and persist access token - $accessToken = $this->issueAccessToken($accessTokenTTL, $client, null, $finalizedScopes); + $accessToken = $this->issueAccessToken($accessTokenTTL, $client, null, $finalizedScopes, $privateClaims); // Send event to emitter $this->getEmitter()->emit(new RequestEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request)); diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index 41ebeb5ff..7101adc18 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -16,6 +16,7 @@ use League\Event\EmitterAwareInterface; use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClaimRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\RequestTypes\AuthorizationRequest; @@ -121,6 +122,13 @@ public function setAccessTokenRepository(AccessTokenRepositoryInterface $accessT */ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository); + /** + * Set the claim repository. + * + * @param ClaimRepositoryInterface $claimRepository + */ + public function setClaimRepository(ClaimRepositoryInterface $claimRepository); + /** * Set the default scope. * diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 17f289bfb..7a906eac9 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -186,11 +186,17 @@ public function completeAuthorizationRequest(AuthorizationRequest $authorization $authorizationRequest->getUser()->getIdentifier() ); + $privateClaims = []; + if($this->claimRepository){ + $privateClaims = $this->claimRepository->getClaims(); + } + $accessToken = $this->issueAccessToken( $this->accessTokenTTL, $authorizationRequest->getClient(), $authorizationRequest->getUser()->getIdentifier(), - $finalizedScopes + $finalizedScopes, + $privateClaims ); $response = new RedirectResponse(); diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 7579fd0d2..0d18249b4 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -56,8 +56,19 @@ public function respondToAccessTokenRequest( // Finalize the requested scopes $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier()); + $privateClaims = []; + if($this->claimRepository){ + $privateClaims = $this->claimRepository->getClaims(); + } + // Issue and persist new access token - $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $user->getIdentifier(), $finalizedScopes); + $accessToken = $this->issueAccessToken( + $accessTokenTTL, + $client, + $user->getIdentifier(), + $finalizedScopes, + $privateClaims + ); $this->getEmitter()->emit(new RequestEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request)); $responseType->setAccessToken($accessToken); diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index b6302bca5..4cbd6dc1c 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -63,8 +63,19 @@ public function respondToAccessTokenRequest( $this->accessTokenRepository->revokeAccessToken($oldRefreshToken['access_token_id']); $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']); + $privateClaim = []; + if($this->claimRepository){ + $privateClaim = $this->claimRepository->getClaims(); + } + // Issue and persist new access token - $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $oldRefreshToken['user_id'], $scopes); + $accessToken = $this->issueAccessToken( + $accessTokenTTL, + $client, + $oldRefreshToken['user_id'], + $scopes, + $privateClaim + ); $this->getEmitter()->emit(new RequestEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request)); $responseType->setAccessToken($accessToken); diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index 72ddf1f4c..42a95e1f1 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -10,6 +10,7 @@ namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; +use League\OAuth2\Server\Entities\ClaimEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; @@ -22,13 +23,19 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface /** * Create a new access token * - * @param ClientEntityInterface $clientEntity + * @param ClientEntityInterface $clientEntity * @param ScopeEntityInterface[] $scopes - * @param mixed $userIdentifier + * @param array $claims + * @param ClaimEntityInterface[] $userIdentifier * * @return AccessTokenEntityInterface */ - public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null); + public function getNewToken( + ClientEntityInterface $clientEntity, + array $scopes, + $userIdentifier = null, + array $claims = [] + ); /** * Persists a new access token to permanent storage. diff --git a/src/Repositories/ClaimRepositoryInterface.php b/src/Repositories/ClaimRepositoryInterface.php new file mode 100644 index 000000000..b2a73e2da --- /dev/null +++ b/src/Repositories/ClaimRepositoryInterface.php @@ -0,0 +1,26 @@ + + * @copyright Copyright (c) Sebastian Kroczek + * @license http://mit-license.org/ + * + * @link https://github.com/thephpleague/oauth2-server + */ + +namespace League\OAuth2\Server\Repositories; + +use League\OAuth2\Server\Entities\ClaimEntityInterface; + +/** + * Claim repository interface. + */ +interface ClaimRepositoryInterface extends RepositoryInterface +{ + /** + * Returns claims + * + * + * @return ClaimEntityInterface[] + */ + public function getClaims(); +} From aefdde5ba0a4f8a0e0f1ff914a4eac9a8d747f87 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 4 Jun 2020 15:21:06 +0200 Subject: [PATCH 02/36] Adds private claims to the grant types --- src/AuthorizationServer.php | 9 +++++++++ src/Grant/AuthCodeGrant.php | 7 ++++++- src/Grant/ClientCredentialsGrant.php | 2 +- src/Grant/ImplicitGrant.php | 7 ++++++- src/Grant/PasswordGrant.php | 2 +- src/Grant/RefreshTokenGrant.php | 11 ++++++++--- src/Repositories/ClaimRepositoryInterface.php | 7 ++++++- 7 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 8b0b2815e..ea4dcada1 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -16,6 +16,7 @@ use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\Grant\GrantTypeInterface; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClaimRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use League\OAuth2\Server\RequestTypes\AuthorizationRequest; @@ -69,6 +70,11 @@ class AuthorizationServer implements EmitterAwareInterface */ private $scopeRepository; + /** + * @var ClaimRepositoryInterface + */ + private $claimRepository; + /** * @var string|Key */ @@ -93,6 +99,7 @@ public function __construct( ClientRepositoryInterface $clientRepository, AccessTokenRepositoryInterface $accessTokenRepository, ScopeRepositoryInterface $scopeRepository, + ClaimRepositoryInterface $claimRepository, $privateKey, $encryptionKey, ResponseTypeInterface $responseType = null @@ -100,6 +107,7 @@ public function __construct( $this->clientRepository = $clientRepository; $this->accessTokenRepository = $accessTokenRepository; $this->scopeRepository = $scopeRepository; + $this->claimRepository = $claimRepository; if ($privateKey instanceof CryptKey === false) { $privateKey = new CryptKey($privateKey); @@ -132,6 +140,7 @@ public function enableGrantType(GrantTypeInterface $grantType, DateInterval $acc $grantType->setAccessTokenRepository($this->accessTokenRepository); $grantType->setClientRepository($this->clientRepository); $grantType->setScopeRepository($this->scopeRepository); + $grantType->setClaimRepository($this->claimRepository); $grantType->setDefaultScope($this->defaultScope); $grantType->setPrivateKey($this->privateKey); $grantType->setEmitter($this->getEmitter()); diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 9e6240608..5650b7c33 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -161,7 +161,12 @@ public function respondToAccessTokenRequest( } $privateClaims = []; if($this->claimRepository){ - $privateClaims = $this->claimRepository->getClaims(); + $privateClaims = $this->claimRepository->getClaims( + $privateClaims, + $this->getIdentifier(), + $client, + $authCodePayload->user_id + ); } // Issue and persist new access token diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index 87bef2dc2..329a3a8b9 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -50,7 +50,7 @@ public function respondToAccessTokenRequest( $privateClaims = []; if($this->claimRepository){ - $privateClaims = $this->claimRepository->getClaims(); + $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client); } // Issue and persist access token diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 7a906eac9..fb40bf646 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -188,7 +188,12 @@ public function completeAuthorizationRequest(AuthorizationRequest $authorization $privateClaims = []; if($this->claimRepository){ - $privateClaims = $this->claimRepository->getClaims(); + $privateClaims = $this->claimRepository->getClaims( + $privateClaims, + $this->getIdentifier(), + $authorizationRequest->getClient(), + $authorizationRequest->getUser()->getIdentifier() + ); } $accessToken = $this->issueAccessToken( diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 0d18249b4..420289f5c 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -58,7 +58,7 @@ public function respondToAccessTokenRequest( $privateClaims = []; if($this->claimRepository){ - $privateClaims = $this->claimRepository->getClaims(); + $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client, $user->getIdentifier()); } // Issue and persist new access token diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 4cbd6dc1c..6b5fe09e4 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -63,9 +63,14 @@ public function respondToAccessTokenRequest( $this->accessTokenRepository->revokeAccessToken($oldRefreshToken['access_token_id']); $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']); - $privateClaim = []; + $privateClaims = []; if($this->claimRepository){ - $privateClaim = $this->claimRepository->getClaims(); + $privateClaims = $this->claimRepository->getClaims( + $privateClaims, + $this->getIdentifier(), + $client, + $oldRefreshToken['user_id'] + ); } // Issue and persist new access token @@ -74,7 +79,7 @@ public function respondToAccessTokenRequest( $client, $oldRefreshToken['user_id'], $scopes, - $privateClaim + $privateClaims ); $this->getEmitter()->emit(new RequestEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request)); $responseType->setAccessToken($accessToken); diff --git a/src/Repositories/ClaimRepositoryInterface.php b/src/Repositories/ClaimRepositoryInterface.php index b2a73e2da..c25173851 100644 --- a/src/Repositories/ClaimRepositoryInterface.php +++ b/src/Repositories/ClaimRepositoryInterface.php @@ -10,6 +10,7 @@ namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\ClaimEntityInterface; +use League\OAuth2\Server\Entities\ClientEntityInterface; /** * Claim repository interface. @@ -22,5 +23,9 @@ interface ClaimRepositoryInterface extends RepositoryInterface * * @return ClaimEntityInterface[] */ - public function getClaims(); + public function getClaims( + array $claims, + $grantType, + ClientEntityInterface $clientEntity, + $userIdentifier = null); } From f6d5ed01d872250f9b06386400afede36a9e2acf Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 4 Jun 2020 16:10:25 +0200 Subject: [PATCH 03/36] Fixes styles --- src/Entities/Traits/AccessTokenTrait.php | 4 ++-- src/Entities/Traits/TokenEntityTrait.php | 2 -- src/Grant/AuthCodeGrant.php | 2 +- src/Grant/ClientCredentialsGrant.php | 2 +- src/Grant/ImplicitGrant.php | 2 +- src/Grant/PasswordGrant.php | 2 +- src/Repositories/AccessTokenRepositoryInterface.php | 4 ++-- 7 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Entities/Traits/AccessTokenTrait.php b/src/Entities/Traits/AccessTokenTrait.php index 101d3a782..4a65940d9 100644 --- a/src/Entities/Traits/AccessTokenTrait.php +++ b/src/Entities/Traits/AccessTokenTrait.php @@ -49,9 +49,9 @@ private function convertToJWT(CryptKey $privateKey) ->issuedAt(\time()) ->canOnlyBeUsedAfter(\time()) ->expiresAt($this->getExpiryDateTime()->getTimestamp()) - ->relatedTo((string)$this->getUserIdentifier()); + ->relatedTo((string) $this->getUserIdentifier()); - foreach ($this->getClaims() as $claim){ + foreach ($this->getClaims() as $claim) { $builder->withClaim($claim->getName(), $claim->getValue()); } diff --git a/src/Entities/Traits/TokenEntityTrait.php b/src/Entities/Traits/TokenEntityTrait.php index 93c3b8671..70aa178e4 100644 --- a/src/Entities/Traits/TokenEntityTrait.php +++ b/src/Entities/Traits/TokenEntityTrait.php @@ -81,8 +81,6 @@ public function getClaims() return $this->claims; } - - /** * Get the token's expiry date time. * diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 5650b7c33..e9114cef7 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -160,7 +160,7 @@ public function respondToAccessTokenRequest( } } $privateClaims = []; - if($this->claimRepository){ + if($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( $privateClaims, $this->getIdentifier(), diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index 329a3a8b9..108dfa2b0 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -49,7 +49,7 @@ public function respondToAccessTokenRequest( $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client); $privateClaims = []; - if($this->claimRepository){ + if($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client); } diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index fb40bf646..0c06e5260 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -187,7 +187,7 @@ public function completeAuthorizationRequest(AuthorizationRequest $authorization ); $privateClaims = []; - if($this->claimRepository){ + if($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( $privateClaims, $this->getIdentifier(), diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 420289f5c..9bc9e151c 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -57,7 +57,7 @@ public function respondToAccessTokenRequest( $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier()); $privateClaims = []; - if($this->claimRepository){ + if($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client, $user->getIdentifier()); } diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index 42a95e1f1..f414d9ca0 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -23,9 +23,9 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface /** * Create a new access token * - * @param ClientEntityInterface $clientEntity + * @param ClientEntityInterface $clientEntity * @param ScopeEntityInterface[] $scopes - * @param array $claims + * @param array $claims * @param ClaimEntityInterface[] $userIdentifier * * @return AccessTokenEntityInterface From 962506e44a302c5dc585520e9b1b194c206faa88 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 4 Jun 2020 16:42:23 +0200 Subject: [PATCH 04/36] Makes ClaimRepository optional in AuthorizationServer constructor. --- src/AuthorizationServer.php | 5 +++-- src/Grant/AbstractGrant.php | 2 +- src/Grant/GrantTypeInterface.php | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index ea4dcada1..8180f3ba1 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -94,15 +94,16 @@ class AuthorizationServer implements EmitterAwareInterface * @param CryptKey|string $privateKey * @param string|Key $encryptionKey * @param null|ResponseTypeInterface $responseType + * @param null|ClaimRepositoryInterface $claimRepository */ public function __construct( ClientRepositoryInterface $clientRepository, AccessTokenRepositoryInterface $accessTokenRepository, ScopeRepositoryInterface $scopeRepository, - ClaimRepositoryInterface $claimRepository, $privateKey, $encryptionKey, - ResponseTypeInterface $responseType = null + ResponseTypeInterface $responseType = null, + ClaimRepositoryInterface $claimRepository = null ) { $this->clientRepository = $clientRepository; $this->accessTokenRepository = $accessTokenRepository; diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index e2acc0b10..1e690a791 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -127,7 +127,7 @@ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository) /** * @param ClaimRepositoryInterface $claimRepository */ - public function setClaimRepository(ClaimRepositoryInterface $claimRepository) + public function setClaimRepository(?ClaimRepositoryInterface $claimRepository) { $this->claimRepository = $claimRepository; } diff --git a/src/Grant/GrantTypeInterface.php b/src/Grant/GrantTypeInterface.php index 7101adc18..a8fa77553 100644 --- a/src/Grant/GrantTypeInterface.php +++ b/src/Grant/GrantTypeInterface.php @@ -127,7 +127,7 @@ public function setScopeRepository(ScopeRepositoryInterface $scopeRepository); * * @param ClaimRepositoryInterface $claimRepository */ - public function setClaimRepository(ClaimRepositoryInterface $claimRepository); + public function setClaimRepository(?ClaimRepositoryInterface $claimRepository); /** * Set the default scope. From d2888f1d283151db463b4f73dee37f7580f7b7a5 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 4 Jun 2020 16:48:18 +0200 Subject: [PATCH 05/36] Fixes styles II --- src/Grant/AuthCodeGrant.php | 2 +- src/Grant/ClientCredentialsGrant.php | 2 +- src/Grant/ImplicitGrant.php | 2 +- src/Grant/PasswordGrant.php | 2 +- src/Grant/RefreshTokenGrant.php | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index e9114cef7..604f18fdf 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -160,7 +160,7 @@ public function respondToAccessTokenRequest( } } $privateClaims = []; - if($this->claimRepository) { + if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( $privateClaims, $this->getIdentifier(), diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index 108dfa2b0..a311dc844 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -49,7 +49,7 @@ public function respondToAccessTokenRequest( $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client); $privateClaims = []; - if($this->claimRepository) { + if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client); } diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index 0c06e5260..fafb2d8bf 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -187,7 +187,7 @@ public function completeAuthorizationRequest(AuthorizationRequest $authorization ); $privateClaims = []; - if($this->claimRepository) { + if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( $privateClaims, $this->getIdentifier(), diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 9bc9e151c..35e26a0ba 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -57,7 +57,7 @@ public function respondToAccessTokenRequest( $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier()); $privateClaims = []; - if($this->claimRepository) { + if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client, $user->getIdentifier()); } diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 6b5fe09e4..1ce000aa3 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -64,7 +64,7 @@ public function respondToAccessTokenRequest( $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']); $privateClaims = []; - if($this->claimRepository){ + if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( $privateClaims, $this->getIdentifier(), From 3630fc7a451c101b1b5506ad8b72d1281ec6f47a Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Fri, 5 Jun 2020 09:12:47 +0200 Subject: [PATCH 06/36] Adds testing for claims --- tests/Grant/AbstractGrantTest.php | 4 ++- tests/Grant/ClientCredentialsGrantTest.php | 5 +++ tests/Grant/ImplicitGrantTest.php | 5 +++ tests/Grant/PasswordGrantTest.php | 5 +++ tests/Grant/RefreshTokenGrantTest.php | 5 +++ .../ResponseTypes/BearerResponseTypeTest.php | 4 +++ tests/Stubs/ClaimEntity.php | 35 +++++++++++++++++++ 7 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 tests/Stubs/ClaimEntity.php diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 98a7f5f1b..80d9c9fc9 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -17,6 +17,7 @@ use League\OAuth2\Server\RequestTypes\AuthorizationRequest; use LeagueTests\Stubs\AccessTokenEntity; use LeagueTests\Stubs\AuthCodeEntity; +use LeagueTests\Stubs\ClaimEntity; use LeagueTests\Stubs\ClientEntity; use LeagueTests\Stubs\RefreshTokenEntity; use LeagueTests\Stubs\ScopeEntity; @@ -360,7 +361,8 @@ public function testIssueAccessToken() new DateInterval('PT1H'), new ClientEntity(), 123, - [new ScopeEntity()] + [new ScopeEntity()], + [new ClaimEntity('private', 'claim')] ); $this->assertInstanceOf(AccessTokenEntityInterface::class, $accessToken); } diff --git a/tests/Grant/ClientCredentialsGrantTest.php b/tests/Grant/ClientCredentialsGrantTest.php index a06db3ad9..762de2c5d 100644 --- a/tests/Grant/ClientCredentialsGrantTest.php +++ b/tests/Grant/ClientCredentialsGrantTest.php @@ -8,6 +8,7 @@ use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Grant\ClientCredentialsGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClaimRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; use LeagueTests\Stubs\AccessTokenEntity; @@ -43,10 +44,14 @@ public function testRespondToRequest() $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + $claimRepositoryMock = $this->getMockBuilder(ClaimRepositoryInterface::class)->getMock(); + $claimRepositoryMock->method('getClaims')->willReturn([]); + $grant = new ClientCredentialsGrant(); $grant->setClientRepository($clientRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); + $grant->setClaimRepository($claimRepositoryMock); $grant->setDefaultScope(self::DEFAULT_SCOPE); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); diff --git a/tests/Grant/ImplicitGrantTest.php b/tests/Grant/ImplicitGrantTest.php index 99fa3f57c..a22977a34 100644 --- a/tests/Grant/ImplicitGrantTest.php +++ b/tests/Grant/ImplicitGrantTest.php @@ -9,6 +9,7 @@ use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; use League\OAuth2\Server\Grant\ImplicitGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClaimRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; @@ -282,10 +283,14 @@ public function testAccessTokenRepositoryUniqueConstraintCheck() $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + $claimRepositoryMock = $this->getMockBuilder(ClaimRepositoryInterface::class)->getMock(); + $claimRepositoryMock->method('getClaims')->willReturn([]); + $grant = new ImplicitGrant(new \DateInterval('PT10M')); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); + $grant->setClaimRepository($claimRepositoryMock); $this->assertInstanceOf(RedirectResponse::class, $grant->completeAuthorizationRequest($authRequest)); } diff --git a/tests/Grant/PasswordGrantTest.php b/tests/Grant/PasswordGrantTest.php index a9720b8bf..74673463d 100644 --- a/tests/Grant/PasswordGrantTest.php +++ b/tests/Grant/PasswordGrantTest.php @@ -9,6 +9,7 @@ use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Grant\PasswordGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClaimRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; @@ -57,10 +58,14 @@ public function testRespondToRequest() $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scope); $scopeRepositoryMock->method('finalizeScopes')->willReturnArgument(0); + $claimRepositoryMock = $this->getMockBuilder(ClaimRepositoryInterface::class)->getMock(); + $claimRepositoryMock->method('getClaims')->willReturn([]); + $grant = new PasswordGrant($userRepositoryMock, $refreshTokenRepositoryMock); $grant->setClientRepository($clientRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); + $grant->setClaimRepository($claimRepositoryMock); $grant->setDefaultScope(self::DEFAULT_SCOPE); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index cd71544f3..b7d6e7fa9 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -9,6 +9,7 @@ use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Grant\RefreshTokenGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; +use League\OAuth2\Server\Repositories\ClaimRepositoryInterface; use League\OAuth2\Server\Repositories\ClientRepositoryInterface; use League\OAuth2\Server\Repositories\RefreshTokenRepositoryInterface; use League\OAuth2\Server\Repositories\ScopeRepositoryInterface; @@ -52,6 +53,9 @@ public function testRespondToRequest() $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $claimRepositoryMock = $this->getMockBuilder(ClaimRepositoryInterface::class)->getMock(); + $claimRepositoryMock->method('getClaims')->willReturn([]); + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); $accessTokenRepositoryMock->expects($this->once())->method('persistNewAccessToken')->willReturnSelf(); @@ -63,6 +67,7 @@ public function testRespondToRequest() $grant = new RefreshTokenGrant($refreshTokenRepositoryMock); $grant->setClientRepository($clientRepositoryMock); $grant->setScopeRepository($scopeRepositoryMock); + $grant->setClaimRepository($claimRepositoryMock); $grant->setAccessTokenRepository($accessTokenRepositoryMock); $grant->setEncryptionKey($this->cryptStub->getKey()); $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 6dc24ff3b..ed257c304 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -12,6 +12,7 @@ use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; use League\OAuth2\Server\ResponseTypes\BearerTokenResponse; use LeagueTests\Stubs\AccessTokenEntity; +use LeagueTests\Stubs\ClaimEntity; use LeagueTests\Stubs\ClientEntity; use LeagueTests\Stubs\RefreshTokenEntity; use LeagueTests\Stubs\ScopeEntity; @@ -32,11 +33,14 @@ public function testGenerateHttpResponse() $scope = new ScopeEntity(); $scope->setIdentifier('basic'); + $claim = new ClaimEntity('_private', 'claim'); + $accessToken = new AccessTokenEntity(); $accessToken->setIdentifier('abcdef'); $accessToken->setExpiryDateTime((new DateTimeImmutable())->add(new DateInterval('PT1H'))); $accessToken->setClient($client); $accessToken->addScope($scope); + $accessToken->addClaim($claim); $accessToken->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); $refreshToken = new RefreshTokenEntity(); diff --git a/tests/Stubs/ClaimEntity.php b/tests/Stubs/ClaimEntity.php new file mode 100644 index 000000000..29c62de44 --- /dev/null +++ b/tests/Stubs/ClaimEntity.php @@ -0,0 +1,35 @@ +name = $name; + $this->value = $value; + } + + public function getName() + { + return $this->name; + } + + public function getValue() + { + return $this->value; + } + + public function jsonSerialize() + { + return ['name' => $this->name, 'value' => $this->value]; + } +} \ No newline at end of file From 108b1ee552cf18b4179b88d763a6135ac708079f Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Fri, 5 Jun 2020 09:15:21 +0200 Subject: [PATCH 07/36] Fixes style of claim entity stub --- tests/Stubs/ClaimEntity.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Stubs/ClaimEntity.php b/tests/Stubs/ClaimEntity.php index 29c62de44..9a8f92014 100644 --- a/tests/Stubs/ClaimEntity.php +++ b/tests/Stubs/ClaimEntity.php @@ -3,12 +3,10 @@ namespace LeagueTests\Stubs; - use League\OAuth2\Server\Entities\ClaimEntityInterface; class ClaimEntity implements ClaimEntityInterface { - private $name; private $value; From 8dd31f5d2522bfd65712bbfa52141ab020d96a15 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Fri, 5 Jun 2020 09:28:36 +0200 Subject: [PATCH 08/36] Fixes phpstan errors --- src/AuthorizationServer.php | 2 +- src/Grant/AbstractGrant.php | 2 +- src/Repositories/AccessTokenRepositoryInterface.php | 4 ++-- tests/Stubs/ClaimEntity.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/AuthorizationServer.php b/src/AuthorizationServer.php index 8180f3ba1..64f464387 100644 --- a/src/AuthorizationServer.php +++ b/src/AuthorizationServer.php @@ -71,7 +71,7 @@ class AuthorizationServer implements EmitterAwareInterface private $scopeRepository; /** - * @var ClaimRepositoryInterface + * @var null|ClaimRepositoryInterface */ private $claimRepository; diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 1e690a791..e0424498e 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -65,7 +65,7 @@ abstract class AbstractGrant implements GrantTypeInterface protected $scopeRepository; /** - * @var ClaimRepositoryInterface + * @var null|ClaimRepositoryInterface */ protected $claimRepository; diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index f414d9ca0..43daaa00d 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -25,8 +25,8 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface * * @param ClientEntityInterface $clientEntity * @param ScopeEntityInterface[] $scopes - * @param array $claims - * @param ClaimEntityInterface[] $userIdentifier + * @param string|null $userIdentifier + * @param ClaimEntityInterface[] $claims * * @return AccessTokenEntityInterface */ diff --git a/tests/Stubs/ClaimEntity.php b/tests/Stubs/ClaimEntity.php index 9a8f92014..1d536dd80 100644 --- a/tests/Stubs/ClaimEntity.php +++ b/tests/Stubs/ClaimEntity.php @@ -30,4 +30,4 @@ public function jsonSerialize() { return ['name' => $this->name, 'value' => $this->value]; } -} \ No newline at end of file +} From 12d864338c961536cf894cbdd6789f43278b3972 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 16 Jul 2020 23:31:57 +0200 Subject: [PATCH 09/36] Removes unused JsonSerializable interface --- src/Entities/ClaimEntityInterface.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Entities/ClaimEntityInterface.php b/src/Entities/ClaimEntityInterface.php index 0fd97440a..c5fc2c20d 100644 --- a/src/Entities/ClaimEntityInterface.php +++ b/src/Entities/ClaimEntityInterface.php @@ -9,9 +9,7 @@ namespace League\OAuth2\Server\Entities; -use JsonSerializable; - -interface ClaimEntityInterface extends JsonSerializable +interface ClaimEntityInterface { /** * Get the claim's name. From d6d45d9a30718b4db9b352cf5468da8a61f1bd7a Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 16 Jul 2020 23:33:46 +0200 Subject: [PATCH 10/36] Adds ClaimEntityTrait --- src/Entities/Traits/ClaimEntityTrait.php | 43 ++++++++++++++++++++++++ tests/Stubs/ClaimEntity.php | 19 ++--------- 2 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 src/Entities/Traits/ClaimEntityTrait.php diff --git a/src/Entities/Traits/ClaimEntityTrait.php b/src/Entities/Traits/ClaimEntityTrait.php new file mode 100644 index 000000000..5afe59350 --- /dev/null +++ b/src/Entities/Traits/ClaimEntityTrait.php @@ -0,0 +1,43 @@ + + * @copyright Copyright (c) Sebastian Kroczek + * @license http://mit-license.org/ + * + * @link https://github.com/thephpleague/oauth2-server + */ + +namespace League\OAuth2\Server\Entities\Traits; + +trait ClaimEntityTrait +{ + /** + * @var string + */ + protected $name; + + /** + * @var mixed + */ + protected $value; + + /** + * Returns the name of the claim + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Returns the claims value + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } +} diff --git a/tests/Stubs/ClaimEntity.php b/tests/Stubs/ClaimEntity.php index 1d536dd80..00281595d 100644 --- a/tests/Stubs/ClaimEntity.php +++ b/tests/Stubs/ClaimEntity.php @@ -4,30 +4,15 @@ namespace LeagueTests\Stubs; use League\OAuth2\Server\Entities\ClaimEntityInterface; +use League\OAuth2\Server\Entities\Traits\ClaimEntityTrait; class ClaimEntity implements ClaimEntityInterface { - private $name; - private $value; + use ClaimEntityTrait; public function __construct($name, $value) { $this->name = $name; $this->value = $value; } - - public function getName() - { - return $this->name; - } - - public function getValue() - { - return $this->value; - } - - public function jsonSerialize() - { - return ['name' => $this->name, 'value' => $this->value]; - } } From ba02f3b435795a98d6c5170c4f8e4d8921aa3412 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 16 Jul 2020 23:38:23 +0200 Subject: [PATCH 11/36] Removes useless claim parameter --- src/Grant/AuthCodeGrant.php | 1 - src/Grant/ClientCredentialsGrant.php | 2 +- src/Grant/ImplicitGrant.php | 1 - src/Grant/PasswordGrant.php | 2 +- src/Grant/RefreshTokenGrant.php | 1 - src/Repositories/ClaimRepositoryInterface.php | 6 ++++-- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 604f18fdf..3629035a9 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -162,7 +162,6 @@ public function respondToAccessTokenRequest( $privateClaims = []; if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( - $privateClaims, $this->getIdentifier(), $client, $authCodePayload->user_id diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index a311dc844..a76e177d6 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -50,7 +50,7 @@ public function respondToAccessTokenRequest( $privateClaims = []; if ($this->claimRepository) { - $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client); + $privateClaims = $this->claimRepository->getClaims($this->getIdentifier(), $client); } // Issue and persist access token diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index fafb2d8bf..a11983327 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -189,7 +189,6 @@ public function completeAuthorizationRequest(AuthorizationRequest $authorization $privateClaims = []; if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( - $privateClaims, $this->getIdentifier(), $authorizationRequest->getClient(), $authorizationRequest->getUser()->getIdentifier() diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 35e26a0ba..509d76e4e 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -58,7 +58,7 @@ public function respondToAccessTokenRequest( $privateClaims = []; if ($this->claimRepository) { - $privateClaims = $this->claimRepository->getClaims($privateClaims, $this->getIdentifier(), $client, $user->getIdentifier()); + $privateClaims = $this->claimRepository->getClaims($this->getIdentifier(), $client, $user->getIdentifier()); } // Issue and persist new access token diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 1ce000aa3..64f630652 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -66,7 +66,6 @@ public function respondToAccessTokenRequest( $privateClaims = []; if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( - $privateClaims, $this->getIdentifier(), $client, $oldRefreshToken['user_id'] diff --git a/src/Repositories/ClaimRepositoryInterface.php b/src/Repositories/ClaimRepositoryInterface.php index c25173851..55f689f7e 100644 --- a/src/Repositories/ClaimRepositoryInterface.php +++ b/src/Repositories/ClaimRepositoryInterface.php @@ -20,12 +20,14 @@ interface ClaimRepositoryInterface extends RepositoryInterface /** * Returns claims * + * @param string $grantType + * @param ClientEntityInterface $clientEntity + * @param string|null $userIdentifier * * @return ClaimEntityInterface[] */ public function getClaims( - array $claims, - $grantType, + string $grantType, ClientEntityInterface $clientEntity, $userIdentifier = null); } From 7ac954bacfa70ad7c77d0ed335936427eb411202 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 16 Jul 2020 23:40:36 +0200 Subject: [PATCH 12/36] Removes confusing ClaimEntity argument --- tests/Grant/AbstractGrantTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index 80d9c9fc9..b976743e0 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -7,6 +7,7 @@ use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\AuthCodeEntityInterface; +use League\OAuth2\Server\Entities\ClaimEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Grant\AbstractGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; @@ -362,7 +363,7 @@ public function testIssueAccessToken() new ClientEntity(), 123, [new ScopeEntity()], - [new ClaimEntity('private', 'claim')] + [] ); $this->assertInstanceOf(AccessTokenEntityInterface::class, $accessToken); } From c659a196668b8d552cde8ae28238a6386fadea54 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 16 Jul 2020 23:42:40 +0200 Subject: [PATCH 13/36] Asserts that the claim has been set --- tests/ResponseTypes/BearerResponseTypeTest.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index ed257c304..94af505ba 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -33,7 +33,7 @@ public function testGenerateHttpResponse() $scope = new ScopeEntity(); $scope->setIdentifier('basic'); - $claim = new ClaimEntity('_private', 'claim'); + $claim = new ClaimEntity('_private', [42]); $accessToken = new AccessTokenEntity(); $accessToken->setIdentifier('abcdef'); @@ -65,6 +65,12 @@ public function testGenerateHttpResponse() $this->assertObjectHasAttribute('expires_in', $json); $this->assertObjectHasAttribute('access_token', $json); $this->assertObjectHasAttribute('refresh_token', $json); + // Extract payload from access token + $payload = \json_decode(\base64_decode(\explode('.',$json->access_token)[1])); + $this->assertObjectHasAttribute('_private', $payload); + $this->assertIsArray($payload->_private); + $this->assertCount(1, $payload->_private); + $this->assertEquals(42, $payload->_private[0]); } public function testGenerateHttpResponseWithExtraParams() From 8e1473c87e0b2e57438eb8f58db569137071da8b Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Fri, 17 Jul 2020 00:07:09 +0200 Subject: [PATCH 14/36] Fixes cs --- tests/Grant/AbstractGrantTest.php | 2 -- tests/ResponseTypes/BearerResponseTypeTest.php | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Grant/AbstractGrantTest.php b/tests/Grant/AbstractGrantTest.php index b976743e0..127c77fc6 100644 --- a/tests/Grant/AbstractGrantTest.php +++ b/tests/Grant/AbstractGrantTest.php @@ -7,7 +7,6 @@ use League\OAuth2\Server\CryptKey; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; use League\OAuth2\Server\Entities\AuthCodeEntityInterface; -use League\OAuth2\Server\Entities\ClaimEntityInterface; use League\OAuth2\Server\Entities\RefreshTokenEntityInterface; use League\OAuth2\Server\Grant\AbstractGrant; use League\OAuth2\Server\Repositories\AccessTokenRepositoryInterface; @@ -18,7 +17,6 @@ use League\OAuth2\Server\RequestTypes\AuthorizationRequest; use LeagueTests\Stubs\AccessTokenEntity; use LeagueTests\Stubs\AuthCodeEntity; -use LeagueTests\Stubs\ClaimEntity; use LeagueTests\Stubs\ClientEntity; use LeagueTests\Stubs\RefreshTokenEntity; use LeagueTests\Stubs\ScopeEntity; diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index 94af505ba..c97a59e8f 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -66,7 +66,7 @@ public function testGenerateHttpResponse() $this->assertObjectHasAttribute('access_token', $json); $this->assertObjectHasAttribute('refresh_token', $json); // Extract payload from access token - $payload = \json_decode(\base64_decode(\explode('.',$json->access_token)[1])); + $payload = \json_decode(\base64_decode(\explode('.', $json->access_token)[1])); $this->assertObjectHasAttribute('_private', $payload); $this->assertIsArray($payload->_private); $this->assertCount(1, $payload->_private); From 7256a3cf04ac60945a5952e084f52e058ec31a3d Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Fri, 17 Jul 2020 00:17:32 +0200 Subject: [PATCH 15/36] Fixes phpstan error --- tests/ResponseTypes/BearerResponseTypeTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/ResponseTypes/BearerResponseTypeTest.php b/tests/ResponseTypes/BearerResponseTypeTest.php index c97a59e8f..9574e3e41 100644 --- a/tests/ResponseTypes/BearerResponseTypeTest.php +++ b/tests/ResponseTypes/BearerResponseTypeTest.php @@ -66,7 +66,9 @@ public function testGenerateHttpResponse() $this->assertObjectHasAttribute('access_token', $json); $this->assertObjectHasAttribute('refresh_token', $json); // Extract payload from access token - $payload = \json_decode(\base64_decode(\explode('.', $json->access_token)[1])); + $payloadString = \base64_decode(\explode('.', $json->access_token)[1]); + $this->assertTrue(\is_string($payloadString)); + $payload = \json_decode($payloadString); $this->assertObjectHasAttribute('_private', $payload); $this->assertIsArray($payload->_private); $this->assertCount(1, $payload->_private); From f0a3e971671da091188bc35028caf5d925f33f03 Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Thu, 23 Jul 2020 20:04:13 +0200 Subject: [PATCH 16/36] Adds and uses TokenInterface::addClaim() method and removes $claims parameter from AccessTokenRepositoryInterface::getNewToken() method --- examples/src/Repositories/AccessTokenRepository.php | 6 +----- src/Entities/TokenInterface.php | 7 +++++++ src/Grant/AbstractGrant.php | 5 ++++- src/Repositories/AccessTokenRepositoryInterface.php | 5 +---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/examples/src/Repositories/AccessTokenRepository.php b/examples/src/Repositories/AccessTokenRepository.php index 4842c448e..6b9177f25 100644 --- a/examples/src/Repositories/AccessTokenRepository.php +++ b/examples/src/Repositories/AccessTokenRepository.php @@ -46,14 +46,10 @@ public function isAccessTokenRevoked($tokenId) public function getNewToken( ClientEntityInterface $clientEntity, array $scopes, - $userIdentifier = null, - array $claims = [] + $userIdentifier = null ) { $accessToken = new AccessTokenEntity(); $accessToken->setClient($clientEntity); - foreach ($claims as $claim) { - $accessToken->addClaim($claim); - } foreach ($scopes as $scope) { $accessToken->addScope($scope); } diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index fca80fdb1..6ad20c747 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -83,6 +83,13 @@ public function addScope(ScopeEntityInterface $scope); */ public function getScopes(); + /** + * Associate a claim with the token. + * + * @param ClaimEntityInterface $claim + */ + public function addClaim(ClaimEntityInterface $claim); + /** * Return an array of claims associated with the token. * diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index e0424498e..fe6832625 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -450,9 +450,12 @@ protected function issueAccessToken( ) { $maxGenerationAttempts = self::MAX_RANDOM_TOKEN_GENERATION_ATTEMPTS; - $accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier, $claims); + $accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier); $accessToken->setExpiryDateTime((new DateTimeImmutable())->add($accessTokenTTL)); $accessToken->setPrivateKey($this->privateKey); + foreach ($claims as $claim) { + $accessToken->addClaim($claim); + } while ($maxGenerationAttempts-- > 0) { $accessToken->setIdentifier($this->generateUniqueIdentifier()); diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index 43daaa00d..ba2b35402 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -10,7 +10,6 @@ namespace League\OAuth2\Server\Repositories; use League\OAuth2\Server\Entities\AccessTokenEntityInterface; -use League\OAuth2\Server\Entities\ClaimEntityInterface; use League\OAuth2\Server\Entities\ClientEntityInterface; use League\OAuth2\Server\Entities\ScopeEntityInterface; use League\OAuth2\Server\Exception\UniqueTokenIdentifierConstraintViolationException; @@ -26,15 +25,13 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface * @param ClientEntityInterface $clientEntity * @param ScopeEntityInterface[] $scopes * @param string|null $userIdentifier - * @param ClaimEntityInterface[] $claims * * @return AccessTokenEntityInterface */ public function getNewToken( ClientEntityInterface $clientEntity, array $scopes, - $userIdentifier = null, - array $claims = [] + $userIdentifier = null ); /** From 381e4158b1c84c0a191c7a3954115afc596e3892 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 12:44:04 +0100 Subject: [PATCH 17/36] Revert formatting change --- examples/src/Repositories/AccessTokenRepository.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/src/Repositories/AccessTokenRepository.php b/examples/src/Repositories/AccessTokenRepository.php index 6b9177f25..19b8bd377 100644 --- a/examples/src/Repositories/AccessTokenRepository.php +++ b/examples/src/Repositories/AccessTokenRepository.php @@ -43,11 +43,7 @@ public function isAccessTokenRevoked($tokenId) /** * {@inheritdoc} */ - public function getNewToken( - ClientEntityInterface $clientEntity, - array $scopes, - $userIdentifier = null - ) { + public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null) { $accessToken = new AccessTokenEntity(); $accessToken->setClient($clientEntity); foreach ($scopes as $scope) { From 1db5e24d373fb60f93886ad7c5f1aa77cf882d35 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 12:46:35 +0100 Subject: [PATCH 18/36] Fix formatting issue --- examples/src/Repositories/AccessTokenRepository.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/src/Repositories/AccessTokenRepository.php b/examples/src/Repositories/AccessTokenRepository.php index 19b8bd377..d7736c763 100644 --- a/examples/src/Repositories/AccessTokenRepository.php +++ b/examples/src/Repositories/AccessTokenRepository.php @@ -43,7 +43,8 @@ public function isAccessTokenRevoked($tokenId) /** * {@inheritdoc} */ - public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null) { + public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null) + { $accessToken = new AccessTokenEntity(); $accessToken->setClient($clientEntity); foreach ($scopes as $scope) { From 9891fdb365e190f835d931a441303abcb94264dd Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 13:51:33 +0100 Subject: [PATCH 19/36] Add blank line above block --- src/Grant/AbstractGrant.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index fe6832625..d6ea3911d 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -453,6 +453,7 @@ protected function issueAccessToken( $accessToken = $this->accessTokenRepository->getNewToken($client, $scopes, $userIdentifier); $accessToken->setExpiryDateTime((new DateTimeImmutable())->add($accessTokenTTL)); $accessToken->setPrivateKey($this->privateKey); + foreach ($claims as $claim) { $accessToken->addClaim($claim); } From e8b1942a025b3d3b05b09b547904627bde9700ad Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 13:53:21 +0100 Subject: [PATCH 20/36] Fix formatting and make if check more explicit --- src/Grant/AuthCodeGrant.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 3629035a9..e032a6db5 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -159,8 +159,10 @@ public function respondToAccessTokenRequest( } } } + $privateClaims = []; - if ($this->claimRepository) { + + if ($this->claimRepository !== null) { $privateClaims = $this->claimRepository->getClaims( $this->getIdentifier(), $client, From 970ef401054e570c7a9f88336908e43bd2b8e7a6 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 13:55:30 +0100 Subject: [PATCH 21/36] Fix formatting and make if check more explicit --- src/Grant/ClientCredentialsGrant.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Grant/ClientCredentialsGrant.php b/src/Grant/ClientCredentialsGrant.php index a76e177d6..b4c096b95 100644 --- a/src/Grant/ClientCredentialsGrant.php +++ b/src/Grant/ClientCredentialsGrant.php @@ -49,7 +49,8 @@ public function respondToAccessTokenRequest( $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client); $privateClaims = []; - if ($this->claimRepository) { + + if ($this->claimRepository !== null) { $privateClaims = $this->claimRepository->getClaims($this->getIdentifier(), $client); } From 5bd812792acd7c36bc44734a66c09cd8991127a6 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 13:57:46 +0100 Subject: [PATCH 22/36] Fix formatting and make if check more explicit --- src/Grant/ImplicitGrant.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Grant/ImplicitGrant.php b/src/Grant/ImplicitGrant.php index a11983327..6daacf528 100644 --- a/src/Grant/ImplicitGrant.php +++ b/src/Grant/ImplicitGrant.php @@ -187,7 +187,8 @@ public function completeAuthorizationRequest(AuthorizationRequest $authorization ); $privateClaims = []; - if ($this->claimRepository) { + + if ($this->claimRepository !== null) { $privateClaims = $this->claimRepository->getClaims( $this->getIdentifier(), $authorizationRequest->getClient(), From 162a02e79046f909ecdd2c154839bdd96e9ae254 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 13:59:05 +0100 Subject: [PATCH 23/36] Fix formatting and make if check more explicit --- src/Grant/PasswordGrant.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 509d76e4e..aa656b140 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -57,7 +57,8 @@ public function respondToAccessTokenRequest( $finalizedScopes = $this->scopeRepository->finalizeScopes($scopes, $this->getIdentifier(), $client, $user->getIdentifier()); $privateClaims = []; - if ($this->claimRepository) { + + if ($this->claimRepository !== null) { $privateClaims = $this->claimRepository->getClaims($this->getIdentifier(), $client, $user->getIdentifier()); } From 88b57057fc7b24b1014925826d4f6e13b19eb355 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 13:59:52 +0100 Subject: [PATCH 24/36] Fix formatting and make if check more explicit --- src/Grant/RefreshTokenGrant.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 64f630652..51692b776 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -64,6 +64,7 @@ public function respondToAccessTokenRequest( $this->refreshTokenRepository->revokeRefreshToken($oldRefreshToken['refresh_token_id']); $privateClaims = []; + if ($this->claimRepository) { $privateClaims = $this->claimRepository->getClaims( $this->getIdentifier(), From 1842975b52b0042e6215de9013c27d5e414806f5 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 14:00:08 +0100 Subject: [PATCH 25/36] Fix formatting and make if check more explicit --- src/Grant/RefreshTokenGrant.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 51692b776..c63662906 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -65,7 +65,7 @@ public function respondToAccessTokenRequest( $privateClaims = []; - if ($this->claimRepository) { + if ($this->claimRepository !== null) { $privateClaims = $this->claimRepository->getClaims( $this->getIdentifier(), $client, From 74a934e7921f83053925df40ff443f70888c0f55 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 14:06:50 +0100 Subject: [PATCH 26/36] Revert docblock hint change as not required for this PR --- src/Repositories/AccessTokenRepositoryInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index ba2b35402..7a3b57920 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -24,7 +24,7 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface * * @param ClientEntityInterface $clientEntity * @param ScopeEntityInterface[] $scopes - * @param string|null $userIdentifier + * @param mixed $userIdentifier * * @return AccessTokenEntityInterface */ From 40fed670c31f00d0b70c3c465b3449b099eb34f4 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Mon, 27 Jul 2020 14:11:55 +0100 Subject: [PATCH 27/36] Revert formatting change --- src/Repositories/AccessTokenRepositoryInterface.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Repositories/AccessTokenRepositoryInterface.php b/src/Repositories/AccessTokenRepositoryInterface.php index 7a3b57920..72ddf1f4c 100644 --- a/src/Repositories/AccessTokenRepositoryInterface.php +++ b/src/Repositories/AccessTokenRepositoryInterface.php @@ -28,11 +28,7 @@ interface AccessTokenRepositoryInterface extends RepositoryInterface * * @return AccessTokenEntityInterface */ - public function getNewToken( - ClientEntityInterface $clientEntity, - array $scopes, - $userIdentifier = null - ); + public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null); /** * Persists a new access token to permanent storage. From d2400529527105a5a08aeb1980aba25829858aef Mon Sep 17 00:00:00 2001 From: Sebastian Kroczek Date: Mon, 27 Jul 2020 20:41:52 +0200 Subject: [PATCH 28/36] Changes copyright --- src/Entities/ClaimEntityInterface.php | 2 +- src/Entities/Traits/ClaimEntityTrait.php | 2 +- src/Repositories/ClaimRepositoryInterface.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Entities/ClaimEntityInterface.php b/src/Entities/ClaimEntityInterface.php index c5fc2c20d..2c45ed5ee 100644 --- a/src/Entities/ClaimEntityInterface.php +++ b/src/Entities/ClaimEntityInterface.php @@ -1,7 +1,7 @@ - * @copyright Copyright (c) Sebastian Kroczek + * @copyright Copyright (c) Alex Bilbie * @license http://mit-license.org/ * * @link https://github.com/thephpleague/oauth2-server diff --git a/src/Entities/Traits/ClaimEntityTrait.php b/src/Entities/Traits/ClaimEntityTrait.php index 5afe59350..2aeb71a90 100644 --- a/src/Entities/Traits/ClaimEntityTrait.php +++ b/src/Entities/Traits/ClaimEntityTrait.php @@ -1,7 +1,7 @@ - * @copyright Copyright (c) Sebastian Kroczek + * @copyright Copyright (c) Alex Bilbie * @license http://mit-license.org/ * * @link https://github.com/thephpleague/oauth2-server diff --git a/src/Repositories/ClaimRepositoryInterface.php b/src/Repositories/ClaimRepositoryInterface.php index 55f689f7e..dca1d460e 100644 --- a/src/Repositories/ClaimRepositoryInterface.php +++ b/src/Repositories/ClaimRepositoryInterface.php @@ -1,7 +1,7 @@ - * @copyright Copyright (c) Sebastian Kroczek + * @copyright Copyright (c) Alex Bilbie * @license http://mit-license.org/ * * @link https://github.com/thephpleague/oauth2-server From 6bcff56a742c2ca45d197e7c36fbdcca51520d3b Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 30 Sep 2020 12:28:55 +0100 Subject: [PATCH 29/36] StyleCI fix --- src/Repositories/ClaimRepositoryInterface.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Repositories/ClaimRepositoryInterface.php b/src/Repositories/ClaimRepositoryInterface.php index dca1d460e..5d716fd9a 100644 --- a/src/Repositories/ClaimRepositoryInterface.php +++ b/src/Repositories/ClaimRepositoryInterface.php @@ -29,5 +29,6 @@ interface ClaimRepositoryInterface extends RepositoryInterface public function getClaims( string $grantType, ClientEntityInterface $clientEntity, - $userIdentifier = null); + $userIdentifier = null + ); } From 568c787469262446446d1dec2546477f955dde7d Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Wed, 30 Sep 2020 12:43:57 +0100 Subject: [PATCH 30/36] Apply StyleCI change --- src/Grant/PasswordGrant.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Grant/PasswordGrant.php b/src/Grant/PasswordGrant.php index 14df2f425..51ada3c72 100644 --- a/src/Grant/PasswordGrant.php +++ b/src/Grant/PasswordGrant.php @@ -57,7 +57,8 @@ public function respondToAccessTokenRequest( $scopes, $this->getIdentifier(), $client, - $user->getIdentifier()); + $user->getIdentifier() + ); $privateClaims = []; From 0aef818d9cd4443be353aa35646c04dbbd56bdf8 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 1 Oct 2020 10:06:18 +0100 Subject: [PATCH 31/36] Fix test --- tests/Grant/RefreshTokenGrantTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index 1808d6764..b71da9484 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -479,7 +479,11 @@ public function testRespondToRequestRevokedToken() public function testRespondToRequestFinalizeScopes() { $client = new ClientEntity(); + $client->setIdentifier('foo'); + $client->setRedirectUri('http://foo/bar'); + + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); $clientRepositoryMock->method('getClientEntity')->willReturn($client); From d43c63c39a0afc9b1efb0f43f4c5abfd87387529 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 1 Oct 2020 10:10:27 +0100 Subject: [PATCH 32/36] StyleCI fixes --- tests/Grant/RefreshTokenGrantTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index b71da9484..8febaa2f7 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -481,7 +481,7 @@ public function testRespondToRequestFinalizeScopes() $client = new ClientEntity(); $client->setIdentifier('foo'); - $client->setRedirectUri('http://foo/bar'); + $client->setRedirectUri('http://foo/bar'); $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); From 5a71aaf1fd697c27a8194a1139c8fb921fd10313 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 1 Oct 2020 10:17:16 +0100 Subject: [PATCH 33/36] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69fe55c1d..5168f9214 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - A CryptKeyInterface to allow developers to change the CryptKey implementation with greater ease (PR #1044) - The authorization server can now finalize scopes when a client uses a refresh token (PR #1094) - An AuthorizationRequestInterface to make it easier to extend the AuthorizationRequest (PR #1110) +- Ability to set custom claims on a JWT (PR #1122) ### Added - Add a `getRedirectUri` function to the `OAuthServerException` class (PR #1123) From 1d79e35d4d55e95f9b8be95dd966f0deff744068 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 1 Oct 2020 10:37:28 +0100 Subject: [PATCH 34/36] Remove getClaims and addClaim from TokenInterface --- src/Entities/TokenInterface.php | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/Entities/TokenInterface.php b/src/Entities/TokenInterface.php index 6ad20c747..7b063e138 100644 --- a/src/Entities/TokenInterface.php +++ b/src/Entities/TokenInterface.php @@ -82,18 +82,4 @@ public function addScope(ScopeEntityInterface $scope); * @return ScopeEntityInterface[] */ public function getScopes(); - - /** - * Associate a claim with the token. - * - * @param ClaimEntityInterface $claim - */ - public function addClaim(ClaimEntityInterface $claim); - - /** - * Return an array of claims associated with the token. - * - * @return ClaimEntityInterface[] - */ - public function getClaims(); } From 671041275bad7acd4e9dc216fc6f8047e11d5080 Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 1 Oct 2020 11:11:35 +0100 Subject: [PATCH 35/36] Add method exists for addClaim on token --- src/Grant/AbstractGrant.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 774557996..0b3aeba87 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -454,8 +454,10 @@ protected function issueAccessToken( $accessToken->setExpiryDateTime((new DateTimeImmutable())->add($accessTokenTTL)); $accessToken->setPrivateKey($this->privateKey); - foreach ($claims as $claim) { - $accessToken->addClaim($claim); + if (method_exists($accessToken, 'addClaim')) { + foreach ($claims as $claim) { + $accessToken->addClaim($claim); + } } while ($maxGenerationAttempts-- > 0) { From 030214128a2813376fbdfa699e3394c5d1277f6d Mon Sep 17 00:00:00 2001 From: Andrew Millington Date: Thu, 1 Oct 2020 11:14:18 +0100 Subject: [PATCH 36/36] StyleCI fixes --- src/Grant/AbstractGrant.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 0b3aeba87..c77330e26 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -454,7 +454,7 @@ protected function issueAccessToken( $accessToken->setExpiryDateTime((new DateTimeImmutable())->add($accessTokenTTL)); $accessToken->setPrivateKey($this->privateKey); - if (method_exists($accessToken, 'addClaim')) { + if (\method_exists($accessToken, 'addClaim')) { foreach ($claims as $claim) { $accessToken->addClaim($claim); }