From 1f3650b98ae278d5c09c0e2885b22b4c634cf72b Mon Sep 17 00:00:00 2001 From: Josh Sherman Date: Sun, 19 Oct 2014 12:01:04 -0400 Subject: [PATCH 1/6] Porting interfaces to Mongo --- src/Mongo.php | 2 +- src/OAuth2/AccessTokenStorage.php | 17 +++++++++------ src/OAuth2/ClientStorage.php | 27 ++++++------------------ src/OAuth2/RefreshTokenStorage.php | 21 ++++++++---------- src/OAuth2/Resource.php | 11 ++-------- src/OAuth2/SessionStorage.php | 34 +++++++++++++++++------------- src/OAuth2/StorageAdapter.php | 6 +++--- 7 files changed, 51 insertions(+), 67 deletions(-) diff --git a/src/Mongo.php b/src/Mongo.php index 2ffcc50..ae0bd98 100644 --- a/src/Mongo.php +++ b/src/Mongo.php @@ -37,7 +37,7 @@ class Mongo extends Object // Instantiates our Mongo client $instance = new \MongoClient($mongo['server']); - $instance->selectDB($mongo['database']); + $instance = $instance->$mongo['database']; // Caches the instance for possible reuse later self::$instances['Mongo'] = $instance; diff --git a/src/OAuth2/AccessTokenStorage.php b/src/OAuth2/AccessTokenStorage.php index 04d8dc0..980cda0 100644 --- a/src/OAuth2/AccessTokenStorage.php +++ b/src/OAuth2/AccessTokenStorage.php @@ -30,6 +30,10 @@ class AccessTokenStorage extends StorageAdapter implements AccessTokenInterface public function getScopes(AbstractTokenEntity $token) { + $response = []; + + /* + @todo Port to Mongo $sql = 'SELECT oauth_scopes.id, oauth_scopes.description' . ' FROM oauth_access_token_scopes' . ' INNER JOIN oauth_scopes' @@ -37,7 +41,6 @@ class AccessTokenStorage extends StorageAdapter implements AccessTokenInterface . ' WHERE oauth_access_token_scopes.access_token_id = ?;'; $results = $this->db->fetch($sql, [$token->getId()]); - $response = []; if (count($results) > 0) { @@ -49,18 +52,18 @@ class AccessTokenStorage extends StorageAdapter implements AccessTokenInterface ]); } } + */ return $response; } public function create($token, $expiration, $session_id) { - $sql = 'INSERT INTO oauth_access_tokens' - . ' (access_token, session_id, expires_at)' - . ' VALUES' - . ' (?, ?, ?);'; - - $this->db->execute($sql, [$token, $session_id, $expiration]); + return $this->mongo->oauth_access_tokens->insert([ + 'access_token' => $token, + 'session_id' => $session_id, // @todo Store as MongoId? + 'expires_at' => $expiration, + ]); } public function associateScope(AbstractTokenEntity $token, ScopeEntity $scope) diff --git a/src/OAuth2/ClientStorage.php b/src/OAuth2/ClientStorage.php index 1a32583..001bf5e 100644 --- a/src/OAuth2/ClientStorage.php +++ b/src/OAuth2/ClientStorage.php @@ -11,40 +11,27 @@ class ClientStorage extends StorageAdapter implements ClientInterface { public function get($client_id, $client_secret = null, $redirect_uri = null, $grant_type = null) { - $sql = 'SELECT oauth_clients.*'; + $criteria = ['_id' => new \MongoId($client_id)]; if ($redirect_uri) { - $sql .= ', oauth_client_redirect_uris.*' - . ' INNER JOIN oauth_redirect_uris' - . ' ON oauth_clients.id = oauth_redirect_uris.client_id'; + // @todo join / query oauth_client_redirect_uris } - $sql .= ' FROM oauth_clients WHERE oauth_clients.id = ?'; - - $parameters = [$client_id]; - if ($client_secret) { - $sql .= ' AND oauth_clients.secret = ?'; - $parameters[] = $client_secret; + $criteria['secret'] = $client_secret; } - if ($redirect_uri) - { - $sql .= 'AND oauth_redirect_uris.redirect_uri = ?'; - $parameters[] = $redirect_uri; - } + $results = $this->mongo->oauth_clients->findOne($criteria); - $results = $this->db->fetch($sql, $parameters); - - if (count($results) === 1) + if ($results) { $client = new ClientEntity($this->server); $client->hydrate([ - 'id' => $results[0]['id'], - 'name' => $results[0]['name'] + 'id' => $results['_id']->{'$id'}, + 'name' => $results['name'] ]); return $client; diff --git a/src/OAuth2/RefreshTokenStorage.php b/src/OAuth2/RefreshTokenStorage.php index bceea31..978a17a 100644 --- a/src/OAuth2/RefreshTokenStorage.php +++ b/src/OAuth2/RefreshTokenStorage.php @@ -29,20 +29,17 @@ class RefreshTokenStorage extends StorageAdapter implements RefreshTokenInterfac public function create($token, $expiration, $access_token) { - $sql = 'SELECT id FROM oauth_access_tokens WHERE access_token = ?;'; - $results = $this->db->fetch($sql, [$access_token]); - $token_id = $results[0]['id']; + $results = $this->mongo->oauth_access_tokens->findOne([ + 'access_token' => $access_token, + ]); - $sql = 'INSERT INTO oauth_refresh_tokens' - . ' (refresh_token, access_token_id, expires_at, client_id)' - . ' VALUES' - . ' (?, ?, ?, ?);'; + $token_id = $results['_id']->{'$id'}; - $this->db->execute($sql, [ - $token, - $token_id, - $expiration, - $this->server->getRequest()->request->get('client_id', null), + return $this->mongo->oauth_refresh_tokens->insert([ + 'refresh_token' => $token, + 'access_token_id' => $token_id, + 'expires_at' => $expiration, + 'client_id' => $this->server->getRequest()->request->get('client_id', null), ]); } diff --git a/src/OAuth2/Resource.php b/src/OAuth2/Resource.php index 2ff78ae..8406d93 100644 --- a/src/OAuth2/Resource.php +++ b/src/OAuth2/Resource.php @@ -6,7 +6,6 @@ use \League\OAuth2\Exception\OAuthException; use \League\OAuth2\Server\AuthorizationServer; use \League\OAuth2\Server\Grant\PasswordGrant; use \League\OAuth2\Server\Grant\RefreshTokenGrant; -use \Pickles\App\Models\User; use \Pickles\Config; class Resource extends \Pickles\Resource @@ -79,14 +78,8 @@ class Resource extends \Pickles\Resource $grant->setVerifyCredentialsCallback(function ($username, $password) { - $user = new User([ - 'conditions' => [ - 'email' => $username, - ], - ]); - - return $user->count() - && password_verify($password, $user->record['password']); + $user = $this->mongo->user->findOne(['email' => $username]); + return $user && password_verify($password, $user['password']); }); break; diff --git a/src/OAuth2/SessionStorage.php b/src/OAuth2/SessionStorage.php index 2754b1d..865d1cc 100644 --- a/src/OAuth2/SessionStorage.php +++ b/src/OAuth2/SessionStorage.php @@ -61,16 +61,18 @@ class SessionStorage extends StorageAdapter implements SessionInterface public function getScopes(SessionEntity $session) { - $sql = 'SELECT oauth_sessions.*' - . ' FROM oauth_sessions' - . ' INNER JOIN oauth_access_token_scopes' - . ' ON oauth_sessions.id = oauth_access_token_scopes.access_token_id' - . ' INNER JOIN oauth_scopes' - . ' ON oauth_scopes.id = oauth_access_token_scopes.scope_id' - . ' WHERE oauth_sessions.id = ?;'; + /* + // @todo + // INNER JOIN oauth_access_token_scopes + // ON oauth_sessions.id = oauth_access_token_scopes.access_token_id + // INNER JOIN oauth_scopes + // ON oauth_scopes.id = oauth_access_token_scopes.scope_id - $results = $this->db->fetch($sql, [$session->getId()]); - $scopes = []; + $results = $this->mongo->oauth_sessions->findOne([ + '_id' => new \MongoId($session->getId()) + ]); + + $scopes = []; foreach ($results as $scope) { @@ -81,16 +83,18 @@ class SessionStorage extends StorageAdapter implements SessionInterface } return $scopes; + */ + + return []; } public function create($owner_type, $owner_id, $client_id, $client_redirect_uri = null) { - $sql = 'INSERT INTO oauth_sessions' - . ' (owner_type, owner_id, client_id)' - . ' VALUES' - . ' (?, ?, ?);'; - - return $this->db->execute($sql, [$owner_type, $owner_id, $client_id]); + return $this->mongo->oauth_sessions->insert([ + 'owner_type' => $owner_type, + 'owner_id' => $owner_id, + 'client_id' => $client_id, + ]); } public function associateScope(SessionEntity $session, ScopeEntity $scope) diff --git a/src/OAuth2/StorageAdapter.php b/src/OAuth2/StorageAdapter.php index 27ab436..56c086d 100644 --- a/src/OAuth2/StorageAdapter.php +++ b/src/OAuth2/StorageAdapter.php @@ -4,17 +4,17 @@ namespace Pickles\OAuth2; use \League\OAuth2\Server\Storage\Adapter; use \Pickles\Config; -use \Pickles\Database; +use \Pickles\Mongo; class StorageAdapter extends Adapter { protected $config; - protected $db; + protected $mongo; public function __construct() { $this->config = Config::getInstance(); - $this->db = Database::getInstance(); + $this->mongo = Mongo::getInstance(); } } From 4bd4625dd3252eaaf2a161f6db9f7ebb5f850b88 Mon Sep 17 00:00:00 2001 From: Josh Sherman Date: Sun, 19 Oct 2014 18:03:04 -0400 Subject: [PATCH 2/6] Swapped the oauth lib again --- composer.json | 2 +- src/OAuth2/AccessTokenStorage.php | 87 ----------------------- src/OAuth2/ClientStorage.php | 68 ------------------ src/OAuth2/RefreshTokenStorage.php | 53 -------------- src/OAuth2/Resource.php | 13 ++-- src/OAuth2/ScopeStorage.php | 26 ------- src/OAuth2/SessionStorage.php | 110 ----------------------------- src/OAuth2/Storage.php | 38 ++++++++++ src/OAuth2/StorageAdapter.php | 20 ------ 9 files changed, 48 insertions(+), 369 deletions(-) delete mode 100644 src/OAuth2/AccessTokenStorage.php delete mode 100644 src/OAuth2/ClientStorage.php delete mode 100644 src/OAuth2/RefreshTokenStorage.php delete mode 100644 src/OAuth2/ScopeStorage.php delete mode 100644 src/OAuth2/SessionStorage.php create mode 100644 src/OAuth2/Storage.php delete mode 100644 src/OAuth2/StorageAdapter.php diff --git a/composer.json b/composer.json index 24f7380..68d79cd 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ }, "require": { "php": ">=5.4", - "league/oauth2-server": "4.0.x-dev" + "bshaffer/oauth2-server-php": "v1.5" }, "suggest": { "mongodb/mongo-php-driver": "Required to use the Mongo storage engine", diff --git a/src/OAuth2/AccessTokenStorage.php b/src/OAuth2/AccessTokenStorage.php deleted file mode 100644 index 980cda0..0000000 --- a/src/OAuth2/AccessTokenStorage.php +++ /dev/null @@ -1,87 +0,0 @@ -= ?;'; - - $results = $this->db->fetch($sql, [$token, time()]); - - if (count($results) === 1) - { - return (new AccessTokenEntity($this->server)) - ->setId($results[0]['access_token']) - ->setExpireTime($results[0]['expires_at']); - } - - return null; - } - - public function getScopes(AbstractTokenEntity $token) - { - $response = []; - - /* - @todo Port to Mongo - $sql = 'SELECT oauth_scopes.id, oauth_scopes.description' - . ' FROM oauth_access_token_scopes' - . ' INNER JOIN oauth_scopes' - . ' ON oauth_access_token_scopes.scope_id = oauth_scopes.id' - . ' WHERE oauth_access_token_scopes.access_token_id = ?;'; - - $results = $this->db->fetch($sql, [$token->getId()]); - - if (count($results) > 0) - { - foreach ($results as $row) - { - $response[] = (new ScopeEntity($this->server))->hydrate([ - 'id' => $row['id'], - 'description' => $row['description'] - ]); - } - } - */ - - return $response; - } - - public function create($token, $expiration, $session_id) - { - return $this->mongo->oauth_access_tokens->insert([ - 'access_token' => $token, - 'session_id' => $session_id, // @todo Store as MongoId? - 'expires_at' => $expiration, - ]); - } - - public function associateScope(AbstractTokenEntity $token, ScopeEntity $scope) - { - $sql = 'INSERT INTO oauth_access_token_scopes' - . ' (access_token, scope)' - . ' VALUES' - . ' (?, ?);'; - - $this->db->execute($sql, [$token->getId(), $scope->getId()]); - } - - public function delete(AbstractTokenEntity $token) - { - $sql = 'DELETE FROM oauth_access_token_scopes' - . ' WHERE access_token = ?;'; - - $this->db->execute($sql, [$token->getId()]); - } -} - diff --git a/src/OAuth2/ClientStorage.php b/src/OAuth2/ClientStorage.php deleted file mode 100644 index 001bf5e..0000000 --- a/src/OAuth2/ClientStorage.php +++ /dev/null @@ -1,68 +0,0 @@ - new \MongoId($client_id)]; - - if ($redirect_uri) - { - // @todo join / query oauth_client_redirect_uris - } - - if ($client_secret) - { - $criteria['secret'] = $client_secret; - } - - $results = $this->mongo->oauth_clients->findOne($criteria); - - if ($results) - { - $client = new ClientEntity($this->server); - - $client->hydrate([ - 'id' => $results['_id']->{'$id'}, - 'name' => $results['name'] - ]); - - return $client; - } - - return null; - } - - public function getBySession(SessionEntity $session) - { - $sql = 'SELECT oauth_clients.id, oauth_clients.name' - . ' FROM oauth_clients' - . ' INNER JOIN oauth_sessions' - . ' ON oauth_clients.id = oauth_sessions.client_id' - . ' WHERE oauth_sessions.id = ?'; - - $results = $this->db->fetch($sql, [$session->getId()]); - - if (count($results) === 1) - { - $client = new ClientEntity($this->server); - - $client->hydrate([ - 'id' => $results[0]['id'], - 'name' => $results[0]['name'] - ]); - - return $client; - } - - return null; - } -} - diff --git a/src/OAuth2/RefreshTokenStorage.php b/src/OAuth2/RefreshTokenStorage.php deleted file mode 100644 index 978a17a..0000000 --- a/src/OAuth2/RefreshTokenStorage.php +++ /dev/null @@ -1,53 +0,0 @@ -= ?;'; - - $results = $this->db->fetch($sql, [$token, time()]); - - if (count($results) === 1) - { - return (new RefreshTokenEntity($this->server)) - ->setId($results[0]['refresh_token']) - ->setExpireTime($results[0]['expires_at']) - ->setAccessTokenId($results[0]['access_token_id']); - } - - return null; - } - - public function create($token, $expiration, $access_token) - { - $results = $this->mongo->oauth_access_tokens->findOne([ - 'access_token' => $access_token, - ]); - - $token_id = $results['_id']->{'$id'}; - - return $this->mongo->oauth_refresh_tokens->insert([ - 'refresh_token' => $token, - 'access_token_id' => $token_id, - 'expires_at' => $expiration, - 'client_id' => $this->server->getRequest()->request->get('client_id', null), - ]); - } - - public function delete(RefreshTokenEntity $token) - { - $sql = 'DELETE FROM oauth_refresh_tokens WHERE refresh_token = ?;'; - - $this->db->execute($sql, [$token->getId()]); - } -} - diff --git a/src/OAuth2/Resource.php b/src/OAuth2/Resource.php index 8406d93..8f03f0e 100644 --- a/src/OAuth2/Resource.php +++ b/src/OAuth2/Resource.php @@ -2,10 +2,9 @@ namespace Pickles\OAuth2; -use \League\OAuth2\Exception\OAuthException; -use \League\OAuth2\Server\AuthorizationServer; -use \League\OAuth2\Server\Grant\PasswordGrant; -use \League\OAuth2\Server\Grant\RefreshTokenGrant; +use \OAuth2\GrantType\UserCredentials; +use \OAuth2\Request; +use \OAuth2\Server; use \Pickles\Config; class Resource extends \Pickles\Resource @@ -28,6 +27,12 @@ class Resource extends \Pickles\Resource case 'oauth/access_token': try { + $storage = new Storage($this->mongo, ['user_table' => 'user']); + $server = new Server($storage); + $server->addGrantType(new UserCredentials($storage)); + $server->handleTokenRequest(Request::createFromGlobals())->send(); + exit; + $server = new AuthorizationServer; $server->setSessionStorage(new SessionStorage); diff --git a/src/OAuth2/ScopeStorage.php b/src/OAuth2/ScopeStorage.php deleted file mode 100644 index c614eb7..0000000 --- a/src/OAuth2/ScopeStorage.php +++ /dev/null @@ -1,26 +0,0 @@ -db->fetch($sql, [$scope]); - - if (count($results) === 0) - { - return null; - } - - return (new ScopeEntity($this->server))->hydrate([ - 'id' => $result[0]['id'], - 'description' => $result[0]['description'], - ]); - } -} - diff --git a/src/OAuth2/SessionStorage.php b/src/OAuth2/SessionStorage.php deleted file mode 100644 index 865d1cc..0000000 --- a/src/OAuth2/SessionStorage.php +++ /dev/null @@ -1,110 +0,0 @@ -db->fetch($sql, [$access_token->getId()]); - - if (count($results) === 1) - { - $session = new SessionEntity($this->server); - $session->setId($result[0]['id']); - $session->setOwner($result[0]['owner_type'], $result[0]['owner_id']); - - return $session; - } - - return null; - } - - public function getByAuthCode(AuthCodeEntity $auth_code) - { - $sql = 'SELECT oauth_sessions.id, oauth_sessions.owner_type,' - . ' oauth_sessions.owner_id, oauth_sessions.client_id,' - . ' oauth_sessions.client_redirect_uri' - . ' FROM oauth_sessions' - . ' INNER JOIN oauth_authorization_codes' - . ' ON oauth_authorization_codes.session_id = oauth_sessions.id' - . ' WHERE oauth_authorization_codes.authorization_code = ?;'; - - $results = $this->db->fetch($sql, [$auth_code->getId()]); - - if (count($results) === 1) - { - $session = new SessionEntity($this->server); - $session->setId($result[0]['id']); - $session->setOwner($result[0]['owner_type'], $result[0]['owner_id']); - - return $session; - } - - return null; - } - - public function getScopes(SessionEntity $session) - { - /* - // @todo - // INNER JOIN oauth_access_token_scopes - // ON oauth_sessions.id = oauth_access_token_scopes.access_token_id - // INNER JOIN oauth_scopes - // ON oauth_scopes.id = oauth_access_token_scopes.scope_id - - $results = $this->mongo->oauth_sessions->findOne([ - '_id' => new \MongoId($session->getId()) - ]); - - $scopes = []; - - foreach ($results as $scope) - { - $scopes[] = (new ScopeEntity($this->server))->hydrate([ - 'id' => $scope['id'], - 'description' => $scope['description'], - ]); - } - - return $scopes; - */ - - return []; - } - - public function create($owner_type, $owner_id, $client_id, $client_redirect_uri = null) - { - return $this->mongo->oauth_sessions->insert([ - 'owner_type' => $owner_type, - 'owner_id' => $owner_id, - 'client_id' => $client_id, - ]); - } - - public function associateScope(SessionEntity $session, ScopeEntity $scope) - { - $sql = 'INSERT INTO oauth_access_token_scopes' - . ' (access_token_id, scope_id)' - . ' VALUES' - . ' (?, ?);'; - - $this->db->execute($sql, [$session->getId(), $scope->getId()]); - } -} - diff --git a/src/OAuth2/Storage.php b/src/OAuth2/Storage.php new file mode 100644 index 0000000..9642d0b --- /dev/null +++ b/src/OAuth2/Storage.php @@ -0,0 +1,38 @@ +mongo = \Pickles\Mongo::getInstance(); + } + + public function getUser($email) + { + return $this->mongo->user->findOne(['email' => $email]); + } + + public function getUserDetails($email) + { + if ($user = $this->getUser($email)) + { + $user['user_id'] = $user['_id']->{'$id'}; + } + + return $user; + } + + protected function checkPassword($user, $password) + { + return $user && password_verify($password, $user['password']); + } +} + diff --git a/src/OAuth2/StorageAdapter.php b/src/OAuth2/StorageAdapter.php deleted file mode 100644 index 56c086d..0000000 --- a/src/OAuth2/StorageAdapter.php +++ /dev/null @@ -1,20 +0,0 @@ -config = Config::getInstance(); - $this->mongo = Mongo::getInstance(); - } -} - From 6ff00619923ea27d483b49bdc4ccd66125f2f1eb Mon Sep 17 00:00:00 2001 From: Josh Sherman Date: Sun, 19 Oct 2014 18:30:27 -0400 Subject: [PATCH 3/6] All that flip flopping on OAuth2 lib --- composer.lock | 174 ++++++++------------------------------------------ 1 file changed, 25 insertions(+), 149 deletions(-) diff --git a/composer.lock b/composer.lock index dfb8338..d794c4c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,160 +4,35 @@ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "65e330b4eb2873d61093fc36aa624d0f", + "hash": "f90250145c5046194b1c3187fc90513a", "packages": [ { - "name": "league/event", - "version": "1.0.0", + "name": "bshaffer/oauth2-server-php", + "version": "v1.5", "source": { "type": "git", - "url": "https://github.com/thephpleague/event.git", - "reference": "06adb7ce55b93346be43a3ba677ac613bbf288a2" + "url": "https://github.com/bshaffer/oauth2-server-php.git", + "reference": "74fcc75e47614c1417c750e907a44567d9ceee1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/event/zipball/06adb7ce55b93346be43a3ba677ac613bbf288a2", - "reference": "06adb7ce55b93346be43a3ba677ac613bbf288a2", + "url": "https://api.github.com/repos/bshaffer/oauth2-server-php/zipball/74fcc75e47614c1417c750e907a44567d9ceee1f", + "reference": "74fcc75e47614c1417c750e907a44567d9ceee1f", "shasum": "" }, "require": { - "php": ">=5.4.0" + "php": ">=5.3.9" }, - "require-dev": { - "henrikbjorn/phpspec-code-coverage": "1.0.*@dev", - "phpspec/phpspec": "2.0.*@dev" + "suggest": { + "aws/aws-sdk-php": "Required to use the DynamoDB storage engine", + "predis/predis": "Required to use the Redis storage engine", + "thobbs/phpcassa": "Required to use the Cassandra storage engine" }, "type": "library", - "autoload": { - "psr-4": { - "League\\Event\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Frank de Jonge", - "email": "info@frenky.net" - } - ], - "description": "Event package", - "keywords": [ - "emitter", - "event", - "listener" - ], - "time": "2014-09-09 14:40:43" - }, - { - "name": "league/oauth2-server", - "version": "dev-develop", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/oauth2-server.git", - "reference": "6333a975f8fb51111b447a7e85806e4519fb52b9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/6333a975f8fb51111b447a7e85806e4519fb52b9", - "reference": "6333a975f8fb51111b447a7e85806e4519fb52b9", - "shasum": "" - }, - "require": { - "league/event": "1.0.*", - "php": ">=5.4.0", - "symfony/http-foundation": "~2.1" - }, - "replace": { - "league/oauth2server": "*", - "lncd/oauth2": "*" - }, - "require-dev": { - "alexbilbie/fizzfuzz": "dev-develop", - "codeception/codeception": "2.0.*", - "league/phpunit-coverage-listener": "~1.0", - "mockery/mockery": "~0.9", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "4.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\OAuth2\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Alex Bilbie", - "email": "hello@alexbilbie.com", - "homepage": "http://www.alexbilbie.com", - "role": "Developer" - } - ], - "description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.", - "homepage": "http://oauth2.thephpleague.com/", - "keywords": [ - "Authentication", - "api", - "auth", - "authorisation", - "authorization", - "oauth", - "oauth 2", - "oauth 2.0", - "oauth2", - "protect", - "resource", - "secure", - "server" - ], - "time": "2014-10-03 13:42:01" - }, - { - "name": "symfony/http-foundation", - "version": "dev-master", - "target-dir": "Symfony/Component/HttpFoundation", - "source": { - "type": "git", - "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "c24942a7ec2d8409d1f60d02c4460ca8317e885a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/c24942a7ec2d8409d1f60d02c4460ca8317e885a", - "reference": "c24942a7ec2d8409d1f60d02c4460ca8317e885a", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/expression-language": "~2.4" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev" - } - }, "autoload": { "psr-0": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Symfony/Component/HttpFoundation/Resources/stubs" - ] + "OAuth2": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -165,17 +40,19 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Brent Shaffer", + "email": "bshafs@gmail.com", + "homepage": "http://brentertainment.com" } ], - "description": "Symfony HttpFoundation Component", - "homepage": "http://symfony.com", - "time": "2014-10-07 14:06:18" + "description": "OAuth2 Server for PHP", + "homepage": "http://github.com/bshaffer/oauth2-server-php", + "keywords": [ + "auth", + "oauth", + "oauth2" + ], + "time": "2014-08-28 02:13:42" } ], "packages-dev": [ @@ -1434,7 +1311,6 @@ "aliases": [], "minimum-stability": "dev", "stability-flags": { - "league/oauth2-server": 20, "phpunit/phpunit": 20, "satooshi/php-coveralls": 20 }, From de2e4b997b5d7fa590ecce5c0d55e8b0fbc175e3 Mon Sep 17 00:00:00 2001 From: Josh Sherman Date: Mon, 20 Oct 2014 04:58:39 -0400 Subject: [PATCH 4/6] No more SQL --- sql/oauth2.sql | 129 ------------------------------------------------- 1 file changed, 129 deletions(-) delete mode 100644 sql/oauth2.sql diff --git a/sql/oauth2.sql b/sql/oauth2.sql deleted file mode 100644 index 5c4fbc1..0000000 --- a/sql/oauth2.sql +++ /dev/null @@ -1,129 +0,0 @@ -CREATE TABLE `oauth_clients` ( - `id` CHAR(40) NOT NULL, - `secret` CHAR(40) NOT NULL, - `name` VARCHAR(255) NOT NULL, - `auto_approve` TINYINT(1) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `u_oacl_clse_clid` (`secret`,`id`) -) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_endpoints` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `client_id` char(40) NOT NULL, - `redirect_uri` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - KEY `i_oaclen_clid` (`client_id`), - CONSTRAINT `f_oaclen_clid` - FOREIGN KEY (`client_id`) - REFERENCES `oauth_clients` (`id`) - ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_sessions` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `client_id` char(40) NOT NULL, - `owner_type` enum('user','client') NOT NULL DEFAULT 'user', - `owner_id` varchar(255) NOT NULL, - PRIMARY KEY (`id`), - KEY `i_uase_clid_owty_owid` (`client_id`,`owner_type`,`owner_id`), - CONSTRAINT `f_oase_clid` - FOREIGN KEY (`client_id`) - REFERENCES `oauth_clients` (`id`) - ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_access_tokens` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `session_id` int(10) unsigned NOT NULL, - `access_token` char(40) NOT NULL, - `expires_at` int(10) unsigned NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `u_oaseacto_acto_seid` (`access_token`,`session_id`), - KEY `f_oaseto_seid` (`session_id`), - CONSTRAINT `f_oaseto_seid` - FOREIGN KEY (`session_id`) - REFERENCES `oauth_sessions` (`id`) - ON DELETE CASCADE ON UPDATE NO ACTION -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_authorization_codes` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `session_id` int(10) unsigned NOT NULL, - `authorization_code` char(40) NOT NULL, - `expires_at` int(10) unsigned NOT NULL, - PRIMARY KEY (`id`), - KEY `session_id` (`session_id`), - CONSTRAINT `oauth_authorization_codes_ibfk_1` - FOREIGN KEY (`session_id`) - REFERENCES `oauth_sessions` (`id`) - ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_redirect_uris` ( - `session_id` int(10) unsigned NOT NULL, - `redirect_uri` varchar(255) NOT NULL, - PRIMARY KEY (`session_id`), - CONSTRAINT `f_oasere_seid` - FOREIGN KEY (`session_id`) - REFERENCES `oauth_sessions` (`id`) - ON DELETE CASCADE ON UPDATE NO ACTION -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_refresh_tokens` ( - `access_token_id` int(10) unsigned NOT NULL, - `refresh_token` char(40) NOT NULL, - `expires_at` int(10) unsigned NOT NULL, - `client_id` char(40) NOT NULL, - PRIMARY KEY (`access_token_id`), - KEY `client_id` (`client_id`), - CONSTRAINT `oauth_refresh_tokens_ibfk_1` - FOREIGN KEY (`client_id`) - REFERENCES `oauth_clients` (`id`) - ON DELETE CASCADE, - CONSTRAINT `f_oasetore_setoid` - FOREIGN KEY (`access_token_id`) - REFERENCES `oauth_access_tokens` (`id`) - ON DELETE CASCADE ON UPDATE NO ACTION -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_scopes` ( - `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, - `scope` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `description` varchar(255) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `u_oasc_sc` (`scope`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_access_token_scopes` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `access_token_id` int(10) unsigned DEFAULT NULL, - `scope_id` smallint(5) unsigned NOT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `u_setosc_setoid_scid` (`access_token_id`,`scope_id`), - KEY `f_oasetosc_scid` (`scope_id`), - CONSTRAINT `f_oasetosc_scid` - FOREIGN KEY (`scope_id`) - REFERENCES `oauth_scopes` (`id`) - ON DELETE CASCADE ON UPDATE NO ACTION, - CONSTRAINT `f_oasetosc_setoid` - FOREIGN KEY (`access_token_id`) - REFERENCES `oauth_access_tokens` (`id`) - ON DELETE CASCADE ON UPDATE NO ACTION -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - -CREATE TABLE `oauth_authorization_code_scopes` ( - `authorization_code_id` int(10) unsigned NOT NULL, - `scope_id` smallint(5) unsigned NOT NULL, - KEY `authorization_code_id` (`authorization_code_id`), - KEY `scope_id` (`scope_id`), - CONSTRAINT `oauth_authorization_code_scopes_ibfk_2` - FOREIGN KEY (`scope_id`) - REFERENCES `oauth_scopes` (`id`) - ON DELETE CASCADE, - CONSTRAINT `oauth_authorization_code_scopes_ibfk_1` - FOREIGN KEY (`authorization_code_id`) - REFERENCES `oauth_authorization_codes` (`id`) - ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE utf8_unicode_ci; - From 1e8e9efd957412abeaadcc96866c3125818b5287 Mon Sep 17 00:00:00 2001 From: Josh Sherman Date: Mon, 20 Oct 2014 05:54:26 -0400 Subject: [PATCH 5/6] Cleaned up OAuth2 response --- src/OAuth2/Resource.php | 66 +++++++++++++---------------------------- src/Redis.php | 0 src/Resource.php | 6 ---- src/Router.php | 2 +- 4 files changed, 22 insertions(+), 52 deletions(-) create mode 100644 src/Redis.php diff --git a/src/OAuth2/Resource.php b/src/OAuth2/Resource.php index 8f03f0e..ae02e81 100644 --- a/src/OAuth2/Resource.php +++ b/src/OAuth2/Resource.php @@ -4,6 +4,7 @@ namespace Pickles\OAuth2; use \OAuth2\GrantType\UserCredentials; use \OAuth2\Request; +use \OAuth2\Response; use \OAuth2\Server; use \Pickles\Config; @@ -24,23 +25,9 @@ class Resource extends \Pickles\Resource switch (substr($_REQUEST['request'], strlen($_SERVER['__version']) + 2)) { - case 'oauth/access_token': + case 'oauth2/token': try { - $storage = new Storage($this->mongo, ['user_table' => 'user']); - $server = new Server($storage); - $server->addGrantType(new UserCredentials($storage)); - $server->handleTokenRequest(Request::createFromGlobals())->send(); - exit; - - $server = new AuthorizationServer; - - $server->setSessionStorage(new SessionStorage); - $server->setAccessTokenStorage(new AccessTokenStorage); - $server->setClientStorage(new ClientStorage); - $server->setScopeStorage(new ScopeStorage); - $server->setRefreshTokenStorage(new RefreshTokenStorage); - $grant_type = $_REQUEST['grant_type']; $grants = ['password']; @@ -54,7 +41,7 @@ class Resource extends \Pickles\Resource throw new \Exception('Unsupported grant type.', 403); } - // Defaults TTLs to 1 day and 1 week respectively + // @todo Defaults TTLs to 1 day and 1 week respectively $token_ttl = 3600; $refresh_ttl = 604800; @@ -78,45 +65,34 @@ class Resource extends \Pickles\Resource break; case 'password': - $grant = new PasswordGrant; - $grant->setAccessTokenTTL($token_ttl); + $storage = new Storage($this->mongo, ['user_table' => 'user']); + $server = new Server($storage); - $grant->setVerifyCredentialsCallback(function ($username, $password) + $server->addGrantType(new UserCredentials($storage)); + + $request = Request::createFromGlobals(); + $response = new Response; + $response = $server->handleTokenRequest($request, $response); + $body = json_decode($response->getResponseBody(), true); + + if (isset($body['error'])) { - $user = $this->mongo->user->findOne(['email' => $username]); - return $user && password_verify($password, $user['password']); - }); + $parameters = $response->getParameters(); + throw new \Exception( + $parameters['error_description'], + $response->getStatusCode() + ); + } + + $response = $body; break; case 'refresh_token': throw new \Exception('Not Implemented', 501); - - // @todo Need to work through this, appears lib is busted - $grant = new RefreshTokenGrant; - //$grant->setAccessTokenTTL($refresh_ttl); - $server->addGrantType($grant); break; } - $server->addGrantType($grant); - - // Adds the refresh token grant if enabled - if ($grant_type != 'refresh_token' - && in_array('refresh_token', $grants)) - { - if (isset($config['ttl']['refresh_token'])) - { - $refresh_ttl = $config['ttl']['refresh_token']; - } - - $grant = new RefreshTokenGrant; - $grant->setAccessTokenTTL($refresh_ttl); - $server->addGrantType($grant); - } - - $response = $server->issueAccessToken(); - return $response; } catch (OAuthException $e) diff --git a/src/Redis.php b/src/Redis.php new file mode 100644 index 0000000..e69de29 diff --git a/src/Resource.php b/src/Resource.php index fadd62f..f9acd0f 100644 --- a/src/Resource.php +++ b/src/Resource.php @@ -14,12 +14,6 @@ namespace Pickles; -use \League\OAuth2\Server\ResourceServer; -use Pickles\OAuth2\AccessTokenStorage; -use Pickles\OAuth2\ClientStorage; -use Pickles\OAuth2\ScopeStorage; -use Pickles\OAuth2\SessionStorage; - /** * Resource Class * diff --git a/src/Router.php b/src/Router.php index 2089c90..f9c10f7 100644 --- a/src/Router.php +++ b/src/Router.php @@ -54,7 +54,7 @@ class Router extends Object $_SERVER['__version'] = substr($version, 1); // Checks if we're trying to rock some OAuth - if ($components[0] == 'oauth') + if ($components[0] == 'oauth2') { $class = 'Pickles\OAuth2\Resource'; } From 15a4b807d593b2e438a052c6f2bb9b57ce2c69be Mon Sep 17 00:00:00 2001 From: Josh Sherman Date: Mon, 20 Oct 2014 07:07:20 -0400 Subject: [PATCH 6/6] Stubbing out the default resource functionality --- src/Resource.php | 31 +++++++++++++++++++++++++++++++ src/Router.php | 3 ++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/Resource.php b/src/Resource.php index f9acd0f..2a3f270 100644 --- a/src/Resource.php +++ b/src/Resource.php @@ -327,6 +327,37 @@ class Resource extends Object } } + // Create + public function POST() + { + // @todo Whatever gets POSTed (aside from OAuth stuff) should be inserted to the collection + } + + // Read + public function GET() + { + if (current($this->uids)) + { + // @todo Pulls the record with this UID + } + else + { + // @todo Do we pull all or return an empty set? + } + } + + // Update + public function PUT() + { + // @todo If we have a UID, update the record with whatever is posted + } + + // Delete + public function DELETE() + { + // @todo If we have a UID, delete it + } + public function respond() { http_response_code($this->status); diff --git a/src/Router.php b/src/Router.php index f9c10f7..4c9092a 100644 --- a/src/Router.php +++ b/src/Router.php @@ -69,7 +69,8 @@ class Router extends Object } else { - $nouns[] = $component; + $nouns[] = $component; + $uids[$component] = null; } }