diff options
Diffstat (limited to 'src')
40 files changed, 346 insertions, 201 deletions
diff --git a/src/OAuth2/Autoloader.php b/src/OAuth2/Autoloader.php index a9673d8..40a42fb 100644 --- a/src/OAuth2/Autoloader.php +++ b/src/OAuth2/Autoloader.php @@ -20,7 +20,7 @@ class OAuth2_Autoloader /** * Registers AdobeDigitalMarketing_Autoloader as an SPL autoloader. */ - static public function register($dir = null) + public static function register($dir = null) { ini_set('unserialize_callback_func', 'spl_autoload_call'); spl_autoload_register(array(new self($dir), 'autoload')); diff --git a/src/OAuth2/Controller/AccessController.php b/src/OAuth2/Controller/AccessController.php index 883c64a..3f2e9e2 100644 --- a/src/OAuth2/Controller/AccessController.php +++ b/src/OAuth2/Controller/AccessController.php @@ -1,16 +1,17 @@ <?php /** -* -*/ + * @see OAuth2_Controller_AccessControllerInterface + */ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessControllerInterface { private $response; private $tokenType; private $tokenStorage; private $config; + private $scopeUtil; - public function __construct(OAuth2_TokenTypeInterface $tokenType, OAuth2_Storage_AccessTokenInterface $tokenStorage, $config = array(), $util = null) + public function __construct(OAuth2_TokenTypeInterface $tokenType, OAuth2_Storage_AccessTokenInterface $tokenStorage, $config = array(), $scopeUtil = null) { $this->tokenType = $tokenType; $this->tokenStorage = $tokenStorage; @@ -19,10 +20,10 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont 'www_realm' => 'Service', ), $config); - if (is_null($util)) { - $util = new OAuth2_Util(); + if (is_null($scopeUtil)) { + $scopeUtil = new OAuth2_Util_Scope(); } - $this->util = $util; + $this->scopeUtil = $scopeUtil; } public function verifyAccessRequest(OAuth2_RequestInterface $request) @@ -30,7 +31,7 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont $token = $this->tokenType->getAccessTokenParameter($request); $this->response = $this->tokenType->getResponse(); if ($token) { - $access_token = $this->getAccessTokenData($token, $request->query('scope')); + $access_token = $this->getAccessTokenData($token, $this->scopeUtil->getScopeFromRequest($request)); return (bool) $access_token; } @@ -65,7 +66,7 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont // Check scope, if provided // If token doesn't have a scope, it's null/empty, or it's insufficient, then throw an error - if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->util->checkScope($scope, $token["scope"]))) { + if ($scope && (!isset($token["scope"]) || !$token["scope"] || !$this->scopeUtil->checkScope($scope, $token["scope"]))) { $this->response = new OAuth2_Response_AuthenticationError(401, 'insufficient_scope', 'The request requires higher privileges than provided by the access token', $this->tokenType->getTokenType(), $this->config['www_realm'], $scope); return null; } @@ -77,4 +78,4 @@ class OAuth2_Controller_AccessController implements OAuth2_Controller_AccessCont { return $this->response; } -}
\ No newline at end of file +} diff --git a/src/OAuth2/Controller/AccessControllerInterface.php b/src/OAuth2/Controller/AccessControllerInterface.php index a7b77c8..9571b9d 100644 --- a/src/OAuth2/Controller/AccessControllerInterface.php +++ b/src/OAuth2/Controller/AccessControllerInterface.php @@ -1,8 +1,21 @@ <?php +/** + * This controller is called when a "resource" is requested. + * call verifyAccessRequest in order to determine if the request + * contains a valid token. + * + * ex: + * > if (!$accessController->verifyAccessRequest(OAuth2_Request::createFromGlobals())) { + * > $accessController->getResponse()->send(); // authorization failed + * > die(); + * > } + * > return json_encode($resource); // valid token! Send the stuff! + * + */ interface OAuth2_Controller_AccessControllerInterface extends OAuth2_Response_ProviderInterface { public function verifyAccessRequest(OAuth2_RequestInterface $request); public function getAccessTokenData($token_param, $scope = null); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Controller/AuthorizeController.php b/src/OAuth2/Controller/AuthorizeController.php index 09ff56c..0a443f7 100644 --- a/src/OAuth2/Controller/AuthorizeController.php +++ b/src/OAuth2/Controller/AuthorizeController.php @@ -1,17 +1,17 @@ <?php /** -* -*/ + * @see OAuth2_Controller_AuthorizeControllerInterface + */ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_AuthorizeControllerInterface { private $response; private $clientStorage; private $responseTypes; private $config; - private $util; + private $scopeUtil; - public function __construct(OAuth2_Storage_ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), $util = null) + public function __construct(OAuth2_Storage_ClientInterface $clientStorage, array $responseTypes = array(), array $config = array(), $scopeUtil = null) { $this->clientStorage = $clientStorage; $this->responseTypes = $responseTypes; @@ -21,10 +21,10 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori 'enforce_state' => false, ), $config); - if (is_null($util)) { - $util = new OAuth2_Util(); + if (is_null($scopeUtil)) { + $scopeUtil = new OAuth2_Util_Scope(); } - $this->util = $util; + $this->scopeUtil = $scopeUtil; } public function handleAuthorizeRequest(OAuth2_RequestInterface $request, $is_authorized, $user_id = null) @@ -50,7 +50,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori } list($redirect_uri, $result) = $authResult; - $uri = $this->util->buildUri($redirect_uri, $result); + $uri = $this->buildUri($redirect_uri, $result); // return redirect response return new OAuth2_Response_Redirect($uri); @@ -94,7 +94,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori } // Only need to validate if redirect_uri provided on input and clientData. - if ($clientData["redirect_uri"] && $redirect_uri && !$this->util->validateRedirectUri($redirect_uri, $clientData["redirect_uri"])) { + if ($clientData["redirect_uri"] && $redirect_uri && !$this->validateRedirectUri($redirect_uri, $clientData["redirect_uri"])) { $this->response = new OAuth2_Response_Error(400, 'redirect_uri_mismatch', 'The redirect URI provided is missing or does not match'); return false; } @@ -103,7 +103,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori $redirect_uri = $redirect_uri ? $redirect_uri : $clientData["redirect_uri"]; $response_type = $request->query('response_type'); $state = $request->query('state'); - $scope = $request->query('scope'); + $scope = $this->scopeUtil->getScopeFromRequest($request); // type and client_id are required if (!$response_type || !in_array($response_type, array(self::RESPONSE_TYPE_AUTHORIZATION_CODE, self::RESPONSE_TYPE_ACCESS_TOKEN))) { @@ -127,7 +127,7 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori } // Validate that the requested scope is supported - if ($scope && !$this->util->checkScope($scope, $this->config['supported_scopes'])) { + if ($scope && !$this->scopeUtil->checkScope($scope, $this->config['supported_scopes'])) { $this->response = new OAuth2_Response_Redirect($redirect_uri, 302, 'invalid_scope', 'An unsupported scope was requested', $state); return false; } @@ -142,8 +142,60 @@ class OAuth2_Controller_AuthorizeController implements OAuth2_Controller_Authori return ((array)$request->getAllQueryParameters() + $clientData + array('state' => null)); } + /** + * Build the absolute URI based on supplied URI and parameters. + * + * @param $uri + * An absolute URI. + * @param $params + * Parameters to be append as GET. + * + * @return + * An absolute URI with supplied parameters. + * + * @ingroup oauth2_section_4 + */ + private function buildUri($uri, $params) + { + $parse_url = parse_url($uri); + + // Add our params to the parsed uri + foreach ( $params as $k => $v ) { + if (isset($parse_url[$k])) { + $parse_url[$k] .= "&" . http_build_query($v); + } else { + $parse_url[$k] = http_build_query($v); + } + } + + // Put humpty dumpty back together + return + ((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "") + . ((isset($parse_url["user"])) ? $parse_url["user"] + . ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") . "@" : "") + . ((isset($parse_url["host"])) ? $parse_url["host"] : "") + . ((isset($parse_url["port"])) ? ":" . $parse_url["port"] : "") + . ((isset($parse_url["path"])) ? $parse_url["path"] : "") + . ((isset($parse_url["query"])) ? "?" . $parse_url["query"] : "") + . ((isset($parse_url["fragment"])) ? "#" . $parse_url["fragment"] : "") + ; + } + + /** + * Internal method for validating redirect URI supplied + * @param string $inputUri + * @param string $storedUri + */ + private function validateRedirectUri($inputUri, $storedUri) + { + if (!$inputUri || !$storedUri) { + return false; // if either one is missing, assume INVALID + } + return strcasecmp(substr($inputUri, 0, strlen($storedUri)), $storedUri) === 0; + } + public function getResponse() { return $this->response; } -}
\ No newline at end of file +} diff --git a/src/OAuth2/Controller/AuthorizeControllerInterface.php b/src/OAuth2/Controller/AuthorizeControllerInterface.php index 4110297..ed01b10 100644 --- a/src/OAuth2/Controller/AuthorizeControllerInterface.php +++ b/src/OAuth2/Controller/AuthorizeControllerInterface.php @@ -1,5 +1,21 @@ <?php +/** + * This controller is called when a user should be authorized + * by an authorization server. As OAuth2 does not handle + * authorization directly, this controller ensures the request is valid, but + * requires the application to determine the value of $is_authorized + * + * ex: + * > $user_id = $this->somehowDetermineUserId(); + * > $is_authorized = $this->somehowDetermineUserAuthorization(); + * > $response = $authorizeController->handleAuthorizeRequest( + * > OAuth2_Request::createFromGlobals(), + * > $is_authorized, + * > $user_id); + * > $response->send(); + * + */ interface OAuth2_Controller_AuthorizeControllerInterface extends OAuth2_Response_ProviderInterface { /** @@ -17,4 +33,4 @@ interface OAuth2_Controller_AuthorizeControllerInterface extends OAuth2_Response public function handleAuthorizeRequest(OAuth2_RequestInterface $request, $is_authorized, $user_id = null); public function validateAuthorizeRequest(OAuth2_RequestInterface $request); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Controller/GrantController.php b/src/OAuth2/Controller/GrantController.php index ba7017b..45a08c3 100644 --- a/src/OAuth2/Controller/GrantController.php +++ b/src/OAuth2/Controller/GrantController.php @@ -1,14 +1,17 @@ <?php +/** + * @see OAuth2_Controller_GrantControllerInterface + */ class OAuth2_Controller_GrantController implements OAuth2_Controller_GrantControllerInterface { private $response; private $clientStorage; private $accessToken; private $grantTypes; - private $util; + private $scopeUtil; - public function __construct(OAuth2_Storage_ClientCredentialsInterface $clientStorage, OAuth2_ResponseType_AccessTokenInterface $accessToken, array $grantTypes = array(), $util = null) + public function __construct(OAuth2_Storage_ClientCredentialsInterface $clientStorage, OAuth2_ResponseType_AccessTokenInterface $accessToken, array $grantTypes = array(), $scopeUtil = null) { $this->clientStorage = $clientStorage; $this->accessToken = $accessToken; @@ -16,10 +19,10 @@ class OAuth2_Controller_GrantController implements OAuth2_Controller_GrantContro $this->addGrantType($grantType); } - if (is_null($util)) { - $util = new OAuth2_Util(); + if (is_null($scopeUtil)) { + $scopeUtil = new OAuth2_Util_Scope(); } - $this->util = $util; + $this->scopeUtil = $scopeUtil; } public function handleGrantRequest(OAuth2_RequestInterface $request) @@ -134,8 +137,10 @@ class OAuth2_Controller_GrantController implements OAuth2_Controller_GrantContro $tokenData["scope"] = null; } + $scope = $this->scopeUtil->getScopeFromRequest($request); // Check scope, if provided - if (null != $request->query('scope') && (!is_array($tokenData) || !isset($tokenData["scope"]) || !$this->util->checkScope($request->query('scope'), $tokenData["scope"]))) { + // @TODO: ScopeStorage + if (null != $scope && (!is_array($tokenData) || !isset($tokenData["scope"]) || !$this->scopeUtil->checkScope($scope, $tokenData["scope"]))) { $this->response = new OAuth2_Response_Error(400, 'invalid_scope', 'An unsupported scope was requested.'); return null; } diff --git a/src/OAuth2/Controller/GrantControllerInterface.php b/src/OAuth2/Controller/GrantControllerInterface.php index 2bdcfd0..eec76a9 100644 --- a/src/OAuth2/Controller/GrantControllerInterface.php +++ b/src/OAuth2/Controller/GrantControllerInterface.php @@ -1,5 +1,15 @@ <?php +/** + * This controller is called when a token is being requested. + * it is called to handle all grant types the application supports. + * It also validates the client's credentials + * + * ex: + * > $response = $grantController->handleGrantRequest(OAuth2_Request::createFromGlobals()); + * > $response->send(); + * + */ interface OAuth2_Controller_GrantControllerInterface extends OAuth2_Response_ProviderInterface { /** @@ -14,4 +24,4 @@ interface OAuth2_Controller_GrantControllerInterface extends OAuth2_Response_Pro public function grantAccessToken(OAuth2_RequestInterface $request); public function getClientCredentials(OAuth2_RequestInterface $request); -}
\ No newline at end of file +} diff --git a/src/OAuth2/GrantType/AuthorizationCode.php b/src/OAuth2/GrantType/AuthorizationCode.php index 2a40b2f..218867b 100644 --- a/src/OAuth2/GrantType/AuthorizationCode.php +++ b/src/OAuth2/GrantType/AuthorizationCode.php @@ -7,6 +7,7 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O { private $storage; private $response; + private $code; public function __construct(OAuth2_Storage_AuthorizationCodeInterface $storage) { @@ -20,7 +21,7 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O public function validateRequest($request) { - if (!$request->query('code')) { + if (!$request->request('code')) { $this->response = new OAuth2_Response_Error(400, 'invalid_request', 'Missing parameter: "code" is required'); return false; } @@ -30,7 +31,8 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O public function getTokenDataFromRequest($request) { - if (!$tokenData = $this->storage->getAuthorizationCode($request->query('code'))) { + $this->code = $request->request('code'); + if (!$tokenData = $this->storage->getAuthorizationCode($this->code)) { $this->response = new OAuth2_Response_Error(400, 'invalid_grant', "Authorization code doesn't exist or is invalid for the client"); return null; } @@ -40,7 +42,7 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O * @uri - http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1.3 */ if (isset($tokenData['redirect_uri']) && $tokenData['redirect_uri']) { - if (!$request->query('redirect_uri') || urldecode($request->query('redirect_uri')) != $tokenData['redirect_uri']) { + if (!$request->request('redirect_uri') || urldecode($request->request('redirect_uri')) != $tokenData['redirect_uri']) { $this->response = new OAuth2_Response_Error(400, 'redirect_uri_mismatch', "The redirect URI is missing or do not match", "#section-4.1.3"); return false; } @@ -68,7 +70,10 @@ class OAuth2_GrantType_AuthorizationCode implements OAuth2_GrantTypeInterface, O public function createAccessToken(OAuth2_ResponseType_AccessTokenInterface $accessToken, array $clientData, array $tokenData) { - return $accessToken->createAccessToken($clientData['client_id'], $tokenData['user_id'], $tokenData['scope']); + $this->storage->expireAuthorizationCode($this->code); + $token = $accessToken->createAccessToken($clientData['client_id'], $tokenData['user_id'], $tokenData['scope']); + + return $token; } public function getResponse() diff --git a/src/OAuth2/GrantType/ClientCredentials.php b/src/OAuth2/GrantType/ClientCredentials.php index 2dae255..a315717 100644 --- a/src/OAuth2/GrantType/ClientCredentials.php +++ b/src/OAuth2/GrantType/ClientCredentials.php @@ -16,7 +16,7 @@ class OAuth2_GrantType_ClientCredentials implements OAuth2_GrantTypeInterface public function getTokenDataFromRequest($request) { // the only piece to pull is the "scope" parameter - $scope = $request->headers('REQUEST_METHOD') == 'POST' ? $request->request('scope') : $request->query('scope'); + $scope = $request->server('REQUEST_METHOD') == 'POST' ? $request->request('scope') : $request->query('scope'); return array( "scope" => $scope ); @@ -37,4 +37,4 @@ class OAuth2_GrantType_ClientCredentials implements OAuth2_GrantTypeInterface $includeRefreshToken = false; return $accessToken->createAccessToken($clientData['client_id'], $tokenData['user_id'], $tokenData['scope'], $includeRefreshToken); } -}
\ No newline at end of file +} diff --git a/src/OAuth2/GrantType/JWTBearer.php b/src/OAuth2/GrantType/JWTBearer.php index 81c139e..1572346 100644 --- a/src/OAuth2/GrantType/JWTBearer.php +++ b/src/OAuth2/GrantType/JWTBearer.php @@ -1,33 +1,54 @@ <?php /** -* +* The JWT bearer authorization grant implements JWT (JSON Web Tokens) as a grant type per the IETF draft. +* @see http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-04#section-4 */ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Response_ProviderInterface, OAuth2_ClientAssertionTypeInterface { private $storage; private $response; - private $audience = NULL; - private $jwt = NULL; + private $audience = null; + private $jwt = null; private $jwtUtil; + /** + * Creates an instance of the JWT bearer grant type. + * + * @param OAuth2_Storage_JWTBearerInterface $storage + * A valid storage interface that implements storage hooks for the JWT bearer grant type. + * @param string $audience + * The audience to validate the token against. This is usually the full URI of the OAuth grant requests endpoint. + * @param OAuth2_Util_JWT OPTIONAL $jwtUtil + * The class used to decode, encode and verify JWTs. + */ public function __construct(OAuth2_Storage_JWTBearerInterface $storage, $audience, OAuth2_Util_JWT $jwtUtil = null) { $this->storage = $storage; $this->audience = $audience; - - if (is_null($jwtUtil)) {
- $jwtUtil = new OAuth2_Util_JWT();
- }
-
+ + if (is_null($jwtUtil)) { + $jwtUtil = new OAuth2_Util_JWT(); + } + $this->jwtUtil = $jwtUtil; } + /** + * Returns the grant_type get parameter to identify the grant type request as JWT bearer authorization grant. + * @return The string identifier for grant_type. + * @see OAuth2_GrantTypeInterface::getQuerystringIdentifier() + */ public function getQuerystringIdentifier() { return 'urn:ietf:params:oauth:grant-type:jwt-bearer'; } + /** + * Validates the request by making share all GET parameters exists. + * @return TRUE if the request is valid, otherwise FALSE. + * @see OAuth2_GrantTypeInterface::validateRequest() + */ public function validateRequest($request) { if (!$request->query("assertion")) { @@ -39,6 +60,11 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re return true; } + /** + * Gets the data from the decoded JWT. + * @return Array containing the token data if the JWT can be decoded. Otherwise, NULL is returned. + * @see OAuth2_GrantTypeInterface::getTokenDataFromRequest() + */ public function getTokenDataFromRequest($request) { @@ -50,7 +76,7 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re //Decode the JWT try { - $jwt = $this->jwtUtil->decode($request->query('assertion'), NULL, FALSE); + $jwt = $this->jwtUtil->decode($request->query('assertion'), null, false); } catch (Exception $e) { $this->response = new OAuth2_Response_Error(400, 'invalid_request', "JWT is malformed"); @@ -81,25 +107,47 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re return $tokenData; } + /** + * Store a copy of the JWT + * @param string $jwt + */ private function setJWT($jwt) { $this->jwt = $jwt; } - private function getJWTParameter($parameter, $default = NULL) + /** + * Helper function to make it easier to return a JWT parameter. + * @param string $parameter + * The JWT parameter to get. + * @param mixed $default + * The value to return if the JWT parameter does not exist. + * @return mixed + * The JWT parameter. + */ + private function getJWTParameter($parameter, $default = null) { - return isset($this->jwt->$parameter) ? $this->jwt->$parameter : NULL; + return isset($this->jwt->$parameter) ? $this->jwt->$parameter : null; } + /** + * Return the data used to verify the request. For JWT bearer authorization grants, this is the 'iss' which is synonymous to the 'client_id'. + * @return array An array of the client data containing the client_id. + * @see OAuth2_ClientAssertionTypeInterface::getClientDataFromRequest() + */ public function getClientDataFromRequest(OAuth2_RequestInterface $request) { $tokenData = $this->getTokenDataFromRequest($request); if($tokenData){ - return array('client_id' => $tokenData['iss']); + return array('client_id' => $tokenData['iss'], 'subject' => $tokenData['sub']); } } + /** + * Validates the client data by checking if the client_id exists in storage. It also checks to see if the client_id is associated with a key to decode the JWT. + * @see OAuth2_ClientAssertionTypeInterface::validateClientData() + */ public function validateClientData(array $clientData) { //Get the iss's public key (http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06#section-4.1.1) @@ -110,10 +158,10 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re return null; } - $publicKey = $this->storage->getClientKey($clientData['client_id']); + $publicKey = $this->storage->getClientKey($clientData['client_id'], $clientData['subject']); if (!$publicKey) { - $this->response = new OAuth2_Response_Error(400, 'invalid_grant', "Invalid issuer (iss) provided"); + $this->response = new OAuth2_Response_Error(400, 'invalid_grant', "Invalid issuer (iss) or subject (sub) provided"); return null; } @@ -121,6 +169,11 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re return true; } + /** + * Validates the token data using the rules in the IETF draft. + * @see http://tools.ietf.org/html/draft-ietf-oauth-jwt-bearer-04#section-3 + * @see OAuth2_GrantTypeInterface::validateTokenData() + */ public function validateTokenData($tokenData, array $clientData) { // Note: Scope is validated in the client class @@ -177,7 +230,7 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re //Verify the JWT try { - $this->jwtUtil->decode($this->jwt, $clientData['client_secret'], TRUE); + $this->jwtUtil->decode($this->jwt, $clientData['client_secret'], true); } catch (Exception $e) { $this->response = new OAuth2_Response_Error(400, 'invalid_grant', "JWT failed signature verification"); @@ -188,19 +241,22 @@ class OAuth2_GrantType_JWTBearer implements OAuth2_GrantTypeInterface, OAuth2_Re return true; } + /** + * Creates an access token that is NOT associated with a refresh token. + * If a subject (sub) the name of the user/account we are accessing data on behalf of. + * @see OAuth2_GrantTypeInterface::createAccessToken() + */ public function createAccessToken(OAuth2_ResponseType_AccessTokenInterface $accessToken, array $clientData, array $tokenData) { $includeRefreshToken = false; - if (isset($tokenData['sub'])) { - $user = $tokenData['sub']; - } else { - $user = $tokenData['iss']; - } - - return $accessToken->createAccessToken($clientData['client_id'], $user, $tokenData['scope'], $includeRefreshToken); + return $accessToken->createAccessToken($clientData['client_id'], $tokenData['sub'], $tokenData['scope'], $includeRefreshToken); } + /** + * Returns the response of this grant type. + * @see OAuth2_Response_ProviderInterface::getResponse() + */ public function getResponse() { return $this->response; diff --git a/src/OAuth2/GrantType/RefreshToken.php b/src/OAuth2/GrantType/RefreshToken.php index 5bc9732..2c54d79 100644 --- a/src/OAuth2/GrantType/RefreshToken.php +++ b/src/OAuth2/GrantType/RefreshToken.php @@ -25,7 +25,7 @@ class OAuth2_GrantType_RefreshToken implements OAuth2_GrantTypeInterface, OAuth2 public function validateRequest($request) { - if (!$request->query("refresh_token")) { + if (!$request->request("refresh_token")) { $this->response = new OAuth2_Response_Error(400, 'invalid_request', 'Missing parameter: "refresh_token" is required'); return false; } @@ -35,7 +35,7 @@ class OAuth2_GrantType_RefreshToken implements OAuth2_GrantTypeInterface, OAuth2 public function getTokenDataFromRequest($request) { - if (!$stored = $this->storage->getRefreshToken($request->query("refresh_token"))) { + if (!$stored = $this->storage->getRefreshToken($request->request("refresh_token"))) { $this->response = new OAuth2_Response_Error(400, 'invalid_grant', 'Invalid refresh token'); return false; } @@ -82,4 +82,4 @@ class OAuth2_GrantType_RefreshToken implements OAuth2_GrantTypeInterface, OAuth2 { return $this->response; } -}
\ No newline at end of file +} diff --git a/src/OAuth2/GrantType/UserCredentials.php b/src/OAuth2/GrantType/UserCredentials.php index 51d05aa..0d4638e 100644 --- a/src/OAuth2/GrantType/UserCredentials.php +++ b/src/OAuth2/GrantType/UserCredentials.php @@ -20,7 +20,7 @@ class OAuth2_GrantType_UserCredentials implements OAuth2_GrantTypeInterface, OAu public function validateRequest($request) { - if (!$request->query("password") || !$request->query("username")) { + if (!$request->request("password") || !$request->request("username")) { $this->response = new OAuth2_Response_Error(400, 'invalid_request', 'Missing parameters: "username" and "password" required'); return false; } @@ -30,12 +30,12 @@ class OAuth2_GrantType_UserCredentials implements OAuth2_GrantTypeInterface, OAu public function getTokenDataFromRequest($request) { - if (!$this->storage->checkUserCredentials($request->query("username"), $request->query("password"))) { + if (!$this->storage->checkUserCredentials($request->request("username"), $request->request("password"))) { $this->response = new OAuth2_Response_Error(400, 'invalid_grant', 'Invalid username and password combination'); return false; } - $tokenData = $this->storage->getUserDetails($request->query("username")); + $tokenData = $this->storage->getUserDetails($request->request("username")); // tokenData can be an empty array if (false === $tokenData || is_null($tokenData)) { diff --git a/src/OAuth2/GrantTypeInterface.php b/src/OAuth2/GrantTypeInterface.php index 0573f9d..c029a1d 100644 --- a/src/OAuth2/GrantTypeInterface.php +++ b/src/OAuth2/GrantTypeInterface.php @@ -7,4 +7,4 @@ interface OAuth2_GrantTypeInterface public function getTokenDataFromRequest($request); public function validateTokenData($tokenData, array $clientData); public function createAccessToken(OAuth2_ResponseType_AccessTokenInterface $accessToken, array $clientData, array $tokenData); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Request.php b/src/OAuth2/Request.php index 3ddc3ff..d0ed7fe 100644 --- a/src/OAuth2/Request.php +++ b/src/OAuth2/Request.php @@ -180,7 +180,7 @@ class OAuth2_Request implements OAuth2_RequestInterface * * @api */ - static public function createFromGlobals() + public static function createFromGlobals() { $class = __CLASS__; $request = new $class($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER); diff --git a/src/OAuth2/RequestInterface.php b/src/OAuth2/RequestInterface.php index 0195605..61eb2d2 100644 --- a/src/OAuth2/RequestInterface.php +++ b/src/OAuth2/RequestInterface.php @@ -11,4 +11,4 @@ interface OAuth2_RequestInterface public function headers($name, $default = null); public function getAllQueryParameters(); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Response.php b/src/OAuth2/Response.php index 183cd3f..4cc9b2b 100644 --- a/src/OAuth2/Response.php +++ b/src/OAuth2/Response.php @@ -10,7 +10,7 @@ class OAuth2_Response protected $parameters = array(); protected $httpHeaders = array(); - static public $statusTexts = array( + public static $statusTexts = array( 100 => 'Continue', 101 => 'Switching Protocols', 200 => 'OK', diff --git a/src/OAuth2/Response/AuthenticationError.php b/src/OAuth2/Response/AuthenticationError.php index c3c5a62..f558401 100644 --- a/src/OAuth2/Response/AuthenticationError.php +++ b/src/OAuth2/Response/AuthenticationError.php @@ -15,4 +15,3 @@ class OAuth2_Response_AuthenticationError extends OAuth2_Response_Error $this->setHttpHeader('WWW-Authenticate', $authHeader); } } - diff --git a/src/OAuth2/Response/Error.php b/src/OAuth2/Response/Error.php index 1eaa26d..bacda74 100644 --- a/src/OAuth2/Response/Error.php +++ b/src/OAuth2/Response/Error.php @@ -46,4 +46,3 @@ class OAuth2_Response_Error extends OAuth2_Response return $this->parameters['error_uri']; } } - diff --git a/src/OAuth2/Response/ProviderInterface.php b/src/OAuth2/Response/ProviderInterface.php index b23c332..9b147c0 100644 --- a/src/OAuth2/Response/ProviderInterface.php +++ b/src/OAuth2/Response/ProviderInterface.php @@ -2,5 +2,5 @@ interface OAuth2_Response_ProviderInterface { - function getResponse(); -}
\ No newline at end of file + public function getResponse(); +} diff --git a/src/OAuth2/Response/Redirect.php b/src/OAuth2/Response/Redirect.php index 4f6a0a2..86ec291 100644 --- a/src/OAuth2/Response/Redirect.php +++ b/src/OAuth2/Response/Redirect.php @@ -42,4 +42,3 @@ class OAuth2_Response_Redirect extends OAuth2_Response } } } - diff --git a/src/OAuth2/ResponseType/AccessToken.php b/src/OAuth2/ResponseType/AccessToken.php index 37b5e54..070fbbe 100644 --- a/src/OAuth2/ResponseType/AccessToken.php +++ b/src/OAuth2/ResponseType/AccessToken.php @@ -122,4 +122,4 @@ class OAuth2_ResponseType_AccessToken implements OAuth2_ResponseType_AccessToken { return $this->generateAccessToken(); // let's reuse the same scheme for token generation } -}
\ No newline at end of file +} diff --git a/src/OAuth2/ResponseType/AccessTokenInterface.php b/src/OAuth2/ResponseType/AccessTokenInterface.php index 457c3b8..d362893 100644 --- a/src/OAuth2/ResponseType/AccessTokenInterface.php +++ b/src/OAuth2/ResponseType/AccessTokenInterface.php @@ -3,4 +3,4 @@ interface OAuth2_ResponseType_AccessTokenInterface extends OAuth2_ResponseTypeInterface { public function createAccessToken($client_id, $user_id, $scope = null, $includeRefreshToken = true); -}
\ No newline at end of file +} diff --git a/src/OAuth2/ResponseType/AuthorizationCode.php b/src/OAuth2/ResponseType/AuthorizationCode.php index 3f8b65c..d8a2626 100644 --- a/src/OAuth2/ResponseType/AuthorizationCode.php +++ b/src/OAuth2/ResponseType/AuthorizationCode.php @@ -3,7 +3,7 @@ /** * */ -class OAuth2_ResponseType_AuthorizationCode implements OAuth2_ResponseTypeInterface +class OAuth2_ResponseType_AuthorizationCode implements OAuth2_ResponseType_AuthorizationCodeInterface { private $storage; private $config; @@ -83,4 +83,4 @@ class OAuth2_ResponseType_AuthorizationCode implements OAuth2_ResponseTypeInterf } return substr(hash('sha512', $randomData), 0, $tokenLen); } -}
\ No newline at end of file +} diff --git a/src/OAuth2/ResponseType/AuthorizationCodeInterface.php b/src/OAuth2/ResponseType/AuthorizationCodeInterface.php index 04067c1..f139ae3 100644 --- a/src/OAuth2/ResponseType/AuthorizationCodeInterface.php +++ b/src/OAuth2/ResponseType/AuthorizationCodeInterface.php @@ -1,6 +1,6 @@ <?php -interface OAuth2_GrantType_AuthorizationCodeInterface extends OAuth2_GrantTypeInterface +interface OAuth2_ResponseType_AuthorizationCodeInterface extends OAuth2_ResponseTypeInterface { /** * @return @@ -10,4 +10,3 @@ interface OAuth2_GrantType_AuthorizationCodeInterface extends OAuth2_GrantTypeIn public function createAuthorizationCode($client_id, $user_id, $redirect_uri, $scope = null); } - diff --git a/src/OAuth2/ResponseTypeInterface.php b/src/OAuth2/ResponseTypeInterface.php index 4eccaed..3df6821 100644 --- a/src/OAuth2/ResponseTypeInterface.php +++ b/src/OAuth2/ResponseTypeInterface.php @@ -3,4 +3,4 @@ interface OAuth2_ResponseTypeInterface { public function getAuthorizeResponse($params, $user_id = null); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Server.php b/src/OAuth2/Server.php index c67057d..51c8eb9 100644 --- a/src/OAuth2/Server.php +++ b/src/OAuth2/Server.php @@ -108,7 +108,7 @@ class OAuth2_Server implements OAuth2_Controller_AccessControllerInterface, if ($this->config['token_type'] == 'bearer') { $config = array_intersect_key($this->config, array_flip(explode(' ', 'token_param_name token_bearer_header_name'))); $tokenType = new OAuth2_TokenType_Bearer($config); - } else if ($this->config['token_type'] == 'mac') { + } elseif ($this->config['token_type'] == 'mac') { $tokenType = new OAuth2_TokenType_MAC(); } else { throw new LogicException('unrecognized token type: '.$this->config['token_type']); diff --git a/src/OAuth2/Storage/AccessTokenInterface.php b/src/OAuth2/Storage/AccessTokenInterface.php index df3120e..d22be0d 100644 --- a/src/OAuth2/Storage/AccessTokenInterface.php +++ b/src/OAuth2/Storage/AccessTokenInterface.php @@ -45,4 +45,4 @@ interface OAuth2_Storage_AccessTokenInterface * @ingroup oauth2_section_4 */ public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Storage/AuthorizationCodeInterface.php b/src/OAuth2/Storage/AuthorizationCodeInterface.php index 4a90946..4b3ed9e 100644 --- a/src/OAuth2/Storage/AuthorizationCodeInterface.php +++ b/src/OAuth2/Storage/AuthorizationCodeInterface.php @@ -69,4 +69,17 @@ interface OAuth2_Storage_AuthorizationCodeInterface */ public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null); -}
\ No newline at end of file + /** + * once an Authorization Code is used, it must be exipired + * + * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.1.2 + * + * The client MUST NOT use the authorization code + * more than once. If an authorization code is used more than + * once, the authorization server MUST deny the request and SHOULD + * revoke (when possible) all tokens previously issued based on + * that authorization code + * + */ + public function expireAuthorizationCode($code); +} diff --git a/src/OAuth2/Storage/ClientCredentialsInterface.php b/src/OAuth2/Storage/ClientCredentialsInterface.php index 374d628..155506b 100644 --- a/src/OAuth2/Storage/ClientCredentialsInterface.php +++ b/src/OAuth2/Storage/ClientCredentialsInterface.php @@ -44,4 +44,4 @@ interface OAuth2_Storage_ClientCredentialsInterface extends OAuth2_Storage_Clien * @ingroup oauth2_section_4 */ public function checkRestrictedGrantType($client_id, $grant_type); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Storage/ClientInterface.php b/src/OAuth2/Storage/ClientInterface.php index dca3c3d..9020f43 100644 --- a/src/OAuth2/Storage/ClientInterface.php +++ b/src/OAuth2/Storage/ClientInterface.php @@ -18,4 +18,4 @@ interface OAuth2_Storage_ClientInterface * @ingroup oauth2_section_4 */ public function getClientDetails($client_id); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Storage/JWTBearerInterface.php b/src/OAuth2/Storage/JWTBearerInterface.php index 58f70fa..8ba8522 100644 --- a/src/OAuth2/Storage/JWTBearerInterface.php +++ b/src/OAuth2/Storage/JWTBearerInterface.php @@ -1,11 +1,10 @@ <?php /** - * All storage engines need to implement this interface in order to use OAuth2 server - * - * @author David Rochwerger <catch.dave@gmail.com> + * All storage engines need to implement this interface in order to use the JWT Authorization Grant. + * @author F21 */ -interface OAuth2_Storage_JWTBearerInterface extends OAuth2_Storage_ClientInterface +interface OAuth2_Storage_JWTBearerInterface { /** @@ -18,5 +17,5 @@ interface OAuth2_Storage_JWTBearerInterface extends OAuth2_Storage_ClientInterfa * STRING Return the public key for the client_id if it exists, and MUST return FALSE if it doesn't. * @endcode */ - public function getClientKey($client_id); + public function getClientKey($client_id, $subject); } diff --git a/src/OAuth2/Storage/Memory.php b/src/OAuth2/Storage/Memory.php index 3d3412f..62ac28e 100644 --- a/src/OAuth2/Storage/Memory.php +++ b/src/OAuth2/Storage/Memory.php @@ -53,6 +53,11 @@ class OAuth2_Storage_Memory implements OAuth2_Storage_AuthorizationCodeInterface $this->authorizationCodes = $authorization_codes; } + public function expireAuthorizationCode($code) + { + unset($this->authorizationCodes[$code]); + } + /* UserCredentialsInterface */ public function checkUserCredentials($username, $password) { @@ -105,7 +110,7 @@ class OAuth2_Storage_Memory implements OAuth2_Storage_AuthorizationCodeInterface return isset($this->refreshTokens[$refresh_token]) ? $this->refreshTokens[$refresh_token] : null; } - public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = NULL) + public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null) { $this->refreshTokens[$refresh_token] = compact('refresh_token', 'client_id', 'user_id', 'expires', 'scope'); } @@ -132,8 +137,20 @@ class OAuth2_Storage_Memory implements OAuth2_Storage_AuthorizationCodeInterface } /*JWTBearerInterface */ - public function getClientKey($client_id) + public function getClientKey($client_id, $subject) { - return isset($this->jwt[$client_id]) ? $this->jwt[$client_id] : null; + if (isset($this->jwt[$client_id])) { + + $jwt = $this->jwt[$client_id]; + + if ($jwt) { + + if ($jwt["subject"] == $subject) { + return $jwt["key"]; + } + } + } + + return null; } } diff --git a/src/OAuth2/Storage/Pdo.php b/src/OAuth2/Storage/Pdo.php index 49fa4cf..54035f9 100644 --- a/src/OAuth2/Storage/Pdo.php +++ b/src/OAuth2/Storage/Pdo.php @@ -44,8 +44,8 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, /* ClientCredentialsInterface */ public function checkClientCredentials($client_id, $client_secret = null) { - $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = "%s"', $this->config['client_table'], $client_id)); - $stmt->execute(); + $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table'])); + $stmt->execute(compact('client_id')); $result = $stmt->fetch(); // make this extensible @@ -54,8 +54,8 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, public function getClientDetails($client_id) { - $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = "%s"', $this->config['client_table'], $client_id)); - $stmt->execute(); + $stmt = $this->db->prepare(sprintf('SELECT * from %s where client_id = :client_id', $this->config['client_table'])); + $stmt->execute(compact('client_id')); return $stmt->fetch(); } @@ -74,9 +74,9 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, /* AccessTokenInterface */ public function getAccessToken($access_token) { - $stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = "%s"', $this->config['access_token_table'], $access_token)); + $stmt = $this->db->prepare(sprintf('SELECT * from %s where access_token = :access_token', $this->config['access_token_table'])); - $token = $stmt->execute(); + $token = $stmt->execute(compact('access_token')); if ($token = $stmt->fetch()) { // convert date string back to timestamp $token['expires'] = strtotime($token['expires']); @@ -102,8 +102,8 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, /* AuthorizationCodeInterface */ public function getAuthorizationCode($code) { - $stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = "%s"', $this->config['code_table'], $code)); - $stmt->execute(); + $stmt = $this->db->prepare(sprintf('SELECT * from %s where authorization_code = :code', $this->config['code_table'])); + $stmt->execute(compact('code')); if ($code = $stmt->fetch()) { // convert date string back to timestamp @@ -127,6 +127,13 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, return $stmt->execute(compact('code', 'client_id', 'user_id', 'redirect_uri', 'expires', 'scope')); } + public function expireAuthorizationCode($code) + { + $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE authorization_code = :code', $this->config['code_table'])); + + return $stmt->execute(compact('code')); + } + /* UserCredentialsInterface */ public function checkUserCredentials($username, $password) { @@ -144,9 +151,9 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, /* RefreshTokenInterface */ public function getRefreshToken($refresh_token) { - $stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = "%s"', $this->config['refresh_token_table'], $refresh_token)); + $stmt = $this->db->prepare(sprintf('SELECT * FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table'])); - $token = $stmt->execute(); + $token = $stmt->execute(compact('refresh_token')); if ($token = $stmt->fetch()) { // convert expires to epoch time $token['expires'] = strtotime($token['expires']); @@ -155,7 +162,7 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, return $token; } - public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = NULL) + public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null) { // convert expires to datestring $expires = date('Y-m-d H:i:s', $expires); @@ -167,9 +174,9 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, public function unsetRefreshToken($refresh_token) { - $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = "%s"', $this->config['refresh_token_table'], $refresh_token)); + $stmt = $this->db->prepare(sprintf('DELETE FROM %s WHERE refresh_token = :refresh_token', $this->config['refresh_token_table'])); - return $stmt->execute(); + return $stmt->execute(compact('refresh_token')); } // plaintext passwords are bad! Override this for your application @@ -196,11 +203,11 @@ class OAuth2_Storage_Pdo implements OAuth2_Storage_AuthorizationCodeInterface, return $stmt->execute(compact('username', 'password', 'firstName', 'lastName')); } - public function getClientKey($client_id) + public function getClientKey($client_id, $subject) { - $stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id', $this->config['jwt_table'])); + $stmt = $this->db->prepare($sql = sprintf('SELECT public_key from %s where client_id=:client_id AND subject=:subject', $this->config['jwt_table'])); - $stmt->execute(array('client_id' => $client_id)); + $stmt->execute(array('client_id' => $client_id, 'subject' => $subject)); return $stmt->fetch(); } } diff --git a/src/OAuth2/Storage/RefreshTokenInterface.php b/src/OAuth2/Storage/RefreshTokenInterface.php index d1a32f7..1dbcdb6 100644 --- a/src/OAuth2/Storage/RefreshTokenInterface.php +++ b/src/OAuth2/Storage/RefreshTokenInterface.php @@ -75,4 +75,4 @@ interface OAuth2_Storage_RefreshTokenInterface * @ingroup oauth2_section_6 */ public function unsetRefreshToken($refresh_token); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Storage/UserCredentialsInterface.php b/src/OAuth2/Storage/UserCredentialsInterface.php index 9fff562..4ca7671 100644 --- a/src/OAuth2/Storage/UserCredentialsInterface.php +++ b/src/OAuth2/Storage/UserCredentialsInterface.php @@ -50,4 +50,4 @@ interface OAuth2_Storage_UserCredentialsInterface * */ public function getUserDetails($username); -}
\ No newline at end of file +} diff --git a/src/OAuth2/TokenType/Bearer.php b/src/OAuth2/TokenType/Bearer.php index 4b4135b..4773ad1 100644 --- a/src/OAuth2/TokenType/Bearer.php +++ b/src/OAuth2/TokenType/Bearer.php @@ -91,4 +91,4 @@ class OAuth2_TokenType_Bearer implements OAuth2_TokenTypeInterface, OAuth2_Respo { return $this->response; } -}
\ No newline at end of file +} diff --git a/src/OAuth2/TokenType/MAC.php b/src/OAuth2/TokenType/MAC.php index 6d47932..c6c8fe3 100644 --- a/src/OAuth2/TokenType/MAC.php +++ b/src/OAuth2/TokenType/MAC.php @@ -15,4 +15,4 @@ class OAuth2_TokenType_MAC implements OAuth2_TokenTypeInterface throw new LogicException("Not supported"); } -}
\ No newline at end of file +} diff --git a/src/OAuth2/TokenTypeInterface.php b/src/OAuth2/TokenTypeInterface.php index 27ca292..8960e9e 100644 --- a/src/OAuth2/TokenTypeInterface.php +++ b/src/OAuth2/TokenTypeInterface.php @@ -4,4 +4,4 @@ interface OAuth2_TokenTypeInterface { public function getTokenType(); public function getAccessTokenParameter(OAuth2_RequestInterface $request); -}
\ No newline at end of file +} diff --git a/src/OAuth2/Util.php b/src/OAuth2/Util.php deleted file mode 100644 index 9e1a12d..0000000 --- a/src/OAuth2/Util.php +++ /dev/null @@ -1,86 +0,0 @@ -<?php - -/** -* Class for common functions used across the Controller classes -* This may be better off in a "BaseController" class -*/ -class OAuth2_Util -{ - /** - * Check if everything in required scope is contained in available scope. - * - * @param $required_scope - * Required scope to be check with. - * - * @return - * TRUE if everything in required scope is contained in available scope, - * and FALSE if it isn't. - * - * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-7 - * - * @ingroup oauth2_section_7 - */ - public function checkScope($required_scope, $available_scope) - { - // The required scope should match or be a subset of the available scope - if (!is_array($required_scope)) { - $required_scope = explode(' ', trim($required_scope)); - } - - if (!is_array($available_scope)) { - $available_scope = explode(' ', trim($available_scope)); - } - - return (count(array_diff($required_scope, $available_scope)) == 0); - } - - /** - * Internal method for validating redirect URI supplied - * @param string $inputUri - * @param string $storedUri - */ - public function validateRedirectUri($inputUri, $storedUri) { - if (!$inputUri || !$storedUri) { - return false; // if either one is missing, assume INVALID - } - return strcasecmp(substr($inputUri, 0, strlen($storedUri)), $storedUri) === 0; - } - - /** - * Build the absolute URI based on supplied URI and parameters. - * - * @param $uri - * An absolute URI. - * @param $params - * Parameters to be append as GET. - * - * @return - * An absolute URI with supplied parameters. - * - * @ingroup oauth2_section_4 - */ - public function buildUri($uri, $params) { - $parse_url = parse_url($uri); - - // Add our params to the parsed uri - foreach ( $params as $k => $v ) { - if (isset($parse_url[$k])) { - $parse_url[$k] .= "&" . http_build_query($v); - } else { - $parse_url[$k] = http_build_query($v); - } - } - - // Put humpty dumpty back together - return - ((isset($parse_url["scheme"])) ? $parse_url["scheme"] . "://" : "") - . ((isset($parse_url["user"])) ? $parse_url["user"] - . ((isset($parse_url["pass"])) ? ":" . $parse_url["pass"] : "") . "@" : "") - . ((isset($parse_url["host"])) ? $parse_url["host"] : "") - . ((isset($parse_url["port"])) ? ":" . $parse_url["port"] : "") - . ((isset($parse_url["path"])) ? $parse_url["path"] : "") - . ((isset($parse_url["query"])) ? "?" . $parse_url["query"] : "") - . ((isset($parse_url["fragment"])) ? "#" . $parse_url["fragment"] : "") - ; - } -}
\ No newline at end of file diff --git a/src/OAuth2/Util/Scope.php b/src/OAuth2/Util/Scope.php new file mode 100644 index 0000000..cd6a4d8 --- /dev/null +++ b/src/OAuth2/Util/Scope.php @@ -0,0 +1,41 @@ +<?php + +/** +* Class for common functions used across the Controller classes +* This may be better off in a "BaseController" class +*/ +class OAuth2_Util_Scope +{ + /** + * Check if everything in required scope is contained in available scope. + * + * @param $required_scope + * Required scope to be check with. + * + * @return + * TRUE if everything in required scope is contained in available scope, + * and FALSE if it isn't. + * + * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-20#section-7 + * + * @ingroup oauth2_section_7 + */ + public function checkScope($required_scope, $available_scope) + { + // The required scope should match or be a subset of the available scope + if (!is_array($required_scope)) { + $required_scope = explode(' ', trim($required_scope)); + } + + if (!is_array($available_scope)) { + $available_scope = explode(' ', trim($available_scope)); + } + + return (count(array_diff($required_scope, $available_scope)) == 0); + } + + public function getScopeFromRequest(OAuth2_RequestInterface $request) + { + return $request->server('REQUEST_METHOD') == 'POST' ? $request->request('scope') : $request->query('scope'); + } +} |
