Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[9.x] Use psr request attributes in 'check client credentials' middleware #1112

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/Http/Middleware/CheckClientCredentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

use Closure;
use Illuminate\Auth\AuthenticationException;
use Laravel\Passport\ClientRepository;
use Laravel\Passport\Exceptions\MissingScopeException;
use Laravel\Passport\TokenRepository;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\ResourceServer;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
Expand All @@ -24,20 +24,20 @@ class CheckClientCredentials
protected $server;

/**
* Token Repository.
* Client Repository.
*
* @var \Laravel\Passport\TokenRepository
* @var \Laravel\Passport\ClientRepository
gdebrauwer marked this conversation as resolved.
Show resolved Hide resolved
*/
protected $repository;

/**
* Create a new middleware instance.
*
* @param \League\OAuth2\Server\ResourceServer $server
* @param \Laravel\Passport\TokenRepository $repository
* @param \Laravel\Passport\ClientRepository $repository
* @return void
*/
public function __construct(ResourceServer $server, TokenRepository $repository)
public function __construct(ResourceServer $server, ClientRepository $repository)
gdebrauwer marked this conversation as resolved.
Show resolved Hide resolved
{
$this->server = $server;
$this->repository = $repository;
Expand Down Expand Up @@ -82,18 +82,18 @@ public function handle($request, Closure $next, ...$scopes)
*/
protected function validate($psr, $scopes)
{
$token = $this->repository->find($psr->getAttribute('oauth_access_token_id'));
$client = $this->repository->find($psr->getAttribute('oauth_client_id'));

if (! $token || $token->client->firstParty()) {
if (! $client || $client->firstParty()) {
throw new AuthenticationException;
}

if (in_array('*', $token->scopes)) {
if (in_array('*', $tokenScopes = $psr->getAttribute('oauth_scopes'))) {
return;
}

foreach ($scopes as $scope) {
if ($token->cant($scope)) {
if (! in_array($scope, $tokenScopes)) {
throw new MissingScopeException($scope);
}
}
Expand Down
18 changes: 9 additions & 9 deletions src/Http/Middleware/CheckClientCredentialsForAnyScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

use Closure;
use Illuminate\Auth\AuthenticationException;
use Laravel\Passport\ClientRepository;
use Laravel\Passport\Exceptions\MissingScopeException;
use Laravel\Passport\TokenRepository;
use League\OAuth2\Server\Exception\OAuthServerException;
use League\OAuth2\Server\ResourceServer;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
Expand All @@ -24,20 +24,20 @@ class CheckClientCredentialsForAnyScope
protected $server;

/**
* Token Repository.
* Client Repository.
*
* @var \Laravel\Passport\TokenRepository
* @var \Laravel\Passport\ClientRepository
gdebrauwer marked this conversation as resolved.
Show resolved Hide resolved
*/
protected $repository;

/**
* Create a new middleware instance.
*
* @param \League\OAuth2\Server\ResourceServer $server
* @param \Laravel\Passport\TokenRepository $repository
* @param \Laravel\Passport\ClientRepository $repository
* @return void
*/
public function __construct(ResourceServer $server, TokenRepository $repository)
public function __construct(ResourceServer $server, ClientRepository $repository)
gdebrauwer marked this conversation as resolved.
Show resolved Hide resolved
{
$this->server = $server;
$this->repository = $repository;
Expand Down Expand Up @@ -84,18 +84,18 @@ public function handle($request, Closure $next, ...$scopes)
*/
protected function validate($psr, $scopes)
{
$token = $this->repository->find($psr->getAttribute('oauth_access_token_id'));
$client = $this->repository->find($psr->getAttribute('oauth_client_id'));

if (! $token || $token->client->firstParty()) {
if (! $client || $client->firstParty()) {
throw new AuthenticationException;
}

if (in_array('*', $token->scopes)) {
if (in_array('*', $tokenScopes = $psr->getAttribute('oauth_scopes'))) {
return true;
}

foreach ($scopes as $scope) {
if ($token->can($scope)) {
if (in_array($scope, $tokenScopes)) {
return true;
}
}
Expand Down
58 changes: 19 additions & 39 deletions tests/CheckClientCredentialsForAnyScopeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

use Illuminate\Http\Request;
use Laravel\Passport\Client;
use Laravel\Passport\ClientRepository;
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;
use Mockery as m;
Expand All @@ -24,21 +23,17 @@ public function test_request_is_passed_along_if_token_is_valid()
$resourceServer = m::mock(ResourceServer::class);
$resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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(['*']);
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);

$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -55,23 +50,17 @@ 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());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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();

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -88,13 +77,13 @@ public function test_request_is_passed_along_if_token_has_any_required_scope()
*/
public function test_exception_is_thrown_when_oauth_throws_exception()
{
$tokenRepository = m::mock(TokenRepository::class);
$clientRepository = m::mock(ClientRepository::class);
$resourceServer = m::mock(ResourceServer::class);
$resourceServer->shouldReceive('validateAuthenticatedRequest')->andThrow(
new OAuthServerException('message', 500, 'error type')
);

$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -112,23 +101,17 @@ 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());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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();
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);

$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -146,20 +129,17 @@ public function test_exception_is_thrown_if_token_belongs_to_first_party_client(
$resourceServer = m::mock(ResourceServer::class);
$resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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')->andReturnTrue();

$token = m::mock(Token::class);
$token->shouldReceive('getAttribute')->with('client')->andReturn($client);

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentialsForAnyScope($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand Down
57 changes: 19 additions & 38 deletions tests/CheckClientCredentialsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

use Illuminate\Http\Request;
use Laravel\Passport\Client;
use Laravel\Passport\ClientRepository;
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;
use Mockery as m;
Expand All @@ -24,21 +23,17 @@ public function test_request_is_passed_along_if_token_is_valid()
$resourceServer = m::mock(ResourceServer::class);
$resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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(['*']);
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);

$middleware = new CheckClientCredentials($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentials($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -55,22 +50,17 @@ 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());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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();

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$middleware = new CheckClientCredentials($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentials($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -87,13 +77,13 @@ public function test_request_is_passed_along_if_token_and_scope_are_valid()
*/
public function test_exception_is_thrown_when_oauth_throws_exception()
{
$tokenRepository = m::mock(TokenRepository::class);
$clientRepository = m::mock(ClientRepository::class);
$resourceServer = m::mock(ResourceServer::class);
$resourceServer->shouldReceive('validateAuthenticatedRequest')->andThrow(
new OAuthServerException('message', 500, 'error type')
);

$middleware = new CheckClientCredentials($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentials($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -111,23 +101,17 @@ 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());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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();
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);

$middleware = new CheckClientCredentials($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentials($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand All @@ -145,20 +129,17 @@ public function test_exception_is_thrown_if_token_belongs_to_first_party_client(
$resourceServer = m::mock(ResourceServer::class);
$resourceServer->shouldReceive('validateAuthenticatedRequest')->andReturn($psr = m::mock());
$psr->shouldReceive('getAttribute')->with('oauth_user_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(1);
$psr->shouldReceive('getAttribute')->with('oauth_client_id')->andReturn(2);
$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')->andReturnTrue();

$token = m::mock(Token::class);
$token->shouldReceive('getAttribute')->with('client')->andReturn($client);

$tokenRepository = m::mock(TokenRepository::class);
$tokenRepository->shouldReceive('find')->with('token')->andReturn($token);
$clientRepository = m::mock(ClientRepository::class);
$clientRepository->shouldReceive('find')->with(2)->andReturn($client);

$middleware = new CheckClientCredentials($resourceServer, $tokenRepository);
$middleware = new CheckClientCredentials($resourceServer, $clientRepository);

$request = Request::create('/');
$request->headers->set('Authorization', 'Bearer token');
Expand Down