mirror of
https://github.com/elyby/oauth2-server.git
synced 2024-11-02 00:43:11 +05:30
Starting the reorganization
This commit is contained in:
parent
0f6f5e2939
commit
31b36f23e7
8
src/Oauth2/MissingAccessTokenException.php
Normal file
8
src/Oauth2/MissingAccessTokenException.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2;
|
||||||
|
|
||||||
|
class MissingAccessTokenException
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
94
src/Oauth2/Request.php
Normal file
94
src/Oauth2/Request.php
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2;
|
||||||
|
|
||||||
|
use OutOfBoundsException;
|
||||||
|
use InvalidMethodCallException;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
class Request implements RequestInterface
|
||||||
|
{
|
||||||
|
protected $get = array();
|
||||||
|
protected $post = array();
|
||||||
|
protected $cookies = array();
|
||||||
|
protected $files = array();
|
||||||
|
protected $server = array();
|
||||||
|
protected $headers = array();
|
||||||
|
|
||||||
|
public static function buildFromGlobals()
|
||||||
|
{
|
||||||
|
return new static($_GET, $_POST, $_COOKIE, $_FILES, $_SERVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __construct(array $get = array(), array $post = array(), array $cookies = array(), array $files = array(), array $server = array(), $headers = array())
|
||||||
|
{
|
||||||
|
$this->get = $get;
|
||||||
|
$this->post = $post;
|
||||||
|
$this->cookies = $cookies;
|
||||||
|
$this->files = $files;
|
||||||
|
$this->server = $server;
|
||||||
|
|
||||||
|
if (empty($headers)) {
|
||||||
|
$this->headers = $this->readHeaders();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get($index = null, $default = null)
|
||||||
|
{
|
||||||
|
return $this->getPropertyValue('get', $index, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function post($index = null, $default = null)
|
||||||
|
{
|
||||||
|
return $this->getPropertyValue('post', $index, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function file($index = null, $default = null)
|
||||||
|
{
|
||||||
|
return $this->getPropertyValue('files', $index, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cookie($index = null, $default = null)
|
||||||
|
{
|
||||||
|
return $this->getPropertyValue('cookies', $index, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function server($index = null, $default = null)
|
||||||
|
{
|
||||||
|
return $this->getPropertyValue('server', $index, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function header($index = null, $default = null)
|
||||||
|
{
|
||||||
|
return $this->getPropertyValue('headers', $index, $default);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function readHeaders()
|
||||||
|
{
|
||||||
|
$headers = array();
|
||||||
|
foreach ($this->server() as $name => $value) {
|
||||||
|
if (substr($name, 0, 5) == 'HTTP_') {
|
||||||
|
$name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
|
||||||
|
$headers[$name] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getPropertyValue($property, $index = null, $default = null)
|
||||||
|
{
|
||||||
|
if ( ! isset($this->{$property})) {
|
||||||
|
throw new InvalidArgumentException("Property '$property' does not exist.");
|
||||||
|
}
|
||||||
|
if (is_null($index)) {
|
||||||
|
return $this->{$property};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! array_key_exists($index, $this->{$property})) {
|
||||||
|
return $default;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->{$property}[$index];
|
||||||
|
}
|
||||||
|
}
|
24
src/Oauth2/RequestInterface.php
Normal file
24
src/Oauth2/RequestInterface.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2;
|
||||||
|
|
||||||
|
interface RequestInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function buildFromGlobals();
|
||||||
|
|
||||||
|
public function __construct(array $get = array(), array $post = array(), array $cookies = array(), array $files = array(), array $server = array(), $headers = array());
|
||||||
|
|
||||||
|
public function get($index = null);
|
||||||
|
|
||||||
|
public function post($index = null);
|
||||||
|
|
||||||
|
public function cookie($index = null);
|
||||||
|
|
||||||
|
public function file($index = null);
|
||||||
|
|
||||||
|
public function server($index = null);
|
||||||
|
|
||||||
|
public function header($index = null);
|
||||||
|
|
||||||
|
}
|
110
src/Oauth2/Resource.php
Normal file
110
src/Oauth2/Resource.php
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2;
|
||||||
|
|
||||||
|
use OutOfBoundsException;
|
||||||
|
use Storage\SessionInterface;
|
||||||
|
use Storage\SessionScopeInterface;
|
||||||
|
|
||||||
|
class Resource
|
||||||
|
{
|
||||||
|
protected $accessToken = null;
|
||||||
|
|
||||||
|
protected $sessionId = null;
|
||||||
|
|
||||||
|
protected $ownerType = null;
|
||||||
|
|
||||||
|
protected $ownerId = null;
|
||||||
|
|
||||||
|
protected $sessionScopes = array();
|
||||||
|
|
||||||
|
protected $storages = array();
|
||||||
|
|
||||||
|
protected $request = null;
|
||||||
|
|
||||||
|
protected $tokenKey = 'oauth_token';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the Resource
|
||||||
|
*
|
||||||
|
* @param SessionInterface The Session Storage Object
|
||||||
|
* @param SessionScopeInterface The Session Scope Storage Object
|
||||||
|
* @param RequestInterface The Request Object
|
||||||
|
*/
|
||||||
|
public function __construct(SessionInterface $session, SessionScopeInterface $session_scope, RequestInterface $request = null)
|
||||||
|
{
|
||||||
|
$this->storages['session'] = $session;
|
||||||
|
$this->storages['session_scope'] = $session_scope;
|
||||||
|
|
||||||
|
if (is_null($request)) {
|
||||||
|
$request = Request::buildFromGlobals();
|
||||||
|
}
|
||||||
|
$this->request = $request;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the Access Token is valid or not.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValid()
|
||||||
|
{
|
||||||
|
$access_token = $this->determineAccessToken();
|
||||||
|
|
||||||
|
$result = $this->storages['session']->validateAccessToken($access_token);
|
||||||
|
|
||||||
|
if ( ! $result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->accessToken = $access_token;
|
||||||
|
$this->sessionId = $result['id'];
|
||||||
|
$this->ownerType = $result['owner_type'];
|
||||||
|
$this->ownerId = $result['owner_id'];
|
||||||
|
|
||||||
|
$this->sessionScopes = $this->storages['session_scope']->getScopes($this->sessionId);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current session has the given scope(s).
|
||||||
|
*
|
||||||
|
* @param array
|
||||||
|
*/
|
||||||
|
public function hasScope($scopes)
|
||||||
|
{
|
||||||
|
if (is_string($scopes)) {
|
||||||
|
if (in_array($scopes, $this->sessionScopes)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} elseif (is_array($scopes)) {
|
||||||
|
foreach ($scopes as $scope) {
|
||||||
|
if ( ! in_array($scope, $this->sessionScopes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function determineAccessToken()
|
||||||
|
{
|
||||||
|
if ($header = $this->request->header('Authorization')) {
|
||||||
|
$access_token = trim(str_replace('Bearer', '', $header));
|
||||||
|
} else {
|
||||||
|
$method = $this->request->server('REQUEST_METHOD');
|
||||||
|
$access_token = $this->request->{$method}($this->tokenKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($access_token)) {
|
||||||
|
throw new MissingAccessTokenException('Access Token is Missing');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,59 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Oauth2\Resource;
|
|
||||||
|
|
||||||
interface Database
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Validate an access token and return the session details.
|
|
||||||
*
|
|
||||||
* Database query:
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* SELECT id, owner_type, owner_id FROM oauth_sessions WHERE access_token =
|
|
||||||
* $accessToken AND stage = 'granted' AND
|
|
||||||
* access_token_expires > UNIX_TIMESTAMP(now())
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* Response:
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* Array
|
|
||||||
* (
|
|
||||||
* [id] => (int) The session ID
|
|
||||||
* [owner_type] => (string) The session owner type
|
|
||||||
* [owner_id] => (string) The session owner's ID
|
|
||||||
* )
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param string $accessToken The access token
|
|
||||||
* @return array|bool Return an array on success or false on failure
|
|
||||||
*/
|
|
||||||
public function validateAccessToken($accessToken);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the scopes that the session is authorised with.
|
|
||||||
*
|
|
||||||
* Database query:
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* SELECT scope FROM oauth_session_scopes WHERE session_id =
|
|
||||||
* $sessionId
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* Response:
|
|
||||||
*
|
|
||||||
* <code>
|
|
||||||
* Array
|
|
||||||
* (
|
|
||||||
* [0] => (string) A scope
|
|
||||||
* [1] => (string) Another scope
|
|
||||||
* ...
|
|
||||||
* )
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param int $sessionId The session ID
|
|
||||||
* @return array A list of scopes
|
|
||||||
*/
|
|
||||||
public function sessionScopes($sessionId);
|
|
||||||
}
|
|
@ -1,253 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Oauth2\Resource;
|
|
||||||
|
|
||||||
class ServerException extends \Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClientException extends \Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class Server
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Reference to the database abstractor
|
|
||||||
* @var object
|
|
||||||
*/
|
|
||||||
private $_db = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The access token.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $_accessToken = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The scopes the access token has access to.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $_scopes = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of owner of the access token.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $_type = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The ID of the owner of the access token.
|
|
||||||
* @access private
|
|
||||||
*/
|
|
||||||
private $_typeId = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Server configuration
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $_config = array(
|
|
||||||
'token_key' => 'oauth_token'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Error codes.
|
|
||||||
*
|
|
||||||
* To provide i8ln errors just overwrite the keys
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $errors = array(
|
|
||||||
'missing_access_token' => 'An access token was not presented with the request',
|
|
||||||
'invalid_access_token' => 'The access token is not registered with the resource server',
|
|
||||||
'missing_access_token_details' => 'The registered database abstractor did not return a valid access token details response',
|
|
||||||
'invalid_access_token_scopes' => 'The registered database abstractor did not return a valid access token scopes response',
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct($options = null)
|
|
||||||
{
|
|
||||||
if ($options !== null) {
|
|
||||||
$this->_config = array_merge($this->_config, $options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Magic method to test if access token represents a particular owner type
|
|
||||||
* @param string $method The method name
|
|
||||||
* @param mixed $arguements The method arguements
|
|
||||||
* @return bool If method is valid, and access token is owned by the requested party then true,
|
|
||||||
*/
|
|
||||||
public function __call($method, $arguements = null)
|
|
||||||
{
|
|
||||||
if (substr($method, 0, 2) === 'is') {
|
|
||||||
|
|
||||||
if ($this->_type === strtolower(substr($method, 2))) {
|
|
||||||
return $this->_typeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
trigger_error('Call to undefined function ' . $method . '()');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register a database abstrator class
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @param object $db A class that implements OAuth2ServerDatabase
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function registerDbAbstractor($db)
|
|
||||||
{
|
|
||||||
$this->_db = $db;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Init function
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function init()
|
|
||||||
{
|
|
||||||
$accessToken = null;
|
|
||||||
|
|
||||||
$_SERVER['REQUEST_METHOD'] = isset($_SERVER['REQUEST_METHOD']) ?
|
|
||||||
$_SERVER['REQUEST_METHOD'] :
|
|
||||||
null;
|
|
||||||
|
|
||||||
// Try and get the access token via an access_token or oauth_token parameter
|
|
||||||
switch ($_SERVER['REQUEST_METHOD'])
|
|
||||||
{
|
|
||||||
case 'POST':
|
|
||||||
$accessToken = isset($_POST[$this->_config['token_key']]) ?
|
|
||||||
$_POST[$this->_config['token_key']] :
|
|
||||||
null;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
$accessToken = isset($_GET[$this->_config['token_key']]) ?
|
|
||||||
$_GET[$this->_config['token_key']] :
|
|
||||||
null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try and get an access token from the auth header
|
|
||||||
if (function_exists('getallheaders')) {
|
|
||||||
|
|
||||||
$headers = getallheaders();
|
|
||||||
|
|
||||||
if (isset($headers['Authorization'])) {
|
|
||||||
|
|
||||||
$rawToken = trim(str_replace('Bearer', '', $headers['Authorization']));
|
|
||||||
|
|
||||||
if ( ! empty($rawToken)) {
|
|
||||||
$accessToken = $rawToken;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($accessToken) {
|
|
||||||
|
|
||||||
$result = $this->_dbCall('validateAccessToken', $accessToken);
|
|
||||||
|
|
||||||
if ($result === false) {
|
|
||||||
|
|
||||||
throw new ClientException($this->errors['invalid_access_token']);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
if ( ! array_key_exists('id', $result) ||
|
|
||||||
! array_key_exists('owner_id', $result) ||
|
|
||||||
! array_key_exists('owner_type', $result)) {
|
|
||||||
throw new ServerException($this->errors['missing_access_token_details']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_accessToken = $accessToken;
|
|
||||||
$this->_type = $result['owner_type'];
|
|
||||||
$this->_typeId = $result['owner_id'];
|
|
||||||
|
|
||||||
// Get the scopes
|
|
||||||
$scopes = $this->_dbCall('sessionScopes', $result['id']);
|
|
||||||
|
|
||||||
if ( ! is_array($scopes))
|
|
||||||
{
|
|
||||||
throw new ServerException($this->errors['invalid_access_token_scopes']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_scopes = $scopes;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
throw new ClientException($this->errors['missing_access_token']);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test if the access token has a specific scope
|
|
||||||
*
|
|
||||||
* @param mixed $scopes Scope(s) to check
|
|
||||||
*
|
|
||||||
* @access public
|
|
||||||
* @return string|bool
|
|
||||||
*/
|
|
||||||
public function hasScope($scopes)
|
|
||||||
{
|
|
||||||
if (is_string($scopes)) {
|
|
||||||
|
|
||||||
if (in_array($scopes, $this->_scopes)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
|
||||||
} elseif (is_array($scopes)) {
|
|
||||||
|
|
||||||
foreach ($scopes as $scope) {
|
|
||||||
|
|
||||||
if ( ! in_array($scope, $this->_scopes)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call database methods from the abstractor
|
|
||||||
*
|
|
||||||
* @return mixed The query result
|
|
||||||
*/
|
|
||||||
private function _dbCall()
|
|
||||||
{
|
|
||||||
if ($this->_db === null) {
|
|
||||||
throw new ServerException('No registered database abstractor');
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( ! $this->_db instanceof Database) {
|
|
||||||
throw new ServerException('The registered database abstractor is not an instance of Oauth2\Resource\Database');
|
|
||||||
}
|
|
||||||
|
|
||||||
$args = func_get_args();
|
|
||||||
$method = $args[0];
|
|
||||||
unset($args[0]);
|
|
||||||
$params = array_values($args);
|
|
||||||
|
|
||||||
return call_user_func_array(array($this->_db, $method), $params);
|
|
||||||
}
|
|
||||||
}
|
|
8
src/Oauth2/Storage/ClientEndpointInterface.php
Normal file
8
src/Oauth2/Storage/ClientEndpointInterface.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2\Storage;
|
||||||
|
|
||||||
|
interface ClientEndpointInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
8
src/Oauth2/Storage/ClientInterface.php
Normal file
8
src/Oauth2/Storage/ClientInterface.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2\Storage;
|
||||||
|
|
||||||
|
interface ClientInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
8
src/Oauth2/Storage/ScopeInterface.php
Normal file
8
src/Oauth2/Storage/ScopeInterface.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2\Storage;
|
||||||
|
|
||||||
|
interface ScopeInterface
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
8
src/Oauth2/Storage/SessionInterface.php
Normal file
8
src/Oauth2/Storage/SessionInterface.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2\Storage;
|
||||||
|
|
||||||
|
interface SessionInterface
|
||||||
|
{
|
||||||
|
public function validateAccessToken($access_token);
|
||||||
|
}
|
8
src/Oauth2/Storage/SessionScopeInterface.php
Normal file
8
src/Oauth2/Storage/SessionScopeInterface.php
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OAuth2\Storage;
|
||||||
|
|
||||||
|
interface SessionScopeInterface
|
||||||
|
{
|
||||||
|
public function getScopes($session_id);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user