diff --git a/src/Exception/InvalidRequestException.php b/src/Exception/InvalidRequestException.php index cafa7df3..05535203 100644 --- a/src/Exception/InvalidRequestException.php +++ b/src/Exception/InvalidRequestException.php @@ -30,7 +30,7 @@ class InvalidRequestException extends OAuthException * {@inheritdoc} */ - public function __construct($parameter, $shouldRedirect = false) + public function __construct($parameter, $redirectUri = null) { parent::__construct( sprintf( @@ -39,6 +39,6 @@ class InvalidRequestException extends OAuthException ) ); - $this->serverShouldRedirect = $shouldRedirect; + $this->redirectUri = $redirectUri; } } diff --git a/src/Exception/InvalidScopeException.php b/src/Exception/InvalidScopeException.php index 0120ca23..f0574f8d 100644 --- a/src/Exception/InvalidScopeException.php +++ b/src/Exception/InvalidScopeException.php @@ -30,7 +30,7 @@ class InvalidScopeException extends OAuthException * {@inheritdoc} */ - public function __construct($parameter, $shouldRedirect = false) + public function __construct($parameter, $redirectUri = null) { parent::__construct( sprintf( @@ -39,6 +39,6 @@ class InvalidScopeException extends OAuthException ) ); - $this->serverShouldRedirect = $shouldRedirect; + $this->redirectUri = $redirectUri; } } diff --git a/src/Exception/OAuthException.php b/src/Exception/OAuthException.php index c4e8d157..229ac1ab 100644 --- a/src/Exception/OAuthException.php +++ b/src/Exception/OAuthException.php @@ -24,10 +24,10 @@ class OAuthException extends \Exception public $httpStatusCode = 400; /** - * If true the server should redirect back to the client - * @var boolean + * Redirect URI if the server should redirect back to the client + * @var string|null */ - public $serverShouldRedirect = false; + public $redirectUri = null; /** * The exception type @@ -48,7 +48,22 @@ class OAuthException extends \Exception */ public function shouldRedirect() { - return $this->serverShouldRedirect; + return is_null($this->redirectUri) ? false : true; + } + + /** + * Return redirect URI if set + * @return string|null + */ + public function getRedirectUri() + { + return \League\OAuth2\Server\Util\RedirectUri::make( + $this->redirectUri, + [ + 'error' => $this->errorType, + 'message' => $this->getMessage(), + ] + ); } /** diff --git a/src/Exception/UnsupportedResponseTypeException.php b/src/Exception/UnsupportedResponseTypeException.php index cfd74c1a..8707f0c5 100644 --- a/src/Exception/UnsupportedResponseTypeException.php +++ b/src/Exception/UnsupportedResponseTypeException.php @@ -29,9 +29,9 @@ class UnsupportedResponseTypeException extends OAuthException /** * {@inheritdoc} */ - public function __construct($parameter) + public function __construct($parameter, $redirectUri = null) { parent::__construct('The authorization server does not support obtaining an access token using this method.'); - $this->serverShouldRedirect = true; + $this->redirectUri = $redirectUri; } } diff --git a/src/Grant/AbstractGrant.php b/src/Grant/AbstractGrant.php index 59cc3ba1..2609fda6 100644 --- a/src/Grant/AbstractGrant.php +++ b/src/Grant/AbstractGrant.php @@ -121,11 +121,12 @@ abstract class AbstractGrant implements GrantTypeInterface /** * Given a list of scopes, validate them and return an array of Scope entities * @param string $scopeParam A string of scopes (e.g. "profile email birthday") - * @param \League\OAuth2\Server\Entity\ClientEntity $client A string of scopes (e.g. "profile email birthday") + * @param \League\OAuth2\Server\Entity\ClientEntity $client Client entity + * @param string|null $redirectUri The redirect URI to return the user to * @return \League\OAuth2\Server\Entity\ScopeEntity[] - * @throws \League\OAuth2\Server\Exception\ClientException If scope is invalid, or no scopes passed when required + * @throws \League\OAuth2\Server\Exception\InvalidScopeException If scope is invalid, or no scopes passed when required */ - public function validateScopes($scopeParam = '', ClientEntity $client) + public function validateScopes($scopeParam = '', ClientEntity $client, $redirectUri = null) { $scopesList = explode($this->server->getScopeDelimeter(), $scopeParam); @@ -160,7 +161,7 @@ abstract class AbstractGrant implements GrantTypeInterface ); if (($scope instanceof ScopeEntity) === false) { - throw new Exception\InvalidScopeException($scopeItem, true); + throw new Exception\InvalidScopeException($scopeItem, $redirectUri); } $scopes[$scope->getId()] = $scope; diff --git a/src/Grant/AuthCodeGrant.php b/src/Grant/AuthCodeGrant.php index 8d73560d..283d7af5 100644 --- a/src/Grant/AuthCodeGrant.php +++ b/src/Grant/AuthCodeGrant.php @@ -99,22 +99,22 @@ class AuthCodeGrant extends AbstractGrant $state = $this->server->getRequest()->query->get('state', null); if ($this->server->stateParamRequired() === true && is_null($state)) { - throw new Exception\InvalidRequestException('state', true); + throw new Exception\InvalidRequestException('state', $redirectUri); } $responseType = $this->server->getRequest()->query->get('response_type', null); if (is_null($responseType)) { - throw new Exception\InvalidRequestException('response_type', true); + throw new Exception\InvalidRequestException('response_type', $redirectUri); } // Ensure response type is one that is recognised if (!in_array($responseType, $this->server->getResponseTypes())) { - throw new Exception\UnsupportedResponseTypeException($responseType); + throw new Exception\UnsupportedResponseTypeException($responseType, $redirectUri); } // Validate any scopes that are in the request $scopeParam = $this->server->getRequest()->query->get('scope', ''); - $scopes = $this->validateScopes($scopeParam, $client); + $scopes = $this->validateScopes($scopeParam, $client, $redirectUri); return [ 'client' => $client,