Skip to content

Commit 38112e9

Browse files
[13.x] Fix determining revoked records (#1751)
* fix is revoked * formatting
1 parent 57931ae commit 38112e9

File tree

5 files changed

+184
-44
lines changed

5 files changed

+184
-44
lines changed

src/Bridge/AuthCodeRepository.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ public function revokeAuthCode(string $codeId): void
4848
*/
4949
public function isAuthCodeRevoked(string $codeId): bool
5050
{
51-
return Passport::authCode()->where('id', $codeId)->where('revoked', 1)->exists();
51+
return Passport::authCode()->where('id', $codeId)->where('revoked', 0)->doesntExist();
5252
}
5353
}

src/RefreshTokenRepository.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ public function revokeRefreshTokensByAccessTokenId($tokenId)
6767
*/
6868
public function isRefreshTokenRevoked($id)
6969
{
70-
if ($token = $this->find($id)) {
71-
return $token->revoked;
72-
}
73-
74-
return true;
70+
return Passport::refreshToken()->where('id', $id)->where('revoked', 0)->doesntExist();
7571
}
7672
}

src/TokenRepository.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,7 @@ public function revokeAccessToken($id)
9797
*/
9898
public function isAccessTokenRevoked($id)
9999
{
100-
if ($token = $this->find($id)) {
101-
return $token->revoked;
102-
}
103-
104-
return true;
100+
return Passport::token()->where('id', $id)->where('revoked', 0)->doesntExist();
105101
}
106102

107103
/**

tests/Feature/RevokedTest.php

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
<?php
2+
3+
use Carbon\CarbonImmutable;
4+
use Laravel\Passport\Bridge\AccessToken;
5+
use Laravel\Passport\Bridge\AccessTokenRepository as BridgeAccessTokenRepository;
6+
use Laravel\Passport\Bridge\AuthCode;
7+
use Laravel\Passport\Bridge\AuthCodeRepository as BridgeAuthCodeRepository;
8+
use Laravel\Passport\Bridge\RefreshToken;
9+
use Laravel\Passport\Bridge\RefreshTokenRepository as BridgeRefreshTokenRepository;
10+
use Laravel\Passport\RefreshTokenRepository;
11+
use Laravel\Passport\Tests\Feature\PassportTestCase;
12+
use Laravel\Passport\TokenRepository;
13+
use Mockery as m;
14+
use Orchestra\Testbench\Concerns\WithLaravelMigrations;
15+
16+
class RevokedTest extends PassportTestCase
17+
{
18+
use WithLaravelMigrations;
19+
20+
public function test_it_can_determine_if_a_access_token_is_revoked()
21+
{
22+
$repository = $this->accessTokenRepository();
23+
$this->persistNewAccessToken($repository, 'tokenId');
24+
25+
$repository->revokeAccessToken('tokenId');
26+
27+
$this->assertTrue($repository->isAccessTokenRevoked('tokenId'));
28+
}
29+
30+
public function test_a_access_token_is_also_revoked_if_it_cannot_be_found()
31+
{
32+
$repository = $this->accessTokenRepository();
33+
34+
$this->assertTrue($repository->isAccessTokenRevoked('notExistingTokenId'));
35+
}
36+
37+
public function test_it_can_determine_if_a_access_token_is_not_revoked()
38+
{
39+
$repository = $this->accessTokenRepository();
40+
$this->persistNewAccessToken($repository, 'tokenId');
41+
42+
$this->assertFalse($repository->isAccessTokenRevoked('tokenId'));
43+
}
44+
45+
public function test_it_can_determine_if_a_auth_code_is_revoked()
46+
{
47+
$repository = $this->authCodeRepository();
48+
$this->persistNewAuthCode($repository, 'tokenId');
49+
50+
$repository->revokeAuthCode('tokenId');
51+
52+
$this->assertTrue($repository->isAuthCodeRevoked('tokenId'));
53+
}
54+
55+
public function test_a_auth_code_is_also_revoked_if_it_cannot_be_found()
56+
{
57+
$repository = $this->authCodeRepository();
58+
59+
$this->assertTrue($repository->isAuthCodeRevoked('notExistingTokenId'));
60+
}
61+
62+
public function test_it_can_determine_if_a_auth_code_is_not_revoked()
63+
{
64+
$repository = $this->authCodeRepository();
65+
$this->persistNewAuthCode($repository, 'tokenId');
66+
67+
$this->assertFalse($repository->isAuthCodeRevoked('tokenId'));
68+
}
69+
70+
public function test_it_can_determine_if_a_refresh_token_is_revoked()
71+
{
72+
$repository = $this->refreshTokenRepository();
73+
$this->persistNewRefreshToken($repository, 'tokenId');
74+
75+
$repository->revokeRefreshToken('tokenId');
76+
77+
$this->assertTrue($repository->isRefreshTokenRevoked('tokenId'));
78+
}
79+
80+
public function test_a_refresh_token_is_also_revoked_if_it_cannot_be_found()
81+
{
82+
$repository = $this->refreshTokenRepository();
83+
84+
$this->assertTrue($repository->isRefreshTokenRevoked('notExistingTokenId'));
85+
}
86+
87+
public function test_it_can_determine_if_a_refresh_token_is_not_revoked()
88+
{
89+
$repository = $this->refreshTokenRepository();
90+
$this->persistNewRefreshToken($repository, 'tokenId');
91+
92+
$this->assertFalse($repository->isRefreshTokenRevoked('tokenId'));
93+
}
94+
95+
private function accessTokenRepository(): BridgeAccessTokenRepository
96+
{
97+
$events = m::mock('Illuminate\Contracts\Events\Dispatcher');
98+
$events->shouldReceive('dispatch');
99+
100+
return new BridgeAccessTokenRepository(new TokenRepository, $events);
101+
}
102+
103+
private function persistNewAccessToken(BridgeAccessTokenRepository $repository, string $id): void
104+
{
105+
$accessToken = m::mock(AccessToken::class);
106+
$accessToken->shouldReceive('getIdentifier')->andReturn($id);
107+
$accessToken->shouldReceive('getUserIdentifier')->andReturn('1');
108+
$accessToken->shouldReceive('getClient->getIdentifier')->andReturn('clientId');
109+
$accessToken->shouldReceive('getScopes')->andReturn([]);
110+
$accessToken->shouldReceive('getExpiryDateTime')->andReturn(CarbonImmutable::now());
111+
112+
$repository->persistNewAccessToken($accessToken);
113+
}
114+
115+
private function authCodeRepository(): BridgeAuthCodeRepository
116+
{
117+
return new BridgeAuthCodeRepository;
118+
}
119+
120+
private function persistNewAuthCode(BridgeAuthCodeRepository $repository, string $id): void
121+
{
122+
$authCode = m::mock(AuthCode::class);
123+
$authCode->shouldReceive('getIdentifier')->andReturn($id);
124+
$authCode->shouldReceive('getUserIdentifier')->andReturn('1');
125+
$authCode->shouldReceive('getClient->getIdentifier')->andReturn('clientId');
126+
$authCode->shouldReceive('getExpiryDateTime')->andReturn(CarbonImmutable::now());
127+
$authCode->shouldReceive('getScopes')->andReturn([]);
128+
129+
$repository->persistNewAuthCode($authCode);
130+
}
131+
132+
private function refreshTokenRepository(): BridgeRefreshTokenRepository
133+
{
134+
$events = m::mock('Illuminate\Contracts\Events\Dispatcher');
135+
$events->shouldReceive('dispatch');
136+
137+
return new BridgeRefreshTokenRepository(new RefreshTokenRepository, $events);
138+
}
139+
140+
private function persistNewRefreshToken(BridgeRefreshTokenRepository $repository, string $id): void
141+
{
142+
$refreshToken = m::mock(RefreshToken::class);
143+
$refreshToken->shouldReceive('getIdentifier')->andReturn($id);
144+
$refreshToken->shouldReceive('getAccessToken->getIdentifier')->andReturn('accessTokenId');
145+
$refreshToken->shouldReceive('getExpiryDateTime')->andReturn(CarbonImmutable::now());
146+
147+
$repository->persistNewRefreshToken($refreshToken);
148+
}
149+
}

tests/Unit/BridgeRefreshTokenRepositoryTest.php

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
namespace Laravel\Passport\Tests\Unit;
44

5+
use Carbon\CarbonImmutable;
6+
use Illuminate\Contracts\Events\Dispatcher;
7+
use Laravel\Passport\Bridge\AccessToken;
8+
use Laravel\Passport\Bridge\Client;
9+
use Laravel\Passport\Bridge\RefreshToken;
510
use Laravel\Passport\Bridge\RefreshTokenRepository as BridgeRefreshTokenRepository;
611
use Laravel\Passport\RefreshTokenRepository;
712
use Mockery as m;
@@ -14,49 +19,43 @@ protected function tearDown(): void
1419
m::close();
1520
}
1621

17-
public function test_it_can_determine_if_a_refresh_token_is_revoked()
22+
public function test_access_tokens_can_be_persisted()
1823
{
19-
$refreshToken = new RevokedRefreshToken;
20-
$repository = $this->repository($refreshToken);
24+
$expiration = CarbonImmutable::now();
2125

22-
$this->assertTrue($repository->isRefreshTokenRevoked('tokenId'));
23-
}
26+
$refreshTokenRepository = m::mock(RefreshTokenRepository::class);
27+
$events = m::mock(Dispatcher::class);
2428

25-
public function test_a_refresh_token_is_also_revoked_if_it_cannot_be_found()
26-
{
27-
$refreshToken = null;
28-
$repository = $this->repository($refreshToken);
29+
$refreshTokenRepository->shouldReceive('create')->once()->andReturnUsing(function ($array) use ($expiration) {
30+
$this->assertEquals('1', $array['id']);
31+
$this->assertEquals('2', $array['access_token_id']);
32+
$this->assertFalse($array['revoked']);
33+
$this->assertEquals($expiration, $array['expires_at']);
34+
});
2935

30-
$this->assertTrue($repository->isRefreshTokenRevoked('tokenId'));
31-
}
36+
$events->shouldReceive('dispatch')->once();
3237

33-
public function test_it_can_determine_if_a_refresh_token_is_not_revoked()
34-
{
35-
$refreshToken = new ActiveRefreshToken;
36-
$repository = $this->repository($refreshToken);
38+
$accessToken = new AccessToken('3', [], m::mock(Client::class));
39+
$accessToken->setIdentifier('2');
40+
41+
$refreshToken = new RefreshToken;
42+
$refreshToken->setIdentifier('1');
43+
$refreshToken->setExpiryDateTime($expiration);
44+
$refreshToken->setAccessToken($accessToken);
45+
46+
$repository = new BridgeRefreshTokenRepository($refreshTokenRepository, $events);
3747

38-
$this->assertFalse($repository->isRefreshTokenRevoked('tokenId'));
48+
$repository->persistNewRefreshToken($refreshToken);
3949
}
4050

41-
private function repository($refreshToken): BridgeRefreshTokenRepository
51+
public function test_can_get_new_refresh_token()
4252
{
43-
$refreshTokenRepository = m::mock(RefreshTokenRepository::class)->makePartial();
44-
$refreshTokenRepository->shouldReceive('find')
45-
->with('tokenId')
46-
->andReturn($refreshToken);
53+
$refreshTokenRepository = m::mock(RefreshTokenRepository::class);
54+
$events = m::mock(Dispatcher::class);
55+
$repository = new BridgeRefreshTokenRepository($refreshTokenRepository, $events);
4756

48-
$events = m::mock('Illuminate\Contracts\Events\Dispatcher');
57+
$token = $repository->getNewRefreshToken();
4958

50-
return new BridgeRefreshTokenRepository($refreshTokenRepository, $events);
59+
$this->assertInstanceOf(RefreshToken::class, $token);
5160
}
5261
}
53-
54-
class ActiveRefreshToken
55-
{
56-
public $revoked = false;
57-
}
58-
59-
class RevokedRefreshToken
60-
{
61-
public $revoked = true;
62-
}

0 commit comments

Comments
 (0)