diff --git a/UPGRADE.md b/UPGRADE.md index 790b9ff31..79c7817b5 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -26,6 +26,12 @@ Passport now always hashes client secrets using Laravel's `Hash` facade. If you In light of this change, the `Passport::$hashesClientSecrets` property and `Passport::hashClientSecrets()` method has been removed. +### The User's Token Instance + +PR: https://github.com/laravel/passport/pull/1755 + +When authenticating users via bearer tokens, the `User` model's `token` method now returns an instance of `Laravel\Passport\AccessToken` class instead of `Laravel\Passport\Token`. + ### Personal Access Client Table and Model Removal PR: https://github.com/laravel/passport/pull/1749 diff --git a/src/AccessToken.php b/src/AccessToken.php new file mode 100644 index 000000000..33c54a59e --- /dev/null +++ b/src/AccessToken.php @@ -0,0 +1,131 @@ + + */ + protected array $attributes = []; + + /** + * Create a new access token instance. + * + * @param array $attributes + */ + public function __construct(array $attributes = []) + { + foreach ($attributes as $key => $value) { + $this->attributes[$key] = $value; + } + } + + /** + * Create a new access token instance from the incoming PSR-7 request. + */ + public static function fromPsrRequest(ServerRequestInterface $request): static + { + return new static($request->getAttributes()); + } + + /** + * Determine if the token has a given scope. + */ + public function can(string $scope): bool + { + if (in_array('*', $this->oauth_scopes)) { + return true; + } + + $scopes = Passport::$withInheritedScopes + ? $this->resolveInheritedScopes($scope) + : [$scope]; + + foreach ($scopes as $scope) { + if (array_key_exists($scope, array_flip($this->oauth_scopes))) { + return true; + } + } + + return false; + } + + /** + * Determine if the token is missing a given scope. + */ + public function cant(string $scope): bool + { + return ! $this->can($scope); + } + + /** + * Determine if the token is a transient JWT token. + */ + public function transient(): bool + { + return false; + } + + /** + * Revoke the token instance. + */ + public function revoke(): bool + { + return Passport::token()->whereKey($this->oauth_access_token_id)->forceFill(['revoked' => true])->save(); + } + + /** + * Get the token instance. + */ + protected function getToken(): ?Token + { + return $this->token ??= Passport::token()->find($this->oauth_access_token_id); + } + + /** + * Dynamically determine if an attribute is set. + */ + public function __isset(string $key): bool + { + return isset($this->attributes[$key]) || isset($this->getToken()?->{$key}); + } + + /** + * Dynamically retrieve the value of an attribute. + */ + public function __get(string $key) + { + if (array_key_exists($key, $this->attributes)) { + return $this->attributes[$key]; + } + + return $this->getToken()?->{$key}; + } + + /** + * Pass dynamic methods onto the token instance. + */ + public function __call(string $method, array $parameters): mixed + { + return $this->forwardCallTo($this->getToken(), $method, $parameters); + } +} diff --git a/src/Guards/TokenGuard.php b/src/Guards/TokenGuard.php index fe067e800..eecbbc240 100644 --- a/src/Guards/TokenGuard.php +++ b/src/Guards/TokenGuard.php @@ -14,6 +14,7 @@ use Illuminate\Cookie\Middleware\EncryptCookies; use Illuminate\Http\Request; use Illuminate\Support\Traits\Macroable; +use Laravel\Passport\AccessToken; use Laravel\Passport\Client; use Laravel\Passport\ClientRepository; use Laravel\Passport\Passport; @@ -203,9 +204,7 @@ protected function authenticateViaBearerToken($request) // Next, we will assign a token instance to this user which the developers may use // to determine if the token has a given scope, etc. This will be useful during // authorization such as within the developer's Laravel model policy classes. - $token = $this->tokens->find( - $psr->getAttribute('oauth_access_token_id') - ); + $token = AccessToken::fromPsrRequest($psr); return $token ? $user->withAccessToken($token) : null; } diff --git a/src/HasApiTokens.php b/src/HasApiTokens.php index e1479cc2c..463c5728f 100644 --- a/src/HasApiTokens.php +++ b/src/HasApiTokens.php @@ -9,7 +9,7 @@ trait HasApiTokens /** * The current access token for the authentication user. * - * @var \Laravel\Passport\Token|\Laravel\Passport\TransientToken|null + * @var \Laravel\Passport\AccessToken|\Laravel\Passport\TransientToken|null */ protected $accessToken; @@ -36,7 +36,7 @@ public function tokens() /** * Get the current access token being used by the user. * - * @return \Laravel\Passport\Token|\Laravel\Passport\TransientToken|null + * @return \Laravel\Passport\AccessToken|\Laravel\Passport\TransientToken|null */ public function token() { @@ -71,7 +71,7 @@ public function createToken($name, array $scopes = []) /** * Set the current access token for the user. * - * @param \Laravel\Passport\Token|\Laravel\Passport\TransientToken|null $accessToken + * @param \Laravel\Passport\AccessToken|\Laravel\Passport\TransientToken|null $accessToken * @return $this */ public function withAccessToken($accessToken) diff --git a/src/Http/Middleware/CheckClientCredentials.php b/src/Http/Middleware/CheckClientCredentials.php index 25644dd24..49180afa8 100644 --- a/src/Http/Middleware/CheckClientCredentials.php +++ b/src/Http/Middleware/CheckClientCredentials.php @@ -10,7 +10,7 @@ class CheckClientCredentials extends CheckCredentials /** * Validate token credentials. * - * @param \Laravel\Passport\Token $token + * @param \Laravel\Passport\AccessToken $token * @return void * * @throws \Laravel\Passport\Exceptions\AuthenticationException @@ -25,7 +25,7 @@ protected function validateCredentials($token) /** * Validate token credentials. * - * @param \Laravel\Passport\Token $token + * @param \Laravel\Passport\AccessToken $token * @param array $scopes * @return void * @@ -33,7 +33,7 @@ protected function validateCredentials($token) */ protected function validateScopes($token, $scopes) { - if (in_array('*', $token->scopes)) { + if (in_array('*', $token->oauth_scopes)) { return; } diff --git a/src/Http/Middleware/CheckClientCredentialsForAnyScope.php b/src/Http/Middleware/CheckClientCredentialsForAnyScope.php index 8da32bf19..cb9467b00 100644 --- a/src/Http/Middleware/CheckClientCredentialsForAnyScope.php +++ b/src/Http/Middleware/CheckClientCredentialsForAnyScope.php @@ -10,7 +10,7 @@ class CheckClientCredentialsForAnyScope extends CheckCredentials /** * Validate token credentials. * - * @param \Laravel\Passport\Token $token + * @param \Laravel\Passport\AccessToken $token * @return void * * @throws \Laravel\Passport\Exceptions\AuthenticationException @@ -25,7 +25,7 @@ protected function validateCredentials($token) /** * Validate token credentials. * - * @param \Laravel\Passport\Token $token + * @param \Laravel\Passport\AccessToken $token * @param array $scopes * @return void * @@ -33,7 +33,7 @@ protected function validateCredentials($token) */ protected function validateScopes($token, $scopes) { - if (in_array('*', $token->scopes)) { + if (in_array('*', $token->oauth_scopes)) { return; } diff --git a/src/Http/Middleware/CheckCredentials.php b/src/Http/Middleware/CheckCredentials.php index 5d7d9273f..1965003f2 100644 --- a/src/Http/Middleware/CheckCredentials.php +++ b/src/Http/Middleware/CheckCredentials.php @@ -3,6 +3,7 @@ namespace Laravel\Passport\Http\Middleware; use Closure; +use Laravel\Passport\AccessToken; use Laravel\Passport\Exceptions\AuthenticationException; use Laravel\Passport\TokenRepository; use League\OAuth2\Server\Exception\OAuthServerException; @@ -95,7 +96,7 @@ public function handle($request, Closure $next, ...$scopes) */ protected function validate($psr, $scopes) { - $token = $this->repository->find($psr->getAttribute('oauth_access_token_id')); + $token = AccessToken::fromPsrRequest($psr); $this->validateCredentials($token); @@ -105,7 +106,7 @@ protected function validate($psr, $scopes) /** * Validate token credentials. * - * @param \Laravel\Passport\Token $token + * @param \Laravel\Passport\AccessToken $token * @return void * * @throws \Laravel\Passport\Exceptions\AuthenticationException @@ -115,7 +116,7 @@ abstract protected function validateCredentials($token); /** * Validate token scopes. * - * @param \Laravel\Passport\Token $token + * @param \Laravel\Passport\AccessToken $token * @param array $scopes * @return void * diff --git a/src/Passport.php b/src/Passport.php index b47221b30..c9599ea62 100644 --- a/src/Passport.php +++ b/src/Passport.php @@ -368,9 +368,10 @@ public static function ignoreCsrfToken($ignoreCsrfToken = true) */ public static function actingAs($user, $scopes = [], $guard = 'api') { - $token = app(self::tokenModel()); - - $token->scopes = $scopes; + $token = new AccessToken([ + 'oauth_user_id' => $user->getKey(), + 'oauth_scopes' => $scopes, + ]); $user->withAccessToken($token); @@ -395,28 +396,15 @@ public static function actingAs($user, $scopes = [], $guard = 'api') */ public static function actingAsClient($client, $scopes = [], $guard = 'api') { - $token = app(self::tokenModel()); - - $token->client_id = $client->getKey(); - $token->setRelation('client', $client); - - $token->scopes = $scopes; - $mock = Mockery::mock(ResourceServer::class); $mock->shouldReceive('validateAuthenticatedRequest') - ->andReturnUsing(function (ServerRequestInterface $request) use ($token) { - return $request->withAttribute('oauth_client_id', $token->client->id) - ->withAttribute('oauth_access_token_id', $token->id) - ->withAttribute('oauth_scopes', $token->scopes); + ->andReturnUsing(function (ServerRequestInterface $request) use ($client, $scopes) { + return $request->withAttribute('oauth_client_id', $client->getKey()) + ->withAttribute('oauth_scopes', $scopes); }); app()->instance(ResourceServer::class, $mock); - $mock = Mockery::mock(TokenRepository::class); - $mock->shouldReceive('find')->andReturn($token); - - app()->instance(TokenRepository::class, $mock); - app('auth')->guard($guard)->setClient($client); app('auth')->shouldUse($guard); diff --git a/src/Token.php b/src/Token.php index 248a33bb4..c78be4a9d 100644 --- a/src/Token.php +++ b/src/Token.php @@ -6,8 +6,6 @@ class Token extends Model { - use ResolvesInheritedScopes; - /** * The database table used by the model. * @@ -81,42 +79,6 @@ public function user() return $this->belongsTo($model, 'user_id', (new $model)->getKeyName()); } - /** - * Determine if the token has a given scope. - * - * @param string $scope - * @return bool - */ - public function can($scope) - { - if (in_array('*', $this->scopes)) { - return true; - } - - $scopes = Passport::$withInheritedScopes - ? $this->resolveInheritedScopes($scope) - : [$scope]; - - foreach ($scopes as $scope) { - if (array_key_exists($scope, array_flip($this->scopes))) { - return true; - } - } - - return false; - } - - /** - * Determine if the token is missing a given scope. - * - * @param string $scope - * @return bool - */ - public function cant($scope) - { - return ! $this->can($scope); - } - /** * Revoke the token instance. * @@ -127,16 +89,6 @@ public function revoke() return $this->forceFill(['revoked' => true])->save(); } - /** - * Determine if the token is a transient JWT token. - * - * @return bool - */ - public function transient() - { - return false; - } - /** * Get the current connection name for the model. * diff --git a/src/TransientToken.php b/src/TransientToken.php index 8d22bb899..54652a4ca 100644 --- a/src/TransientToken.php +++ b/src/TransientToken.php @@ -6,32 +6,24 @@ class TransientToken { /** * Determine if the token has a given scope. - * - * @param string $scope - * @return bool */ - public function can($scope) + public function can(string $scope): bool { return true; } /** * Determine if the token is missing a given scope. - * - * @param string $scope - * @return bool */ - public function cant($scope) + public function cant(string $scope): bool { return false; } /** * Determine if the token is a transient JWT token. - * - * @return bool */ - public function transient() + public function transient(): bool { return true; } diff --git a/tests/Unit/TokenTest.php b/tests/Unit/AccessTokenTest.php similarity index 60% rename from tests/Unit/TokenTest.php rename to tests/Unit/AccessTokenTest.php index ec207319b..771dcbe17 100644 --- a/tests/Unit/TokenTest.php +++ b/tests/Unit/AccessTokenTest.php @@ -2,12 +2,12 @@ namespace Laravel\Passport\Tests\Unit; +use Laravel\Passport\AccessToken; use Laravel\Passport\Passport; -use Laravel\Passport\Token; use PHPUnit\Framework\TestCase; use ReflectionObject; -class TokenTest extends TestCase +class AccessTokenTest extends TestCase { protected function tearDown(): void { @@ -16,9 +16,34 @@ protected function tearDown(): void Passport::$withInheritedScopes = false; } + public function test_token_attributes_are_accessible() + { + $token = new AccessToken([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 2, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => ['*'], + 'foo' => 'bar', + ]); + + $this->assertFalse($token->transient()); + + $this->assertSame(1, $token->oauth_user_id); + $this->assertSame(2, $token->oauth_client_id); + $this->assertSame('token', $token->oauth_access_token_id); + $this->assertSame(['*'], $token->oauth_scopes); + $this->assertSame('bar', $token->foo); + + $this->assertTrue(isset($token->oauth_user_id)); + $this->assertTrue(isset($token->oauth_client_id)); + $this->assertTrue(isset($token->oauth_access_token_id)); + $this->assertTrue(isset($token->oauth_scopes)); + $this->assertTrue(isset($token->foo)); + } + public function test_token_can_determine_if_it_has_scopes() { - $token = new Token(['scopes' => ['user']]); + $token = new AccessToken(['oauth_scopes' => ['user']]); $this->assertTrue($token->can('user')); $this->assertFalse($token->can('something')); @@ -27,7 +52,7 @@ public function test_token_can_determine_if_it_has_scopes() $this->assertTrue($token->cant('user:read')); - $token = new Token(['scopes' => ['*']]); + $token = new AccessToken(['oauth_scopes' => ['*']]); $this->assertTrue($token->can('user')); $this->assertTrue($token->can('something')); } @@ -36,8 +61,8 @@ public function test_token_can_determine_if_it_has_inherited_scopes() { Passport::$withInheritedScopes = true; - $token = new Token([ - 'scopes' => [ + $token = new AccessToken([ + 'oauth_scopes' => [ 'user', 'group', 'admin:webhooks:read', @@ -54,7 +79,7 @@ public function test_token_can_determine_if_it_has_inherited_scopes() $this->assertFalse($token->can('something')); - $token = new Token(['scopes' => ['*']]); + $token = new AccessToken(['oauth_scopes' => ['*']]); $this->assertTrue($token->can('user')); $this->assertTrue($token->can('something')); $this->assertTrue($token->can('admin:webhooks:write')); @@ -62,7 +87,7 @@ public function test_token_can_determine_if_it_has_inherited_scopes() public function test_token_resolves_inherited_scopes() { - $token = new Token; + $token = new AccessToken; $reflector = new ReflectionObject($token); $method = $reflector->getMethod('resolveInheritedScopes'); diff --git a/tests/Unit/CheckClientCredentialsForAnyScopeTest.php b/tests/Unit/CheckClientCredentialsForAnyScopeTest.php index 58ddd9f23..bd93a24cd 100644 --- a/tests/Unit/CheckClientCredentialsForAnyScopeTest.php +++ b/tests/Unit/CheckClientCredentialsForAnyScopeTest.php @@ -3,10 +3,8 @@ namespace Laravel\Passport\Tests\Unit; use Illuminate\Http\Request; -use Laravel\Passport\Client; use Laravel\Passport\Exceptions\AuthenticationException; use Laravel\Passport\Http\Middleware\CheckClientCredentialsForAnyScope; -use Laravel\Passport\Token; use Laravel\Passport\TokenRepository; use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\ResourceServer; @@ -25,20 +23,14 @@ public function test_request_is_passed_along_if_token_is_valid() { $resourceServer = m::mock(ResourceServer::class); $resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock(ServerRequestInterface::class)); - $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); - $psr->shouldReceive('getAttribute')->with('oauth_scopes')->andReturn(['*']); - - $client = m::mock(Client::class); - $client->shouldReceive('firstParty')->andReturnFalse(); - - $token = m::mock(Token::class); - $token->shouldReceive('getAttribute')->with('client')->andReturn($client); - $token->shouldReceive('getAttribute')->with('scopes')->andReturn(['*']); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => ['*'], + ]); $tokenRepository = m::mock(TokenRepository::class); - $tokenRepository->shouldReceive('find')->with('token')->andReturn($token); $middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository); @@ -56,22 +48,14 @@ public function test_request_is_passed_along_if_token_has_any_required_scope() { $resourceServer = m::mock(ResourceServer::class); $resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock(ServerRequestInterface::class)); - $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); - $psr->shouldReceive('getAttribute')->with('oauth_scopes')->andReturn(['foo', 'bar', 'baz']); - - $client = m::mock(Client::class); - $client->shouldReceive('firstParty')->andReturnFalse(); - - $token = m::mock(Token::class); - $token->shouldReceive('getAttribute')->with('client')->andReturn($client); - $token->shouldReceive('getAttribute')->with('scopes')->andReturn(['foo', 'bar', 'baz']); - $token->shouldReceive('can')->with('notfoo')->andReturnFalse(); - $token->shouldReceive('can')->with('bar')->andReturnTrue(); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => ['foo', 'bar', 'baz'], + ]); $tokenRepository = m::mock(TokenRepository::class); - $tokenRepository->shouldReceive('find')->with('token')->andReturn($token); $middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository); @@ -111,22 +95,14 @@ public function test_exception_is_thrown_if_token_does_not_have_required_scope() $resourceServer = m::mock(ResourceServer::class); $resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock(ServerRequestInterface::class)); - $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); - $psr->shouldReceive('getAttribute')->with('oauth_scopes')->andReturn(['foo', 'bar']); - - $client = m::mock(Client::class); - $client->shouldReceive('firstParty')->andReturnFalse(); - - $token = m::mock(Token::class); - $token->shouldReceive('getAttribute')->with('client')->andReturn($client); - $token->shouldReceive('getAttribute')->with('scopes')->andReturn(['foo', 'bar']); - $token->shouldReceive('can')->with('baz')->andReturnFalse(); - $token->shouldReceive('can')->with('notbar')->andReturnFalse(); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => ['foo', 'bar'], + ]); $tokenRepository = m::mock(TokenRepository::class); - $tokenRepository->shouldReceive('find')->with('token')->andReturn($token); $middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository); diff --git a/tests/Unit/CheckClientCredentialsTest.php b/tests/Unit/CheckClientCredentialsTest.php index 8c002a490..45dcd8133 100644 --- a/tests/Unit/CheckClientCredentialsTest.php +++ b/tests/Unit/CheckClientCredentialsTest.php @@ -3,10 +3,8 @@ namespace Laravel\Passport\Tests\Unit; use Illuminate\Http\Request; -use Laravel\Passport\Client; use Laravel\Passport\Exceptions\AuthenticationException; use Laravel\Passport\Http\Middleware\CheckClientCredentials; -use Laravel\Passport\Token; use Laravel\Passport\TokenRepository; use League\OAuth2\Server\Exception\OAuthServerException; use League\OAuth2\Server\ResourceServer; @@ -25,20 +23,14 @@ public function test_request_is_passed_along_if_token_is_valid() { $resourceServer = m::mock(ResourceServer::class); $resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock(ServerRequestInterface::class)); - $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); - $psr->shouldReceive('getAttribute')->with('oauth_scopes')->andReturn(['*']); - - $client = m::mock(Client::class); - $client->shouldReceive('firstParty')->andReturnFalse(); - - $token = m::mock(Token::class); - $token->shouldReceive('getAttribute')->with('client')->andReturn($client); - $token->shouldReceive('getAttribute')->with('scopes')->andReturn(['*']); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => ['*'], + ]); $tokenRepository = m::mock(TokenRepository::class); - $tokenRepository->shouldReceive('find')->with('token')->andReturn($token); $middleware = new CheckClientCredentials($resourceServer, $tokenRepository); @@ -56,21 +48,14 @@ public function test_request_is_passed_along_if_token_and_scope_are_valid() { $resourceServer = m::mock(ResourceServer::class); $resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock(ServerRequestInterface::class)); - $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); - $psr->shouldReceive('getAttribute')->with('oauth_scopes')->andReturn(['see-profile']); - - $client = m::mock(Client::class); - $client->shouldReceive('firstParty')->andReturnFalse(); - - $token = m::mock(Token::class); - $token->shouldReceive('getAttribute')->with('client')->andReturn($client); - $token->shouldReceive('getAttribute')->with('scopes')->andReturn(['see-profile']); - $token->shouldReceive('cant')->with('see-profile')->andReturnFalse(); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => ['see-profile'], + ]); $tokenRepository = m::mock(TokenRepository::class); - $tokenRepository->shouldReceive('find')->with('token')->andReturn($token); $middleware = new CheckClientCredentials($resourceServer, $tokenRepository); @@ -110,22 +95,14 @@ public function test_exception_is_thrown_if_token_does_not_have_required_scopes( $resourceServer = m::mock(ResourceServer::class); $resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock(ServerRequestInterface::class)); - $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); - $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); - $psr->shouldReceive('getAttribute')->with('oauth_scopes')->andReturn(['foo', 'notbar']); - - $client = m::mock(Client::class); - $client->shouldReceive('firstParty')->andReturnFalse(); - - $token = m::mock(Token::class); - $token->shouldReceive('getAttribute')->with('client')->andReturn($client); - $token->shouldReceive('getAttribute')->with('scopes')->andReturn(['foo', 'notbar']); - $token->shouldReceive('cant')->with('foo')->andReturnFalse(); - $token->shouldReceive('cant')->with('bar')->andReturnTrue(); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => ['foo', 'notbar'], + ]); $tokenRepository = m::mock(TokenRepository::class); - $tokenRepository->shouldReceive('find')->with('token')->andReturn($token); $middleware = new CheckClientCredentials($resourceServer, $tokenRepository); diff --git a/tests/Unit/TokenGuardTest.php b/tests/Unit/TokenGuardTest.php index de2d4d234..2e34e2a67 100644 --- a/tests/Unit/TokenGuardTest.php +++ b/tests/Unit/TokenGuardTest.php @@ -10,6 +10,7 @@ use Illuminate\Cookie\CookieValuePrefix; use Illuminate\Encryption\Encrypter; use Illuminate\Http\Request; +use Laravel\Passport\AccessToken; use Laravel\Passport\ClientRepository; use Laravel\Passport\Guards\TokenGuard; use Laravel\Passport\HasApiTokens; @@ -47,16 +48,21 @@ public function test_user_can_be_pulled_via_bearer_token() $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => [], + ]); $userProvider->shouldReceive('retrieveById')->with(1)->andReturn(new TokenGuardTestUser); $userProvider->shouldReceive('getProviderName')->andReturn(null); - $tokens->shouldReceive('find')->once()->with('token')->andReturn($token = m::mock()); $clients->shouldReceive('revoked')->with(1)->andReturn(false); $clients->shouldReceive('findActive')->with(1)->andReturn(new TokenGuardTestClient); $user = $guard->user(); $this->assertInstanceOf(TokenGuardTestUser::class, $user); - $this->assertEquals($token, $user->token()); + $this->assertEquals(AccessToken::fromPsrRequest($psr), $user->token()); } public function test_user_is_resolved_only_once() @@ -76,9 +82,14 @@ public function test_user_is_resolved_only_once() $psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1); $psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1); $psr->shouldReceive('getAttribute')->with('oauth_access_token_id')->andReturn('token'); + $psr->shouldReceive('getAttributes')->andReturn([ + 'oauth_user_id' => 1, + 'oauth_client_id' => 1, + 'oauth_access_token_id' => 'token', + 'oauth_scopes' => [], + ]); $userProvider->shouldReceive('retrieveById')->with(1)->andReturn(new TokenGuardTestUser); $userProvider->shouldReceive('getProviderName')->andReturn(null); - $tokens->shouldReceive('find')->once()->with('token')->andReturn($token = m::mock()); $clients->shouldReceive('revoked')->with(1)->andReturn(false); $clients->shouldReceive('findActive')->with(1)->andReturn(new TokenGuardTestClient); @@ -89,7 +100,7 @@ public function test_user_is_resolved_only_once() $user2 = $guard->user(); $this->assertInstanceOf(TokenGuardTestUser::class, $user); - $this->assertEquals($token, $user->token()); + $this->assertEquals(AccessToken::fromPsrRequest($psr), $user->token()); $this->assertSame($user, $user2); }