Created
April 1, 2014 07:13
-
-
Save magnetik/9909298 to your computer and use it in GitHub Desktop.
ManiaConnect Client.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Maniaplanet Web Services SDK for PHP | |
* | |
* @see http://code.google.com/p/maniaplanet-ws-sdk/ | |
* @copyright Copyright (c) 2009-2011 NADEO (http://www.nadeo.com) | |
* @license http://www.gnu.org/licenses/lgpl.html LGPL License 3 | |
* @author $Author$: | |
* @version $Revision$: | |
* @date $Date$: | |
*/ | |
namespace Maniaplanet\WebServices\ManiaConnect; | |
/** | |
* OAuth2 client implementation | |
*/ | |
abstract class Client extends \Maniaplanet\WebServices\HTTPClient | |
{ | |
/** | |
* Path for the OAuth2 Token Endpoint on our API | |
* | |
* @var string | |
*/ | |
const TOKEN_PATH = '/oauth2/token/'; | |
protected $loginURL = 'https://ws.maniaplanet.com/oauth2/authorize/'; | |
protected $logoutURL = 'https://ws.maniaplanet.com/oauth2/authorize/logout/'; | |
/** | |
* An implementation of the Peristance interface to store data (such as | |
* access tokens) between requests. Default implementation is using PHP | |
* session but you can easily write your own if needed. | |
* | |
* @param \Maniaplanet\WebServices\ManiaConnect\Persistance | |
*/ | |
static protected $persistance; | |
static function setPersistance(Persistance $object) | |
{ | |
if(self::$persistance) | |
{ | |
throw new \Maniaplanet\WebServices\Exception( | |
'You must set the persistance object before instanciating the '. | |
'services.'); | |
} | |
self::$persistance = $object; | |
} | |
function __construct($username = null, $password = null) | |
{ | |
parent::__construct($username, $password); | |
// Default persistance is using the PHP sessions | |
if(!self::$persistance) | |
{ | |
self::$persistance = new Session(); | |
} | |
self::$persistance->init(); | |
} | |
/** | |
* When a user is not authentified, you need to create a link to the URL | |
* returned by this method. | |
* | |
* @param string $scope Space-separated list of scopes. Leave empty if you just need the basic one | |
* @param string $redirectURI Where to redirect the user after auth. Leave empty for the current URI | |
* @return string Login URL | |
*/ | |
function getLoginURL($scope = null, $redirectURI = null) | |
{ | |
$redirectURI = $redirectURI ? : $this->getCurrentURI(); | |
self::$persistance->setVariable('redirect_uri', $redirectURI); | |
return $this->getAuthorizationURL($redirectURI, $scope); | |
} | |
/** | |
* If you want to place a "logout" button, you can use this link to log the | |
* user out of the player page too. Don't forget to empty your sessions . | |
* | |
* @see \Maniaplanet\WebServices\ManiaConnect\Client::logout() | |
* @param string $redirectURI Where to redirect the user after he logged out. Leave empty for current URI | |
* @return string Logout URL | |
*/ | |
function getLogoutURL($redirectURI = null) | |
{ | |
$redirectURI = $redirectURI ? : $this->getCurrentURI(); | |
return $this->logoutURL.'?'.http_build_query(array('redirect_uri' => $redirectURI), | |
'', '&'); | |
} | |
/** | |
* Destroys the persistance. Call that when you want to log a | |
* user out, or implement your own way of logging out. | |
*/ | |
function logout() | |
{ | |
self::$persistance->destroy(); | |
} | |
/** | |
* Returns the Current URL. | |
* | |
* @return string The current URL. | |
* @see http://code.google.com/p/oauth2-php | |
* @author Originally written by Naitik Shah <[email protected]>. | |
* @author Update to draft v10 by Edison Wong <[email protected]> | |
*/ | |
protected function getCurrentURI() | |
{ | |
$protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https://' : 'http://'; | |
$current_uri = $protocol.$_SERVER['HTTP_HOST'].$this->getRequestURI(); | |
$parts = parse_url($current_uri); | |
$query = ''; | |
if(!empty($parts['query'])) | |
{ | |
$params = array(); | |
parse_str($parts['query'], $params); | |
$params = array_filter($params); | |
if(!empty($params)) | |
{ | |
$query = '?'.http_build_query($params, '', '&'); | |
} | |
} | |
// Use port if non default. | |
$port = isset($parts['port']) && | |
(($protocol === 'http://' && $parts['port'] !== 80) || ($protocol === 'https://' && $parts['port'] !== 443)) ? ':'.$parts['port'] | |
: ''; | |
// Rebuild. | |
return $protocol.$parts['host'].$port.$parts['path'].$query; | |
} | |
/** | |
* Since $_SERVER['REQUEST_URI'] is only available on Apache, we | |
* generate an equivalent using other environment variables. | |
* | |
* @see http://code.google.com/p/oauth2-php | |
* @author Originally written by Naitik Shah <[email protected]>. | |
* @author Update to draft v10 by Edison Wong <[email protected]> | |
*/ | |
protected function getRequestURI() | |
{ | |
if(isset($_SERVER['REQUEST_URI'])) | |
{ | |
$uri = $_SERVER['REQUEST_URI']; | |
} | |
else | |
{ | |
if(isset($_SERVER['argv'])) | |
{ | |
$uri = $_SERVER['SCRIPT_NAME'].'?'.$_SERVER['argv'][0]; | |
} | |
elseif(isset($_SERVER['QUERY_STRING'])) | |
{ | |
$uri = $_SERVER['SCRIPT_NAME'].'?'.$_SERVER['QUERY_STRING']; | |
} | |
else | |
{ | |
$uri = $_SERVER['SCRIPT_NAME']; | |
} | |
} | |
// Prevent multiple slashes to avoid cross site requests | |
$uri = '/'.ltrim($uri, '/'); | |
return $uri; | |
} | |
private function getAuthorizationURL($redirectURI, $scope = 'basic') | |
{ | |
$params = http_build_query(array( | |
'client_id' => $this->username, | |
'redirect_uri' => $redirectURI, | |
'scope' => $scope, | |
'response_type' => 'code', | |
), '', '&'); | |
return $this->loginURL.'?'.$params; | |
} | |
/** | |
* Tries to get an access token. | |
* If one is found in the session, it returns it. | |
* If a code is found in the request, it tries to exchange it for an access | |
* token on the OAuth2 Token Endpoint | |
* Else it returns false | |
* | |
* @return string An OAuth2 access token, or false if none is found | |
*/ | |
protected function getAccessToken() | |
{ | |
$token = self::$persistance->getVariable('token'); | |
if(!$this->isAccessTokenExpired($token)) | |
{ | |
return $token->access_token; | |
} | |
else if ($token !== null && $token->refresh_token !== null) | |
{ | |
$token = $this->getTokenFromRefreshToken($token->refresh_token); | |
return $token->access_token; | |
} | |
if(isset($_REQUEST['code'])) | |
{ | |
$code = $_REQUEST['code']; | |
if($code) | |
{ | |
$redirectURI = self::$persistance->getVariable('redirect_uri') ? : $this->getCurrentURI(); | |
$token = $this->getTokenFromCode($code, $redirectURI); | |
self::$persistance->deleteVariable('redirect_uri'); | |
self::$persistance->deleteVariable('code'); | |
return $token->access_token; | |
} | |
} | |
} | |
private function getTokenFromCode($authorizationCode, $redirectURI) | |
{ | |
return $this->getTokenFromParamsArray(array( | |
'client_id' => $this->username, | |
'client_secret' => $this->password, | |
'redirect_uri' => $redirectURI, | |
'grant_type' => 'authorization_code', | |
'code' => $authorizationCode, | |
)); | |
} | |
private function getTokenFromRefreshToken($refreshToken) | |
{ | |
return $this->getTokenFromParamsArray(array( | |
'client_id' => $this->username, | |
'client_secret' => $this->password, | |
'grant_type' => 'refresh_token', | |
'refresh_token' => $refreshToken, | |
)); | |
} | |
private function getTokenFromParamsArray(array $params) | |
{ | |
$contentType = $this->contentType; | |
$serializeCallback = $this->serializeCallback; | |
$this->contentType = 'application/x-www-form-urlencoded'; | |
$this->serializeCallback = null; | |
$params = http_build_query($params, '', '&'); | |
try | |
{ | |
$token = $this->execute('POST', self::TOKEN_PATH, array($params)); | |
$token->created = time(); | |
self::$persistance->setVariable('token', $token); | |
} | |
catch(\Maniaplanet\WebServices\Exception $e) | |
{ | |
switch($e->getMessage()) | |
{ | |
case 'invalid_request': | |
$message = | |
'invalid_request: The request is missing a required '. | |
'parameter, includes an unsupported parameter or '. | |
'parameter value, or is otherwise malformed.'; | |
break; | |
case 'invalid_client': | |
$message = | |
'invalid_client: Application authentication failed. '; | |
break; | |
case 'invalid_grant': | |
$message = | |
'invalid_grant: The provided access grant is invalid, '. | |
'expired, or revoked (e.g. invalid assertion, expired '. | |
'authorization token, bad end-user password credentials, '. | |
'or mismatching authorization code and redirection URI).'; | |
break; | |
default: | |
throw $e; | |
} | |
throw new \Maniaplanet\WebServices\Exception($message, $e->getCode(), | |
$e->getHTTPStatusCode(), $e->getHTTPStatusMessage()); | |
} | |
$this->contentType = $contentType; | |
$this->serializeCallback = $serializeCallback; | |
return $token; | |
} | |
/** | |
* Executes an request on the API with an OAuth2 access token. | |
* It works just like its parent execute() method. | |
* | |
* @see \Maniaplanet\WebServices\HTTPClient::execute() | |
*/ | |
protected function executeOAuth2($method, $ressource, array $params = array()) | |
{ | |
$this->headers['authorization'] = sprintf('Authorization: Bearer %s', $this->getAccessToken()); | |
// We don't need auth since we are using an access token | |
$this->enableAuth = false; | |
try | |
{ | |
$result = $this->execute($method, $ressource, $params); | |
$this->enableAuth = true; | |
return $result; | |
} | |
catch(Exception $e) | |
{ | |
$this->enableAuth = true; | |
throw $e; | |
} | |
} | |
protected function isAccessTokenExpired($token) | |
{ | |
if ($token == null) | |
{ | |
return true; | |
} | |
return ($token->created + ($token->expires_in - 30)) < time(); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment