mirror of
https://github.com/elyby/oauth2-server.git
synced 2024-12-16 02:08:56 +05:30
Lots of updates so it all works now
Signed-off-by: Alex Bilbie <alex@alexbilbie.com>
This commit is contained in:
parent
af83b1e80e
commit
b1082ecb41
@ -37,5 +37,8 @@
|
|||||||
"psr-0": {
|
"psr-0": {
|
||||||
"Oauth2": "src/"
|
"Oauth2": "src/"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"lncd/oauth2-facebook": "Adds support for Facebook as an IDP"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace OAuth2\Client;
|
|
||||||
|
|
||||||
include_once('Exception.php');
|
|
||||||
|
|
||||||
class Client
|
|
||||||
{
|
|
||||||
public function __construct($name, array $options = null)
|
|
||||||
{
|
|
||||||
if ( ! class_exists($name)) {
|
|
||||||
|
|
||||||
throw new OAuth2\Client\Exception('There is no identity provider called: '.$name);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return new $name($options);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,83 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace OAuth2\Client;
|
|
||||||
|
|
||||||
class Exception extends \Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The result from the API server that represents the exception information.
|
|
||||||
*/
|
|
||||||
protected $result;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make a new API Exception with the given result.
|
|
||||||
*
|
|
||||||
* @param $result
|
|
||||||
* The result from the API server.
|
|
||||||
*/
|
|
||||||
public function __construct($result)
|
|
||||||
{
|
|
||||||
$this->result = $result;
|
|
||||||
|
|
||||||
$code = isset($result['code']) ? $result['code'] : 0;
|
|
||||||
|
|
||||||
if (isset($result['error'])) {
|
|
||||||
|
|
||||||
// OAuth 2.0 Draft 10 style
|
|
||||||
$message = $result['error'];
|
|
||||||
|
|
||||||
} elseif (isset($result['message'])) {
|
|
||||||
|
|
||||||
// cURL style
|
|
||||||
$message = $result['message'];
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
$message = 'Unknown Error.';
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::__construct($message, $code);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the associated type for the error. This will default to
|
|
||||||
* 'Exception' when a type is not available.
|
|
||||||
*
|
|
||||||
* @return
|
|
||||||
* The type for the error.
|
|
||||||
*/
|
|
||||||
public function getType()
|
|
||||||
{
|
|
||||||
if (isset($this->result['error'])) {
|
|
||||||
|
|
||||||
$message = $this->result['error'];
|
|
||||||
|
|
||||||
if (is_string($message)) {
|
|
||||||
// OAuth 2.0 Draft 10 style
|
|
||||||
return $message;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'Exception';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* To make debugging easier.
|
|
||||||
*
|
|
||||||
* @returns
|
|
||||||
* The string representation of the error.
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
$str = $this->getType() . ': ';
|
|
||||||
|
|
||||||
if ($this->code != 0) {
|
|
||||||
$str .= $this->code . ': ';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $str . $this->message;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -2,128 +2,229 @@
|
|||||||
|
|
||||||
namespace OAuth2\Client;
|
namespace OAuth2\Client;
|
||||||
|
|
||||||
use Guzzle\Service\Client;
|
use Guzzle\Service\Client as GuzzleClient;
|
||||||
|
|
||||||
class IDPException extends \Exception {}
|
class IDPException extends \Exception
|
||||||
|
{
|
||||||
|
protected $result;
|
||||||
|
|
||||||
class IDP {
|
public function __construct($result)
|
||||||
|
{
|
||||||
|
$this->result = $result;
|
||||||
|
|
||||||
public $clientId = '';
|
$code = isset($result['code']) ? $result['code'] : 0;
|
||||||
|
|
||||||
public $clientSecret = '';
|
if (isset($result['error'])) {
|
||||||
|
|
||||||
public $redirectUri = '';
|
// OAuth 2.0 Draft 10 style
|
||||||
|
$message = $result['error'];
|
||||||
|
|
||||||
public $name;
|
} elseif (isset($result['message'])) {
|
||||||
|
|
||||||
public $uidKey = 'uid';
|
// cURL style
|
||||||
|
$message = $result['message'];
|
||||||
|
|
||||||
public $scopes = array();
|
} else {
|
||||||
|
|
||||||
public $method = 'post';
|
$message = 'Unknown Error.';
|
||||||
|
|
||||||
public $scopeSeperator = ',';
|
}
|
||||||
|
|
||||||
public $responseType = 'json';
|
parent::__construct($message['message'], $message['code']);
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct()
|
public function getType()
|
||||||
{
|
{
|
||||||
//$this->redirectUri = $_SERVER[]
|
if (isset($this->result['error'])) {
|
||||||
}
|
|
||||||
|
|
||||||
public function __get($key)
|
$message = $this->result['error'];
|
||||||
{
|
|
||||||
return $this->$key;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract public function urlAuthorize();
|
if (is_string($message)) {
|
||||||
|
// OAuth 2.0 Draft 10 style
|
||||||
|
return $message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract public function urlAccessToken();
|
return 'Exception';
|
||||||
|
}
|
||||||
|
|
||||||
abstract public function urlUserInfo();
|
/**
|
||||||
|
* To make debugging easier.
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
* The string representation of the error.
|
||||||
|
*/
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
$str = $this->getType() . ': ';
|
||||||
|
|
||||||
public function authorize($options = array())
|
if ($this->code != 0) {
|
||||||
{
|
$str .= $this->code . ': ';
|
||||||
$state = md5(uniqid(rand(), TRUE));
|
}
|
||||||
setcookie($this->name.'_authorize_state', $state);
|
|
||||||
|
|
||||||
$params = array(
|
return $str . $this->message;
|
||||||
'client_id' => $this->clientId,
|
}
|
||||||
'redirect_uri' => $this->redirectUri,
|
|
||||||
'state' => $state,
|
|
||||||
'scope' => is_array($this->scope) ? implode($this->scopeSeperator, $this->scope) : $this->scope,
|
|
||||||
'response_type' => isset($options['response_type']) ? $options['response_type'] : 'code',
|
|
||||||
'approval_prompt' => 'force' // - google force-recheck
|
|
||||||
);
|
|
||||||
|
|
||||||
header('Location: ' . $this->urlAuthorize().'?'.http_build_query($params));
|
}
|
||||||
exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getAccessToken()
|
abstract class IDP {
|
||||||
{
|
|
||||||
$params = array(
|
|
||||||
'client_id' => $this->clientId,
|
|
||||||
'client_secret' => $this->clientSecret,
|
|
||||||
'grant_type' => isset($options['grant_type']) ? $options['grant_type'] : 'authorization_code',
|
|
||||||
);
|
|
||||||
|
|
||||||
switch ($params['grant_type']) {
|
public $clientId = '';
|
||||||
|
|
||||||
case 'authorization_code':
|
public $clientSecret = '';
|
||||||
$params['code'] = $code;
|
|
||||||
$params['redirect_uri'] = isset($options['redirect_uri']) ? $options['redirect_uri'] : $this->redirect_uri;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'refresh_token':
|
public $redirectUri = '';
|
||||||
$params['refresh_token'] = $code;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
public $name;
|
||||||
|
|
||||||
switch ($this->method) {
|
public $uidKey = 'uid';
|
||||||
|
|
||||||
case 'get':
|
public $scopes = array();
|
||||||
$client = new Client($this->urlAccessToken() .= '?'.http_build_query($params));
|
|
||||||
$response = $client->get();
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
public $method = 'post';
|
||||||
$client = new Client($this->urlAccessToken());
|
|
||||||
$response = $client->{$this->method}(null, null, $params);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
public $scopeSeperator = ',';
|
||||||
|
|
||||||
switch ($this->responseType) {
|
public $responseType = 'json';
|
||||||
|
|
||||||
case 'json':
|
public function __construct($options)
|
||||||
$result = json_decode($response, true);
|
{
|
||||||
break;
|
foreach ($options as $option => $value) {
|
||||||
|
if (isset($this->{$option})) {
|
||||||
|
$this->{$option} = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 'string':
|
abstract public function urlAuthorize();
|
||||||
parse_str($response, $result);
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
abstract public function urlAccessToken();
|
||||||
|
|
||||||
if (isset($result['error']) && ! empty($result['error'])) {
|
abstract public function urlUserDetails(\Oauth2\Client\Token\Access $token);
|
||||||
|
|
||||||
throw new Oauth2\Client\IDPException($result);
|
abstract public function userDetails($response, \Oauth2\Client\Token\Access $token);
|
||||||
|
|
||||||
}
|
public function authorize($options = array())
|
||||||
|
{
|
||||||
|
$state = md5(uniqid(rand(), TRUE));
|
||||||
|
setcookie($this->name.'_authorize_state', $state);
|
||||||
|
|
||||||
switch ($params['grant_type']) {
|
$params = array(
|
||||||
|
'client_id' => $this->clientId,
|
||||||
|
'redirect_uri' => $this->redirectUri,
|
||||||
|
'state' => $state,
|
||||||
|
'scope' => is_array($this->scope) ? implode($this->scopeSeperator, $this->scope) : $this->scope,
|
||||||
|
'response_type' => isset($options['response_type']) ? $options['response_type'] : 'code',
|
||||||
|
'approval_prompt' => 'force' // - google force-recheck
|
||||||
|
);
|
||||||
|
|
||||||
case 'authorization_code':
|
header('Location: ' . $this->urlAuthorize().'?'.http_build_query($params));
|
||||||
return Oauth2\Client\Token::factory('access', $result);
|
exit;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case 'refresh_token':
|
public function getAccessToken($code = NULL, $options = array())
|
||||||
return Oauth2\Client\Token::factory('refresh', $result);
|
{
|
||||||
break;
|
if ($code === NULL) {
|
||||||
|
throw new \BadMethodCallException('Missing authorization code');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
$params = array(
|
||||||
}
|
'client_id' => $this->clientId,
|
||||||
|
'client_secret' => $this->clientSecret,
|
||||||
|
'grant_type' => isset($options['grantType']) ? $options['grantType'] : 'authorization_code',
|
||||||
|
);
|
||||||
|
|
||||||
|
switch ($params['grant_type']) {
|
||||||
|
|
||||||
|
case 'authorization_code':
|
||||||
|
$params['code'] = $code;
|
||||||
|
$params['redirect_uri'] = isset($options['redirectUri']) ? $options['redirectUri'] : $this->redirectUri;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'refresh_token':
|
||||||
|
$params['refresh_token'] = $code;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
switch ($this->method) {
|
||||||
|
|
||||||
|
case 'get':
|
||||||
|
|
||||||
|
$client = new GuzzleClient($this->urlAccessToken() . '?' . http_build_query($params));
|
||||||
|
$request = $client->send();
|
||||||
|
$response = $request->getBody();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'post':
|
||||||
|
|
||||||
|
$client = new GuzzleClient($this->urlAccessToken());
|
||||||
|
$request = $client->post(null, null, $params)->send();
|
||||||
|
$response = $request->getBody();
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (\Guzzle\Http\Exception\BadResponseException $e)
|
||||||
|
{
|
||||||
|
$raw_response = explode("\n", $e->getResponse());
|
||||||
|
$response = end($raw_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($this->responseType) {
|
||||||
|
|
||||||
|
case 'json':
|
||||||
|
$result = json_decode($response, true);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'string':
|
||||||
|
parse_str($response, $result);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($result['error']) && ! empty($result['error'])) {
|
||||||
|
|
||||||
|
throw new \Oauth2\Client\IDPException($result);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($params['grant_type']) {
|
||||||
|
|
||||||
|
case 'authorization_code':
|
||||||
|
return \Oauth2\Client\Token::factory('access', $result);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'refresh_token':
|
||||||
|
return \Oauth2\Client\Token::factory('refresh', $result);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getUserDetails(\Oauth2\Client\Token\Access $token)
|
||||||
|
{
|
||||||
|
$url = $this->urlUserDetails($token);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$client = new GuzzleClient($url);
|
||||||
|
$request = $client->get()->send();
|
||||||
|
$response = $request->getBody();
|
||||||
|
|
||||||
|
return $this->userDetails(json_decode($response), $token);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (\Guzzle\Http\Exception\BadResponseException $e)
|
||||||
|
{
|
||||||
|
$raw_response = explode("\n", $e->getResponse());
|
||||||
|
throw new \Oauth2\Client\IDPException(end($raw_response));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,7 +16,7 @@ abstract class Token
|
|||||||
{
|
{
|
||||||
include_once 'Token/'.ucfirst(strtolower($name)).'.php';
|
include_once 'Token/'.ucfirst(strtolower($name)).'.php';
|
||||||
|
|
||||||
$class = $name.'Token';
|
$class = 'Oauth2\Client\Token\\'.ucfirst($name);
|
||||||
|
|
||||||
return new $class($options);
|
return new $class($options);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace Oauth2\Client\Token;
|
|||||||
* @copyright (c) 2011 HappyNinjas Ltd
|
* @copyright (c) 2011 HappyNinjas Ltd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Access extends Oauth2\Client\Token
|
class Access extends \Oauth2\Client\Token
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string accessToken
|
* @var string accessToken
|
||||||
@ -42,26 +42,26 @@ class Access extends Oauth2\Client\Token
|
|||||||
public function __construct(array $options = null)
|
public function __construct(array $options = null)
|
||||||
{
|
{
|
||||||
if ( ! isset($options['access_token'])) {
|
if ( ! isset($options['access_token'])) {
|
||||||
throw new Exception('Required option not passed: access_token'.PHP_EOL.print_r($options, true));
|
throw new \BadMethodCallException('Required option not passed: access_token'.PHP_EOL.print_r($options, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->accessToken = $options['access_token'];
|
$this->accessToken = $options['access_token'];
|
||||||
|
|
||||||
// Some providers (not many) give the uid here, so lets take it
|
// Some providers (not many) give the uid here, so lets take it
|
||||||
isset($options['uid']) and $this->uid = $options['uid'];
|
isset($options['uid']) and $this->uid = $options['uid'];
|
||||||
|
|
||||||
//Vkontakte uses user_id instead of uid
|
//Vkontakte uses user_id instead of uid
|
||||||
isset($options['user_id']) and $this->uid = $options['user_id'];
|
isset($options['user_id']) and $this->uid = $options['user_id'];
|
||||||
|
|
||||||
//Mailru uses x_mailru_vid instead of uid
|
//Mailru uses x_mailru_vid instead of uid
|
||||||
isset($options['x_mailru_vid']) and $this->uid = $options['x_mailru_vid'];
|
isset($options['x_mailru_vid']) and $this->uid = $options['x_mailru_vid'];
|
||||||
|
|
||||||
// We need to know when the token expires, add num. seconds to current time
|
// We need to know when the token expires, add num. seconds to current time
|
||||||
isset($options['expires_in']) and $this->expires = time() + ((int) $options['expires_in']);
|
isset($options['expires_in']) and $this->expires = time() + ((int) $options['expires_in']);
|
||||||
|
|
||||||
// Facebook is just being a spec ignoring jerk
|
// Facebook is just being a spec ignoring jerk
|
||||||
isset($options['expires']) and $this->expires = time() + ((int) $options['expires']);
|
isset($options['expires']) and $this->expires = time() + ((int) $options['expires']);
|
||||||
|
|
||||||
// Grab a refresh token so we can update access tokens when they expires
|
// Grab a refresh token so we can update access tokens when they expires
|
||||||
isset($options['refresh_token']) and $this->refreshToken = $options['refresh_token'];
|
isset($options['refresh_token']) and $this->refreshToken = $options['refresh_token'];
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* @copyright (c) 2011 HappyNinjas Ltd
|
* @copyright (c) 2011 HappyNinjas Ltd
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Authorize extends Oauth2\Client\Token
|
class Authorize extends \Oauth2\Client\Token
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @var string code
|
* @var string code
|
||||||
@ -35,9 +35,9 @@ class Authorize extends Oauth2\Client\Token
|
|||||||
} elseif ( ! isset($options['redirect_uri'])) {
|
} elseif ( ! isset($options['redirect_uri'])) {
|
||||||
|
|
||||||
throw new Exception('Required option not passed: redirect_uri');
|
throw new Exception('Required option not passed: redirect_uri');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->code = $options['code'];
|
$this->code = $options['code'];
|
||||||
$this->redirectUri = $options['redirect_uri'];
|
$this->redirectUri = $options['redirect_uri'];
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user