Skip to content

Commit

Permalink
[11.x] Support prompting re-consent when redirecting for authorization (
Browse files Browse the repository at this point in the history
#1567)

* Support prompting re-consent

* Update AuthorizationController.php

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
hafezdivandari and taylorotwell authored Sep 1, 2022
1 parent 8aeec71 commit cae735a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 9 deletions.
27 changes: 20 additions & 7 deletions src/Http/Controllers/AuthorizationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,11 @@ public function authorize(ServerRequestInterface $psrRequest,
});

$scopes = $this->parseScopes($authRequest);
$user = $request->user();
$client = $clients->find($authRequest->getClient()->getIdentifier());

$token = $tokens->findValidToken(
$user = $request->user(),
$client = $clients->find($authRequest->getClient()->getIdentifier())
);

if (($token && $token->scopes === collect($scopes)->pluck('id')->all()) ||
$client->skipsAuthorization()) {
if ($request->get('prompt') !== 'consent' &&
($client->skipsAuthorization() || $this->hasValidToken($tokens, $user, $client, $scopes))) {
return $this->approveRequest($authRequest, $user);
}

Expand Down Expand Up @@ -101,6 +98,22 @@ protected function parseScopes($authRequest)
);
}

/**
* Determine if a valid token exists for the given user, client, and scopes.
*
* @param \Laravel\Passport\TokenRepository $tokens
* @param \Illuminate\Database\Eloquent\Model $user
* @param \Laravel\Passport\Client $client
* @param array $scopes
* @return bool
*/
protected function hasValidToken($tokens, $user, $client, $scopes)
{
$token = $tokens->findValidToken($user, $client);

return $token && $token->scopes === collect($scopes)->pluck('id')->all();
}

/**
* Approve the authorization request.
*
Expand Down
53 changes: 51 additions & 2 deletions tests/Unit/AuthorizationControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function test_authorization_view_is_presented()
$session->shouldReceive('put')->withSomeOfArgs('authToken');
$session->shouldReceive('put')->with('authRequest', $authRequest);
$request->shouldReceive('user')->andReturn($user = m::mock());
$request->shouldReceive('get')->with('prompt')->andReturn(null);

$authRequest->shouldReceive('getClient->getIdentifier')->andReturn(1);
$authRequest->shouldReceive('getScopes')->andReturn([new Scope('scope-1')]);
Expand Down Expand Up @@ -116,18 +117,21 @@ public function test_request_is_approved_if_valid_token_exists()
$request->shouldReceive('user')->once()->andReturn($user = m::mock());
$user->shouldReceive('getAuthIdentifier')->andReturn(1);
$request->shouldNotReceive('session');
$request->shouldReceive('get')->with('prompt')->andReturn(null);

$authRequest->shouldReceive('getClient->getIdentifier')->once()->andReturn(1);
$authRequest->shouldReceive('getScopes')->once()->andReturn([new Scope('scope-1')]);
$authRequest->shouldReceive('setUser')->once()->andReturnNull();
$authRequest->shouldReceive('setAuthorizationApproved')->once()->with(true);

$clients = m::mock(ClientRepository::class);
$clients->shouldReceive('find')->with(1)->andReturn('client');
$clients->shouldReceive('find')->with(1)->andReturn($client = m::mock(Client::class));

$client->shouldReceive('skipsAuthorization')->andReturn(false);

$tokens = m::mock(TokenRepository::class);
$tokens->shouldReceive('findValidToken')
->with($user, 'client')
->with($user, $client)
->andReturn($token = m::mock(Token::class));
$token->shouldReceive('getAttribute')->with('scopes')->andReturn(['scope-1']);

Expand Down Expand Up @@ -158,6 +162,7 @@ public function test_request_is_approved_if_client_can_skip_authorization()
$request->shouldReceive('user')->once()->andReturn($user = m::mock());
$user->shouldReceive('getAuthIdentifier')->andReturn(1);
$request->shouldNotReceive('session');
$request->shouldReceive('get')->with('prompt')->andReturn(null);

$authRequest->shouldReceive('getClient->getIdentifier')->once()->andReturn(1);
$authRequest->shouldReceive('getScopes')->once()->andReturn([new Scope('scope-1')]);
Expand All @@ -178,4 +183,48 @@ public function test_request_is_approved_if_client_can_skip_authorization()
m::mock(ServerRequestInterface::class), $request, $clients, $tokens
)->getContent());
}

public function test_authorization_view_is_presented_if_request_has_prompt_equals_to_consent()
{
Passport::tokensCan([
'scope-1' => 'description',
]);

$server = m::mock(AuthorizationServer::class);
$response = m::mock(ResponseFactory::class);

$controller = new AuthorizationController($server, $response);
$server->shouldReceive('validateAuthorizationRequest')
->andReturn($authRequest = m::mock(AuthorizationRequest::class));

$request = m::mock(Request::class);
$request->shouldReceive('session')->andReturn($session = m::mock());
$session->shouldReceive('put')->withSomeOfArgs('authToken');
$session->shouldReceive('put')->with('authRequest', $authRequest);
$request->shouldReceive('user')->andReturn($user = m::mock());
$request->shouldReceive('get')->with('prompt')->andReturn('consent');

$authRequest->shouldReceive('getClient->getIdentifier')->once()->andReturn(1);
$authRequest->shouldReceive('getScopes')->once()->andReturn([new Scope('scope-1')]);

$clients = m::mock(ClientRepository::class);
$clients->shouldReceive('find')->with(1)->andReturn($client = m::mock(Client::class));
$client->shouldReceive('skipsAuthorization')->andReturn(false);

$tokens = m::mock(TokenRepository::class);
$tokens->shouldNotReceive('findValidToken');

$response->shouldReceive('view')->once()->andReturnUsing(function ($view, $data) use ($client, $user) {
$this->assertSame('passport::authorize', $view);
$this->assertEquals($client, $data['client']);
$this->assertEquals($user, $data['user']);
$this->assertSame('description', $data['scopes'][0]->description);

return 'view';
});

$this->assertSame('view', $controller->authorize(
m::mock(ServerRequestInterface::class), $request, $clients, $tokens
));
}
}

0 comments on commit cae735a

Please sign in to comment.