diff --git a/src/Oauth2/MissingAccessTokenException.php b/src/Oauth2/MissingAccessTokenException.php
new file mode 100644
index 00000000..0eb4ff0c
--- /dev/null
+++ b/src/Oauth2/MissingAccessTokenException.php
@@ -0,0 +1,8 @@
+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];
+ }
+}
diff --git a/src/Oauth2/RequestInterface.php b/src/Oauth2/RequestInterface.php
new file mode 100644
index 00000000..458711ba
--- /dev/null
+++ b/src/Oauth2/RequestInterface.php
@@ -0,0 +1,24 @@
+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;
+ }
+
+}
diff --git a/src/Oauth2/Resource/Database.php b/src/Oauth2/Resource/Database.php
deleted file mode 100644
index 8408df3a..00000000
--- a/src/Oauth2/Resource/Database.php
+++ /dev/null
@@ -1,59 +0,0 @@
-
- * SELECT id, owner_type, owner_id FROM oauth_sessions WHERE access_token =
- * $accessToken AND stage = 'granted' AND
- * access_token_expires > UNIX_TIMESTAMP(now())
- *
- *
- * Response:
- *
- *
- * Array
- * (
- * [id] => (int) The session ID
- * [owner_type] => (string) The session owner type
- * [owner_id] => (string) The session owner's ID
- * )
- *
- *
- * @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:
- *
- *
- * SELECT scope FROM oauth_session_scopes WHERE session_id =
- * $sessionId
- *
- *
- * Response:
- *
- *
- * Array
- * (
- * [0] => (string) A scope
- * [1] => (string) Another scope
- * ...
- * )
- *
- *
- * @param int $sessionId The session ID
- * @return array A list of scopes
- */
- public function sessionScopes($sessionId);
-}
\ No newline at end of file
diff --git a/src/Oauth2/Resource/Server.php b/src/Oauth2/Resource/Server.php
deleted file mode 100644
index 64a29d6e..00000000
--- a/src/Oauth2/Resource/Server.php
+++ /dev/null
@@ -1,253 +0,0 @@
- '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);
- }
-}
\ No newline at end of file
diff --git a/src/Oauth2/Storage/ClientEndpointInterface.php b/src/Oauth2/Storage/ClientEndpointInterface.php
new file mode 100644
index 00000000..ae83eb93
--- /dev/null
+++ b/src/Oauth2/Storage/ClientEndpointInterface.php
@@ -0,0 +1,8 @@
+