From 9dec6c4bfe4d839123747828b508380cc2912c34 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 2 Jun 2013 14:25:06 +0100 Subject: [PATCH] Added Doctrine/DBAL implementation of storage classes (thanks @inanimatt) --- composer.json | 3 +- .../OAuth2/Server/Storage/DBAL/Client.php | 52 ++++++ .../OAuth2/Server/Storage/DBAL/Scope.php | 38 ++++ .../OAuth2/Server/Storage/DBAL/Session.php | 176 ++++++++++++++++++ 4 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 src/League/OAuth2/Server/Storage/DBAL/Client.php create mode 100644 src/League/OAuth2/Server/Storage/DBAL/Scope.php create mode 100644 src/League/OAuth2/Server/Storage/DBAL/Session.php diff --git a/composer.json b/composer.json index 40db4273..11ac8a95 100644 --- a/composer.json +++ b/composer.json @@ -43,6 +43,7 @@ } }, "suggest": { - "zetacomponents/database": "Allows use of the build in PDO storage classes" + "zetacomponents/database": "A PDO implementation of the storage classes", + "doctrine/dbal": "A Doctrine/DBAL implementation of the storage classes" } } \ No newline at end of file diff --git a/src/League/OAuth2/Server/Storage/DBAL/Client.php b/src/League/OAuth2/Server/Storage/DBAL/Client.php new file mode 100644 index 00000000..91e86f88 --- /dev/null +++ b/src/League/OAuth2/Server/Storage/DBAL/Client.php @@ -0,0 +1,52 @@ + + */ +namespace League\OAuth2\Server\Storage\DBAL; + +use League\OAuth2\Server\Storage\ClientInterface; + +class Client implements ClientInterface +{ + protected $db; + + public function __construct($db) + { + $this->db = $db; + } + + public function getClient($clientId, $clientSecret = null, $redirectUri = null, $grantType = null) + { + if ( ! is_null($redirectUri) && is_null($clientSecret)) { + $stmt = $this->db->prepare('SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name FROM oauth_clients LEFT JOIN oauth_client_endpoints ON oauth_client_endpoints.client_id = oauth_clients.id WHERE oauth_clients.id = :clientId AND oauth_client_endpoints.redirect_uri = :redirectUri'); + $stmt->bindValue(':redirectUri', $redirectUri); + } + + elseif ( ! is_null($clientSecret) && is_null($redirectUri)) { + $stmt = $this->db->prepare('SELECT oauth_clients.id, oauth_clients.secret, oauth_clients.name FROM oauth_clients WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret'); + $stmt->bindValue(':clientSecret', $clientSecret); + } + + elseif ( ! is_null($clientSecret) && ! is_null($redirectUri)) { + $stmt = $this->db->prepare('SELECT oauth_clients.id, oauth_clients.secret, oauth_client_endpoints.redirect_uri, oauth_clients.name FROM oauth_clients LEFT JOIN oauth_client_endpoints ON oauth_client_endpoints.client_id = oauth_clients.id WHERE oauth_clients.id = :clientId AND oauth_clients.secret = :clientSecret AND oauth_client_endpoints.redirect_uri = :redirectUri'); + $stmt->bindValue(':redirectUri', $redirectUri); + $stmt->bindValue(':clientSecret', $clientSecret); + } + + $stmt->bindValue(':clientId', $clientId); + $stmt->execute(); + + $row = $stmt->fetch(\PDO::FETCH_OBJ); + + if ($row === false) { + return false; + } + + return array( + 'client_id' => $row->id, + 'client_secret' => $row->secret, + 'redirect_uri' => (isset($row->redirect_uri)) ? $row->redirect_uri : null, + 'name' => $row->name + ); + } +} \ No newline at end of file diff --git a/src/League/OAuth2/Server/Storage/DBAL/Scope.php b/src/League/OAuth2/Server/Storage/DBAL/Scope.php new file mode 100644 index 00000000..3c5639ea --- /dev/null +++ b/src/League/OAuth2/Server/Storage/DBAL/Scope.php @@ -0,0 +1,38 @@ + + */ +namespace League\OAuth2\Server\Storage\DBAL; + +use League\OAuth2\Server\Storage\ScopeInterface; + +class Scope implements ScopeInterface +{ + protected $db; + + public function __construct($db) + { + $this->db = $db; + } + + public function getScope($scope, $clientId = null, $grantType = null) + { + $stmt = $this->db->prepare('SELECT * FROM oauth_scopes WHERE oauth_scopes.scope = :scope'); + $stmt->bindValue(':scope', $scope); + $stmt->execute(); + + $row = $stmt->fetch(\PDO::FETCH_OBJ); + + if ($row === false) { + return false; + } + + return array( + 'id' => $row->id, + 'scope' => $row->scope, + 'name' => $row->name, + 'description' => $row->description + ); + + } +} \ No newline at end of file diff --git a/src/League/OAuth2/Server/Storage/DBAL/Session.php b/src/League/OAuth2/Server/Storage/DBAL/Session.php new file mode 100644 index 00000000..58f8e515 --- /dev/null +++ b/src/League/OAuth2/Server/Storage/DBAL/Session.php @@ -0,0 +1,176 @@ + + */ +namespace League\OAuth2\Server\Storage\DBAL; + +use League\OAuth2\Server\Storage\SessionInterface; + +class Session implements SessionInterface +{ + protected $db; + + public function __construct($db) + { + $this->db = $db; + } + + public function createSession($clientId, $ownerType, $ownerId) + { + $this->db->insert('oauth_sessions', array( + 'client_id' => $clientId, + 'owner_type' => $ownerType, + 'owner_id' => $ownerId, + )); + + return $this->db->lastInsertId(); + } + + public function deleteSession($clientId, $ownerType, $ownerId) + { + $this->db->delete('oauth_sessions', array( + 'client_id' => $clientId, + 'owner_type' => $ownerType, + 'owner_id' => $ownerId, + )); + } + + public function associateRedirectUri($sessionId, $redirectUri) + { + $this->db->insert('oauth_session_redirects', array( + 'session_id' => $sessionId, + 'redirect_uri' => $redirectUri, + )); + } + + public function associateAccessToken($sessionId, $accessToken, $expireTime) + { + $this->db->insert('oauth_session_access_tokens', array( + 'session_id' => $sessionId, + 'access_token' => $accessToken, + 'access_token_expires' => $expireTime, + )); + + return $this->db->lastInsertId(); + } + + public function associateRefreshToken($accessTokenId, $refreshToken, $expireTime, $clientId) + { + $this->db->insert('oauth_session_refresh_tokens', array( + 'session_access_token_id' => $accessTokenId, + 'refresh_token' => $refreshToken, + 'refresh_token_expires' => $expireTime, + 'client_id' => $clientId, + )); + } + + public function associateAuthCode($sessionId, $authCode, $expireTime) + { + $this->db->insert('oauth_session_authcodes', array( + 'session_id' => $sessionId, + 'auth_code' => $authCode, + 'auth_code_expires' => $expireTime, + )); + + return $this->db->lastInsertId(); + } + + public function removeAuthCode($sessionId) + { + $this->db->delete('oauth_session_authcodes', array( + 'session_id' => $sessionId, + )); + } + + public function validateAuthCode($clientId, $redirectUri, $authCode) + { + $stmt = $this->db->prepare('SELECT oauth_sessions.id AS session_id, oauth_session_authcodes.id AS authcode_id + FROM oauth_sessions JOIN oauth_session_authcodes ON oauth_session_authcodes.`session_id` + = oauth_sessions.id JOIN oauth_session_redirects ON oauth_session_redirects.`session_id` + = oauth_sessions.id WHERE oauth_sessions.client_id = :clientId AND oauth_session_authcodes.`auth_code` + = :authCode AND `oauth_session_authcodes`.`auth_code_expires` >= :time AND + `oauth_session_redirects`.`redirect_uri` = :redirectUri'); + $stmt->bindValue(':clientId', $clientId); + $stmt->bindValue(':redirectUri', $redirectUri); + $stmt->bindValue(':authCode', $authCode); + $stmt->bindValue(':time', time()); + $stmt->execute(); + + $result = $stmt->fetch(\PDO::FETCH_OBJ); + + return ($result === false) ? false : (array) $result; + } + + public function validateAccessToken($accessToken) + { + $stmt = $this->db->prepare('SELECT session_id, oauth_sessions.`client_id`, oauth_sessions.`owner_id`, oauth_sessions.`owner_type` FROM `oauth_session_access_tokens` JOIN oauth_sessions ON oauth_sessions.`id` = session_id WHERE access_token = :accessToken AND access_token_expires >= ' . time()); + $stmt->bindValue(':accessToken', $accessToken); + $stmt->execute(); + + $result = $stmt->fetch(\PDO::FETCH_OBJ); + return ($result === false) ? false : (array) $result; + } + + public function removeRefreshToken($refreshToken) + { + $this->db->delete('oauth_session_refresh_tokens', array( + 'refresh_token' => $refreshToken, + )); + } + + public function validateRefreshToken($refreshToken, $clientId) + { + $stmt = $this->db->prepare('SELECT session_access_token_id FROM `oauth_session_refresh_tokens` WHERE + refresh_token = :refreshToken AND client_id = :clientId AND refresh_token_expires >= ' . time()); + $stmt->bindValue(':refreshToken', $refreshToken); + $stmt->bindValue(':clientId', $clientId); + $stmt->execute(); + + $result = $stmt->fetch(\PDO::FETCH_OBJ); + return ($result === false) ? false : $result->session_access_token_id; + } + + public function getAccessToken($accessTokenId) + { + $stmt = $this->db->prepare('SELECT * FROM `oauth_session_access_tokens` WHERE `id` = :accessTokenId'); + $stmt->bindValue(':accessTokenId', $accessTokenId); + $stmt->execute(); + + $result = $stmt->fetch(\PDO::FETCH_OBJ); + return ($result === false) ? false : (array) $result; + } + + public function associateAuthCodeScope($authCodeId, $scopeId) + { + $this->db->insert('oauth_session_authcode_scopes', array( + 'oauth_session_authcode_id' => $authCodeId, + 'scope_id' => $scopeId, + )); + } + + public function getAuthCodeScopes($oauthSessionAuthCodeId) + { + $stmt = $db->prepare('SELECT scope_id FROM `oauth_session_authcode_scopes` WHERE oauth_session_authcode_id = :authCodeId'); + $stmt->bindValue(':authCodeId', $oauthSessionAuthCodeId); + $stmt->execute(); + + return $stmt->fetchAll(); + } + + public function associateScope($accessTokenId, $scopeId) + { + $this->db->insert('oauth_session_token_scopes', array( + 'session_access_token_id' => $accessTokenId, + 'scope_id' => $scopeId, + )); + } + + public function getScopes($accessToken) + { + $stmt = $this->db->prepare('SELECT oauth_scopes.* FROM oauth_session_token_scopes JOIN oauth_session_access_tokens ON oauth_session_access_tokens.`id` = `oauth_session_token_scopes`.`session_access_token_id` JOIN oauth_scopes ON oauth_scopes.id = `oauth_session_token_scopes`.`scope_id` WHERE access_token = :accessToken'); + $stmt->bindValue(':accessToken', $accessToken); + $stmt->execute(); + + return $stmt->fetchAll(); + } +} \ No newline at end of file