From 33f4f5b7ab07c0b67149dd42ddef28af5c3cd16b Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Sat, 31 May 2014 16:11:00 -0500 Subject: [PATCH] Add $required parameter to hasScope(), triggers InsufficientScopeException --- .../Exception/InsufficientScopeException.php | 20 +++++++++++ src/League/OAuth2/Server/Resource.php | 31 ++++++++--------- tests/resource/ResourceServerTest.php | 33 +++++++++++++++++++ 3 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 src/League/OAuth2/Server/Exception/InsufficientScopeException.php diff --git a/src/League/OAuth2/Server/Exception/InsufficientScopeException.php b/src/League/OAuth2/Server/Exception/InsufficientScopeException.php new file mode 100644 index 00000000..04f66848 --- /dev/null +++ b/src/League/OAuth2/Server/Exception/InsufficientScopeException.php @@ -0,0 +1,20 @@ + + * @copyright Copyright (c) 2014 PHP League of Extraordinary Packages + * @license http://mit-license.org/ + * @link http://github.com/php-loep/oauth2-server + */ + +namespace League\OAuth2\Server\Exception; + +/** + * InsufficientScope Exception + */ +class InsufficientScopeException extends OAuth2Exception +{ + +} diff --git a/src/League/OAuth2/Server/Resource.php b/src/League/OAuth2/Server/Resource.php index 4ba64b13..158d9087 100644 --- a/src/League/OAuth2/Server/Resource.php +++ b/src/League/OAuth2/Server/Resource.php @@ -93,7 +93,7 @@ class Resource protected static $exceptionMessages = array( 'invalid_request' => 'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed. Check the "%s" parameter.', 'invalid_token' => 'The access token provided is expired, revoked, malformed, or invalid for other reasons.', - 'insufficient_scope' => 'The request requires higher privileges than provided by the access token.', + 'insufficient_scope' => 'The request requires higher privileges than provided by the access token. Required scopes are: %s.', ); /** @@ -328,25 +328,26 @@ class Resource * Checks if the presented access token has the given scope(s). * * @param array|string An array of scopes or a single scope as a string + * @param bool If scopes are required, missing scope will trigger an exception + * @throws Exception\InsufficientScopeException Thrown if the any of the given scopes are not in the session * @return bool Returns bool if all scopes are found, false if any fail */ - public function hasScope($scopes) + public function hasScope($scopes, $required = false) { - if (is_string($scopes)) { - if (in_array($scopes, $this->sessionScopes)) { - return true; - } - return false; - } elseif (is_array($scopes)) { - foreach ($scopes as $scope) { - if (! in_array($scope, $this->sessionScopes)) { - return false; - } - } - return true; + if (!is_array($scopes)) { + $scopes = array($scopes); } - return false; + $missing = array_diff($scopes, $this->sessionScopes); + + if ($missing) { + if ($required) { + $missing = implode(', ', $missing); + throw new Exception\InsufficientScopeException(sprintf(self::$exceptionMessages['insufficient_scope'], $missing), 3); + } + return false; + } + return true; } /** diff --git a/tests/resource/ResourceServerTest.php b/tests/resource/ResourceServerTest.php index 9658cba5..3c459294 100644 --- a/tests/resource/ResourceServerTest.php +++ b/tests/resource/ResourceServerTest.php @@ -192,6 +192,39 @@ class Resource_Server_test extends PHPUnit_Framework_TestCase $this->assertEquals('abcdef', $result); } + public function test_hasScope_isRequired() + { + $s = $this->returnDefault(); + + $reflector = new ReflectionClass($s); + $param = $reflector->getProperty('sessionScopes'); + $param->setAccessible(true); + $param->setValue($s, array( + 'a', 'b', 'c' + )); + + $result = $s->hasScope(array('a', 'b'), true); + + $this->assertEquals(true, $result); + } + + /** + * @expectedException League\OAuth2\Server\Exception\InsufficientScopeException + */ + public function test_hasScope_isRequiredFailure() + { + $s = $this->returnDefault(); + + $reflector = new ReflectionClass($s); + $param = $reflector->getProperty('sessionScopes'); + $param->setAccessible(true); + $param->setValue($s, array( + 'a', 'b', 'c' + )); + + $s->hasScope('d', true); + } + /** * @expectedException League\OAuth2\Server\Exception\InvalidAccessTokenException */