From 4ffc542b000f16bd13bf1c85d9d004aee4dbc6dc Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Thu, 4 Jul 2024 18:48:14 +0330 Subject: [PATCH] [13.x] Cleanup and add feature tests (#1767) * cleanup * add test * fix tests * formatting --- src/ClientRepository.php | 64 ------------------- src/HasApiTokens.php | 2 +- src/PassportServiceProvider.php | 15 ----- src/PersonalAccessTokenFactory.php | 33 +++++----- .../PersonalAccessTokenFactoryTest.php | 44 +++++++++++++ tests/Unit/BridgeClientRepositoryTest.php | 21 ------ tests/Unit/HasApiTokensTest.php | 2 +- tests/Unit/PassportTest.php | 9 --- tests/Unit/PersonalAccessTokenFactoryTest.php | 64 ------------------- 9 files changed, 61 insertions(+), 193 deletions(-) create mode 100644 tests/Feature/PersonalAccessTokenFactoryTest.php delete mode 100644 tests/Unit/PersonalAccessTokenFactoryTest.php diff --git a/src/ClientRepository.php b/src/ClientRepository.php index 934eaa54..5b443ded 100644 --- a/src/ClientRepository.php +++ b/src/ClientRepository.php @@ -3,37 +3,9 @@ namespace Laravel\Passport; use Illuminate\Support\Str; -use RuntimeException; class ClientRepository { - /** - * The personal access client ID. - * - * @var int|string|null - */ - protected $personalAccessClientId; - - /** - * The personal access client secret. - * - * @var string|null - */ - protected $personalAccessClientSecret; - - /** - * Create a new client repository. - * - * @param int|string|null $personalAccessClientId - * @param string|null $personalAccessClientSecret - * @return void - */ - public function __construct($personalAccessClientId = null, $personalAccessClientSecret = null) - { - $this->personalAccessClientId = $personalAccessClientId; - $this->personalAccessClientSecret = $personalAccessClientSecret; - } - /** * Get a client by the given ID. * @@ -103,22 +75,6 @@ public function activeForUser($userId) })->values(); } - /** - * Get the personal access token client for the application. - * - * @return \Laravel\Passport\Client - * - * @throws \RuntimeException - */ - public function personalAccessClient() - { - $client = $this->personalAccessClientId ? $this->find($this->personalAccessClientId) : null; - - return $client ?? throw new RuntimeException( - 'Personal access client not found. Please create one and set the `PASSPORT_PERSONAL_ACCESS_CLIENT_ID` and `PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET` environment variables.' - ); - } - /** * Store a new client. * @@ -233,24 +189,4 @@ public function delete(Client $client) $client->forceFill(['revoked' => true])->save(); } - - /** - * Get the personal access client id. - * - * @return int|string|null - */ - public function getPersonalAccessClientId() - { - return $this->personalAccessClientId; - } - - /** - * Get the personal access client secret. - * - * @return string|null - */ - public function getPersonalAccessClientSecret() - { - return $this->personalAccessClientSecret; - } } diff --git a/src/HasApiTokens.php b/src/HasApiTokens.php index 6eb2af9e..1faa29e3 100644 --- a/src/HasApiTokens.php +++ b/src/HasApiTokens.php @@ -64,7 +64,7 @@ public function tokenCan($scope) public function createToken($name, array $scopes = []) { return Container::getInstance()->make(PersonalAccessTokenFactory::class)->make( - $this->getKey(), $name, $scopes + $this->getAuthIdentifier(), $name, $scopes ); } diff --git a/src/PassportServiceProvider.php b/src/PassportServiceProvider.php index b0b560c0..38e9f8fa 100644 --- a/src/PassportServiceProvider.php +++ b/src/PassportServiceProvider.php @@ -131,7 +131,6 @@ public function register() ->give(fn () => Auth::guard(config('passport.guard', null))); $this->registerAuthorizationServer(); - $this->registerClientRepository(); $this->registerJWTParser(); $this->registerResourceServer(); $this->registerGuard(); @@ -265,20 +264,6 @@ public function makeAuthorizationServer() ); } - /** - * Register the client repository. - * - * @return void - */ - protected function registerClientRepository() - { - $this->app->singleton(ClientRepository::class, function ($container) { - $config = $container->make('config')->get('passport.personal_access_client'); - - return new ClientRepository($config['id'] ?? null, $config['secret'] ?? null); - }); - } - /** * Register the JWT Parser. * diff --git a/src/PersonalAccessTokenFactory.php b/src/PersonalAccessTokenFactory.php index 6e3cd268..f62ecfc7 100644 --- a/src/PersonalAccessTokenFactory.php +++ b/src/PersonalAccessTokenFactory.php @@ -7,6 +7,7 @@ use Nyholm\Psr7\Response; use Nyholm\Psr7\ServerRequest; use Psr\Http\Message\ServerRequestInterface; +use RuntimeException; class PersonalAccessTokenFactory { @@ -17,13 +18,6 @@ class PersonalAccessTokenFactory */ protected $server; - /** - * The client repository instance. - * - * @var \Laravel\Passport\ClientRepository - */ - protected $clients; - /** * The token repository instance. * @@ -42,20 +36,15 @@ class PersonalAccessTokenFactory * Create a new personal access token factory instance. * * @param \League\OAuth2\Server\AuthorizationServer $server - * @param \Laravel\Passport\ClientRepository $clients * @param \Laravel\Passport\TokenRepository $tokens * @param \Lcobucci\JWT\Parser $jwt * @return void */ - public function __construct(AuthorizationServer $server, - ClientRepository $clients, - TokenRepository $tokens, - JwtParser $jwt) + public function __construct(AuthorizationServer $server, TokenRepository $tokens, JwtParser $jwt) { $this->jwt = $jwt; $this->tokens = $tokens; $this->server = $server; - $this->clients = $clients; } /** @@ -63,10 +52,10 @@ public function __construct(AuthorizationServer $server, * * @param mixed $userId * @param string $name - * @param array $scopes + * @param string[] $scopes * @return \Laravel\Passport\PersonalAccessTokenResult */ - public function make($userId, $name, array $scopes = []) + public function make($userId, string $name, array $scopes = []) { $response = $this->dispatchRequestToAuthorizationServer( $this->createRequest($userId, $scopes) @@ -88,15 +77,23 @@ public function make($userId, $name, array $scopes = []) * Create a request instance for the given client. * * @param mixed $userId - * @param array $scopes + * @param string[] $scopes * @return \Psr\Http\Message\ServerRequestInterface */ protected function createRequest($userId, array $scopes) { + $config = config('passport.personal_access_client'); + + if (! $config) { + throw new RuntimeException( + 'Personal access client not found. Please create one and set the `PASSPORT_PERSONAL_ACCESS_CLIENT_ID` and `PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET` environment variables.' + ); + } + return (new ServerRequest('POST', 'not-important'))->withParsedBody([ 'grant_type' => 'personal_access', - 'client_id' => $this->clients->getPersonalAccessClientId(), - 'client_secret' => $this->clients->getPersonalAccessClientSecret(), + 'client_id' => $config['id'] ?? null, + 'client_secret' => $config['secret'] ?? null, 'user_id' => $userId, 'scope' => implode(' ', $scopes), ]); diff --git a/tests/Feature/PersonalAccessTokenFactoryTest.php b/tests/Feature/PersonalAccessTokenFactoryTest.php new file mode 100644 index 00000000..a9120eca --- /dev/null +++ b/tests/Feature/PersonalAccessTokenFactoryTest.php @@ -0,0 +1,44 @@ +create([ + 'email' => 'foo@gmail.com', + 'password' => $this->app->make(Hasher::class)->make('foobar123'), + ]); + + /** @var Client $client */ + $client = ClientFactory::new()->asPersonalAccessTokenClient()->create(); + + config([ + 'passport.personal_access_client.id' => $client->getKey(), + 'passport.personal_access_client.secret' => $client->plainSecret, + ]); + + Passport::tokensCan([ + 'foo' => 'Do foo', + 'bar' => 'Do bar', + ]); + + $result = $user->createToken('test', ['bar']); + + $this->assertInstanceOf(PersonalAccessTokenResult::class, $result); + $this->assertSame($client->getKey(), $result->token->client_id); + $this->assertSame($user->getAuthIdentifier(), $result->token->user_id); + $this->assertSame(['bar'], $result->token->scopes); + } +} diff --git a/tests/Unit/BridgeClientRepositoryTest.php b/tests/Unit/BridgeClientRepositoryTest.php index 18b8c2ff..2f440b92 100644 --- a/tests/Unit/BridgeClientRepositoryTest.php +++ b/tests/Unit/BridgeClientRepositoryTest.php @@ -197,25 +197,4 @@ class BridgeClientRepositoryTestClientStub extends \Laravel\Passport\Client public $password_client = false; public $provider = null; - - public $grant_types; - - public function firstParty() - { - return $this->personal_access_client || $this->password_client; - } - - public function confidential() - { - return ! empty($this->secret); - } - - public function hasGrantType($grantType) - { - if (! isset($this->grant_types) || ! is_array($this->grant_types)) { - return true; - } - - return in_array($grantType, $this->grant_types); - } } diff --git a/tests/Unit/HasApiTokensTest.php b/tests/Unit/HasApiTokensTest.php index 68258a5b..85bf2c61 100644 --- a/tests/Unit/HasApiTokensTest.php +++ b/tests/Unit/HasApiTokensTest.php @@ -45,7 +45,7 @@ class HasApiTokensTestStub { use HasApiTokens; - public function getKey() + public function getAuthIdentifier() { return 1; } diff --git a/tests/Unit/PassportTest.php b/tests/Unit/PassportTest.php index 72a45131..615be333 100644 --- a/tests/Unit/PassportTest.php +++ b/tests/Unit/PassportTest.php @@ -4,7 +4,6 @@ use Laravel\Passport\AuthCode; use Laravel\Passport\Client; -use Laravel\Passport\ClientRepository; use Laravel\Passport\Passport; use Laravel\Passport\RefreshToken; use Laravel\Passport\Token; @@ -39,14 +38,6 @@ public function test_client_instance_can_be_created() $this->assertInstanceOf(Passport::clientModel(), $client); } - public function test_missing_personal_access_client_is_reported() - { - $this->expectException('RuntimeException'); - - $clientRepository = new ClientRepository; - $clientRepository->personalAccessClient(); - } - public function test_token_instance_can_be_created() { $token = Passport::token(); diff --git a/tests/Unit/PersonalAccessTokenFactoryTest.php b/tests/Unit/PersonalAccessTokenFactoryTest.php deleted file mode 100644 index 2c55353d..00000000 --- a/tests/Unit/PersonalAccessTokenFactoryTest.php +++ /dev/null @@ -1,64 +0,0 @@ -shouldReceive('getPersonalAccessClientId')->andReturn('1'); - $clients->shouldReceive('getPersonalAccessClientSecret')->andReturn('secret'); - $server->shouldReceive('respondToAccessTokenRequest')->andReturn($response = m::mock(ResponseInterface::class)); - $response->shouldReceive('getBody->__toString')->andReturn(json_encode([ - 'access_token' => 'foo', - ])); - - $parsedToken = new PlainToken( - new DataSet([], ''), - new DataSet([RegisteredClaims::ID => 'token'], ''), - new Signature('', '') - ); - - $jwt->shouldReceive('parse')->with('foo')->andReturn($parsedToken); - $tokens->shouldReceive('find') - ->with('token') - ->andReturn($foundToken = new PersonalAccessTokenFactoryTestModelStub); - $tokens->shouldReceive('save')->with($foundToken); - - $result = $factory->make(1, 'token', ['scopes']); - - $this->assertInstanceOf(PersonalAccessTokenResult::class, $result); - } -} - -class PersonalAccessTokenFactoryTestModelStub extends Token -{ - public $id = 1; -}