From 0f6f5e293951ad1b200358a372802f8b7e603487 Mon Sep 17 00:00:00 2001 From: Daniel Horrigan Date: Wed, 19 Dec 2012 16:12:48 -0500 Subject: [PATCH 01/14] Added the user_credentials and refresh_token grants. Fixed expires_in so it is inline with the spec, but added expires for the old usage of expires_in. Made redirect_uri in oauth_sessions ALLOW NULL since user_credential grants don't have a redirect --- sql/database.sql | 5 +- src/Oauth2/Authentication/Database.php | 22 +++ src/Oauth2/Authentication/Server.php | 202 +++++++++++++++++++++++-- 3 files changed, 214 insertions(+), 15 deletions(-) diff --git a/sql/database.sql b/sql/database.sql index 8c01870c..b260d9f0 100644 --- a/sql/database.sql +++ b/sql/database.sql @@ -21,11 +21,12 @@ CREATE TABLE `client_endpoints` ( CREATE TABLE `oauth_sessions` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `client_id` varchar(40) NOT NULL DEFAULT '', - `redirect_uri` varchar(250) NOT NULL DEFAULT '', + `redirect_uri` varchar(250) DEFAULT '', `owner_type` enum('user','client') NOT NULL DEFAULT 'user', `owner_id` varchar(255) DEFAULT NULL, `auth_code` varchar(40) DEFAULT '', `access_token` varchar(40) DEFAULT '', + `refresh_token` varchar(40) NOT NULL, `access_token_expires` int(10) DEFAULT NULL, `stage` enum('requested','granted') NOT NULL DEFAULT 'requested', `first_requested` int(10) unsigned NOT NULL, @@ -56,4 +57,4 @@ CREATE TABLE `oauth_session_scopes` ( KEY `scope` (`scope`), CONSTRAINT `oauth_session_scopes_ibfk_3` FOREIGN KEY (`scope`) REFERENCES `scopes` (`scope`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `oauth_session_scopes_ibfk_4` FOREIGN KEY (`session_id`) REFERENCES `oauth_sessions` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/src/Oauth2/Authentication/Database.php b/src/Oauth2/Authentication/Database.php index b46a05ec..d4ef203f 100644 --- a/src/Oauth2/Authentication/Database.php +++ b/src/Oauth2/Authentication/Database.php @@ -77,6 +77,7 @@ interface Database $typeId = null, $authCode = null, $accessToken = null, + $refreshToken = null, $accessTokenExpire = null, $stage = 'requested' ); @@ -102,6 +103,7 @@ interface Database $sessionId, $authCode = null, $accessToken = null, + $refreshToken = null, $accessTokenExpire = null, $stage = 'requested' ); @@ -125,6 +127,26 @@ interface Database $typeId ); + + /** + * Update the refresh token + * + * Database query: + * + * + * UPDATE oauth_sessions SET access_token = $newAccessToken, refresh_token = + * $newRefreshToken, access_toke_expires = $accessTokenExpires, last_updated = UNIX_TIMESTAMP(NOW()) WHERE + * refresh_token = $currentRefreshToken + * + * + * @param string $currentRefreshToken The session's current refresh token + * @param string $newAccessToken The new access token for this session + * @param string $newRefreshToken The new refresh token for the session + * @param int $accessTokenExpires The UNIX timestamp of when the new token expires + * @return bool Whether the $currentRefreshToken was valid or not. + */ + public function refreshToken($currentRefreshToken, $newAccessToken, $newRefreshToken, $accessTokenExpires); + /** * Validate that an authorisation code is valid * diff --git a/src/Oauth2/Authentication/Server.php b/src/Oauth2/Authentication/Server.php index 3e295626..2a191c21 100644 --- a/src/Oauth2/Authentication/Server.php +++ b/src/Oauth2/Authentication/Server.php @@ -30,8 +30,8 @@ class Server * @var array */ private $_config = array( - 'scope_delimeter' => ',', - 'access_token_ttl' => null + 'scope_delimeter' => ',', + 'access_token_ttl' => 3600 ); /** @@ -47,7 +47,9 @@ class Server * @var array */ private $_grantTypes = array( - 'authorization_code' + 'authorization_code', + 'user_credentials', + 'refresh_token', ); /** @@ -75,16 +77,18 @@ class Server * @var array */ public $errors = 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.', - 'unauthorized_client' => 'The client is not authorized to request an access token using this method.', - 'access_denied' => 'The resource owner or authorization server denied the request.', + '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.', + 'unauthorized_client' => 'The client is not authorized to request an access token using this method.', + 'access_denied' => 'The resource owner or authorization server denied the request.', 'unsupported_response_type' => 'The authorization server does not support obtaining an access token using this method.', - 'invalid_scope' => 'The requested scope is invalid, unknown, or malformed. Check the "%s" scope.', - 'server_error' => 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.', + 'invalid_scope' => 'The requested scope is invalid, unknown, or malformed. Check the "%s" scope.', + 'server_error' => 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.', 'temporarily_unavailable' => 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.', 'unsupported_grant_type' => 'The authorization grant type is not supported by the authorization server', - 'invalid_client' => 'Client authentication failed', - 'invalid_grant' => 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.' + 'invalid_client' => 'Client authentication failed', + 'invalid_grant' => 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.', + 'invalid_credentials' => 'Invalid Credentials', + 'invalid_refresh' => 'Invalid Refresh Token', ); /** @@ -284,7 +288,7 @@ class Server * @param string $accessToken The access token (default = null) * @return string An authorisation code */ - private function newAuthCode($clientId, $type, $typeId, $redirectUri, $scopes = array(), $accessToken = null) + private function newAuthCode($clientId, $type, $typeId, $redirectUri, $scopes = array(), $accessToken = null, $refreshToken = null) { $authCode = $this->generateCode(); @@ -299,6 +303,7 @@ class Server $typeId, $authCode, $accessToken, + $refreshToken, 'requested' ); @@ -374,9 +379,17 @@ class Server return $this->completeAuthCodeGrant($authParams, $params); break; + case 'user_credentials': + return $this->completeUserCredentialsGrant($authParams, $params); + break; + case 'refresh_token': // Refresh token + return $this->completeRefreshTokenGrant($authParams, $params); + break; + case 'password': // Resource owner password credentials grant case 'client_credentials': // Client credentials grant + default: // Unsupported throw new ServerException($this->errors['server_error'] . 'Tried to process an unsuppported grant type.', 5); break; @@ -479,16 +492,19 @@ class Server // remove the authorisation code, change the stage to 'granted' $accessToken = $this->generateCode(); + $refreshToken = $this->generateCode(); $accessTokenExpires = ($this->_config['access_token_ttl'] === null) ? null : time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl']; $this->_dbCall( 'updateSession', $session['id'], null, $accessToken, + $refreshToken, $accessTokenExpires, 'granted' ); @@ -497,17 +513,177 @@ class Server $this->_dbCall( 'updateSessionScopeAccessToken', $session['id'], - $accessToken + $accessToken, + $refreshToken ); return array( 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, 'token_type' => 'bearer', - 'expires_in' => $this->_config['access_token_ttl'] + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn ); } } + /** + * Complete the user credentials grant + * + * @access private + * + * @param array $authParams Array of parsed $_POST keys + * @param array $params Generated parameters from issueAccessToken() + * + * @return array Authorise request parameters + */ + private function completeUserCredentialsGrant($authParams = array(), $params = array()) + { + $params = array(); + + if ( ! isset($authParams['user_auth_callback'])) { + throw new \InvalidArgumentException('You must set a user_auth_callback when using the user_credentials grant type.'); + } + + // Client ID + if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) { + throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); + } else { + $params['client_id'] = (isset($authParams['client_id'])) ? + $authParams['client_id'] : + $_POST['client_id']; + } + + // Client secret + if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) { + throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0); + } else { + $params['client_secret'] = (isset($authParams['client_secret'])) ? + $authParams['client_secret'] : + $_POST['client_secret']; + } + + // Validate client ID and redirect URI + $clientDetails = $this->_dbCall( + 'validateClient', + $params['client_id'], + $params['client_secret'], + null + ); + + if ($clientDetails === false) { + throw new \Oauth2\Authentication\ClientException($this->errors['invalid_client'], 8); + } + + // Check for grant + if ( ! isset($_POST['grant_type'])) { + throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); + } else { + $params['grant_type'] = $_POST['grant_type']; + } + + if ($params['grant_type'] == 'user_credentials') + { + // Check if user's u+p are correct + $userId = call_user_func($authParams['user_auth_callback']); + + if ($userId === false) + { + throw new \Oauth2\Authentication\ClientException($this->errors['invalid_credentials'], 0); + } + + else + { + // Generate an access token + $accessToken = $this->generateCode(); + $refreshToken = $this->generateCode(); + + $accessTokenExpires = ($this->_config['access_token_ttl'] === null) ? + null : + time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl']; + + // Delete any existing sessions just to be sure + $this->_dbCall('deleteSession', $params['client_id'], 'user', $userId); + + // Create a new session + $this->_dbCall('newSession', $params['client_id'], null, 'user', $userId, null, $accessToken, $refreshToken, $accessTokenExpires, 'granted'); + + return array( + 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, + 'token_type' => 'bearer', + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn + ); + } + } else { + throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7); + } + + } + + /** + * Complete the refresh token grant + * + * @access private + * + * @param array $authParams Array of parsed $_POST keys + * @param array $params Generated parameters from issueAccessToken() + * + * @return array Authorise request parameters + */ + private function completeRefreshTokenGrant($authParams = array(), $params = array()) + { + $params = array(); + + // Check for grant + if ( ! isset($_POST['grant_type'])) { + throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'grant_type'), 0); + } else { + $params['grant_type'] = $_POST['grant_type']; + } + + if ( ! isset($authParams['refresh_token']) && ! isset($_POST['refresh_token'])) { + throw new ClientException(sprintf($this->errors['invalid_request'], 'refresh_token'), 0); + } else { + $params['refresh_token'] = (isset($authParams['refresh_token'])) ? + $authParams['refresh_token'] : + $_POST['refresh_token']; + } + + if ($params['grant_type'] == 'refresh_token') + { + // Generate an access token + $accessToken = $this->generateCode(); + $refreshToken = $this->generateCode(); + + $accessTokenExpires = ($this->_config['access_token_ttl'] === null) ? + null : + time() + $this->_config['access_token_ttl']; + + $accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl']; + + // Delete any existing sessions just to be sure + $result = $this->_dbCall('refreshToken', $params['refresh_token'], $accessToken, $refreshToken, $accessTokenExpires); + + if ( ! $result) { + throw new \Oauth2\Authentication\ClientException($this->errors['invalid_refresh'], 0); + } + + return array( + 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, + 'token_type' => 'bearer', + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn + ); + } else { + throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7); + } + + } + /** * Generates the redirect uri with appended params * From d99e871e117784ba2f8b478d7d2af19824a0e20b Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 20:31:16 +0000 Subject: [PATCH 02/14] Set a default token ttl of one hour --- src/Oauth2/Authentication/Server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Oauth2/Authentication/Server.php b/src/Oauth2/Authentication/Server.php index 3e295626..a3c825ed 100644 --- a/src/Oauth2/Authentication/Server.php +++ b/src/Oauth2/Authentication/Server.php @@ -30,8 +30,8 @@ class Server * @var array */ private $_config = array( - 'scope_delimeter' => ',', - 'access_token_ttl' => null + 'scope_delimeter' => ',', + 'access_token_ttl' => 3600 ); /** From 0f30b2a803afcf021e7bad72ecedf9a7feb64c88 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 21:21:37 +0000 Subject: [PATCH 03/14] Removed lots of unnecessary if/else blocks. Removed null value of expires/expiresIn parameter --- src/Oauth2/Authentication/Server.php | 300 +++++++++++---------------- 1 file changed, 116 insertions(+), 184 deletions(-) diff --git a/src/Oauth2/Authentication/Server.php b/src/Oauth2/Authentication/Server.php index 2a191c21..887d958f 100644 --- a/src/Oauth2/Authentication/Server.php +++ b/src/Oauth2/Authentication/Server.php @@ -130,30 +130,22 @@ class Server // Client ID if ( ! isset($authParams['client_id']) && ! isset($_GET['client_id'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); - - } else { - - $params['client_id'] = (isset($authParams['client_id'])) ? - $authParams['client_id'] : - $_GET['client_id']; - } + $params['client_id'] = (isset($authParams['client_id'])) ? + $authParams['client_id'] : + $_GET['client_id']; + // Redirect URI if ( ! isset($authParams['redirect_uri']) && ! isset($_GET['redirect_uri'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'redirect_uri'), 0); - - } else { - - $params['redirect_uri'] = (isset($authParams['redirect_uri'])) ? - $authParams['redirect_uri'] : - $_GET['redirect_uri']; - } + $params['redirect_uri'] = (isset($authParams['redirect_uri'])) ? + $authParams['redirect_uri'] : + $_GET['redirect_uri']; + // Validate client ID and redirect URI $clientDetails = $this->_dbCall( 'validateClient', @@ -163,7 +155,6 @@ class Server ); if ($clientDetails === false) { - throw new ClientException($this->errors['invalid_client'], 8); } @@ -171,29 +162,24 @@ class Server // Response type if ( ! isset($authParams['response_type']) && ! isset($_GET['response_type'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'response_type'), 0); + } - } else { + $params['response_type'] = (isset($authParams['response_type'])) ? + $authParams['response_type'] : + $_GET['response_type']; - $params['response_type'] = (isset($authParams['response_type'])) ? - $authParams['response_type'] : - $_GET['response_type']; - - // Ensure response type is one that is recognised - if ( ! in_array($params['response_type'], $this->_responseTypes)) { - - throw new ClientException($this->errors['unsupported_response_type'], 3); - - } + // Ensure response type is one that is recognised + if ( ! in_array($params['response_type'], $this->_responseTypes)) { + throw new ClientException($this->errors['unsupported_response_type'], 3); } // Get and validate scopes if (isset($authParams['scope']) || isset($_GET['scope'])) { $scopes = (isset($_GET['scope'])) ? - $_GET['scope'] : - $authParams['scope']; + $_GET['scope'] : + $authParams['scope']; $scopes = explode($this->_config['scope_delimeter'], $scopes); @@ -208,7 +194,6 @@ class Server } if (count($scopes) === 0) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'scope'), 0); } @@ -222,9 +207,7 @@ class Server ); if ($scopeDetails === false) { - throw new ClientException(sprintf($this->errors['invalid_scope'], $scope), 4); - } $params['scopes'][] = $scopeDetails; @@ -355,21 +338,16 @@ class Server $params = array(); if ( ! isset($authParams['grant_type']) && ! isset($_POST['grant_type'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'grant_type'), 0); + } - } else { + $params['grant_type'] = (isset($authParams['grant_type'])) ? + $authParams['grant_type'] : + $_POST['grant_type']; - $params['grant_type'] = (isset($authParams['grant_type'])) ? - $authParams['grant_type'] : - $_POST['grant_type']; - - // Ensure grant type is one that is recognised - if ( ! in_array($params['grant_type'], $this->_grantTypes)) { - - throw new ClientException($this->errors['unsupported_grant_type'], 7); - - } + // Ensure grant type is one that is recognised + if ( ! in_array($params['grant_type'], $this->_grantTypes)) { + throw new ClientException($this->errors['unsupported_grant_type'], 7); } switch ($params['grant_type']) @@ -410,43 +388,31 @@ class Server { // Client ID if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); - - } else { - - $params['client_id'] = (isset($authParams['client_id'])) ? - $authParams['client_id'] : - $_POST['client_id']; - } + $params['client_id'] = (isset($authParams['client_id'])) ? + $authParams['client_id'] : + $_POST['client_id']; + // Client secret if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0); - - } else { - - $params['client_secret'] = (isset($authParams['client_secret'])) ? - $authParams['client_secret'] : - $_POST['client_secret']; - } + $params['client_secret'] = (isset($authParams['client_secret'])) ? + $authParams['client_secret'] : + $_POST['client_secret']; + // Redirect URI if ( ! isset($authParams['redirect_uri']) && ! isset($_POST['redirect_uri'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'redirect_uri'), 0); - - } else { - - $params['redirect_uri'] = (isset($authParams['redirect_uri'])) ? - $authParams['redirect_uri'] : - $_POST['redirect_uri']; - } + $params['redirect_uri'] = (isset($authParams['redirect_uri'])) ? + $authParams['redirect_uri'] : + $_POST['redirect_uri']; + // Validate client ID and redirect URI $clientDetails = $this->_dbCall( 'validateClient', @@ -456,25 +422,19 @@ class Server ); if ($clientDetails === false) { - throw new ClientException($this->errors['invalid_client'], 8); } // The authorization code if ( ! isset($authParams['code']) && ! isset($_POST['code'])) { - throw new ClientException(sprintf($this->errors['invalid_request'], 'code'), 0); - - } else { - - $params['code'] = (isset($authParams['code'])) ? - $authParams['code'] : - $_POST['code']; - } - // Verify the authorization code matches the client_id and the - // request_uri + $params['code'] = (isset($authParams['code'])) ? + $authParams['code'] : + $_POST['code']; + + // Verify the authorization code matches the client_id and the request_uri $session = $this->_dbCall( 'validateAuthCode', $params['client_id'], @@ -483,58 +443,51 @@ class Server ); if ( ! $session) { - throw new ClientException(sprintf($this->errors['invalid_grant'], 'code'), 9); - - } else { - - // A session ID was returned so update it with an access token, - // remove the authorisation code, change the stage to 'granted' - - $accessToken = $this->generateCode(); - $refreshToken = $this->generateCode(); - - $accessTokenExpires = ($this->_config['access_token_ttl'] === null) ? - null : - time() + $this->_config['access_token_ttl']; - $accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl']; - - $this->_dbCall( - 'updateSession', - $session['id'], - null, - $accessToken, - $refreshToken, - $accessTokenExpires, - 'granted' - ); - - // Update the session's scopes to reference the access token - $this->_dbCall( - 'updateSessionScopeAccessToken', - $session['id'], - $accessToken, - $refreshToken - ); - - return array( - 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, - 'token_type' => 'bearer', - 'expires' => $accessTokenExpires, - 'expires_in' => $accessTokenExpiresIn - ); } + + // A session ID was returned so update it with an access token, + // remove the authorisation code, change the stage to 'granted' + + $accessToken = $this->generateCode(); + $refreshToken = $this->generateCode(); + + $accessTokenExpires = time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = $this->_config['access_token_ttl']; + + $this->_dbCall( + 'updateSession', + $session['id'], + null, + $accessToken, + $refreshToken, + $accessTokenExpires, + 'granted' + ); + + // Update the session's scopes to reference the access token + $this->_dbCall( + 'updateSessionScopeAccessToken', + $session['id'], + $accessToken, + $refreshToken + ); + + return array( + 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, + 'token_type' => 'bearer', + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn + ); } /** * Complete the user credentials grant * * @access private - * * @param array $authParams Array of parsed $_POST keys * @param array $params Generated parameters from issueAccessToken() - * * @return array Authorise request parameters */ private function completeUserCredentialsGrant($authParams = array(), $params = array()) @@ -548,20 +501,19 @@ class Server // Client ID if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) { throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); - } else { - $params['client_id'] = (isset($authParams['client_id'])) ? - $authParams['client_id'] : - $_POST['client_id']; } + $params['client_id'] = (isset($authParams['client_id'])) ? + $authParams['client_id'] : + $_POST['client_id']; + // Client secret if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) { throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0); - } else { - $params['client_secret'] = (isset($authParams['client_secret'])) ? - $authParams['client_secret'] : - $_POST['client_secret']; } + $params['client_secret'] = (isset($authParams['client_secret'])) ? + $authParams['client_secret'] : + $_POST['client_secret']; // Validate client ID and redirect URI $clientDetails = $this->_dbCall( @@ -578,45 +530,39 @@ class Server // Check for grant if ( ! isset($_POST['grant_type'])) { throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); - } else { - $params['grant_type'] = $_POST['grant_type']; } - if ($params['grant_type'] == 'user_credentials') - { + $params['grant_type'] = $_POST['grant_type']; + + if ($params['grant_type'] == 'user_credentials') { // Check if user's u+p are correct $userId = call_user_func($authParams['user_auth_callback']); - if ($userId === false) - { + if ($userId === false) { throw new \Oauth2\Authentication\ClientException($this->errors['invalid_credentials'], 0); } - else - { - // Generate an access token - $accessToken = $this->generateCode(); - $refreshToken = $this->generateCode(); + // Generate an access token + $accessToken = $this->generateCode(); + $refreshToken = $this->generateCode(); - $accessTokenExpires = ($this->_config['access_token_ttl'] === null) ? - null : - time() + $this->_config['access_token_ttl']; - $accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl']; + $accessTokenExpires = time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = $this->_config['access_token_ttl']; - // Delete any existing sessions just to be sure - $this->_dbCall('deleteSession', $params['client_id'], 'user', $userId); + // Delete any existing sessions just to be sure + $this->_dbCall('deleteSession', $params['client_id'], 'user', $userId); - // Create a new session - $this->_dbCall('newSession', $params['client_id'], null, 'user', $userId, null, $accessToken, $refreshToken, $accessTokenExpires, 'granted'); + // Create a new session + $this->_dbCall('newSession', $params['client_id'], null, 'user', $userId, null, $accessToken, $refreshToken, $accessTokenExpires, 'granted'); + + return array( + 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, + 'token_type' => 'bearer', + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn + ); - return array( - 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, - 'token_type' => 'bearer', - 'expires' => $accessTokenExpires, - 'expires_in' => $accessTokenExpiresIn - ); - } } else { throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7); } @@ -640,29 +586,26 @@ class Server // Check for grant if ( ! isset($_POST['grant_type'])) { throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'grant_type'), 0); - } else { - $params['grant_type'] = $_POST['grant_type']; } + $params['grant_type'] = $_POST['grant_type']; + if ( ! isset($authParams['refresh_token']) && ! isset($_POST['refresh_token'])) { throw new ClientException(sprintf($this->errors['invalid_request'], 'refresh_token'), 0); - } else { - $params['refresh_token'] = (isset($authParams['refresh_token'])) ? - $authParams['refresh_token'] : - $_POST['refresh_token']; } - if ($params['grant_type'] == 'refresh_token') - { + $params['refresh_token'] = (isset($authParams['refresh_token'])) ? + $authParams['refresh_token'] : + $_POST['refresh_token']; + + if ($params['grant_type'] == 'refresh_token') { + // Generate an access token $accessToken = $this->generateCode(); $refreshToken = $this->generateCode(); - $accessTokenExpires = ($this->_config['access_token_ttl'] === null) ? - null : - time() + $this->_config['access_token_ttl']; - - $accessTokenExpiresIn = ($this->_config['access_token_ttl'] === null) ? 0 : $this->_config['access_token_ttl']; + $accessTokenExpires = time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = $this->_config['access_token_ttl']; // Delete any existing sessions just to be sure $result = $this->_dbCall('refreshToken', $params['refresh_token'], $accessToken, $refreshToken, $accessTokenExpires); @@ -678,6 +621,7 @@ class Server 'expires' => $accessTokenExpires, 'expires_in' => $accessTokenExpiresIn ); + } else { throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7); } @@ -695,19 +639,7 @@ class Server */ public function redirectUri($redirectUri, $params = array(), $queryDelimeter = '?') { - - if (strstr($redirectUri, $queryDelimeter)) { - - $redirectUri = $redirectUri . '&' . http_build_query($params); - - } else { - - $redirectUri = $redirectUri . $queryDelimeter . http_build_query($params); - - } - - return $redirectUri; - + return (strstr($redirectUri, $queryDelimeter)) ? $redirectUri . '&' . http_build_query($params) : $redirectUri . $queryDelimeter . http_build_query($params); } /** From df85c98e536a3f65444984309ae916b65f7dcef5 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 21:36:30 +0000 Subject: [PATCH 04/14] PSR fixes --- tests/authentication/server_test.php | 671 ++++++++++++++------------- 1 file changed, 337 insertions(+), 334 deletions(-) diff --git a/tests/authentication/server_test.php b/tests/authentication/server_test.php index 7af8651e..171de546 100644 --- a/tests/authentication/server_test.php +++ b/tests/authentication/server_test.php @@ -1,398 +1,401 @@ oauth = new Oauth2\Authentication\Server(); + $this->oauth = new Oauth2\Authentication\Server(); - require_once('database_mock.php'); - $this->oauthdb = new OAuthdb(); - $this->assertInstanceOf('Oauth2\Authentication\Database', $this->oauthdb); - $this->oauth->registerDbAbstractor($this->oauthdb); - } + require_once 'database_mock.php'; + $this->oauthdb = new OAuthdb(); + $this->assertInstanceOf('Oauth2\Authentication\Database', $this->oauthdb); + $this->oauth->registerDbAbstractor($this->oauthdb); + } - function test_generateCode() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('generateCode'); - $method->setAccessible(true); + public function test_generateCode() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('generateCode'); + $method->setAccessible(true); - $result = $method->invoke($this->oauth); - $result2 = $method->invoke($this->oauth); + $result = $method->invoke($this->oauth); + $result2 = $method->invoke($this->oauth); - $this->assertEquals(40, strlen($result)); - $this->assertNotEquals($result, $result2); - } + $this->assertEquals(40, strlen($result)); + $this->assertNotEquals($result, $result2); + } - function test_redirectUri() - { - $result1 = $this->oauth->redirectUri('http://example.com/foo'); - $result2 = $this->oauth->redirectUri('http://example.com/foo', array('foo' => 'bar')); - $result3 = $this->oauth->redirectUri('http://example.com/foo', array('foo' => 'bar'), '#'); + public function test_redirectUri() + { + $result1 = $this->oauth->redirectUri('http://example.com/foo'); + $result2 = $this->oauth->redirectUri('http://example.com/foo', array('foo' => 'bar')); + $result3 = $this->oauth->redirectUri('http://example.com/foo', array('foo' => 'bar'), '#'); - $this->assertEquals('http://example.com/foo?', $result1); - $this->assertEquals('http://example.com/foo?foo=bar', $result2); - $this->assertEquals('http://example.com/foo#foo=bar', $result3); - } + $this->assertEquals('http://example.com/foo?', $result1); + $this->assertEquals('http://example.com/foo?foo=bar', $result2); + $this->assertEquals('http://example.com/foo#foo=bar', $result3); + } - function test_checkClientAuthoriseParams_GET() - { - $_GET['client_id'] = 'test'; - $_GET['redirect_uri'] = 'http://example.com/test'; - $_GET['response_type'] = 'code'; - $_GET['scope'] = 'test'; - - $expect = array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'response_type' => 'code', - 'scopes' => array( - 0 => array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - ) - ) - ); + public function test_checkClientAuthoriseParams_GET() + { + $_GET['client_id'] = 'test'; + $_GET['redirect_uri'] = 'http://example.com/test'; + $_GET['response_type'] = 'code'; + $_GET['scope'] = 'test'; - $result = $this->oauth->checkClientAuthoriseParams(); + $expect = array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'response_type' => 'code', + 'scopes' => array( + 0 => array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + ) + ) + ); - $this->assertEquals($expect, $result); - } + $result = $this->oauth->checkClientAuthoriseParams(); - function test_checkClientAuthoriseParams_PassedParams() - { - unset($_GET['client_id']); - unset($_GET['redirect_uri']); - unset($_GET['response_type']); - unset($_GET['scope']); + $this->assertEquals($expect, $result); + } - $params = array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'response_type' => 'code', - 'scope' => 'test' - ); + public function test_checkClientAuthoriseParams_PassedParams() + { + unset($_GET['client_id']); + unset($_GET['redirect_uri']); + unset($_GET['response_type']); + unset($_GET['scope']); - $this->assertEquals(array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'response_type' => 'code', - 'scopes' => array(0 => array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - )) - ), $this->oauth->checkClientAuthoriseParams($params)); - } + $params = array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'response_type' => 'code', + 'scope' => 'test' + ); - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_checkClientAuthoriseParams_missingClientId() - { - $this->oauth->checkClientAuthoriseParams(); - } + $this->assertEquals(array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'response_type' => 'code', + 'scopes' => array(0 => array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + ), $this->oauth->checkClientAuthoriseParams($params)); + } - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_checkClientAuthoriseParams_missingRedirectUri() - { - $_GET['client_id'] = 'test'; + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_checkClientAuthoriseParams_missingClientId() + { + $this->oauth->checkClientAuthoriseParams(); + } - $this->oauth->checkClientAuthoriseParams(); - } + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_checkClientAuthoriseParams_missingRedirectUri() + { + $_GET['client_id'] = 'test'; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_checkClientAuthoriseParams_missingResponseType() - { - $_GET['client_id'] = 'test'; - $_GET['redirect_uri'] = 'http://example.com/test'; + $this->oauth->checkClientAuthoriseParams(); + } - $this->oauth->checkClientAuthoriseParams(); - } + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_checkClientAuthoriseParams_missingResponseType() + { + $_GET['client_id'] = 'test'; + $_GET['redirect_uri'] = 'http://example.com/test'; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_checkClientAuthoriseParams_missingScopes() - { - $_GET['client_id'] = 'test'; - $_GET['redirect_uri'] = 'http://example.com/test'; - $_GET['response_type'] = 'code'; - $_GET['scope'] = ' '; + $this->oauth->checkClientAuthoriseParams(); + } - $this->oauth->checkClientAuthoriseParams(); - } + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_checkClientAuthoriseParams_missingScopes() + { + $_GET['client_id'] = 'test'; + $_GET['redirect_uri'] = 'http://example.com/test'; + $_GET['response_type'] = 'code'; + $_GET['scope'] = ' '; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 4 - */ - function test_checkClientAuthoriseParams_invalidScopes() - { - $_GET['client_id'] = 'test'; - $_GET['redirect_uri'] = 'http://example.com/test'; - $_GET['response_type'] = 'code'; - $_GET['scope'] = 'blah'; + $this->oauth->checkClientAuthoriseParams(); + } - $this->oauth->checkClientAuthoriseParams(); - } + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 4 + */ + public function test_checkClientAuthoriseParams_invalidScopes() + { + $_GET['client_id'] = 'test'; + $_GET['redirect_uri'] = 'http://example.com/test'; + $_GET['response_type'] = 'code'; + $_GET['scope'] = 'blah'; - function test_newAuthoriseRequest() - { - $result = $this->oauth->newAuthoriseRequest('user', '123', array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'scopes' => array(array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - )) - )); + $this->oauth->checkClientAuthoriseParams(); + } - $this->assertEquals(40, strlen($result)); - } + public function test_newAuthoriseRequest() + { + $result = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); - function test_newAuthoriseRequest_isUnique() - { - $result1 = $this->oauth->newAuthoriseRequest('user', '123', array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'scopes' => array(array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - )) - )); + $this->assertEquals(40, strlen($result)); + } - $result2 = $this->oauth->newAuthoriseRequest('user', '123', array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'scopes' => array(array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - )) - )); + public function test_newAuthoriseRequest_isUnique() + { + $result1 = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); - $this->assertNotEquals($result1, $result2); - } + $result2 = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); - function test_issueAccessToken_POST() - { - $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'scopes' => array(array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - )) - )); + $this->assertNotEquals($result1, $result2); + } - $_POST['client_id'] = 'test'; - $_POST['client_secret'] = 'test'; - $_POST['redirect_uri'] = 'http://example.com/test'; - $_POST['grant_type'] = 'authorization_code'; - $_POST['code'] = $auth_code; + public function test_issueAccessToken_POST() + { + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); - $result = $this->oauth->issueAccessToken(); + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['redirect_uri'] = 'http://example.com/test'; + $_POST['grant_type'] = 'authorization_code'; + $_POST['code'] = $auth_code; - $this->assertCount(3, $result); - $this->assertArrayHasKey('access_token', $result); - $this->assertArrayHasKey('token_type', $result); - $this->assertArrayHasKey('expires_in', $result); - } + $result = $this->oauth->issueAccessToken(); - function test_issueAccessToken_PassedParams() - { - $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( - 'client_id' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'scopes' => array(array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - )) - )); + $this->assertCount(3, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + } - $params['client_id'] = 'test'; - $params['client_secret'] = 'test'; - $params['redirect_uri'] = 'http://example.com/test'; - $params['grant_type'] = 'authorization_code'; - $params['code'] = $auth_code; + public function test_issueAccessToken_PassedParams() + { + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); - $result = $this->oauth->issueAccessToken($params); + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['redirect_uri'] = 'http://example.com/test'; + $params['grant_type'] = 'authorization_code'; + $params['code'] = $auth_code; - $this->assertCount(3, $result); - $this->assertArrayHasKey('access_token', $result); - $this->assertArrayHasKey('token_type', $result); - $this->assertArrayHasKey('expires_in', $result); - } + $result = $this->oauth->issueAccessToken($params); - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_issueAccessToken_missingGrantType() - { - $this->oauth->issueAccessToken(); - } + $this->assertCount(3, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + } - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 7 - */ - function test_issueAccessToken_unsupportedGrantType() - { - $params['grant_type'] = 'blah'; + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_issueAccessToken_missingGrantType() + { + $this->oauth->issueAccessToken(); + } - $this->oauth->issueAccessToken($params); - } + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 7 + */ + public function test_issueAccessToken_unsupportedGrantType() + { + $params['grant_type'] = 'blah'; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_completeAuthCodeGrant_missingClientId() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); - $method->setAccessible(true); + $this->oauth->issueAccessToken($params); + } - $method->invoke($this->oauth); - } + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_completeAuthCodeGrant_missingClientId() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('completeAuthCodeGrant'); + $method->setAccessible(true); - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_completeAuthCodeGrant_missingClientSecret() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); - $method->setAccessible(true); + $method->invoke($this->oauth); + } - $authParams['client_id'] = 'test'; + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_completeAuthCodeGrant_missingClientSecret() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('completeAuthCodeGrant'); + $method->setAccessible(true); - $method->invoke($this->oauth, $authParams); - } + $authParams['client_id'] = 'test'; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_completeAuthCodeGrant_missingRedirectUri() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); - $method->setAccessible(true); + $method->invoke($this->oauth, $authParams); + } - $authParams['client_id'] = 'test'; - $authParams['client_secret'] = 'test'; + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_completeAuthCodeGrant_missingRedirectUri() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('completeAuthCodeGrant'); + $method->setAccessible(true); - $method->invoke($this->oauth, $authParams); - } + $authParams['client_id'] = 'test'; + $authParams['client_secret'] = 'test'; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 8 - */ - function test_completeAuthCodeGrant_invalidClient() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); - $method->setAccessible(true); + $method->invoke($this->oauth, $authParams); + } - $authParams['client_id'] = 'test'; - $authParams['client_secret'] = 'test123'; - $authParams['redirect_uri'] = 'http://example.com/test'; + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 8 + */ + public function test_completeAuthCodeGrant_invalidClient() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('completeAuthCodeGrant'); + $method->setAccessible(true); - $method->invoke($this->oauth, $authParams); - } + $authParams['client_id'] = 'test'; + $authParams['client_secret'] = 'test123'; + $authParams['redirect_uri'] = 'http://example.com/test'; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 0 - */ - function test_completeAuthCodeGrant_missingCode() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); - $method->setAccessible(true); + $method->invoke($this->oauth, $authParams); + } - $authParams['client_id'] = 'test'; - $authParams['client_secret'] = 'test'; - $authParams['redirect_uri'] = 'http://example.com/test'; + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_completeAuthCodeGrant_missingCode() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('completeAuthCodeGrant'); + $method->setAccessible(true); - $method->invoke($this->oauth, $authParams); - } + $authParams['client_id'] = 'test'; + $authParams['client_secret'] = 'test'; + $authParams['redirect_uri'] = 'http://example.com/test'; - /** - * @expectedException Oauth2\Authentication\ClientException - * @expectedExceptionCode 9 - */ - function test_completeAuthCodeGrant_invalidCode() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); - $method->setAccessible(true); + $method->invoke($this->oauth, $authParams); + } - $authParams['client_id'] = 'test'; - $authParams['client_secret'] = 'test'; - $authParams['redirect_uri'] = 'http://example.com/test'; - $authParams['code'] = 'blah'; + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 9 + */ + public function test_completeAuthCodeGrant_invalidCode() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('completeAuthCodeGrant'); + $method->setAccessible(true); - $method->invoke($this->oauth, $authParams); - } + $authParams['client_id'] = 'test'; + $authParams['client_secret'] = 'test'; + $authParams['redirect_uri'] = 'http://example.com/test'; + $authParams['code'] = 'blah'; - /** - * @expectedException Oauth2\Authentication\ServerException - * @expectedExceptionMessage No registered database abstractor - */ - function test_noRegisteredDatabaseAbstractor() - { - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('_dbCall'); - $method->setAccessible(true); + $method->invoke($this->oauth, $authParams); + } - $dbAbstractor = $reflector->getProperty('_db'); - $dbAbstractor->setAccessible(true); - $dbAbstractor->setValue($this->oauth, null); + /** + * @expectedException Oauth2\Authentication\ServerException + * @expectedExceptionMessage No registered database abstractor + */ + public function test_noRegisteredDatabaseAbstractor() + { + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('_dbCall'); + $method->setAccessible(true); - $result = $method->invoke($this->oauth); - } + $dbAbstractor = $reflector->getProperty('_db'); + $dbAbstractor->setAccessible(true); + $dbAbstractor->setValue($this->oauth, null); - /** - * @expectedException Oauth2\Authentication\ServerException - * @expectedExceptionMessage Registered database abstractor is not an instance of Oauth2\Authentication\Database - */ - function test_invalidRegisteredDatabaseAbstractor() - { - $fake = new stdClass; - $this->oauth->registerDbAbstractor($fake); + $result = $method->invoke($this->oauth); + } - $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('_dbCall'); - $method->setAccessible(true); + /** + * @expectedException Oauth2\Authentication\ServerException + * @expectedExceptionMessage Registered database abstractor is not an instance of Oauth2\Authentication\Database + */ + public function test_invalidRegisteredDatabaseAbstractor() + { + $fake = new stdClass; + $this->oauth->registerDbAbstractor($fake); - $result = $method->invoke($this->oauth); - } + $reflector = new ReflectionClass($this->oauth); + $method = $reflector->getMethod('_dbCall'); + $method->setAccessible(true); -} \ No newline at end of file + $result = $method->invoke($this->oauth); + } + +} From 38c50c00b0a60e9c40c2f396c6a6e2366df38f5e Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 21:39:42 +0000 Subject: [PATCH 05/14] PSR fixes --- tests/authentication/database_mock.php | 230 ++++++++++++------------- 1 file changed, 110 insertions(+), 120 deletions(-) diff --git a/tests/authentication/database_mock.php b/tests/authentication/database_mock.php index f13c1537..30862fa6 100644 --- a/tests/authentication/database_mock.php +++ b/tests/authentication/database_mock.php @@ -4,151 +4,141 @@ use Oauth2\Authentication\Database; class OAuthdb implements Database { - private $sessions = array(); - private $sessions_client_type_id = array(); - private $sessions_code = array(); - private $session_scopes = array(); + private $sessions = array(); + private $sessions_client_type_id = array(); + private $sessions_code = array(); + private $session_scopes = array(); - private $clients = array(0 => array( - 'client_id' => 'test', - 'client_secret' => 'test', - 'redirect_uri' => 'http://example.com/test', - 'name' => 'Test Client' - )); + private $clients = array(0 => array( + 'client_id' => 'test', + 'client_secret' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'name' => 'Test Client' + )); - private $scopes = array('test' => array( - 'id' => 1, - 'scope' => 'test', - 'name' => 'test', - 'description' => 'test' - )); + private $scopes = array('test' => array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )); - public function validateClient($clientId, $clientSecret = null, $redirectUri = null) - { - if ($clientId !== $this->clients[0]['client_id']) - { - return false; - } + public function validateClient($clientId, $clientSecret = null, $redirectUri = null) + { + if ($clientId !== $this->clients[0]['client_id']) { + return false; + } - if ($clientSecret !== null && $clientSecret !== $this->clients[0]['client_secret']) - { - return false; - } + if ($clientSecret !== null && $clientSecret !== $this->clients[0]['client_secret']) { + return false; + } - if ($redirectUri !== null && $redirectUri !== $this->clients[0]['redirect_uri']) - { - return false; - } + if ($redirectUri !== null && $redirectUri !== $this->clients[0]['redirect_uri']) { + return false; + } - return $this->clients[0]; - } + return $this->clients[0]; + } - public function newSession($clientId, $redirectUri, $type = 'user', $typeId = null, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested') - { - $id = count($this->sessions); + public function newSession($clientId, $redirectUri, $type = 'user', $typeId = null, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested') + { + $id = count($this->sessions); - $this->sessions[$id] = array( - 'id' => $id, - 'client_id' => $clientId, - 'redirect_uri' => $redirectUri, - 'owner_type' => $type, - 'owner_id' => $typeId, - 'auth_code' => $authCode, - 'access_token' => $accessToken, - 'access_token_expire' => $accessTokenExpire, - 'stage' => $stage - ); + $this->sessions[$id] = array( + 'id' => $id, + 'client_id' => $clientId, + 'redirect_uri' => $redirectUri, + 'owner_type' => $type, + 'owner_id' => $typeId, + 'auth_code' => $authCode, + 'access_token' => $accessToken, + 'access_token_expire' => $accessTokenExpire, + 'stage' => $stage + ); - $this->sessions_client_type_id[$clientId . ':' . $type . ':' . $typeId] = $id; - $this->sessions_code[$clientId . ':' . $redirectUri . ':' . $authCode] = $id; + $this->sessions_client_type_id[$clientId . ':' . $type . ':' . $typeId] = $id; + $this->sessions_code[$clientId . ':' . $redirectUri . ':' . $authCode] = $id; - return $id; - } + return $id; + } - public function updateSession($sessionId, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested') - { - $this->sessions[$sessionId]['auth_code'] = $authCode; - $this->sessions[$sessionId]['access_token'] = $accessToken; - $this->sessions[$sessionId]['access_token_expire'] = $accessTokenExpire; - $this->sessions[$sessionId]['stage'] = $stage; + public function updateSession($sessionId, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested') + { + $this->sessions[$sessionId]['auth_code'] = $authCode; + $this->sessions[$sessionId]['access_token'] = $accessToken; + $this->sessions[$sessionId]['access_token_expire'] = $accessTokenExpire; + $this->sessions[$sessionId]['stage'] = $stage; - return true; - } + return true; + } - public function deleteSession($clientId, $type, $typeId) - { - $key = $clientId . ':' . $type . ':' . $typeId; - if (isset($this->sessions_client_type_id[$key])) - { - unset($this->sessions[$this->sessions_client_type_id[$key]]); - } - return true; - } + public function deleteSession($clientId, $type, $typeId) + { + $key = $clientId . ':' . $type . ':' . $typeId; + if (isset($this->sessions_client_type_id[$key])) { + unset($this->sessions[$this->sessions_client_type_id[$key]]); + } + return true; + } - public function validateAuthCode($clientId, $redirectUri, $authCode) - { - $key = $clientId . ':' . $redirectUri . ':' . $authCode; + public function validateAuthCode($clientId, $redirectUri, $authCode) + { + $key = $clientId . ':' . $redirectUri . ':' . $authCode; - if (isset($this->sessions_code[$key])) - { - return $this->sessions[$this->sessions_code[$key]]; - } + if (isset($this->sessions_code[$key])) { + return $this->sessions[$this->sessions_code[$key]]; + } - return false; - } + return false; + } - public function hasSession($type, $typeId, $clientId) - { - die('not implemented hasSession'); - } + public function hasSession($type, $typeId, $clientId) + { + die('not implemented hasSession'); + } - public function getAccessToken($sessionId) - { - die('not implemented getAccessToken'); - } + public function getAccessToken($sessionId) + { + die('not implemented getAccessToken'); + } - public function removeAuthCode($sessionId) - { - die('not implemented removeAuthCode'); - } + public function removeAuthCode($sessionId) + { + die('not implemented removeAuthCode'); + } - public function setAccessToken( - $sessionId, - $accessToken - ) - { - die('not implemented setAccessToken'); - } + public function setAccessToken($sessionId, $accessToken) + { + die('not implemented setAccessToken'); + } - public function addSessionScope($sessionId, $scope) - { - if ( ! isset($this->session_scopes[$sessionId])) - { - $this->session_scopes[$sessionId] = array(); - } + public function addSessionScope($sessionId, $scope) + { + if ( ! isset($this->session_scopes[$sessionId])) { + $this->session_scopes[$sessionId] = array(); + } - $this->session_scopes[$sessionId][] = $scope; + $this->session_scopes[$sessionId][] = $scope; - return true; - } + return true; + } - public function getScope($scope) - { - if ( ! isset($this->scopes[$scope])) - { - return false; - } + public function getScope($scope) + { + if ( ! isset($this->scopes[$scope])) { + return false; + } - return $this->scopes[$scope]; - } + return $this->scopes[$scope]; + } - public function updateSessionScopeAccessToken($sessionId, $accessToken) - { - return true; - } + public function updateSessionScopeAccessToken($sessionId, $accessToken) + { + return true; + } - public function accessTokenScopes($accessToken) - { - die('not implemented accessTokenScopes'); - } + public function accessTokenScopes($accessToken) + { + die('not implemented accessTokenScopes'); + } } \ No newline at end of file From 6eeb7e13e45fcdc6a9b77630bfd99ca9caefa529 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 22:11:33 +0000 Subject: [PATCH 06/14] Updated unit tests --- tests/authentication/database_mock.php | 11 +++++++++-- tests/authentication/server_test.php | 24 ++++++++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/tests/authentication/database_mock.php b/tests/authentication/database_mock.php index 30862fa6..a3a712a0 100644 --- a/tests/authentication/database_mock.php +++ b/tests/authentication/database_mock.php @@ -40,7 +40,7 @@ class OAuthdb implements Database return $this->clients[0]; } - public function newSession($clientId, $redirectUri, $type = 'user', $typeId = null, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested') + public function newSession($clientId, $redirectUri, $type = 'user', $typeId = null, $authCode = null, $accessToken = null, $refreshToken = null, $accessTokenExpire = null, $stage = 'requested') { $id = count($this->sessions); @@ -52,6 +52,7 @@ class OAuthdb implements Database 'owner_id' => $typeId, 'auth_code' => $authCode, 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, 'access_token_expire' => $accessTokenExpire, 'stage' => $stage ); @@ -62,10 +63,11 @@ class OAuthdb implements Database return $id; } - public function updateSession($sessionId, $authCode = null, $accessToken = null, $accessTokenExpire = null, $stage = 'requested') + public function updateSession($sessionId, $authCode = null, $accessToken = null, $refreshToken = null, $accessTokenExpire = null, $stage = 'requested') { $this->sessions[$sessionId]['auth_code'] = $authCode; $this->sessions[$sessionId]['access_token'] = $accessToken; + $this->sessions[$sessionId]['refresh_token'] = $accessToken; $this->sessions[$sessionId]['access_token_expire'] = $accessTokenExpire; $this->sessions[$sessionId]['stage'] = $stage; @@ -81,6 +83,11 @@ class OAuthdb implements Database return true; } + public function refreshToken($currentRefreshToken, $newAccessToken, $newRefreshToken, $accessTokenExpires) + { + die('not implemented refreshToken'); + } + public function validateAuthCode($clientId, $redirectUri, $authCode) { $key = $clientId . ':' . $redirectUri . ':' . $authCode; diff --git a/tests/authentication/server_test.php b/tests/authentication/server_test.php index 171de546..b94d897e 100644 --- a/tests/authentication/server_test.php +++ b/tests/authentication/server_test.php @@ -4,8 +4,8 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase { public function setUp() { - require 'src/OAuth2/Authentication/Server.php'; - require 'src/OAuth2/Authentication/Database.php'; + require_once 'src/OAuth2/Authentication/Server.php'; + require_once 'src/OAuth2/Authentication/Database.php'; $this->oauth = new Oauth2\Authentication\Server(); @@ -49,6 +49,12 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $expect = array( 'client_id' => 'test', 'redirect_uri' => 'http://example.com/test', + 'client_details' => array( + 'client_id' => 'test', + 'client_secret' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'name' => 'Test Client' + ), 'response_type' => 'code', 'scopes' => array( 0 => array( @@ -82,6 +88,12 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $this->assertEquals(array( 'client_id' => 'test', 'redirect_uri' => 'http://example.com/test', + 'client_details' => array( + 'client_id' => 'test', + 'client_secret' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'name' => 'Test Client' + ), 'response_type' => 'code', 'scopes' => array(0 => array( 'id' => 1, @@ -216,10 +228,12 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $result = $this->oauth->issueAccessToken(); - $this->assertCount(3, $result); + $this->assertCount(5, $result); $this->assertArrayHasKey('access_token', $result); $this->assertArrayHasKey('token_type', $result); $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + $this->assertArrayHasKey('refresh_token', $result); } public function test_issueAccessToken_PassedParams() @@ -243,10 +257,12 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $result = $this->oauth->issueAccessToken($params); - $this->assertCount(3, $result); + $this->assertCount(5, $result); $this->assertArrayHasKey('access_token', $result); $this->assertArrayHasKey('token_type', $result); $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + $this->assertArrayHasKey('refresh_token', $result); } /** From 2545ea7dc113ed7a4a856b39752897329355195e Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 22:12:44 +0000 Subject: [PATCH 07/14] Added refresh token params and examples --- src/Oauth2/Authentication/Database.php | 30 ++++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Oauth2/Authentication/Database.php b/src/Oauth2/Authentication/Database.php index d4ef203f..e3babb80 100644 --- a/src/Oauth2/Authentication/Database.php +++ b/src/Oauth2/Authentication/Database.php @@ -56,18 +56,19 @@ interface Database * * * INSERT INTO oauth_sessions (client_id, redirect_uri, owner_type, - * owner_id, auth_code, access_token, stage, first_requested, last_updated) - * VALUES ($clientId, $redirectUri, $type, $typeId, $authCode, - * $accessToken, $stage, UNIX_TIMESTAMP(NOW()), UNIX_TIMESTAMP(NOW())) + * owner_id, auth_code, access_token, refresh_token, stage, first_requested, + * last_updated) VALUES ($clientId, $redirectUri, $type, $typeId, $authCode, + * $accessToken, $stage, UNIX_TIMESTAMP(NOW()), UNIX_TIMESTAMP(NOW())) * * - * @param string $clientId The client ID - * @param string $redirectUri The redirect URI - * @param string $type The session owner's type (default = "user") - * @param string $typeId The session owner's ID (default = "null") - * @param string $authCode The authorisation code (default = "null") - * @param string $accessToken The access token (default = "null") - * @param string $stage The stage of the session (default ="request") + * @param string $clientId The client ID + * @param string $redirectUri The redirect URI + * @param string $type The session owner's type (default = "user") + * @param string $typeId The session owner's ID (default = "null") + * @param string $authCode The authorisation code (default = "null") + * @param string $accessToken The access token (default = "null") + * @param string $refreshToken The refresh token (default = "null") + * @param string $stage The stage of the session (default ="request") * @return int The session ID */ public function newSession( @@ -93,10 +94,11 @@ interface Database * id = $sessionId * * - * @param string $sessionId The session ID - * @param string $authCode The authorisation code (default = "null") - * @param string $accessToken The access token (default = "null") - * @param string $stage The stage of the session (default ="request") + * @param string $sessionId The session ID + * @param string $authCode The authorisation code (default = "null") + * @param string $accessToken The access token (default = "null") + * @param string $refreshToken The refresh token (default = "null") + * @param string $stage The stage of the session (default ="request") * @return void */ public function updateSession( From 0876fd9ad3dc7b89dfea5cd1f17664114e32fbc4 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 22:12:51 +0000 Subject: [PATCH 08/14] Spacing fixes --- src/Oauth2/Authentication/Server.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Oauth2/Authentication/Server.php b/src/Oauth2/Authentication/Server.php index 887d958f..d799cf60 100644 --- a/src/Oauth2/Authentication/Server.php +++ b/src/Oauth2/Authentication/Server.php @@ -38,7 +38,7 @@ class Server * Supported response types * @var array */ - private $_responseTypes = array( + private $_responseTypes = array( 'code' ); @@ -46,7 +46,7 @@ class Server * Supported grant types * @var array */ - private $_grantTypes = array( + private $_grantTypes = array( 'authorization_code', 'user_credentials', 'refresh_token', From 0fcbeb8158dadac2da10ddd1db79a34db8c0cce4 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 23 Dec 2012 22:13:22 +0000 Subject: [PATCH 09/14] PSR fixes --- tests/resource/server_test.php | 177 +++++++++++++++++---------------- 1 file changed, 90 insertions(+), 87 deletions(-) diff --git a/tests/resource/server_test.php b/tests/resource/server_test.php index 7feb4389..707d73ee 100644 --- a/tests/resource/server_test.php +++ b/tests/resource/server_test.php @@ -2,120 +2,123 @@ class Resource_Server_test extends PHPUnit_Framework_TestCase { - function setUp() - { - require_once('database_mock.php'); - $this->server = new Oauth2\Resource\Server(); - $this->db = new ResourceDB(); + function setUp() + { + require_once 'src/OAuth2/Resource/Server.php'; + require_once 'src/OAuth2/Resource/Database.php'; - $this->assertInstanceOf('Oauth2\Resource\Database', $this->db); - $this->server->registerDbAbstractor($this->db); - } + require_once('database_mock.php'); + $this->server = new Oauth2\Resource\Server(); + $this->db = new ResourceDB(); - function test_init_POST() - { - $_SERVER['REQUEST_METHOD'] = 'POST'; - $_POST['oauth_token'] = 'test12345'; + $this->assertInstanceOf('Oauth2\Resource\Database', $this->db); + $this->server->registerDbAbstractor($this->db); + } - $this->server->init(); + function test_init_POST() + { + $_SERVER['REQUEST_METHOD'] = 'POST'; + $_POST['oauth_token'] = 'test12345'; - $reflector = new ReflectionClass($this->server); + $this->server->init(); - $_accessToken = $reflector->getProperty('_accessToken'); - $_accessToken->setAccessible(true); + $reflector = new ReflectionClass($this->server); - $_type = $reflector->getProperty('_type'); - $_type->setAccessible(true); + $_accessToken = $reflector->getProperty('_accessToken'); + $_accessToken->setAccessible(true); - $_typeId = $reflector->getProperty('_typeId'); - $_typeId->setAccessible(true); + $_type = $reflector->getProperty('_type'); + $_type->setAccessible(true); - $_scopes = $reflector->getProperty('_scopes'); - $_scopes->setAccessible(true); + $_typeId = $reflector->getProperty('_typeId'); + $_typeId->setAccessible(true); - $this->assertEquals($_accessToken->getValue($this->server), $_POST['oauth_token']); - $this->assertEquals($_type->getValue($this->server), 'user'); - $this->assertEquals($_typeId->getValue($this->server), 123); - $this->assertEquals($_scopes->getValue($this->server), array('foo', 'bar')); - } + $_scopes = $reflector->getProperty('_scopes'); + $_scopes->setAccessible(true); - function test_init_GET() - { - $_GET['oauth_token'] = 'test12345'; + $this->assertEquals($_accessToken->getValue($this->server), $_POST['oauth_token']); + $this->assertEquals($_type->getValue($this->server), 'user'); + $this->assertEquals($_typeId->getValue($this->server), 123); + $this->assertEquals($_scopes->getValue($this->server), array('foo', 'bar')); + } - $this->server->init(); + function test_init_GET() + { + $_GET['oauth_token'] = 'test12345'; - $reflector = new ReflectionClass($this->server); + $this->server->init(); - $_accessToken = $reflector->getProperty('_accessToken'); - $_accessToken->setAccessible(true); + $reflector = new ReflectionClass($this->server); - $_type = $reflector->getProperty('_type'); - $_type->setAccessible(true); + $_accessToken = $reflector->getProperty('_accessToken'); + $_accessToken->setAccessible(true); - $_typeId = $reflector->getProperty('_typeId'); - $_typeId->setAccessible(true); + $_type = $reflector->getProperty('_type'); + $_type->setAccessible(true); - $_scopes = $reflector->getProperty('_scopes'); - $_scopes->setAccessible(true); + $_typeId = $reflector->getProperty('_typeId'); + $_typeId->setAccessible(true); - $this->assertEquals($_accessToken->getValue($this->server), $_GET['oauth_token']); - $this->assertEquals($_type->getValue($this->server), 'user'); - $this->assertEquals($_typeId->getValue($this->server), 123); - $this->assertEquals($_scopes->getValue($this->server), array('foo', 'bar')); - } + $_scopes = $reflector->getProperty('_scopes'); + $_scopes->setAccessible(true); - function test_init_header() - { - // Test with authorisation header - $this->markTestIncomplete('Authorisation header test has not been implemented yet.'); - } + $this->assertEquals($_accessToken->getValue($this->server), $_GET['oauth_token']); + $this->assertEquals($_type->getValue($this->server), 'user'); + $this->assertEquals($_typeId->getValue($this->server), 123); + $this->assertEquals($_scopes->getValue($this->server), array('foo', 'bar')); + } - /** - * @expectedException \Oauth2\Resource\ClientException - * @expectedExceptionMessage An access token was not presented with the request - */ - function test_init_missingToken() - { - $this->server->init(); - } + function test_init_header() + { + // Test with authorisation header + $this->markTestIncomplete('Authorisation header test has not been implemented yet.'); + } - /** - * @expectedException \Oauth2\Resource\ClientException - * @expectedExceptionMessage The access token is not registered with the resource server - */ - function test_init_wrongToken() - { - $_POST['oauth_token'] = 'blah'; - $_SERVER['REQUEST_METHOD'] = 'POST'; + /** + * @expectedException \Oauth2\Resource\ClientException + * @expectedExceptionMessage An access token was not presented with the request + */ + function test_init_missingToken() + { + $this->server->init(); + } - $this->server->init(); - } + /** + * @expectedException \Oauth2\Resource\ClientException + * @expectedExceptionMessage The access token is not registered with the resource server + */ + function test_init_wrongToken() + { + $_POST['oauth_token'] = 'blah'; + $_SERVER['REQUEST_METHOD'] = 'POST'; - function test_hasScope() - { - $_POST['oauth_token'] = 'test12345'; - $_SERVER['REQUEST_METHOD'] = 'POST'; + $this->server->init(); + } - $this->server->init(); + function test_hasScope() + { + $_POST['oauth_token'] = 'test12345'; + $_SERVER['REQUEST_METHOD'] = 'POST'; - $this->assertEquals(true, $this->server->hasScope('foo')); - $this->assertEquals(true, $this->server->hasScope('bar')); - $this->assertEquals(true, $this->server->hasScope(array('foo', 'bar'))); + $this->server->init(); - $this->assertEquals(false, $this->server->hasScope('foobar')); - $this->assertEquals(false, $this->server->hasScope(array('foobar'))); - } + $this->assertEquals(true, $this->server->hasScope('foo')); + $this->assertEquals(true, $this->server->hasScope('bar')); + $this->assertEquals(true, $this->server->hasScope(array('foo', 'bar'))); - function test___call() - { - $_POST['oauth_token'] = 'test12345'; - $_SERVER['REQUEST_METHOD'] = 'POST'; + $this->assertEquals(false, $this->server->hasScope('foobar')); + $this->assertEquals(false, $this->server->hasScope(array('foobar'))); + } - $this->server->init(); + function test___call() + { + $_POST['oauth_token'] = 'test12345'; + $_SERVER['REQUEST_METHOD'] = 'POST'; - $this->assertEquals(123, $this->server->isUser()); - $this->assertEquals(false, $this->server->isMachine()); - } + $this->server->init(); + + $this->assertEquals(123, $this->server->isUser()); + $this->assertEquals(false, $this->server->isMachine()); + } } \ No newline at end of file From 7d1aa28087866c1bd3f7ab1902f279b20b4cd6d6 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 30 Dec 2012 21:31:19 +0000 Subject: [PATCH 10/14] Added .travis.yml --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..133c78b8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: php + +php: + - 5.3 + - 5.4 + +script: phpunit --coverage-text --configuration build/phpunit.xml \ No newline at end of file From 2b8a27ef479d77aecf98136bc1438cabc9973a88 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Wed, 2 Jan 2013 19:12:53 +0000 Subject: [PATCH 11/14] Ignore code coverage in ../tests folder --- build/phpunit.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/build/phpunit.xml b/build/phpunit.xml index e74535da..18e40915 100644 --- a/build/phpunit.xml +++ b/build/phpunit.xml @@ -13,6 +13,7 @@ PEAR_INSTALL_DIR PHP_LIBDIR ../vendor/composer + ../tests From 94945ec49ebc4d37ea00ce95b2adfaf7ceb13ed4 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Wed, 2 Jan 2013 19:14:22 +0000 Subject: [PATCH 12/14] Added support for refresh tokens, user credentials and client credentials grant. 100% unit test code coverage for authentication. Fixes #2 --- src/Oauth2/Authentication/Database.php | 9 +- src/Oauth2/Authentication/Server.php | 422 +++++++++++++------- tests/authentication/database_mock.php | 19 +- tests/authentication/server_test.php | 520 ++++++++++++++++++++++++- 4 files changed, 805 insertions(+), 165 deletions(-) diff --git a/src/Oauth2/Authentication/Database.php b/src/Oauth2/Authentication/Database.php index e3babb80..b9de679b 100644 --- a/src/Oauth2/Authentication/Database.php +++ b/src/Oauth2/Authentication/Database.php @@ -129,6 +129,7 @@ interface Database $typeId ); + public function validateRefreshToken($refreshToken, $clientId); /** * Update the refresh token @@ -138,16 +139,16 @@ interface Database * * UPDATE oauth_sessions SET access_token = $newAccessToken, refresh_token = * $newRefreshToken, access_toke_expires = $accessTokenExpires, last_updated = UNIX_TIMESTAMP(NOW()) WHERE - * refresh_token = $currentRefreshToken + * id = $sessionId * * - * @param string $currentRefreshToken The session's current refresh token + * @param string $sessionId The session ID * @param string $newAccessToken The new access token for this session * @param string $newRefreshToken The new refresh token for the session * @param int $accessTokenExpires The UNIX timestamp of when the new token expires - * @return bool Whether the $currentRefreshToken was valid or not. + * @return void */ - public function refreshToken($currentRefreshToken, $newAccessToken, $newRefreshToken, $accessTokenExpires); + public function updateRefreshToken($sessionId, $newAccessToken, $newRefreshToken, $accessTokenExpires); /** * Validate that an authorisation code is valid diff --git a/src/Oauth2/Authentication/Server.php b/src/Oauth2/Authentication/Server.php index d799cf60..82a2800a 100644 --- a/src/Oauth2/Authentication/Server.php +++ b/src/Oauth2/Authentication/Server.php @@ -47,9 +47,14 @@ class Server * @var array */ private $_grantTypes = array( - 'authorization_code', - 'user_credentials', - 'refresh_token', + 'authorization_code' => false, + 'client_credentials' => false, + 'password' => false, + 'refresh_token' => false, + ); + + private $_grantTypeCallbacks = array( + 'password' => null ); /** @@ -84,11 +89,11 @@ class Server 'invalid_scope' => 'The requested scope is invalid, unknown, or malformed. Check the "%s" scope.', 'server_error' => 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.', 'temporarily_unavailable' => 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.', - 'unsupported_grant_type' => 'The authorization grant type is not supported by the authorization server', + 'unsupported_grant_type' => 'The authorization grant type "%s" is not supported by the authorization server', 'invalid_client' => 'Client authentication failed', 'invalid_grant' => 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. Check the "%s" parameter.', - 'invalid_credentials' => 'Invalid Credentials', - 'invalid_refresh' => 'Invalid Refresh Token', + 'invalid_credentials' => 'The user credentials were incorrect.', + 'invalid_refresh' => 'The refresh token is invalid.', ); /** @@ -101,7 +106,7 @@ class Server public function __construct($options = null) { if ($options !== null) { - $this->options = array_merge($this->_config, $options); + $this->_config = array_merge($this->_config, $options); } } @@ -117,6 +122,27 @@ class Server $this->_db = $db; } + /** + * Enable a grant type + * + * @access public + * @return void + */ + public function enableGrantType($type, $callback = null) + { + if (isset($this->_grantTypes[$type])) { + $this->_grantTypes[$type] = true; + } + + if (in_array($type, array_keys($this->_grantTypeCallbacks))) { + if (is_null($callback) || ! is_callable($callback)) { + throw new ServerException('No registered callback function for grant type `'.$type.'`'); + } + + $this->_grantTypeCallbacks[$type] = $callback; + } + } + /** * Check client authorise parameters * @@ -237,7 +263,7 @@ class Server ); // Create the new auth code - $authCode = $this->newAuthCode( + $authCode = $this->_newAuthCode( $authoriseParams['client_id'], 'user', $typeId, @@ -255,7 +281,7 @@ class Server * * @return string A unique code */ - private function generateCode() + private function _generateCode() { return sha1(uniqid(microtime())); } @@ -271,54 +297,35 @@ class Server * @param string $accessToken The access token (default = null) * @return string An authorisation code */ - private function newAuthCode($clientId, $type, $typeId, $redirectUri, $scopes = array(), $accessToken = null, $refreshToken = null) + private function _newAuthCode($clientId, $type, $typeId, $redirectUri, $scopes = array()) { - $authCode = $this->generateCode(); + $authCode = $this->_generateCode(); - // If an access token exists then update the existing session with the - // new authorisation code otherwise create a new session - if ($accessToken !== null) { + // Delete any existing sessions just to be sure + $this->_dbCall('deleteSession', $clientId, $type, $typeId); + + // Create a new session + $sessionId = $this->_dbCall( + 'newSession', + $clientId, + $redirectUri, + $type, + $typeId, + $authCode, + null, + null, + 'requested' + ); + + // Add the scopes + foreach ($scopes as $key => $scope) { $this->_dbCall( - 'updateSession', - $clientId, - $type, - $typeId, - $authCode, - $accessToken, - $refreshToken, - 'requested' + 'addSessionScope', + $sessionId, + $scope['scope'] ); - } else { - - // Delete any existing sessions just to be sure - $this->_dbCall('deleteSession', $clientId, $type, $typeId); - - // Create a new session - $sessionId = $this->_dbCall( - 'newSession', - $clientId, - $redirectUri, - $type, - $typeId, - $authCode, - null, - null, - 'requested' - ); - - // Add the scopes - foreach ($scopes as $key => $scope) { - - $this->_dbCall( - 'addSessionScope', - $sessionId, - $scope['scope'] - ); - - } - } return $authCode; @@ -335,8 +342,6 @@ class Server */ public function issueAccessToken($authParams = null) { - $params = array(); - if ( ! isset($authParams['grant_type']) && ! isset($_POST['grant_type'])) { throw new ClientException(sprintf($this->errors['invalid_request'], 'grant_type'), 0); } @@ -345,33 +350,35 @@ class Server $authParams['grant_type'] : $_POST['grant_type']; - // Ensure grant type is one that is recognised - if ( ! in_array($params['grant_type'], $this->_grantTypes)) { - throw new ClientException($this->errors['unsupported_grant_type'], 7); + // Ensure grant type is one that is recognised and is enabled + if ( ! in_array($params['grant_type'], array_keys($this->_grantTypes)) || $this->_grantTypes[$params['grant_type']] !== true) { + throw new ClientException(sprintf($this->errors['unsupported_grant_type'], $params['grant_type']), 7); } switch ($params['grant_type']) { - case 'authorization_code': // Authorization code grant - return $this->completeAuthCodeGrant($authParams, $params); + return $this->_completeAuthCodeGrant($authParams, $params); break; - case 'user_credentials': - return $this->completeUserCredentialsGrant($authParams, $params); - break; - - case 'refresh_token': // Refresh token - return $this->completeRefreshTokenGrant($authParams, $params); + case 'client_credentials': // Client credentials grant + return $this->_completeClientCredentialsGrant($authParams, $params); break; case 'password': // Resource owner password credentials grant - case 'client_credentials': // Client credentials grant + return $this->_completeUserCredentialsGrant($authParams, $params); + break; + case 'refresh_token': // Refresh token grant + return $this->_completeRefreshTokenGrant($authParams, $params); + break; + + // @codeCoverageIgnoreStart default: // Unsupported throw new ServerException($this->errors['server_error'] . 'Tried to process an unsuppported grant type.', 5); break; } + // @codeCoverageIgnoreEnd } /** @@ -384,7 +391,7 @@ class Server * * @return array Authorise request parameters */ - private function completeAuthCodeGrant($authParams = array(), $params = array()) + private function _completeAuthCodeGrant($authParams = array(), $params = array()) { // Client ID if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) { @@ -449,8 +456,10 @@ class Server // A session ID was returned so update it with an access token, // remove the authorisation code, change the stage to 'granted' - $accessToken = $this->generateCode(); - $refreshToken = $this->generateCode(); + $accessToken = $this->_generateCode(); + $refreshToken = ($this->_grantTypes['refresh_token']) ? + $this->_generateCode() : + null; $accessTokenExpires = time() + $this->_config['access_token_ttl']; $accessTokenExpiresIn = $this->_config['access_token_ttl']; @@ -473,34 +482,35 @@ class Server $refreshToken ); - return array( + $response = array( 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, 'token_type' => 'bearer', 'expires' => $accessTokenExpires, 'expires_in' => $accessTokenExpiresIn ); + + if ($this->_grantTypes['refresh_token']) { + $response['refresh_token'] = $refreshToken; + } + + return $response; } /** - * Complete the user credentials grant + * Complete the resource owner password credentials grant * * @access private * @param array $authParams Array of parsed $_POST keys * @param array $params Generated parameters from issueAccessToken() * @return array Authorise request parameters */ - private function completeUserCredentialsGrant($authParams = array(), $params = array()) + private function _completeClientCredentialsGrant($authParams = array(), $params = array()) { - $params = array(); - - if ( ! isset($authParams['user_auth_callback'])) { - throw new \InvalidArgumentException('You must set a user_auth_callback when using the user_credentials grant type.'); - } - // Client ID if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) { + // @codeCoverageIgnoreStart throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); + // @codeCoverageIgnoreEnd } $params['client_id'] = (isset($authParams['client_id'])) ? @@ -509,13 +519,16 @@ class Server // Client secret if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) { + // @codeCoverageIgnoreStart throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0); + // @codeCoverageIgnoreEnd } + $params['client_secret'] = (isset($authParams['client_secret'])) ? $authParams['client_secret'] : $_POST['client_secret']; - // Validate client ID and redirect URI + // Validate client ID and client secret $clientDetails = $this->_dbCall( 'validateClient', $params['client_id'], @@ -524,72 +537,187 @@ class Server ); if ($clientDetails === false) { - throw new \Oauth2\Authentication\ClientException($this->errors['invalid_client'], 8); + // @codeCoverageIgnoreStart + throw new ClientException($this->errors['invalid_client'], 8); + // @codeCoverageIgnoreEnd } - // Check for grant - if ( ! isset($_POST['grant_type'])) { - throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); + // Generate an access token + $accessToken = $this->_generateCode(); + $refreshToken = ($this->_grantTypes['refresh_token']) ? + $this->_generateCode() : + null; + + $accessTokenExpires = time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = $this->_config['access_token_ttl']; + + // Delete any existing sessions just to be sure + $this->_dbCall('deleteSession', $params['client_id'], 'client', $params['client_id']); + + // Create a new session + $this->_dbCall('newSession', $params['client_id'], null, 'client', $params['client_id'], null, $accessToken, $refreshToken, $accessTokenExpires, 'granted'); + + $response = array( + 'access_token' => $accessToken, + 'token_type' => 'bearer', + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn + ); + + if ($this->_grantTypes['refresh_token']) { + $response['refresh_token'] = $refreshToken; } - $params['grant_type'] = $_POST['grant_type']; + return $response; + } - if ($params['grant_type'] == 'user_credentials') { - // Check if user's u+p are correct - $userId = call_user_func($authParams['user_auth_callback']); - - if ($userId === false) { - throw new \Oauth2\Authentication\ClientException($this->errors['invalid_credentials'], 0); - } - - // Generate an access token - $accessToken = $this->generateCode(); - $refreshToken = $this->generateCode(); - - $accessTokenExpires = time() + $this->_config['access_token_ttl']; - $accessTokenExpiresIn = $this->_config['access_token_ttl']; - - // Delete any existing sessions just to be sure - $this->_dbCall('deleteSession', $params['client_id'], 'user', $userId); - - // Create a new session - $this->_dbCall('newSession', $params['client_id'], null, 'user', $userId, null, $accessToken, $refreshToken, $accessTokenExpires, 'granted'); - - return array( - 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, - 'token_type' => 'bearer', - 'expires' => $accessTokenExpires, - 'expires_in' => $accessTokenExpiresIn - ); - - } else { - throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7); + /** + * Complete the resource owner password credentials grant + * + * @access private + * @param array $authParams Array of parsed $_POST keys + * @param array $params Generated parameters from issueAccessToken() + * @return array Authorise request parameters + */ + private function _completeUserCredentialsGrant($authParams = array(), $params = array()) + { + // Client ID + if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) { + // @codeCoverageIgnoreStart + throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); + // @codeCoverageIgnoreEnd } + $params['client_id'] = (isset($authParams['client_id'])) ? + $authParams['client_id'] : + $_POST['client_id']; + + // Client secret + if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) { + // @codeCoverageIgnoreStart + throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0); + // @codeCoverageIgnoreEnd + } + + $params['client_secret'] = (isset($authParams['client_secret'])) ? + $authParams['client_secret'] : + $_POST['client_secret']; + + // Validate client ID and client secret + $clientDetails = $this->_dbCall( + 'validateClient', + $params['client_id'], + $params['client_secret'], + null + ); + + if ($clientDetails === false) { + // @codeCoverageIgnoreStart + throw new ClientException($this->errors['invalid_client'], 8); + // @codeCoverageIgnoreEnd + } + + // User's username + if ( ! isset($authParams['username']) && ! isset($_POST['username'])) { + throw new ClientException(sprintf($this->errors['invalid_request'], 'username'), 0); + } + + $params['username'] = (isset($authParams['username'])) ? + $authParams['username'] : + $_POST['username']; + + // User's password + if ( ! isset($authParams['password']) && ! isset($_POST['password'])) { + throw new ClientException(sprintf($this->errors['invalid_request'], 'password'), 0); + } + + $params['password'] = (isset($authParams['password'])) ? + $authParams['password'] : + $_POST['password']; + + // Check if user's username and password are correct + $userId = call_user_func($this->_grantTypeCallbacks['password'], $params['username'], $params['password']); + + if ($userId === false) { + throw new \Oauth2\Authentication\ClientException($this->errors['invalid_credentials'], 0); + } + + // Generate an access token + $accessToken = $this->_generateCode(); + $refreshToken = ($this->_grantTypes['refresh_token']) ? + $this->_generateCode() : + null; + + $accessTokenExpires = time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = $this->_config['access_token_ttl']; + + // Delete any existing sessions just to be sure + $this->_dbCall('deleteSession', $params['client_id'], 'user', $userId); + + // Create a new session + $this->_dbCall('newSession', $params['client_id'], null, 'user', $userId, null, $accessToken, $refreshToken, $accessTokenExpires, 'granted'); + + $response = array( + 'access_token' => $accessToken, + 'token_type' => 'bearer', + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn + ); + + if ($this->_grantTypes['refresh_token']) { + $response['refresh_token'] = $refreshToken; + } + + return $response; } /** * Complete the refresh token grant * * @access private - * * @param array $authParams Array of parsed $_POST keys * @param array $params Generated parameters from issueAccessToken() - * * @return array Authorise request parameters */ - private function completeRefreshTokenGrant($authParams = array(), $params = array()) + private function _completeRefreshTokenGrant($authParams = array(), $params = array()) { - $params = array(); - - // Check for grant - if ( ! isset($_POST['grant_type'])) { - throw new \Oauth2\Authentication\ClientException(sprintf($this->errors['invalid_request'], 'grant_type'), 0); + // Client ID + if ( ! isset($authParams['client_id']) && ! isset($_POST['client_id'])) { + // @codeCoverageIgnoreStart + throw new ClientException(sprintf($this->errors['invalid_request'], 'client_id'), 0); + // @codeCoverageIgnoreEnd } - $params['grant_type'] = $_POST['grant_type']; + $params['client_id'] = (isset($authParams['client_id'])) ? + $authParams['client_id'] : + $_POST['client_id']; + // Client secret + if ( ! isset($authParams['client_secret']) && ! isset($_POST['client_secret'])) { + // @codeCoverageIgnoreStart + throw new ClientException(sprintf($this->errors['invalid_request'], 'client_secret'), 0); + // @codeCoverageIgnoreEnd + } + + $params['client_secret'] = (isset($authParams['client_secret'])) ? + $authParams['client_secret'] : + $_POST['client_secret']; + + // Validate client ID and client secret + $clientDetails = $this->_dbCall( + 'validateClient', + $params['client_id'], + $params['client_secret'], + null + ); + + if ($clientDetails === false) { + // @codeCoverageIgnoreStart + throw new ClientException($this->errors['invalid_client'], 8); + // @codeCoverageIgnoreEnd + } + + // Refresh token if ( ! isset($authParams['refresh_token']) && ! isset($_POST['refresh_token'])) { throw new ClientException(sprintf($this->errors['invalid_request'], 'refresh_token'), 0); } @@ -598,34 +726,30 @@ class Server $authParams['refresh_token'] : $_POST['refresh_token']; - if ($params['grant_type'] == 'refresh_token') { + // Validate refresh token + $sessionId = $this->_dbCall('validateRefreshToken', $params['refresh_token'], $params['client_id']); - // Generate an access token - $accessToken = $this->generateCode(); - $refreshToken = $this->generateCode(); - - $accessTokenExpires = time() + $this->_config['access_token_ttl']; - $accessTokenExpiresIn = $this->_config['access_token_ttl']; - - // Delete any existing sessions just to be sure - $result = $this->_dbCall('refreshToken', $params['refresh_token'], $accessToken, $refreshToken, $accessTokenExpires); - - if ( ! $result) { - throw new \Oauth2\Authentication\ClientException($this->errors['invalid_refresh'], 0); - } - - return array( - 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, - 'token_type' => 'bearer', - 'expires' => $accessTokenExpires, - 'expires_in' => $accessTokenExpiresIn - ); - - } else { - throw new \Oauth2\Authentication\ClientException($this->errors['unsupported_grant_type'], 7); + if ($sessionId === false) { + throw new \Oauth2\Authentication\ClientException($this->errors['invalid_refresh'], 0); } + // Generate new tokens + $accessToken = $this->_generateCode(); + $refreshToken = $this->_generateCode(); + + $accessTokenExpires = time() + $this->_config['access_token_ttl']; + $accessTokenExpiresIn = $this->_config['access_token_ttl']; + + // Update the tokens + $this->_dbCall('updateRefreshToken', $sessionId, $accessToken, $refreshToken, $accessTokenExpires); + + return array( + 'access_token' => $accessToken, + 'refresh_token' => $refreshToken, + 'token_type' => 'bearer', + 'expires' => $accessTokenExpires, + 'expires_in' => $accessTokenExpiresIn + ); } /** diff --git a/tests/authentication/database_mock.php b/tests/authentication/database_mock.php index a3a712a0..594d2665 100644 --- a/tests/authentication/database_mock.php +++ b/tests/authentication/database_mock.php @@ -67,7 +67,7 @@ class OAuthdb implements Database { $this->sessions[$sessionId]['auth_code'] = $authCode; $this->sessions[$sessionId]['access_token'] = $accessToken; - $this->sessions[$sessionId]['refresh_token'] = $accessToken; + $this->sessions[$sessionId]['refresh_token'] = $refreshToken; $this->sessions[$sessionId]['access_token_expire'] = $accessTokenExpire; $this->sessions[$sessionId]['stage'] = $stage; @@ -148,4 +148,21 @@ class OAuthdb implements Database { die('not implemented accessTokenScopes'); } + + public function validateRefreshToken($refreshToken, $clientId) + { + if ($refreshToken !== $this->sessions[0]['refresh_token']) + { + return false; + } + + return true; + } + + public function updateRefreshToken($sessionId, $newAccessToken, $newRefreshToken, $accessTokenExpires) + { + $this->sessions[$sessionId]['access_token'] = $newAccessToken; + $this->sessions[$sessionId]['refresh_token'] = $newRefreshToken; + $this->sessions[$sessionId]['access_token_expire'] = $accessTokenExpires; + } } \ No newline at end of file diff --git a/tests/authentication/server_test.php b/tests/authentication/server_test.php index b94d897e..ef677c7e 100644 --- a/tests/authentication/server_test.php +++ b/tests/authentication/server_test.php @@ -15,10 +15,24 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $this->oauth->registerDbAbstractor($this->oauthdb); } + public function test_setupWithOptions() + { + $o = new Oauth2\Authentication\Server(array( + 'access_token_ttl' => 86400 + )); + + $reflector = new ReflectionClass($o); + $param = $reflector->getProperty('_config'); + $param->setAccessible(true); + $array = $param->getValue($o); + + $this->assertEquals(86400, $array['access_token_ttl']); + } + public function test_generateCode() { $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('generateCode'); + $method = $reflector->getMethod('_generateCode'); $method->setAccessible(true); $result = $method->invoke($this->oauth); @@ -164,6 +178,34 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $this->oauth->checkClientAuthoriseParams(); } + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 8 + */ + public function test_checkClientAuthoriseParams_invalidClient() + { + $_GET['client_id'] = 'test'; + $_GET['redirect_uri'] = 'http://example.com/test2'; + $_GET['response_type'] = 'code'; + $_GET['scope'] = 'blah'; + + $this->oauth->checkClientAuthoriseParams(); + } + + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 3 + */ + public function test_checkClientAuthoriseParams_invalidResponseType() + { + $_GET['client_id'] = 'test'; + $_GET['redirect_uri'] = 'http://example.com/test'; + $_GET['response_type'] = 'blah'; + $_GET['scope'] = 'blah'; + + $this->oauth->checkClientAuthoriseParams(); + } + public function test_newAuthoriseRequest() { $result = $this->oauth->newAuthoriseRequest('user', '123', array( @@ -207,7 +249,11 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $this->assertNotEquals($result1, $result2); } - public function test_issueAccessToken_POST() + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 7 + */ + public function test_issueAccessTokenNoRegisteredGrant() { $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( 'client_id' => 'test', @@ -227,16 +273,38 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $_POST['code'] = $auth_code; $result = $this->oauth->issueAccessToken(); + } - $this->assertCount(5, $result); + public function test_issueAccessToken_POST_authorization_code() + { + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['redirect_uri'] = 'http://example.com/test'; + $_POST['grant_type'] = 'authorization_code'; + $_POST['code'] = $auth_code; + + $this->oauth->enableGrantType('authorization_code'); + $result = $this->oauth->issueAccessToken(); + + $this->assertCount(4, $result); $this->assertArrayHasKey('access_token', $result); $this->assertArrayHasKey('token_type', $result); $this->assertArrayHasKey('expires_in', $result); $this->assertArrayHasKey('expires', $result); - $this->assertArrayHasKey('refresh_token', $result); } - public function test_issueAccessToken_PassedParams() + public function test_issueAccessToken_PassedParams_authorization_code() { $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( 'client_id' => 'test', @@ -255,6 +323,38 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $params['grant_type'] = 'authorization_code'; $params['code'] = $auth_code; + $this->oauth->enableGrantType('authorization_code'); + $result = $this->oauth->issueAccessToken($params); + + $this->assertCount(4, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + } + + public function test_issueAccessToken_refresh_token() + { + $this->oauth->enableGrantType('authorization_code'); + $this->oauth->enableGrantType('refresh_token'); + + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['redirect_uri'] = 'http://example.com/test'; + $params['grant_type'] = 'authorization_code'; + $params['code'] = $auth_code; + $result = $this->oauth->issueAccessToken($params); $this->assertCount(5, $result); @@ -263,6 +363,404 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase $this->assertArrayHasKey('expires_in', $result); $this->assertArrayHasKey('expires', $result); $this->assertArrayHasKey('refresh_token', $result); + + // Wait for a few seconds for the access token to age + sleep(1); + + // Refresh the token + $params2['client_id'] = 'test'; + $params2['client_secret'] = 'test'; + $params2['redirect_uri'] = 'http://example.com/test'; + $params2['grant_type'] = 'refresh_token'; + $params2['refresh_token'] = $result['refresh_token']; + + $result2 = $this->oauth->issueAccessToken($params2); + + $this->assertCount(5, $result2); + $this->assertArrayHasKey('access_token', $result2); + $this->assertArrayHasKey('token_type', $result2); + $this->assertArrayHasKey('expires_in', $result2); + $this->assertArrayHasKey('expires', $result2); + $this->assertArrayHasKey('refresh_token', $result2); + + $this->assertNotEquals($result['access_token'], $result2['access_token']); + $this->assertNotEquals($result['refresh_token'], $result2['refresh_token']); + $this->assertNotEquals($result['expires'], $result2['expires']); + $this->assertEquals($result['expires_in'], $result2['expires_in']); + $this->assertEquals($result['token_type'], $result2['token_type']); + } + + public function test_issueAccessToken_client_credentials() + { + $this->oauth->enableGrantType('client_credentials'); + + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['redirect_uri'] = 'http://example.com/test'; + $params['grant_type'] = 'client_credentials'; + $params['code'] = $auth_code; + + $result = $this->oauth->issueAccessToken($params); + + $this->assertCount(4, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + } + + public function test_issueAccessToken_client_credentialsPOST() + { + $this->oauth->enableGrantType('client_credentials'); + + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['redirect_uri'] = 'http://example.com/test'; + $_POST['grant_type'] = 'client_credentials'; + $_POST['code'] = $auth_code; + + $result = $this->oauth->issueAccessToken(); + + $this->assertCount(4, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + } + + public function test_issueAccessToken_client_credentials_withRefreshToken() + { + $this->oauth->enableGrantType('client_credentials'); + $this->oauth->enableGrantType('refresh_token'); + + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['redirect_uri'] = 'http://example.com/test'; + $params['grant_type'] = 'client_credentials'; + $params['code'] = $auth_code; + + $result = $this->oauth->issueAccessToken($params); + + $this->assertCount(5, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + $this->assertArrayHasKey('refresh_token', $result); + } + + public function test_issueAccessToken_refresh_tokenPOST() + { + $this->oauth->enableGrantType('authorization_code'); + $this->oauth->enableGrantType('refresh_token'); + + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['redirect_uri'] = 'http://example.com/test'; + $_POST['grant_type'] = 'authorization_code'; + $_POST['code'] = $auth_code; + + $result = $this->oauth->issueAccessToken(); + + $this->assertCount(5, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + $this->assertArrayHasKey('refresh_token', $result); + + // Wait for a few seconds for the access token to age + sleep(1); + + // Refresh the token + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['redirect_uri'] = 'http://example.com/test'; + $_POST['grant_type'] = 'refresh_token'; + $_POST['refresh_token'] = $result['refresh_token']; + + $result2 = $this->oauth->issueAccessToken(); + + $this->assertCount(5, $result2); + $this->assertArrayHasKey('access_token', $result2); + $this->assertArrayHasKey('token_type', $result2); + $this->assertArrayHasKey('expires_in', $result2); + $this->assertArrayHasKey('expires', $result2); + $this->assertArrayHasKey('refresh_token', $result2); + + $this->assertNotEquals($result['access_token'], $result2['access_token']); + $this->assertNotEquals($result['refresh_token'], $result2['refresh_token']); + $this->assertNotEquals($result['expires'], $result2['expires']); + $this->assertEquals($result['expires_in'], $result2['expires_in']); + $this->assertEquals($result['token_type'], $result2['token_type']); + } + + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_issueAccessToken_refresh_tokenMissingToken() + { + $this->oauth->enableGrantType('authorization_code'); + $this->oauth->enableGrantType('refresh_token'); + + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['redirect_uri'] = 'http://example.com/test'; + $_POST['grant_type'] = 'authorization_code'; + $_POST['code'] = $auth_code; + + $result = $this->oauth->issueAccessToken(); + + $this->assertCount(5, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + $this->assertArrayHasKey('refresh_token', $result); + + // Wait for a few seconds for the access token to age + sleep(1); + + // Refresh the token + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['redirect_uri'] = 'http://example.com/test'; + $_POST['grant_type'] = 'refresh_token'; + + $result2 = $this->oauth->issueAccessToken(); + } + + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_issueAccessToken_invalid_refresh_token() + { + $this->oauth->enableGrantType('authorization_code'); + $this->oauth->enableGrantType('refresh_token'); + + $auth_code = $this->oauth->newAuthoriseRequest('user', '123', array( + 'client_id' => 'test', + 'redirect_uri' => 'http://example.com/test', + 'scopes' => array(array( + 'id' => 1, + 'scope' => 'test', + 'name' => 'test', + 'description' => 'test' + )) + )); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['redirect_uri'] = 'http://example.com/test'; + $params['grant_type'] = 'authorization_code'; + $params['code'] = $auth_code; + + $result = $this->oauth->issueAccessToken($params); + + $this->assertCount(5, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + $this->assertArrayHasKey('refresh_token', $result); + + // Wait for a few seconds for the access token to age + sleep(1); + + // Refresh the token + $params2['client_id'] = 'test'; + $params2['client_secret'] = 'test'; + $params2['redirect_uri'] = 'http://example.com/test'; + $params2['grant_type'] = 'refresh_token'; + $params2['refresh_token'] = 'blah'; + + $result2 = $this->oauth->issueAccessToken($params2); + } + + /** + * @expectedException Oauth2\Authentication\ServerException + * @expectedExceptionCode 0 + */ + public function test_issueAccessToken_password_grant_Missing_Callback() + { + $this->oauth->enableGrantType('password'); + } + + public function test_issueAccessToken_password_grant() + { + $this->oauth->enableGrantType('password', function(){ + return true; + }); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['grant_type'] = 'password'; + $params['username'] = 'alexbilbie'; + $params['password'] = 'helloworld'; + + $result = $this->oauth->issueAccessToken($params); + + $this->assertCount(4, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + } + + public function test_issueAccessToken_password_grantPOST() + { + $this->oauth->enableGrantType('password', function(){ + return true; + }); + + $_POST['client_id'] = 'test'; + $_POST['client_secret'] = 'test'; + $_POST['grant_type'] = 'password'; + $_POST['username'] = 'alexbilbie'; + $_POST['password'] = 'helloworld'; + + $result = $this->oauth->issueAccessToken(); + + $this->assertCount(4, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + } + + public function test_issueAccessToken_password_grant_withRefreshToken() + { + $this->oauth->enableGrantType('password', function(){ + return true; + }); + + $this->oauth->enableGrantType('refresh_token'); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['grant_type'] = 'password'; + $params['username'] = 'alexbilbie'; + $params['password'] = 'helloworld'; + + $result = $this->oauth->issueAccessToken($params); + + $this->assertCount(5, $result); + $this->assertArrayHasKey('access_token', $result); + $this->assertArrayHasKey('token_type', $result); + $this->assertArrayHasKey('expires_in', $result); + $this->assertArrayHasKey('expires', $result); + $this->assertArrayHasKey('refresh_token', $result); + } + + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_issueAccessToken_password_grant_wrongCreds() + { + $this->oauth->enableGrantType('password', function(){ + return false; + }); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['grant_type'] = 'password'; + $params['username'] = 'alexbilbie'; + $params['password'] = 'helloworld'; + + $result = $this->oauth->issueAccessToken($params); + } + + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_issueAccessToken_password_grant_missingUsername() + { + $this->oauth->enableGrantType('password', function(){ + return true; + }); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['grant_type'] = 'password'; + + $result = $this->oauth->issueAccessToken($params); + } + + /** + * @expectedException Oauth2\Authentication\ClientException + * @expectedExceptionCode 0 + */ + public function test_issueAccessToken_password_grant_missingPassword() + { + $this->oauth->enableGrantType('password', function(){ + return true; + }); + + $params['client_id'] = 'test'; + $params['client_secret'] = 'test'; + $params['grant_type'] = 'password'; + $params['username'] = 'alexbilbie'; + + $result = $this->oauth->issueAccessToken($params); } /** @@ -292,7 +790,7 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase public function test_completeAuthCodeGrant_missingClientId() { $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); + $method = $reflector->getMethod('_completeAuthCodeGrant'); $method->setAccessible(true); $method->invoke($this->oauth); @@ -305,7 +803,7 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase public function test_completeAuthCodeGrant_missingClientSecret() { $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); + $method = $reflector->getMethod('_completeAuthCodeGrant'); $method->setAccessible(true); $authParams['client_id'] = 'test'; @@ -320,7 +818,7 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase public function test_completeAuthCodeGrant_missingRedirectUri() { $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); + $method = $reflector->getMethod('_completeAuthCodeGrant'); $method->setAccessible(true); $authParams['client_id'] = 'test'; @@ -336,7 +834,7 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase public function test_completeAuthCodeGrant_invalidClient() { $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); + $method = $reflector->getMethod('_completeAuthCodeGrant'); $method->setAccessible(true); $authParams['client_id'] = 'test'; @@ -353,7 +851,7 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase public function test_completeAuthCodeGrant_missingCode() { $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); + $method = $reflector->getMethod('_completeAuthCodeGrant'); $method->setAccessible(true); $authParams['client_id'] = 'test'; @@ -370,7 +868,7 @@ class Authentication_Server_test extends PHPUnit_Framework_TestCase public function test_completeAuthCodeGrant_invalidCode() { $reflector = new ReflectionClass($this->oauth); - $method = $reflector->getMethod('completeAuthCodeGrant'); + $method = $reflector->getMethod('_completeAuthCodeGrant'); $method->setAccessible(true); $authParams['client_id'] = 'test'; From 2e1f1c05cffe23f558c6b5fb3e97d8e52f77c443 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Wed, 2 Jan 2013 19:16:16 +0000 Subject: [PATCH 13/14] Updated README --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index eb16e602..ff47bfce 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,8 @@ The framework is provided as a Composer package which can be installed by adding ```javascript { - "require": { - "lncd\Oauth2": "*" + "require": { + "lncd\Oauth2": "*" } } ``` @@ -22,7 +22,12 @@ Check out the [wiki](https://github.com/lncd/OAuth2/wiki) ### Authentication Server -The authentication server is a flexible class that supports the standard authorization code grant. +The authentication server is a flexible class that supports the following grants: + +* authentication code +* refresh token +* client credentials +* password (user credentials) ### Resource Server From f351cea442ae87746190f37e948d40ae77865ff5 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Wed, 2 Jan 2013 19:16:51 +0000 Subject: [PATCH 14/14] Version bump --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index f2a89158..e87e8077 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "lncd/oauth2", "description": "OAuth 2.0 Framework", - "version": "0.3.5", + "version": "0.4", "homepage": "https://github.com/lncd/OAuth2", "license": "MIT", "require": {