From d5419d58cbbc41c8e6691ed6e1b51713151c174c Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Thu, 8 Aug 2024 09:26:37 -0400 Subject: [PATCH 1/4] Fix refresh token int user ID --- src/Grant/RefreshTokenGrant.php | 2 +- tests/Grant/RefreshTokenGrantTest.php | 64 +++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index a632990c7..42cef93d4 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -78,7 +78,7 @@ public function respondToAccessTokenRequest( } // Issue and persist new access token - $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $oldRefreshToken['user_id'], $scopes); + $accessToken = $this->issueAccessToken($accessTokenTTL, $client, (string)$oldRefreshToken['user_id'], $scopes); $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request, $accessToken)); $responseType->setAccessToken($accessToken); diff --git a/tests/Grant/RefreshTokenGrantTest.php b/tests/Grant/RefreshTokenGrantTest.php index b37001a80..0b1f090fa 100644 --- a/tests/Grant/RefreshTokenGrantTest.php +++ b/tests/Grant/RefreshTokenGrantTest.php @@ -734,4 +734,68 @@ public function testUnrevokedRefreshToken(): void self::assertFalse($refreshTokenRepositoryMock->isRefreshTokenRevoked($refreshTokenId)); } + + public function testRespondToRequestWithIntUserId(): void + { + $client = new ClientEntity(); + $client->setIdentifier('foo'); + $client->setRedirectUri('http://foo/bar'); + + $clientRepositoryMock = $this->getMockBuilder(ClientRepositoryInterface::class)->getMock(); + $clientRepositoryMock->method('getClientEntity')->willReturn($client); + $clientRepositoryMock->method('validateClient')->willReturn(true); + + $scopeEntity = new ScopeEntity(); + $scopeEntity->setIdentifier('foo'); + $scopeRepositoryMock = $this->getMockBuilder(ScopeRepositoryInterface::class)->getMock(); + $scopeRepositoryMock->method('getScopeEntityByIdentifier')->willReturn($scopeEntity); + $scopeRepositoryMock->method('finalizeScopes')->willReturn([$scopeEntity]); + + $accessTokenRepositoryMock = $this->getMockBuilder(AccessTokenRepositoryInterface::class)->getMock(); + $accessTokenRepositoryMock->method('getNewToken')->willReturn(new AccessTokenEntity()); + $accessTokenRepositoryMock->expects(self::once())->method('persistNewAccessToken')->willReturnSelf(); + + $refreshTokenRepositoryMock = $this->getMockBuilder(RefreshTokenRepositoryInterface::class)->getMock(); + $refreshTokenRepositoryMock->method('getNewRefreshToken')->willReturn(new RefreshTokenEntity()); + $refreshTokenRepositoryMock->expects(self::once())->method('persistNewRefreshToken')->willReturnSelf(); + + $grant = new RefreshTokenGrant($refreshTokenRepositoryMock); + $grant->setClientRepository($clientRepositoryMock); + $grant->setScopeRepository($scopeRepositoryMock); + $grant->setAccessTokenRepository($accessTokenRepositoryMock); + $grant->setEncryptionKey($this->cryptStub->getKey()); + $grant->setPrivateKey(new CryptKey('file://' . __DIR__ . '/../Stubs/private.key')); + $grant->revokeRefreshTokens(true); + + $oldRefreshToken = json_encode( + [ + 'client_id' => 'foo', + 'refresh_token_id' => 'zyxwvu', + 'access_token_id' => 'abcdef', + 'scopes' => ['foo'], + 'user_id' => 123, + 'expire_time' => time() + 3600, + ] + ); + + if ($oldRefreshToken === false) { + self::fail('json_encode failed'); + } + + $encryptedOldRefreshToken = $this->cryptStub->doEncrypt( + $oldRefreshToken + ); + + $serverRequest = (new ServerRequest())->withParsedBody([ + 'client_id' => 'foo', + 'client_secret' => 'bar', + 'refresh_token' => $encryptedOldRefreshToken, + 'scopes' => ['foo'], + ]); + + $responseType = new StubResponseType(); + $grant->respondToAccessTokenRequest($serverRequest, $responseType, new DateInterval('PT5M')); + + self::assertInstanceOf(RefreshTokenEntityInterface::class, $responseType->getRefreshToken()); + } } From 113bb14daca8f03b74bb6113c38b49e4f7a9b3b9 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Thu, 8 Aug 2024 09:30:05 -0400 Subject: [PATCH 2/4] Prevent casing null user ID to string --- src/Grant/RefreshTokenGrant.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 42cef93d4..3a9516097 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -78,7 +78,10 @@ public function respondToAccessTokenRequest( } // Issue and persist new access token - $accessToken = $this->issueAccessToken($accessTokenTTL, $client, (string)$oldRefreshToken['user_id'], $scopes); + $userId = $oldRefreshToken['user_id']; + if (is_int($userId)) + $userId = (string)$userId; + $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $userId, $scopes); $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request, $accessToken)); $responseType->setAccessToken($accessToken); From e0d630c99bb0d3b9b6d99186690e1b2ff0e608b6 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Thu, 8 Aug 2024 09:30:53 -0400 Subject: [PATCH 3/4] Fix coding style --- src/Grant/RefreshTokenGrant.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Grant/RefreshTokenGrant.php b/src/Grant/RefreshTokenGrant.php index 3a9516097..f0488d3d8 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -79,8 +79,9 @@ public function respondToAccessTokenRequest( // Issue and persist new access token $userId = $oldRefreshToken['user_id']; - if (is_int($userId)) + if (is_int($userId)) { $userId = (string)$userId; + } $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $userId, $scopes); $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request, $accessToken)); $responseType->setAccessToken($accessToken); From c406da5818388f3c6b7b5539a0ccf67ed1702ce2 Mon Sep 17 00:00:00 2001 From: Stephen Sigwart Date: Thu, 8 Aug 2024 09:31:26 -0400 Subject: [PATCH 4/4] More code style fixes --- 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 f0488d3d8..35de791fb 100644 --- a/src/Grant/RefreshTokenGrant.php +++ b/src/Grant/RefreshTokenGrant.php @@ -80,7 +80,7 @@ public function respondToAccessTokenRequest( // Issue and persist new access token $userId = $oldRefreshToken['user_id']; if (is_int($userId)) { - $userId = (string)$userId; + $userId = (string) $userId; } $accessToken = $this->issueAccessToken($accessTokenTTL, $client, $userId, $scopes); $this->getEmitter()->emit(new RequestAccessTokenEvent(RequestEvent::ACCESS_TOKEN_ISSUED, $request, $accessToken));