diff --git a/src/League/OAuth2/Server/Authorization.php b/src/League/OAuth2/Server/Authorization.php index a4b91d10..3f3342b0 100644 --- a/src/League/OAuth2/Server/Authorization.php +++ b/src/League/OAuth2/Server/Authorization.php @@ -476,18 +476,18 @@ class Authorization public function getStorage($obj) { if (!isset($this->storages[$obj])) { - throw new ServerException('The `'.$obj.'` storage interface has not been registered with the authorization - server'); + throw new ServerException( + 'The `'.$obj.'` storage interface has not been registered with the authorization server' + ); } return $this->storages[$obj]; } /** * Issue an access token - * @param array $inputParams Optional array of parsed $_POST keys * @return array Authorise request parameters */ - public function issueAccessToken($inputParams = []) + public function issueAccessToken() { $grantType = $this->getRequest()->request->get('grant_type'); if (is_null($grantType)) { @@ -500,7 +500,7 @@ class Authorization } // Complete the flow - return $this->getGrantType($grantType)->completeFlow($inputParams); + return $this->getGrantType($grantType)->completeFlow(); } /** diff --git a/src/League/OAuth2/Server/Entities/AbstractToken.php b/src/League/OAuth2/Server/Entities/AbstractToken.php index c5b5b391..ddc31140 100644 --- a/src/League/OAuth2/Server/Entities/AbstractToken.php +++ b/src/League/OAuth2/Server/Entities/AbstractToken.php @@ -14,8 +14,8 @@ namespace League\OAuth2\Server\Entities; use League\OAuth2\Server\Storage\SessionStorageInterface; use League\OAuth2\Server\Util\SecureKey; use League\OAuth2\Server\Exception\ServerException; -use \League\OAuth2\Server\Authorization; -use \League\OAuth2\Server\Resource; +use League\OAuth2\Server\Authorization; +use League\OAuth2\Server\Resource; use Symfony\Component\HttpFoundation\ParameterBag; /** @@ -29,12 +29,6 @@ abstract class AbstractToken */ protected $token; - /** - * Session ID - * @var string - */ - protected $sessionId; - /** * Associated session * @var \League\OAuth2\Server\Session @@ -71,7 +65,6 @@ abstract class AbstractToken } $this->server = $server; - $this->scopes = new ParameterBag(); return $this; } @@ -96,11 +89,8 @@ abstract class AbstractToken return $this->session; } - if ($this->sessionId !== null) { - $session = $this->server->getStorage('session')->getSession($this->sessionId); - } - - throw new ServerException('No session ID set for this token'); + $this->session = $this->server->getStorage('session')->getByAccessToken($this->token); + return $this->session; } /** @@ -148,10 +138,10 @@ abstract class AbstractToken * @param \League\OAuth2\Server\Entities\Scope $scope * @return self */ - public function associateScope($scope) + public function associateScope(Scope $scope) { - if (!$this->scopes->has($scope->getId())) { - $this->scopes->set($scope->getId(), $scope); + if (!isset($this->scopes[$scope->getId()])) { + $this->scopes[$scope->getId()] = $scope; } return $this; @@ -164,18 +154,44 @@ abstract class AbstractToken */ public function hasScope($scope) { - return $this->scopes->has($scope); + if ($this->scopes === null) { + $this->getScopes(); + } + + return isset($this->scopes[$scope]); } /** - * Return all associated scopes - * @return ParameterBag + * Return all scopes associated with the session + * @return array Array of \League\OAuth2\Server\Entities\Scope */ public function getScopes() { + if ($this->scopes === null) { + $this->scopes = $this->formatScopes( + $this->server->getStorage('access_token')->getScopes($this->getToken()) + ); + } + return $this->scopes; } + /** + * Format the local scopes array + * @param array $unformated Array of Array of \League\OAuth2\Server\Entities\Scope + * @return array + */ + private function formatScopes($unformated = []) + { + $scopes = []; + foreach ($unformated as $scope) { + if ($scope instanceof Scope) { + $scopes[$scope->getId()] = $scope; + } + } + return $scopes; + } + /** * Expire the token * @return void diff --git a/src/League/OAuth2/Server/Entities/AccessToken.php b/src/League/OAuth2/Server/Entities/AccessToken.php index 5c48c2d4..57805674 100644 --- a/src/League/OAuth2/Server/Entities/AccessToken.php +++ b/src/League/OAuth2/Server/Entities/AccessToken.php @@ -27,7 +27,7 @@ class AccessToken extends AbstractToken */ public function save() { - $this->server->getStorage('access_token')->createAccessToken( + $this->server->getStorage('access_token')->create( $this->getToken(), $this->getExpireTime(), $this->getSession()->getId() @@ -40,4 +40,12 @@ class AccessToken extends AbstractToken return $this; } + + /** + * {@inheritdoc} + */ + public function expire() + { + $this->server->getStorage('access_token')->delete($this->getToken()); + } } diff --git a/src/League/OAuth2/Server/Entities/RefreshToken.php b/src/League/OAuth2/Server/Entities/RefreshToken.php index 8be3fc43..7d91f0ad 100644 --- a/src/League/OAuth2/Server/Entities/RefreshToken.php +++ b/src/League/OAuth2/Server/Entities/RefreshToken.php @@ -45,6 +45,9 @@ class RefreshToken extends AbstractToken */ public function getAccessToken() { + if (! $this->accessToken instanceof AccessToken) { + $this->accessToken = $this->server->getStorage('access_token')->getByRefreshToken($this->getToken()); + } return $this->accessToken; } @@ -53,7 +56,7 @@ class RefreshToken extends AbstractToken */ public function save() { - $this->server->getStorage('refresh_token')->createAccessToken( + $this->server->getStorage('refresh_token')->create( $this->getToken(), $this->getExpireTime(), $this->getAccessToken()->getToken() @@ -64,4 +67,12 @@ class RefreshToken extends AbstractToken $this->server->getStorage('refresh_token')->associateScope($this->getToken(), $scope->getId()); } } + + /** + * {@inheritdoc} + */ + public function expire() + { + $this->server->getStorage('refresh_token')->delete($this->getToken()); + } } diff --git a/src/League/OAuth2/Server/Entities/Scope.php b/src/League/OAuth2/Server/Entities/Scope.php index 8d6ec4bd..3e52d203 100644 --- a/src/League/OAuth2/Server/Entities/Scope.php +++ b/src/League/OAuth2/Server/Entities/Scope.php @@ -11,6 +11,10 @@ namespace League\OAuth2\Server\Entities; +use League\OAuth2\Server\Exception\ServerException; +use League\OAuth2\Server\Authorization; +use League\OAuth2\Server\Resource; + /** * Scope entity class */ diff --git a/src/League/OAuth2/Server/Entities/Session.php b/src/League/OAuth2/Server/Entities/Session.php index 050f4c5e..8c1b0d72 100644 --- a/src/League/OAuth2/Server/Entities/Session.php +++ b/src/League/OAuth2/Server/Entities/Session.php @@ -88,7 +88,7 @@ class Session throw new ServerException('No instance of Authorization or Resource server injected'); } - $this->scopes = new ParameterBag(); + $this->server = $server; return $this; } @@ -117,10 +117,10 @@ class Session * @param \League\OAuth2\Server\Entities\Scope $scope * @return self */ - public function associateScope($scope) + public function associateScope(Scope $scope) { - if (!$this->scopes->has($scope->getId())) { - $this->scopes->set($scope->getId(), $scope); + if (!isset($this->scopes[$scope->getId()])) { + $this->scopes[$scope->getId()] = $scope; } return $this; @@ -133,7 +133,11 @@ class Session */ public function hasScope($scope) { - return $this->scopes->has($scope); + if ($this->scopes === null) { + $this->getScopes(); + } + + return isset($this->scopes[$scope]); } /** @@ -142,7 +146,27 @@ class Session */ public function getScopes() { - return $this->scopes->all(); + if ($this->scopes === null) { + $this->scopes = $this->formatScopes($this->server->getStorage('session')->getScopes($this->getId())); + } + + return $this->scopes; + } + + /** + * Format the local scopes array + * @param array $unformated Array of Array of \League\OAuth2\Server\Entities\Scope + * @return array + */ + private function formatScopes($unformated = []) + { + $scopes = []; + foreach ($unformated as $scope) { + if ($scope instanceof Scope) { + $scopes[$scope->getId()] = $scope; + } + } + return $scopes; } /** @@ -237,7 +261,7 @@ class Session public function save() { // Save the session and get an identifier - $id = $this->server->getStorage('session')->createSession( + $id = $this->server->getStorage('session')->create( $this->getOwnerType(), $this->getOwnerId(), $this->getClient()->getId(), diff --git a/src/League/OAuth2/Server/Grant/AbstractGrant.php b/src/League/OAuth2/Server/Grant/AbstractGrant.php index cb27b2ca..c800d53c 100644 --- a/src/League/OAuth2/Server/Grant/AbstractGrant.php +++ b/src/League/OAuth2/Server/Grant/AbstractGrant.php @@ -29,25 +29,25 @@ abstract class AbstractGrant implements GrantTypeInterface * Response type * @var string */ - protected $responseType = null; + protected $responseType; /** * Callback to authenticate a user's name and password * @var function */ - protected $callback = null; + protected $callback; /** * AuthServer instance * @var AuthServer */ - protected $server = null; + protected $server; /** * Access token expires in override * @var int */ - protected $accessTokenTTL = null; + protected $accessTokenTTL; /** * Return the identifier @@ -132,7 +132,7 @@ abstract class AbstractGrant implements GrantTypeInterface $scopes = []; foreach ($scopesList as $scopeItem) { - $scope = $this->server->getStorage('scope')->getScope( + $scope = $this->server->getStorage('scope')->get( $scopeItem, $this->getIdentifier() ); @@ -141,12 +141,28 @@ abstract class AbstractGrant implements GrantTypeInterface throw new ClientException(sprintf($this->server->getExceptionMessage('invalid_scope'), $scopeItem), 4); } - $scopes[] = $scope; + $scopes[$scope->getId()] = $scope; } return $scopes; } + /** + * Format the local scopes array + * @param array $unformated Array of Array of \League\OAuth2\Server\Entities\Scope + * @return array + */ + protected function formatScopes($unformated = []) + { + $scopes = []; + foreach ($unformated as $scope) { + if ($scope instanceof Scope) { + $scopes[$scope->getId()] = $scope; + } + } + return $scopes; + } + /** * Complete the grant flow * diff --git a/src/League/OAuth2/Server/Grant/ClientCredentials.php b/src/League/OAuth2/Server/Grant/ClientCredentials.php index 5e718e1d..8c573fa5 100644 --- a/src/League/OAuth2/Server/Grant/ClientCredentials.php +++ b/src/League/OAuth2/Server/Grant/ClientCredentials.php @@ -76,7 +76,7 @@ class ClientCredentials extends AbstractGrant } // Validate client ID and client secret - $client = $this->server->getStorage('client')->getClient( + $client = $this->server->getStorage('client')->get( $clientId, $clientSecret, null, @@ -92,12 +92,12 @@ class ClientCredentials extends AbstractGrant $scopes = $this->validateScopes($scopeParam); // Create a new session - $session = new Session(); + $session = new Session($this->server); $session->setOwner('client', $client->getId()); $session->associateClient($client); // Generate an access token - $accessToken = new AccessToken(); + $accessToken = new AccessToken($this->server); $accessToken->setToken(SecureKey::make()); $accessToken->setExpireTime($this->server->getAccessTokenTTL() + time()); diff --git a/src/League/OAuth2/Server/Grant/Password.php b/src/League/OAuth2/Server/Grant/Password.php index 85231dff..a4842ec1 100644 --- a/src/League/OAuth2/Server/Grant/Password.php +++ b/src/League/OAuth2/Server/Grant/Password.php @@ -39,25 +39,19 @@ class Password extends AbstractGrant * Response type * @var string */ - protected $responseType = null; + protected $responseType; /** * Callback to authenticate a user's name and password * @var function */ - protected $callback = null; - - /** - * AuthServer instance - * @var AuthServer - */ - protected $authServer = null; + protected $callback; /** * Access token expires in override * @var int */ - protected $accessTokenTTL = null; + protected $accessTokenTTL; /** * Set the callback to verify a user's username and password @@ -107,7 +101,7 @@ class Password extends AbstractGrant } // Validate client ID and client secret - $client = $this->server->getStorage('client')->getClient( + $client = $this->server->getStorage('client')->get( $clientId, $clientSecret, null, @@ -177,13 +171,13 @@ class Password extends AbstractGrant } // Save everything - $session->save($this->server->getStorage('session')); + $session->save(); $accessToken->setSession($session); - $accessToken->save($this->server->getStorage('access_token')); + $accessToken->save(); if ($this->server->hasGrantType('refresh_token')) { $refreshToken->setAccessToken($accessToken); - $refreshToken->save($this->server->getStorage('refresh_token')); + $refreshToken->save(); } return $response; diff --git a/src/League/OAuth2/Server/Grant/RefreshToken.php b/src/League/OAuth2/Server/Grant/RefreshToken.php index 067aaa8a..b816f277 100644 --- a/src/League/OAuth2/Server/Grant/RefreshToken.php +++ b/src/League/OAuth2/Server/Grant/RefreshToken.php @@ -80,7 +80,7 @@ class RefreshToken extends AbstractGrant } // Validate client ID and client secret - $client = $this->server->getStorage('client')->getClient( + $client = $this->server->getStorage('client')->get( $clientId, $clientSecret, null, @@ -100,7 +100,7 @@ class RefreshToken extends AbstractGrant } // Validate refresh token - $oldRefreshToken = $this->server->getStorage('refresh_token')->getToken($oldRefreshTokenParam); + $oldRefreshToken = $this->server->getStorage('refresh_token')->get($oldRefreshTokenParam); if (($oldRefreshToken instanceof RT) === false) { throw new Exception\ClientException($this->server->getExceptionMessage('invalid_refresh'), 0); @@ -110,7 +110,7 @@ class RefreshToken extends AbstractGrant // Get the scopes for the original session $session = $oldAccessToken->getSession(); - $scopes = $session->getScopes(); + $scopes = $this->formatScopes($session->getScopes()); // Get and validate any requested scopes $requestedScopesString = $this->server->getRequest()->request->get('scope', ''); @@ -124,14 +124,19 @@ class RefreshToken extends AbstractGrant // the request doesn't include any new scopes foreach ($requestedScopes as $requestedScope) { - // if () + if (!isset($scopes[$requestedScope->getId()])) { + throw new Exception\ClientException( + sprintf($this->server->getExceptionMessage('invalid_scope'), $requestedScope->getId()), + 0 + ); + } } $newScopes = $requestedScopes; } // Generate a new access token and assign it the correct sessions - $newAccessToken = new AccessToken(); + $newAccessToken = new AccessToken($this->server); $newAccessToken->setToken(SecureKey::make()); $newAccessToken->setExpireTime($this->server->getAccessTokenTTL() + time()); $newAccessToken->setSession($session); @@ -155,7 +160,7 @@ class RefreshToken extends AbstractGrant $oldRefreshToken->expire($this->server->getStorage('refresh_token')); // Generate a new refresh token - $newRefreshToken = new RT(); + $newRefreshToken = new RT($this->server); $newRefreshToken->setToken(SecureKey::make()); $newRefreshToken->setExpireTime($this->getRefreshTokenTTL() + time()); $newRefreshToken->setAccessToken($newAccessToken); diff --git a/src/League/OAuth2/Server/Storage/AccessTokenInterface.php b/src/League/OAuth2/Server/Storage/AccessTokenInterface.php index 79d2edb9..1e4afdf9 100644 --- a/src/League/OAuth2/Server/Storage/AccessTokenInterface.php +++ b/src/League/OAuth2/Server/Storage/AccessTokenInterface.php @@ -21,14 +21,16 @@ interface AccessTokenInterface * @param string $token The access token * @return \League\OAuth2\Server\Entities\AccessToken */ - public function getToken($token); + public function get($token); + + public function getByRefreshToken($refreshToken); /** * Get the scopes for an access token * @param string $token The access token * @return array Array of \League\OAuth2\Server\Entities\Scope */ - public function getTokenScopes($token); + public function getScopes($token); /** * Creates a new access token @@ -37,7 +39,7 @@ interface AccessTokenInterface * @param string|integer $sessionId The session ID * @return \League\OAuth2\Server\Entities\AccessToken */ - public function createAccessToken($token, $expireTime, $sessionId); + public function create($token, $expireTime, $sessionId); /** * Associate a scope with an acess token diff --git a/src/League/OAuth2/Server/Storage/AuthCodeInterface.php b/src/League/OAuth2/Server/Storage/AuthCodeInterface.php index 58add25d..e3d2b876 100644 --- a/src/League/OAuth2/Server/Storage/AuthCodeInterface.php +++ b/src/League/OAuth2/Server/Storage/AuthCodeInterface.php @@ -21,5 +21,5 @@ interface AuthCodeInterface * @param string $code * @return \League\OAuth2\Server\Entities\AuthCode */ - public function getCode($code); + public function get($code); } diff --git a/src/League/OAuth2/Server/Storage/ClientInterface.php b/src/League/OAuth2/Server/Storage/ClientInterface.php index b21e4194..705e89f9 100644 --- a/src/League/OAuth2/Server/Storage/ClientInterface.php +++ b/src/League/OAuth2/Server/Storage/ClientInterface.php @@ -18,34 +18,11 @@ interface ClientInterface { /** * Validate a client - * - * Example SQL query: - * - * - * # Client ID + redirect URI - * SELECT oauth_clients.id, oauth_clients.secret, oauth_endpoints.redirect_uri, oauth_clients.name - * FROM oauth_clients - * LEFT JOIN oauth_client_endpoints ON oauth_client_endpoints.client_id = oauth_clients.id - * WHERE oauth_clients.id = :clientId AND oauth_client_endpoints.redirect_uri = :redirectUri - * - * # Client ID + client secret - * SELECT oauth_clients.id, oauth_clients.secret, oauth_clients.name - * FROM oauth_clients - * WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret - * - * # Client ID + client secret + redirect URI - * SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name - * FROM oauth_clients LEFT JOIN oauth_client_endpoints - * ON oauth_client_endpoints.client_id = oauth_clients.id - * WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret AND - * oauth_client_endpoints.redirect_uri = :redirectUri - * - * * @param string $clientId The client's ID * @param string $clientSecret The client's secret (default = "null") * @param string $redirectUri The client's redirect URI (default = "null") * @param string $grantType The grant type used in the request (default = "null") * @return League\OAuth2\Server\Entities\Client|null */ - public function getClient($clientId, $clientSecret = null, $redirectUri = null, $grantType = null); + public function get($clientId, $clientSecret = null, $redirectUri = null, $grantType = null); } diff --git a/src/League/OAuth2/Server/Storage/RefreshTokenInterface.php b/src/League/OAuth2/Server/Storage/RefreshTokenInterface.php index e77fe37d..eed16f3f 100644 --- a/src/League/OAuth2/Server/Storage/RefreshTokenInterface.php +++ b/src/League/OAuth2/Server/Storage/RefreshTokenInterface.php @@ -21,7 +21,7 @@ interface RefreshTokenInterface * @param string $token * @return \League\OAuth2\Server\Entities\RefreshToken */ - public function getToken($token); + public function get($token); /** * Create a new refresh token_name @@ -30,7 +30,7 @@ interface RefreshTokenInterface * @param string $accessToken * @return \League\OAuth2\Server\Entities\RefreshToken */ - public function createRefreshToken($token, $expireTime, $accessToken); + public function create($token, $expireTime, $accessToken); /** * Delete the refresh token diff --git a/src/League/OAuth2/Server/Storage/ScopeInterface.php b/src/League/OAuth2/Server/Storage/ScopeInterface.php index a6d8b6ac..26454389 100644 --- a/src/League/OAuth2/Server/Storage/ScopeInterface.php +++ b/src/League/OAuth2/Server/Storage/ScopeInterface.php @@ -29,5 +29,5 @@ interface ScopeInterface * @param string $grantType The grant type used in the request (default = "null") * @return bool|array If the scope doesn't exist return false */ - public function getScope($scope, $grantType = null); + public function get($scope, $grantType = null); } diff --git a/src/League/OAuth2/Server/Storage/SessionInterface.php b/src/League/OAuth2/Server/Storage/SessionInterface.php index c5bc767e..1be23ba8 100644 --- a/src/League/OAuth2/Server/Storage/SessionInterface.php +++ b/src/League/OAuth2/Server/Storage/SessionInterface.php @@ -17,25 +17,25 @@ namespace League\OAuth2\Server\Storage; interface SessionInterface { /** - * Get a session - * - * @param int $sessionId - * @return array (As described above) + * Get a session from it's identifier + * @param string $sessionId + * @return \League\OAuth2\Server\Entities\Session */ - public function getSession($sessionId); + public function get($sessionId); + + /** + * Get a session from an access token + * @param string $accessToken The access token + * @return \League\OAuth2\Server\Entities\Session + */ + public function getByAccessToken($accessToken); /** * Get a session's scopes - * - * Response: - * - * - * - * - * @param int $sessionId - * @return array (As described aboce) + * @param integer $sessionId + * @return array Array of \League\OAuth2\Server\Entities\Scope */ - public function getSessionScopes($sessionId); + public function getScopes($sessionId); /** * Create a new session @@ -43,14 +43,14 @@ interface SessionInterface * @param string $ownerId Session owner's ID * @param string $clientId Client ID * @param string $clientRedirectUri Client redirect URI (default = null) - * @return int Session ID + * @return integer The session's ID */ - public function createSession($ownerType, $ownerId, $clientId, $clientRedirectUri = null); + public function create($ownerType, $ownerId, $clientId, $clientRedirectUri = null); /** * Associate a scope with a session - * @param int $sessionId - * @param int|string $scopeId The scopes ID might be an integer or string + * @param integer $sessionId + * @param string $scopeId The scopes ID might be an integer or string * @return void */ public function associateScope($sessionId, $scopeId);