2013-01-05 01:14:02 +05:30
< ? php
namespace OAuth2 ;
2013-02-05 21:25:38 +05:30
use OAuth2\Util\Request ;
2013-01-29 22:23:39 +05:30
use OAuth2\Util\SecureKey ;
2013-01-29 19:46:47 +05:30
use OAuth2\Storage\SessionInterface ;
use OAuth2\Storage\ClientInterface ;
use OAuth2\Storage\ScopeInterface ;
2013-02-01 20:11:10 +05:30
use OAuth2\Grant\GrantTypeInterface ;
2013-01-29 19:46:47 +05:30
2013-01-22 22:03:09 +05:30
class AuthServer
2013-01-05 01:14:02 +05:30
{
2013-01-29 19:48:13 +05:30
/**
* The delimeter between scopes specified in the scope query string parameter
*
* The OAuth 2 specification states it should be a space but that is stupid
* and everyone excepted Google use a comma instead .
*
* @ var string
*/
2013-01-05 01:14:02 +05:30
protected $scopeDelimeter = ',' ;
2013-02-01 20:58:25 +05:30
static protected $expiresIn = 3600 ;
2013-01-05 01:14:02 +05:30
2013-01-29 19:47:56 +05:30
protected $responseTypes = array ();
2013-01-05 01:14:02 +05:30
2013-02-01 20:11:10 +05:30
static protected $storages = array ();
2013-01-05 01:14:02 +05:30
2013-02-01 20:53:04 +05:30
static protected $grantTypes = array ();
2013-01-05 01:14:02 +05:30
2013-02-01 20:37:47 +05:30
static protected $request = null ;
2013-01-22 21:55:51 +05:30
2013-01-29 19:49:23 +05:30
/**
* Exception error codes
* @ var array
*/
protected $exceptionCodes = array (
0 => 'invalid_request' ,
1 => 'unauthorized_client' ,
2 => 'access_denied' ,
3 => 'unsupported_response_type' ,
4 => 'invalid_scope' ,
5 => 'server_error' ,
6 => 'temporarily_unavailable' ,
7 => 'unsupported_grant_type' ,
8 => 'invalid_client' ,
9 => 'invalid_grant'
);
/**
* Exception error messages
* @ var array
*/
2013-02-01 20:11:10 +05:30
static protected $exceptionMessages = array (
2013-01-29 19:49:23 +05:30
'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.' ,
'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 "%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' => 'The user credentials were incorrect.' ,
'invalid_refresh' => 'The refresh token is invalid.' ,
);
2013-01-05 01:14:02 +05:30
2013-02-01 20:11:10 +05:30
public static function getExceptionMessage ( $error = '' )
{
return self :: $exceptionMessages [ $error ];
}
2013-01-29 19:46:47 +05:30
public function __construct ( ClientInterface $client , SessionInterface $session , ScopeInterface $scope )
{
2013-02-01 20:11:10 +05:30
self :: $storages = array (
2013-01-29 19:46:47 +05:30
'client' => $client ,
'session' => $session ,
'scope' => $scope
);
2013-01-05 01:14:02 +05:30
}
2013-01-29 19:47:56 +05:30
public function addGrantType ( GrantTypeInterface $grantType , $identifier = null )
2013-01-05 01:14:02 +05:30
{
if ( is_null ( $identifier )) {
2013-01-29 19:47:56 +05:30
$identifier = $grantType -> getIdentifier ();
}
2013-02-01 20:58:40 +05:30
self :: $grantTypes [ $identifier ] = $grantType ;
2013-01-29 19:47:56 +05:30
2013-01-29 21:51:53 +05:30
if ( ! is_null ( $grantType -> getResponseType ())) {
2013-01-29 19:47:56 +05:30
$this -> responseTypes [] = $grantType -> getResponseType ();
2013-01-05 01:14:02 +05:30
}
}
2013-02-01 20:11:10 +05:30
public static function hasGrantType ( $identifier )
{
2013-02-01 20:53:04 +05:30
return ( array_key_exists ( $identifier , self :: $grantTypes ));
2013-02-01 20:11:10 +05:30
}
2013-01-22 21:55:51 +05:30
public function getScopeDelimeter ()
{
return $this -> scopeDelimeter ;
}
2013-01-05 01:14:02 +05:30
public function setScopeDelimeter ( $scope_delimeter )
{
$this -> scopeDelimeter = $scope_delimeter ;
}
2013-02-01 20:11:10 +05:30
public static function getExpiresIn ()
2013-01-22 21:55:51 +05:30
{
2013-02-01 20:58:25 +05:30
return self :: $expiresIn ;
2013-01-22 21:55:51 +05:30
}
2013-02-01 20:11:10 +05:30
public function setExpiresIn ( $expiresIn )
2013-01-05 01:14:02 +05:30
{
2013-02-04 21:02:21 +05:30
self :: $expiresIn = $expiresIn ;
2013-01-05 01:14:02 +05:30
}
2013-01-22 21:55:51 +05:30
/**
* Sets the Request Object
*
* @ param RequestInterface The Request Object
*/
2013-02-05 21:25:38 +05:30
public function setRequest ( Util\RequestInterface $request )
2013-01-22 21:55:51 +05:30
{
2013-02-05 00:01:13 +05:30
self :: $request = $request ;
2013-01-22 21:55:51 +05:30
}
/**
* Gets the Request object . It will create one from the globals if one is not set .
*
* @ return RequestInterface
*/
2013-02-01 20:37:47 +05:30
public static function getRequest ()
2013-01-22 21:55:51 +05:30
{
2013-02-01 20:37:47 +05:30
if ( self :: $request === null ) {
2013-02-05 01:15:34 +05:30
// @codeCoverageIgnoreStart
2013-02-01 20:37:47 +05:30
self :: $request = Request :: buildFromGlobals ();
2013-02-05 01:15:34 +05:30
2013-01-22 21:55:51 +05:30
}
2013-02-05 01:15:34 +05:30
// @codeCoverageIgnoreEnd
2013-01-22 21:55:51 +05:30
2013-02-01 20:37:47 +05:30
return self :: $request ;
2013-01-22 21:55:51 +05:30
}
2013-02-01 20:11:10 +05:30
public static function getStorage ( $obj )
2013-01-29 19:46:47 +05:30
{
2013-02-01 20:11:10 +05:30
return self :: $storages [ $obj ];
2013-01-29 19:46:47 +05:30
}
2013-01-22 21:55:51 +05:30
/**
2013-01-29 21:55:14 +05:30
* Check authorise parameters
2013-01-22 21:55:51 +05:30
*
* @ access public
2013-02-01 20:11:10 +05:30
* @ param array $inputParams Optional array of parsed $_GET keys
2013-01-22 21:55:51 +05:30
* @ return array Authorise request parameters
*/
2013-02-01 20:11:10 +05:30
public function checkAuthoriseParams ( $inputParams = array ())
2013-01-22 21:55:51 +05:30
{
2013-02-01 20:11:10 +05:30
$authParams = array ();
2013-01-22 21:55:51 +05:30
2013-01-29 20:26:17 +05:30
// Client ID
2013-02-01 20:11:10 +05:30
$authParams [ 'client_id' ] = ( isset ( $inputParams [ 'client_id' ])) ?
$inputParams [ 'client_id' ] :
2013-02-01 20:37:47 +05:30
self :: getRequest () -> get ( 'client_id' );
2013-01-29 20:26:17 +05:30
2013-02-01 20:11:10 +05:30
if ( is_null ( $authParams [ 'client_id' ])) {
throw new Exception\ClientException ( sprintf ( self :: $exceptionMessages [ 'invalid_request' ], 'client_id' ), 0 );
2013-01-29 20:26:17 +05:30
}
// Redirect URI
2013-02-01 20:11:10 +05:30
$authParams [ 'redirect_uri' ] = ( isset ( $inputParams [ 'redirect_uri' ])) ?
$inputParams [ 'redirect_uri' ] :
2013-02-01 20:37:47 +05:30
self :: getRequest () -> get ( 'redirect_uri' );
2013-01-29 20:26:17 +05:30
2013-02-01 20:11:10 +05:30
if ( is_null ( $authParams [ 'redirect_uri' ])) {
throw new Exception\ClientException ( sprintf ( self :: $exceptionMessages [ 'invalid_request' ], 'redirect_uri' ), 0 );
2013-01-29 20:26:17 +05:30
}
// Validate client ID and redirect URI
2013-02-05 00:14:19 +05:30
$clientDetails = self :: getStorage ( 'client' ) -> getClient ( $authParams [ 'client_id' ], null , $authParams [ 'redirect_uri' ]);
2013-01-29 20:26:17 +05:30
if ( $clientDetails === false ) {
2013-02-01 20:11:10 +05:30
throw new Exception\ClientException ( self :: $exceptionMessages [ 'invalid_client' ], 8 );
2013-01-29 20:26:17 +05:30
}
2013-02-01 20:11:10 +05:30
$authParams [ 'client_details' ] = $clientDetails ;
2013-01-29 20:26:17 +05:30
// Response type
2013-02-01 20:11:10 +05:30
$authParams [ 'response_type' ] = ( isset ( $inputParams [ 'response_type' ])) ?
$inputParams [ 'response_type' ] :
2013-02-01 20:37:47 +05:30
self :: getRequest () -> get ( 'response_type' );
2013-01-29 20:26:17 +05:30
2013-02-01 20:11:10 +05:30
if ( is_null ( $authParams [ 'response_type' ])) {
throw new Exception\ClientException ( sprintf ( self :: $exceptionMessages [ 'invalid_request' ], 'response_type' ), 0 );
2013-01-29 20:26:17 +05:30
}
// Ensure response type is one that is recognised
2013-02-01 20:11:10 +05:30
if ( ! in_array ( $authParams [ 'response_type' ], $this -> responseTypes )) {
throw new Exception\ClientException ( self :: $exceptionMessages [ 'unsupported_response_type' ], 3 );
2013-01-29 20:26:17 +05:30
}
// Get and validate scopes
2013-02-01 20:11:10 +05:30
$scopes = ( isset ( $inputParams [ 'scope' ])) ?
$inputParams [ 'scope' ] :
2013-02-01 20:37:47 +05:30
self :: getRequest () -> get ( 'scope' , '' );
2013-01-29 20:26:17 +05:30
2013-02-01 20:11:10 +05:30
$scopes = explode ( $this -> scopeDelimeter , $scopes );
2013-01-29 20:26:17 +05:30
for ( $i = 0 ; $i < count ( $scopes ); $i ++ ) {
$scopes [ $i ] = trim ( $scopes [ $i ]);
if ( $scopes [ $i ] === '' ) unset ( $scopes [ $i ]); // Remove any junk scopes
}
if ( count ( $scopes ) === 0 ) {
2013-02-01 20:11:10 +05:30
throw new Exception\ClientException ( sprintf ( self :: $exceptionMessages [ 'invalid_request' ], 'scope' ), 0 );
2013-01-29 20:26:17 +05:30
}
2013-02-01 20:11:10 +05:30
$authParams [ 'scopes' ] = array ();
2013-01-29 20:26:17 +05:30
foreach ( $scopes as $scope ) {
2013-02-05 00:14:19 +05:30
$scopeDetails = self :: getStorage ( 'scope' ) -> getScope ( $scope );
2013-01-29 20:26:17 +05:30
if ( $scopeDetails === false ) {
2013-02-01 20:11:10 +05:30
throw new Exception\ClientException ( sprintf ( self :: $exceptionMessages [ 'invalid_scope' ], $scope ), 4 );
2013-01-29 20:26:17 +05:30
}
2013-02-01 20:11:10 +05:30
$authParams [ 'scopes' ][] = $scopeDetails ;
2013-01-29 20:26:17 +05:30
}
2013-02-01 20:11:10 +05:30
return $authParams ;
2013-01-22 21:55:51 +05:30
}
/**
* Parse a new authorise request
*
* @ param string $type The session owner ' s type
* @ param string $typeId The session owner ' s ID
* @ param array $authoriseParams The authorise request $_GET parameters
* @ return string An authorisation code
*/
2013-02-01 20:11:10 +05:30
public function newAuthoriseRequest ( $type , $typeId , $authParams = array ())
2013-01-22 21:55:51 +05:30
{
2013-01-29 21:53:41 +05:30
// Generate an auth code
$authCode = SecureKey :: make ();
2013-01-22 21:55:51 +05:30
2013-01-29 21:53:41 +05:30
// Remove any old sessions the user might have
2013-02-04 20:11:40 +05:30
self :: getStorage ( 'session' ) -> deleteSession ( $authParams [ 'client_id' ], $type , $typeId );
2013-01-29 21:53:41 +05:30
// Create a new session
2013-02-04 20:11:40 +05:30
$sessionId = self :: getStorage ( 'session' ) -> createSession ( $authParams [ 'client_id' ], $authParams [ 'redirect_uri' ], $type , $typeId , $authCode );
2013-01-29 21:53:41 +05:30
// Associate scopes with the new session
2013-02-01 20:11:10 +05:30
foreach ( $authParams [ 'scopes' ] as $scope )
2013-01-29 21:53:41 +05:30
{
2013-02-01 20:11:10 +05:30
self :: getStorage ( 'session' ) -> associateScope ( $sessionId , $scope [ 'id' ]);
2013-01-29 21:53:41 +05:30
}
return $authCode ;
2013-01-22 21:55:51 +05:30
}
/**
* Issue an access token
*
* @ access public
2013-02-01 20:11:10 +05:30
* @ param array $inputParams Optional array of parsed $_POST keys
2013-01-22 21:55:51 +05:30
* @ return array Authorise request parameters
*/
2013-02-01 20:11:10 +05:30
public function issueAccessToken ( $inputParams = array ())
2013-01-22 21:55:51 +05:30
{
2013-02-01 20:11:10 +05:30
$authParams [ 'grant_type' ] = ( isset ( $inputParams [ 'grant_type' ])) ?
$inputParams [ 'grant_type' ] :
2013-02-01 20:37:47 +05:30
self :: getRequest () -> post ( 'grant_type' );
2013-01-22 21:55:51 +05:30
2013-02-01 20:11:10 +05:30
if ( is_null ( $authParams [ 'grant_type' ])) {
throw new Exception\ClientException ( sprintf ( self :: $exceptionMessages [ 'invalid_request' ], 'grant_type' ), 0 );
2013-01-29 21:54:28 +05:30
}
2013-01-22 21:55:51 +05:30
2013-01-29 21:54:28 +05:30
// Ensure grant type is one that is recognised and is enabled
2013-02-01 20:58:40 +05:30
if ( ! in_array ( $authParams [ 'grant_type' ], array_keys ( self :: $grantTypes ))) {
2013-02-01 20:11:10 +05:30
throw new Exception\ClientException ( sprintf ( self :: $exceptionMessages [ 'unsupported_grant_type' ], $authParams [ 'grant_type' ]), 7 );
2013-01-29 21:54:28 +05:30
}
2013-01-22 21:55:51 +05:30
2013-01-29 21:54:48 +05:30
// Complete the flow
2013-02-05 00:00:56 +05:30
return $this -> getGrantType ( $authParams [ 'grant_type' ]) -> completeFlow ( $inputParams , $authParams );
2013-01-29 21:54:48 +05:30
}
2013-01-22 21:55:51 +05:30
2013-02-05 00:00:56 +05:30
protected function getGrantType ( $grantType )
2013-01-29 21:54:48 +05:30
{
2013-02-01 20:58:40 +05:30
return self :: $grantTypes [ $grantType ];
2013-01-22 21:55:51 +05:30
}
2013-01-05 01:14:02 +05:30
}