Skip to content

Commit

Permalink
Merge pull request #5 from designmynight/refactor-exceptions
Browse files Browse the repository at this point in the history
Refactor exceptions
  • Loading branch information
robbytaylor authored Jun 26, 2018
2 parents a07ed34 + 8ae09cd commit f21f3b6
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 82 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"require": {
"php": "^7.0",
"guzzlehttp/guzzle": "~6.0",
"laravel/framework": "^5.5"
"laravel/framework": "^5.5",
"laravel/passport": "^4.0"
},
"autoload": {
"psr-4": {"DesignMyNight\\Laravel\\OAuth2\\": "src/"}
Expand Down
6 changes: 0 additions & 6 deletions src/Exceptions/InvalidAccessTokenException.php

This file was deleted.

6 changes: 0 additions & 6 deletions src/Exceptions/InvalidEndpointException.php

This file was deleted.

6 changes: 0 additions & 6 deletions src/Exceptions/InvalidInputException.php

This file was deleted.

122 changes: 59 additions & 63 deletions src/VerifyAccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,45 @@
namespace DesignMyNight\Laravel\OAuth2;

use Closure;
use DesignMyNight\Laravel\OAuth2\Exceptions\InvalidAccessTokenException;
use DesignMyNight\Laravel\OAuth2\Exceptions\InvalidEndpointException;
use DesignMyNight\Laravel\OAuth2\Exceptions\InvalidInputException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\Facades\Cache;
use Laravel\Passport\Exceptions\MissingScopeException;

class VerifyAccessToken
{
protected $accessTokenCacheKey = 'access_token';

private $client = null;

private function getClient(): Client
protected function checkScopes($scopesForToken, $requiredScopes)
{
if ($this->client === null) {
$this->setClient(new Client());
if (!is_array($requiredScopes)) {
$requiredScopes = [$requiredScopes];
}

return $this->client;
$misingScopes = array_diff($scopesForToken, $scopesForToken);

if (count($misingScopes) > 0) {
throw new MissingScopeException($misingScopes);
}
}

public function setClient(Client $client): self
protected function getAccessToken(): string
{
$this->client = $client;
$accessToken = Cache::get($this->accessTokenCacheKey);

return $this;
return $accessToken ?: $this->getNewAccessToken();
}

private function getClient(): Client
{
if ($this->client === null) {
$this->setClient(new Client());
}

return $this->client;
}

protected function getIntrospect($accessToken)
Expand All @@ -46,37 +58,6 @@ protected function getIntrospect($accessToken)
return json_decode((string) $response->getBody(), true);
}

protected function getAccessToken(): string
{
$accessToken = Cache::get($this->accessTokenCacheKey);

return $accessToken ?: $this->getNewAccessToken();
}

protected function getNewAccessToken(): string
{
$response = $this->getClient()->post(config('authorizationserver.token_url'), [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => config('authorizationserver.client_id'),
'client_secret' => config('authorizationserver.client_secret'),
'scope' => '',
],
]);

$result = json_decode((string) $response->getBody(), true);

if (isset($result['access_token'])) {
$accessToken = $result['access_token'];

Cache::add($this->accessTokenCacheKey, $accessToken, intVal($result['expires_in']) / 60);

return $accessToken;
}

throw new InvalidEndpointException('Did not receive an access token');
}

/**
* Handle an incoming request.
*
Expand All @@ -86,50 +67,65 @@ protected function getNewAccessToken(): string
*/
public function handle($request, Closure $next, ...$scopes)
{
$authorization = $request->header('Authorization');

if (!$authorization) {
throw new InvalidInputException('No Authorization header present');
}

$bearerToken = $request->bearerToken();

if (!$bearerToken) {
throw new InvalidInputException('No Bearer token in the Authorization header present');
throw new AuthenticationException('No Bearer token present');
}

try {
$result = $this->getIntrospect($bearerToken);

if (!$result['active']) {
throw new InvalidAccessTokenException('Invalid token!');
throw new AuthenticationException('Invalid token!');
}

if ($scopes != null) {
if (!\is_array($scopes)) {
$scopes = [$scopes];
}

$scopesForToken = \explode(' ', $result['scope']);

if (count($misingScopes = array_diff($scopes, $scopesForToken)) > 0) {
throw new InvalidAccessTokenException('Missing the following required scopes: ' . implode(' ,', $misingScopes));
}
if ($scopes !== null) {
$this->checkScopes(explode(' ', $result['scope']), $scopes);
}
} catch (RequestException $e) {
if ($e->hasResponse()) {
$result = json_decode((string) $e->getResponse()->getBody(), true);

if (isset($result['error'])) {
throw new InvalidAccessTokenException($result['error']['title'] ?? 'Invalid token!');
throw new AuthenticationException($result['error']['title'] ?? '');
}

throw new InvalidAccessTokenException('Invalid token!');
}

throw new InvalidAccessTokenException($e);
throw new AuthenticationException($e->getMessage());
}

return $next($request);
}

protected function getNewAccessToken(): string
{
$response = $this->getClient()->post(config('authorizationserver.token_url'), [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => config('authorizationserver.client_id'),
'client_secret' => config('authorizationserver.client_secret'),
'scope' => '',
],
]);

$result = json_decode((string) $response->getBody(), true);

if (isset($result['access_token'])) {
$accessToken = $result['access_token'];

Cache::add($this->accessTokenCacheKey, $accessToken, intVal($result['expires_in']) / 60);

return $accessToken;
}

throw new AuthenticationException('Did not receive an access token');
}

public function setClient(Client $client): self
{
$this->client = $client;

return $this;
}
}

0 comments on commit f21f3b6

Please sign in to comment.