diff --git a/src/League/OAuth2/Server/Grant/ClientCredentials.php b/src/League/OAuth2/Server/Grant/ClientCredentials.php index aa072d09..7d9bff3b 100644 --- a/src/League/OAuth2/Server/Grant/ClientCredentials.php +++ b/src/League/OAuth2/Server/Grant/ClientCredentials.php @@ -11,9 +11,12 @@ namespace League\OAuth2\Server\Grant; -use League\OAuth2\Server\Request; use League\OAuth2\Server\Authorization; -use League\OAuth2\Server\Exception; +use League\OAuth2\Server\Entities\AccessToken; +use League\OAuth2\Server\Entities\Client; +use League\OAuth2\Server\Entities\Session; +use League\OAuth2\Server\Entities\Scope; +use League\OAuth2\Server\Exception\ClientException; use League\OAuth2\Server\Util\SecureKey; use League\OAuth2\Server\Storage\SessionInterface; use League\OAuth2\Server\Storage\ClientInterface; @@ -22,8 +25,8 @@ use League\OAuth2\Server\Storage\ScopeInterface; /** * Client credentials grant class */ -class ClientCredentials implements GrantTypeInterface { - +class ClientCredentials implements GrantTypeInterface +{ use GrantTrait; /** @@ -42,7 +45,7 @@ class ClientCredentials implements GrantTypeInterface { * AuthServer instance * @var AuthServer */ - protected $authServer = null; + protected $server = null; /** * Access token expires in override @@ -50,115 +53,78 @@ class ClientCredentials implements GrantTypeInterface { */ protected $accessTokenTTL = null; - /** - * Return the identifier - * @return string - */ - public function getIdentifier() - { - return $this->identifier; - } - - /** - * Return the response type - * @return string - */ - public function getResponseType() - { - return $this->responseType; - } - - /** - * Override the default access token expire time - * @param int $accessTokenTTL - * @return void - */ - public function setAccessTokenTTL($accessTokenTTL) - { - $this->accessTokenTTL = $accessTokenTTL; - } - /** * Complete the client credentials grant * @param null|array $inputParams * @return array */ - public function completeFlow($inputParams = null) + public function completeFlow() { // Get the required params - $authParams = $this->authServer->getParam(array('client_id', 'client_secret'), 'post', $inputParams); - - if (is_null($authParams['client_id'])) { - throw new Exception\ClientException(sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_id'), 0); + $clientId = $this->server->getRequest()->request->get('client_id', null); + if (is_null($clientId)) { + throw new ClientException( + sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_id'), + 0 + ); } - if (is_null($authParams['client_secret'])) { - throw new Exception\ClientException(sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_secret'), 0); + $clientSecret = $this->server->getRequest()->request->get('client_secret', null); + if (is_null($clientSecret)) { + throw new ClientException( + sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_secret'), + 0 + ); } // Validate client ID and client secret - $clientDetails = $this->authServer->getStorage('client')->getClient($authParams['client_id'], $authParams['client_secret'], null, $this->identifier); + $clientDetails = $this->server->getStorage('client')->getClient( + $clientId, + $clientSecret, + null, + $this->getIdentifier() + ); if ($clientDetails === false) { - throw new Exception\ClientException(Authorization::getExceptionMessage('invalid_client'), 8); + throw new ClientException(Authorization::getExceptionMessage('invalid_client'), 8); } - $authParams['client_details'] = $clientDetails; + $client = new Client; + $client->setId($clientDetails['id']); + $client->setSecret($clientDetails['secret']); // Validate any scopes that are in the request - $scope = $this->authServer->getParam('scope', 'post', $inputParams, ''); - $scopes = explode($this->authServer->getScopeDelimeter(), $scope); - - for ($i = 0; $i < count($scopes); $i++) { - $scopes[$i] = trim($scopes[$i]); - if ($scopes[$i] === '') unset($scopes[$i]); // Remove any junk scopes - } - - if ($this->authServer->scopeParamRequired() === true && $this->authServer->getDefaultScope() === null && count($scopes) === 0) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'scope'), 0); - } elseif (count($scopes) === 0 && $this->authServer->getDefaultScope() !== null) { - if (is_array($this->authServer->getDefaultScope())) { - $scopes = $this->authServer->getDefaultScope(); - } else { - $scopes = array($this->authServer->getDefaultScope()); - } - } - - $authParams['scopes'] = array(); - - foreach ($scopes as $scope) { - $scopeDetails = $this->authServer->getStorage('scope')->getScope($scope, $authParams['client_id'], $this->identifier); - - if ($scopeDetails === false) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_scope'), $scope), 4); - } - - $authParams['scopes'][] = $scopeDetails; - } - - // Generate an access token - $accessToken = SecureKey::make(); - $accessTokenExpiresIn = ($this->accessTokenTTL !== null) ? $this->accessTokenTTL : $this->authServer->getAccessTokenTTL(); - $accessTokenExpires = time() + $accessTokenExpiresIn; + $scopeParam = $this->server->getRequest()->request->get('scope', ''); + $scopes = $this->validateScopes($scopeParam); // Create a new session - $sessionId = $this->authServer->getStorage('session')->createSession($authParams['client_id'], 'client', $authParams['client_id']); + $session = new Session($this->server->getStorage('session')); + $session->setOwner('client', $client->getId()); + $session->associateClient($client); - // Add the access token - $accessTokenId = $this->authServer->getStorage('session')->associateAccessToken($sessionId, $accessToken, $accessTokenExpires); + // Generate an access token + $accessToken = new AccessToken($this->server->getStorage('access_token')); + $accessToken->setId(SecureKey::make()); + $accessToken->setTimestamp(time()); + $accessToken->setTTL($this->server->getAccessTokenTTL()); - // Associate scopes with the new session - foreach ($authParams['scopes'] as $scope) - { - $this->authServer->getStorage('session')->associateScope($accessTokenId, $scope['id']); + // Associate scopes with the session and access token + foreach ($scopes as $scope) { + $accessToken->associateScope($scope); + $session->associateScope($scope); } - $response = array( - 'access_token' => $accessToken, + // Save everything + $session->save(); + $accessToken->setSession($session); + $accessToken->save(); + + $response = [ + 'access_token' => $accessToken->getId(), 'token_type' => 'Bearer', - 'expires' => $accessTokenExpires, - 'expires_in' => $accessTokenExpiresIn - ); + 'expires' => $accessToken->getExpireTime(), + 'expires_in' => $accessToken->getTTL() + ]; return $response; } diff --git a/src/League/OAuth2/Server/Grant/GrantTrait.php b/src/League/OAuth2/Server/Grant/GrantTrait.php index 0d555319..438e34f2 100644 --- a/src/League/OAuth2/Server/Grant/GrantTrait.php +++ b/src/League/OAuth2/Server/Grant/GrantTrait.php @@ -17,18 +17,10 @@ trait GrantTrait { /** * Constructor - * @param Authorization $authServer Authorization server instance * @return void */ - public function __construct(Authorization $authServer = null) + public function __construct() { - // @codeCoverageIgnoreStart - if ($authServer instanceof Authorization) { - trigger_error( - 'Server is now automatically injected into grant as of v3.1 of this library', - E_USER_DEPRECATED - ); - } // @codeCoverageIgnoreEnd } /** @@ -73,13 +65,59 @@ trait GrantTrait { /** * Inject the authorization server into the grant - * @param Authorization $authServer The authorization server instance + * @param Authorization $server The authorization server instance * @return self */ - public function setAuthorizationServer(Authorization $authServer) + public function setAuthorizationServer(Authorization $server) { - $this->authServer = $authServer; + $this->server = $server; return $this; } + public function validateScopes($scopeParam = '') + { + $scopesList = explode($this->server->getScopeDelimeter(), $scopeParam); + + for ($i = 0; $i < count($scopesList); $i++) { + $scopesList[$i] = trim($scopesList[$i]); + if ($scopesList[$i] === '') unset($scopesList[$i]); // Remove any junk scopes + } + + if ( + $this->server->scopeParamRequired() === true && + $this->server->getDefaultScope() === null && + count($scopesList) === 0 + ) { + throw new ClientException(sprintf($this->server->getExceptionMessage('invalid_request'), 'scope'), 0); + } elseif (count($scopesList) === 0 && $this->server->getDefaultScope() !== null) { + if (is_array($this->server->getDefaultScope())) { + $scopesList = $this->server->getDefaultScope(); + } else { + $scopesList = [0 => $this->server->getDefaultScope()]; + } + } + + $scopes = []; + + foreach ($scopesList as $scopeItem) { + $scopeDetails = $this->server->getStorage('scope')->getScope( + $scopeItem, + $client->getId(), + $this->getIdentifier() + ); + + if ($scopeDetails === false) { + throw new ClientException(sprintf($this->server->getExceptionMessage('invalid_scope'), $scopeItem), 4); + } + + $scope = new Scope($this->server->getStorage('scope')); + $scope->setId($scopeDetails['id']); + $scope->setName($scopeDetails['name']); + + $scopes[] = $scope; + } + + return $scopes; + } + } diff --git a/src/League/OAuth2/Server/Grant/GrantTypeInterface.php b/src/League/OAuth2/Server/Grant/GrantTypeInterface.php index 2301bd4e..18ef774b 100644 --- a/src/League/OAuth2/Server/Grant/GrantTypeInterface.php +++ b/src/League/OAuth2/Server/Grant/GrantTypeInterface.php @@ -23,9 +23,10 @@ interface GrantTypeInterface { /** * Constructor + * * @return void */ - public function __construct(Authorization $authServer = null); + public function __construct(); /** * Complete the grant flow @@ -41,8 +42,7 @@ interface GrantTypeInterface * ) * * - * @param null|array $inputParams Null unless the input parameters have been manually set * @return array An array of parameters to be passed back to the client */ - public function completeFlow($inputParams = null); + public function completeFlow(); } diff --git a/src/League/OAuth2/Server/Grant/Password.php b/src/League/OAuth2/Server/Grant/Password.php index 54410586..91e6e5c3 100644 --- a/src/League/OAuth2/Server/Grant/Password.php +++ b/src/League/OAuth2/Server/Grant/Password.php @@ -11,9 +11,14 @@ namespace League\OAuth2\Server\Grant; -use League\OAuth2\Server\Request; use League\OAuth2\Server\Authorization; -use League\OAuth2\Server\Exception; +use League\OAuth2\Server\Entities\AccessToken; +use League\OAuth2\Server\Entities\Client; +use League\OAuth2\Server\Entities\RefreshToken; +use League\OAuth2\Server\Entities\Session; +use League\OAuth2\Server\Entities\Scope; +use League\OAuth2\Server\Exception\ClientException; +use League\OAuth2\Server\Exception\InvalidGrantTypeException; use League\OAuth2\Server\Util\SecureKey; use League\OAuth2\Server\Storage\SessionInterface; use League\OAuth2\Server\Storage\ClientInterface; @@ -61,7 +66,7 @@ class Password implements GrantTypeInterface { * @param callable $callback The callback function * @return void */ - public function setVerifyCredentialsCallback($callback) + public function setVerifyCredentialsCallback(callable $callback) { $this->callback = $callback; } @@ -73,7 +78,7 @@ class Password implements GrantTypeInterface { protected function getVerifyCredentialsCallback() { if (is_null($this->callback) || ! is_callable($this->callback)) { - throw new Exception\InvalidGrantTypeException('Null or non-callable callback set'); + throw new InvalidGrantTypeException('Null or non-callable callback set on Password grant'); } return $this->callback; @@ -87,100 +92,108 @@ class Password implements GrantTypeInterface { public function completeFlow($inputParams = null) { // Get the required params - $authParams = $this->authServer->getParam(array('client_id', 'client_secret', 'username', 'password'), 'post', $inputParams); - - if (is_null($authParams['client_id'])) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_id'), 0); + $clientId = $this->server->getRequest()->request->get('client_id', null); + if (is_null($clientId)) { + throw new ClientException( + sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_id'), + 0 + ); } - if (is_null($authParams['client_secret'])) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'client_secret'), 0); + $clientSecret = $this->server->getRequest()->request->get('client_secret', null); + if (is_null($clientSecret)) { + throw new ClientException( + sprintf(Authorization::getExceptionMessage('invalid_request'), 'client_secret'), + 0 + ); } - // Validate client credentials - $clientDetails = $this->authServer->getStorage('client')->getClient($authParams['client_id'], $authParams['client_secret'], null, $this->identifier); + // Validate client ID and client secret + $clientDetails = $this->server->getStorage('client')->getClient( + $clientId, + $clientSecret, + null, + $this->getIdentifier() + ); if ($clientDetails === false) { - throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_client'), 8); + throw new ClientException(Authorization::getExceptionMessage('invalid_client'), 8); } - $authParams['client_details'] = $clientDetails; + $client = new Client; + $client->setId($clientDetails['id']); + $client->setSecret($clientDetails['secret']); - if (is_null($authParams['username'])) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'username'), 0); + + + $username = $this->server->getRequest()->request->get('username', null); + if (is_null($username)) { + throw new ClientException( + sprintf(Authorization::getExceptionMessage('invalid_request'), 'username'), + 0 + ); } - if (is_null($authParams['password'])) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'password'), 0); + $password = $this->server->getRequest()->request->get('password', null); + if (is_null($password)) { + throw new ClientException( + sprintf(Authorization::getExceptionMessage('invalid_request'), 'password'), + 0 + ); } // Check if user's username and password are correct - $userId = call_user_func($this->getVerifyCredentialsCallback(), $authParams['username'], $authParams['password']); + $userId = call_user_func($this->getVerifyCredentialsCallback(), $username, $password); if ($userId === false) { throw new Exception\ClientException($this->authServer->getExceptionMessage('invalid_credentials'), 0); } // Validate any scopes that are in the request - $scope = $this->authServer->getParam('scope', 'post', $inputParams, ''); - $scopes = explode($this->authServer->getScopeDelimeter(), $scope); - - for ($i = 0; $i < count($scopes); $i++) { - $scopes[$i] = trim($scopes[$i]); - if ($scopes[$i] === '') unset($scopes[$i]); // Remove any junk scopes - } - - if ($this->authServer->scopeParamRequired() === true && $this->authServer->getDefaultScope() === null && count($scopes) === 0) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_request'), 'scope'), 0); - } elseif (count($scopes) === 0 && $this->authServer->getDefaultScope() !== null) { - if (is_array($this->authServer->getDefaultScope())) { - $scopes = $this->authServer->getDefaultScope(); - } else { - $scopes = array($this->authServer->getDefaultScope()); - } - } - - $authParams['scopes'] = array(); - - foreach ($scopes as $scope) { - $scopeDetails = $this->authServer->getStorage('scope')->getScope($scope, $authParams['client_id'], $this->identifier); - - if ($scopeDetails === false) { - throw new Exception\ClientException(sprintf($this->authServer->getExceptionMessage('invalid_scope'), $scope), 4); - } - - $authParams['scopes'][] = $scopeDetails; - } - - // Generate an access token - $accessToken = SecureKey::make(); - $accessTokenExpiresIn = ($this->accessTokenTTL !== null) ? $this->accessTokenTTL : $this->authServer->getAccessTokenTTL(); - $accessTokenExpires = time() + $accessTokenExpiresIn; + $scopeParam = $this->server->getRequest()->request->get('scope', ''); + $scopes = $this->validateScopes($scopeParam); // Create a new session - $sessionId = $this->authServer->getStorage('session')->createSession($authParams['client_id'], 'user', $userId); + $session = new Session($this->server->getStorage('session')); + $session->setOwner('user', $userId); + $session->associateClient($client); - // Associate an access token with the session - $accessTokenId = $this->authServer->getStorage('session')->associateAccessToken($sessionId, $accessToken, $accessTokenExpires); + // Generate an access token + $accessToken = new AccessToken($this->server->getStorage('access_token')); + $accessToken->setId(SecureKey::make()); + $accessToken->setTimestamp(time()); + $accessToken->setTTL($this->server->getAccessTokenTTL()); - // Associate scopes with the access token - foreach ($authParams['scopes'] as $scope) { - $this->authServer->getStorage('session')->associateScope($accessTokenId, $scope['id']); + // Associate scopes with the session and access token + foreach ($scopes as $scope) { + $accessToken->associateScope($scope); + $session->associateScope($scope); } - $response = array( - 'access_token' => $accessToken, + $response = [ + 'access_token' => $accessToken->getId(), 'token_type' => 'Bearer', - 'expires' => $accessTokenExpires, - 'expires_in' => $accessTokenExpiresIn - ); + 'expires' => $accessToken->getExpireTime(), + 'expires_in' => $accessToken->getTTL() + ]; // Associate a refresh token if set - if ($this->authServer->hasGrantType('refresh_token')) { - $refreshToken = SecureKey::make(); - $refreshTokenTTL = time() + $this->authServer->getGrantType('refresh_token')->getRefreshTokenTTL(); - $this->authServer->getStorage('session')->associateRefreshToken($accessTokenId, $refreshToken, $refreshTokenTTL, $authParams['client_id']); - $response['refresh_token'] = $refreshToken; + if ($this->server->hasGrantType('refresh_token')) { + $refreshToken = new RefreshToken($this->server->getStorage('refresh_token')); + $refreshToken->setId(SecureKey::make()); + $refreshToken->setTimestamp(time()); + $refreshToken->setTTL($this->server->getGrantType('refresh_token')->getRefreshTokenTTL()); + $response['refresh_token'] = $refreshToken->getId(); + } + + // Save everything + $session->save(); + $accessToken->setSession($session); + $accessToken->save(); + + if ($this->server->hasGrantType('refresh_token')) { + $refreshToken->setAccessToken($accessToken); + $refreshToken->save(); } return $response;