Skip to content

Commit

Permalink
Upgrade to league/oauth2-server 8.0
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-allan committed Jul 17, 2019
1 parent 839b842 commit 97e3026
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 43 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"illuminate/encryption": "~5.8.0|~5.9.0",
"illuminate/http": "~5.8.0|~5.9.0",
"illuminate/support": "~5.8.0|~5.9.0",
"league/oauth2-server": "^7.0",
"league/oauth2-server": "^8.0",
"phpseclib/phpseclib": "^2.0",
"symfony/psr-http-message-bridge": "^1.0",
"zendframework/zend-diactoros": "^2.0"
Expand Down
6 changes: 5 additions & 1 deletion src/Bridge/AccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Laravel\Passport\Bridge;

use League\OAuth2\Server\Entities\Traits\EntityTrait;
use League\OAuth2\Server\Entities\ClientEntityInterface;
use League\OAuth2\Server\Entities\Traits\AccessTokenTrait;
use League\OAuth2\Server\Entities\Traits\TokenEntityTrait;
use League\OAuth2\Server\Entities\AccessTokenEntityInterface;
Expand All @@ -16,14 +17,17 @@ class AccessToken implements AccessTokenEntityInterface
*
* @param string $userIdentifier
* @param array $scopes
* @param ClientEntityInterface $client
* @return void
*/
public function __construct($userIdentifier, array $scopes = [])
public function __construct($userIdentifier, array $scopes, ClientEntityInterface $client)
{
$this->setUserIdentifier($userIdentifier);

foreach ($scopes as $scope) {
$this->addScope($scope);
}

$this->setClient($client);
}
}
2 changes: 1 addition & 1 deletion src/Bridge/AccessTokenRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function __construct(TokenRepository $tokenRepository, Dispatcher $events
*/
public function getNewToken(ClientEntityInterface $clientEntity, array $scopes, $userIdentifier = null)
{
return new AccessToken($userIdentifier, $scopes);
return new AccessToken($userIdentifier, $scopes, $clientEntity);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/Bridge/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ class Client implements ClientEntityInterface
* @param string $identifier
* @param string $name
* @param string $redirectUri
* @param bool $isConfidential
* @return void
*/
public function __construct($identifier, $name, $redirectUri)
public function __construct($identifier, $name, $redirectUri, $isConfidential = false)
{
$this->setIdentifier((string) $identifier);

$this->name = $name;
$this->redirectUri = explode(',', $redirectUri);
$this->isConfidential = $isConfidential;
}
}
31 changes: 16 additions & 15 deletions src/Bridge/ClientRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,32 @@ public function __construct(ClientModelRepository $clients)
/**
* {@inheritdoc}
*/
public function getClientEntity($clientIdentifier, $grantType = null,
$clientSecret = null, $mustValidateSecret = true)
public function getClientEntity($clientIdentifier)
{
// First, we will verify that the client exists and is authorized to create personal
// access tokens. Generally personal access tokens are only generated by the user
// from the main interface. We'll only let certain clients generate the tokens.
$record = $this->clients->findActive($clientIdentifier);

if (! $record || ! $this->handlesGrant($record, $grantType)) {
if (! $record) {
return;
}

// Once we have an existing client record we will create this actual client instance
// and verify the secret if necessary. If the secret is valid we will be ready to
// return this client instance back out to the consuming methods and finish up.
$client = new Client(
$clientIdentifier, $record->name, $record->redirect
return new Client(
$clientIdentifier, $record->name, $record->redirect, ! is_null($record->secret)
);
}

if ($mustValidateSecret &&
! hash_equals($record->secret, (string) $clientSecret)) {
return;
public function validateClient($clientIdentifier, $clientSecret, $grantType)
{
// First, we will verify that the client exists and is authorized to create personal
// access tokens. Generally personal access tokens are only generated by the user
// from the main interface. We'll only let certain clients generate the tokens.
$record = $this->clients->findActive($clientIdentifier);

if (! $record || ! $this->handlesGrant($record, $grantType)) {
return false;
}

return $client;
// Once we have an existing client record we will verify the secret.
return hash_equals($record->secret, (string) $clientSecret);
}

/**
Expand Down
24 changes: 20 additions & 4 deletions tests/BridgeAccessTokenRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Laravel\Passport\Tests;

use Mockery as m;
use Carbon\Carbon;
use Carbon\CarbonImmutable;
use PHPUnit\Framework\TestCase;
use Laravel\Passport\Bridge\Scope;
use Laravel\Passport\Bridge\Client;
Expand All @@ -21,7 +21,7 @@ public function tearDown()

public function test_access_tokens_can_be_persisted()
{
$expiration = Carbon::now();
$expiration = CarbonImmutable::now();

$tokenRepository = m::mock(TokenRepository::class);
$events = m::mock(Dispatcher::class);
Expand All @@ -39,13 +39,29 @@ public function test_access_tokens_can_be_persisted()

$events->shouldReceive('dispatch')->once();

$accessToken = new AccessToken(2, [new Scope('scopes')]);
$accessToken = new AccessToken(2, [new Scope('scopes')], new Client('client-id', 'name', 'redirect'));
$accessToken->setIdentifier(1);
$accessToken->setExpiryDateTime($expiration);
$accessToken->setClient(new Client('client-id', 'name', 'redirect'));

$repository = new AccessTokenRepository($tokenRepository, $events);

$repository->persistNewAccessToken($accessToken);
}

public function test_can_get_new_access_token()
{
$tokenRepository = m::mock(TokenRepository::class);
$events = m::mock(Dispatcher::class);
$repository = new AccessTokenRepository($tokenRepository, $events);
$client = new Client('client-id', 'name', 'redirect');
$scopes = [new Scope('place-orders'), new Scope('check-status')];
$userIdentifier = 123;

$token = $repository->getNewToken($client, $scopes, $userIdentifier);

$this->assertInstanceOf(AccessToken::class, $token);
$this->assertEquals($client, $token->getClient());
$this->assertEquals($scopes, $token->getScopes());
$this->assertEquals($userIdentifier, $token->getUserIdentifier());
}
}
47 changes: 27 additions & 20 deletions tests/BridgeClientRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,93 +38,100 @@ public function tearDown()
unset($this->clientModelRepository, $this->repository);
}

public function test_can_get_client_for_auth_code_grant()
public function test_can_get_client()
{
$client = $this->repository->getClientEntity(1, 'authorization_code', 'secret', true);
$client = $this->repository->getClientEntity(1);

$this->assertInstanceOf(Client::class, $client);
$this->assertNull($this->repository->getClientEntity(1, 'authorization_code', 'wrong-secret', true));
$this->assertNull($this->repository->getClientEntity(1, 'client_credentials', 'wrong-secret', true));
$this->assertEquals('1', $client->getIdentifier());
$this->assertEquals('Client', $client->getName());
$this->assertEquals(['http://localhost'], $client->getRedirectUri());
$this->assertTrue($client->isConfidential());
}

public function test_can_get_client_for_client_credentials_grant()
public function test_can_validate_client_for_auth_code_grant()
{
$this->assertTrue($this->repository->validateClient(1, 'secret', 'authorization_code'));
$this->assertFalse($this->repository->validateClient(1, 'wrong-secret', 'authorization_code'));
$this->assertFalse($this->repository->validateClient(1, 'wrong-secret', 'client_credentials'));
}

public function test_can_validate_client_for_client_credentials_grant()
{
$client = $this->clientModelRepository->findActive(1);
$client->personal_access_client = true;

$this->assertInstanceOf(
Client::class,
$this->repository->getClientEntity(1, 'client_credentials', 'secret', true)
);
$this->assertNull($this->repository->getClientEntity(1, 'authorization_code', 'secret', true));
$this->assertTrue($this->repository->validateClient(1, 'secret', 'client_credentials'));
$this->assertFalse($this->repository->validateClient(1, 'wrong-secret', 'client_credentials'));
$this->assertFalse($this->repository->validateClient(1, 'secret', 'authorization_code'));
}

public function test_password_grant_is_permitted()
{
$client = $this->clientModelRepository->findActive(1);
$client->password_client = true;

$this->assertInstanceOf(Client::class, $this->repository->getClientEntity(1, 'password', 'secret'));
$this->assertTrue($this->repository->validateClient(1, 'secret', 'password'));
}

public function test_password_grant_is_prevented()
{
$this->assertNull($this->repository->getClientEntity(1, 'password', 'secret'));
$this->assertFalse($this->repository->validateClient(1, 'secret', 'password'));
}

public function test_authorization_code_grant_is_permitted()
{
$this->assertInstanceOf(Client::class, $this->repository->getClientEntity(1, 'authorization_code', 'secret'));
$this->assertTrue($this->repository->validateClient(1, 'secret', 'authorization_code'));
}

public function test_authorization_code_grant_is_prevented()
{
$client = $this->clientModelRepository->findActive(1);
$client->password_client = true;

$this->assertNull($this->repository->getClientEntity(1, 'authorization_code', 'secret'));
$this->assertFalse($this->repository->validateClient(1, 'secret', 'authorization_code'));
}

public function test_personal_access_grant_is_permitted()
{
$client = $this->clientModelRepository->findActive(1);
$client->personal_access_client = true;

$this->assertInstanceOf(Client::class, $this->repository->getClientEntity(1, 'personal_access', 'secret'));
$this->assertTrue($this->repository->validateClient(1, 'secret', 'personal_access'));
}

public function test_personal_access_grant_is_prevented()
{
$this->assertNull($this->repository->getClientEntity(1, 'personal_access', 'secret'));
$this->assertFalse($this->repository->validateClient(1, 'secret', 'personal_access'));
}

public function test_client_credentials_grant_is_permitted()
{
$this->assertInstanceOf(Client::class, $this->repository->getClientEntity(1, 'client_credentials', 'secret'));
$this->assertTrue($this->repository->validateClient(1, 'secret', 'client_credentials'));
}

public function test_client_credentials_grant_is_prevented()
{
$client = $this->clientModelRepository->findActive(1);
$client->secret = null;

$this->assertNull($this->repository->getClientEntity(1, 'client_credentials', 'secret'));
$this->assertFalse($this->repository->validateClient(1, 'secret', 'client_credentials'));
}

public function test_grant_types_allows_request()
{
$client = $this->clientModelRepository->findActive(1);
$client->grant_types = ['client_credentials'];

$this->assertInstanceOf(Client::class, $this->repository->getClientEntity(1, 'client_credentials', 'secret'));
$this->assertTrue($this->repository->validateClient(1, 'secret', 'client_credentials'));
}

public function test_grant_types_disallows_request()
{
$client = $this->clientModelRepository->findActive(1);
$client->grant_types = ['client_credentials'];

$this->assertNull($this->repository->getClientEntity(1, 'authorization_code', 'secret'));
$this->assertFalse($this->repository->validateClient(1, 'secret', 'authorization_code'));
}
}

Expand Down

0 comments on commit 97e3026

Please sign in to comment.