aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb/auth/provider/oauth
diff options
context:
space:
mode:
authorMaat <maat-pub@mageia.biz>2020-05-08 21:52:11 +0200
committerMaat <maat-pub@mageia.biz>2020-05-08 21:52:11 +0200
commit8ea437e30605e0f66b5220bf904a61d7c1d11ddd (patch)
treee0db2bb4a012d5b06a633160b19f62f4868ecd28 /phpBB/phpbb/auth/provider/oauth
parent36bc1870f21fac04736a1049c1d5b8e127d729f4 (diff)
parent2fdd46b36431ae0f58bb2e78e42553168db9a0ff (diff)
downloadforums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar
forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar.gz
forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar.bz2
forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.tar.xz
forums-8ea437e30605e0f66b5220bf904a61d7c1d11ddd.zip
Merge remote-tracking branch 'upstream/prep-release-3.2.9'
Diffstat (limited to 'phpBB/phpbb/auth/provider/oauth')
-rw-r--r--phpBB/phpbb/auth/provider/oauth/oauth.php141
-rw-r--r--phpBB/phpbb/auth/provider/oauth/service/twitter.php102
-rw-r--r--phpBB/phpbb/auth/provider/oauth/token_storage.php254
3 files changed, 461 insertions, 36 deletions
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php
index bd2a414033..e3f8394bba 100644
--- a/phpBB/phpbb/auth/provider/oauth/oauth.php
+++ b/phpBB/phpbb/auth/provider/oauth/oauth.php
@@ -63,6 +63,13 @@ class oauth extends \phpbb\auth\provider\base
protected $auth_provider_oauth_token_storage_table;
/**
+ * OAuth state table
+ *
+ * @var string
+ */
+ protected $auth_provider_oauth_state_table;
+
+ /**
* OAuth account association table
*
* @var string
@@ -127,6 +134,7 @@ class oauth extends \phpbb\auth\provider\base
* @param \phpbb\request\request_interface $request
* @param \phpbb\user $user
* @param string $auth_provider_oauth_token_storage_table
+ * @param string $auth_provider_oauth_state_table
* @param string $auth_provider_oauth_token_account_assoc
* @param \phpbb\di\service_collection $service_providers Contains \phpbb\auth\provider\oauth\service_interface
* @param string $users_table
@@ -135,7 +143,7 @@ class oauth extends \phpbb\auth\provider\base
* @param string $phpbb_root_path
* @param string $php_ext
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, \phpbb\event\dispatcher_interface $dispatcher, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request_interface $request, \phpbb\user $user, $auth_provider_oauth_token_storage_table, $auth_provider_oauth_state_table, $auth_provider_oauth_token_account_assoc, \phpbb\di\service_collection $service_providers, $users_table, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, \phpbb\event\dispatcher_interface $dispatcher, $phpbb_root_path, $php_ext)
{
$this->db = $db;
$this->config = $config;
@@ -143,6 +151,7 @@ class oauth extends \phpbb\auth\provider\base
$this->request = $request;
$this->user = $user;
$this->auth_provider_oauth_token_storage_table = $auth_provider_oauth_token_storage_table;
+ $this->auth_provider_oauth_state_table = $auth_provider_oauth_state_table;
$this->auth_provider_oauth_token_account_assoc = $auth_provider_oauth_token_account_assoc;
$this->service_providers = $service_providers;
$this->users_table = $users_table;
@@ -182,7 +191,7 @@ class oauth extends \phpbb\auth\provider\base
return $provider->login($username, $password);
}
- // Requst the name of the OAuth service
+ // Request the name of the OAuth service
$service_name_original = $this->request->variable('oauth_service', '', false);
$service_name = 'auth.provider.oauth.service.' . strtolower($service_name_original);
if ($service_name_original === '' || !array_key_exists($service_name, $this->service_providers))
@@ -197,26 +206,57 @@ class oauth extends \phpbb\auth\provider\base
// Get the service credentials for the given service
$service_credentials = $this->service_providers[$service_name]->get_service_credentials();
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table);
+ $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
$query = 'mode=login&login=external&oauth_service=' . $service_name_original;
$service = $this->get_service($service_name_original, $storage, $service_credentials, $query, $this->service_providers[$service_name]->get_auth_scope());
- if ($this->request->is_set('code', \phpbb\request\request_interface::GET))
+ if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
+ || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
{
$this->service_providers[$service_name]->set_external_service_provider($service);
$unique_id = $this->service_providers[$service_name]->perform_auth_login();
- // Check to see if this provider is already assosciated with an account
+ /**
+ * Check to see if this provider is already associated with an account.
+ *
+ * Enforcing a data type to make data contains strings and not integers,
+ * so values are quoted in the SQL WHERE statement.
+ */
$data = array(
- 'provider' => $service_name_original,
- 'oauth_provider_id' => $unique_id
+ 'provider' => (string) $service_name_original,
+ 'oauth_provider_id' => (string) $unique_id
);
+
$sql = 'SELECT user_id FROM ' . $this->auth_provider_oauth_token_account_assoc . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);
$this->db->sql_freeresult($result);
+ $redirect_data = array(
+ 'auth_provider' => 'oauth',
+ 'login_link_oauth_service' => $service_name_original,
+ );
+
+ /**
+ * Event is triggered before check if provider is already associated with an account
+ *
+ * @event core.oauth_login_after_check_if_provider_id_has_match
+ * @var array row User row
+ * @var array data Provider data
+ * @var array redirect_data Data to be appended to the redirect url
+ * @var \OAuth\Common\Service\ServiceInterface service OAuth service
+ * @since 3.2.3-RC1
+ * @changed 3.2.6-RC1 Added redirect_data
+ */
+ $vars = array(
+ 'row',
+ 'data',
+ 'redirect_data',
+ 'service',
+ );
+ extract($this->dispatcher->trigger_event('core.oauth_login_after_check_if_provider_id_has_match', compact($vars)));
+
if (!$row)
{
// The user does not yet exist, ask to link or create profile
@@ -224,15 +264,12 @@ class oauth extends \phpbb\auth\provider\base
'status' => LOGIN_SUCCESS_LINK_PROFILE,
'error_msg' => 'LOGIN_OAUTH_ACCOUNT_NOT_LINKED',
'user_row' => array(),
- 'redirect_data' => array(
- 'auth_provider' => 'oauth',
- 'login_link_oauth_service' => $service_name_original,
- ),
+ 'redirect_data' => $redirect_data,
);
}
// Retrieve the user's account
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type, user_login_attempts
+ $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_ip, user_type, user_login_attempts
FROM ' . $this->users_table . '
WHERE user_id = ' . (int) $row['user_id'];
$result = $this->db->sql_query($sql);
@@ -244,11 +281,36 @@ class oauth extends \phpbb\auth\provider\base
throw new \Exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_ENTRY');
}
+ /**
+ * Check if the user is banned.
+ * The fourth parameter, return, has to be true,
+ * otherwise the OAuth login is still called and
+ * an uncaught exception is thrown as there is no
+ * token stored in the database.
+ */
+ $ban = $this->user->check_ban($row['user_id'], $row['user_ip'], $row['user_email'], true);
+ if (!empty($ban))
+ {
+ $till_date = !empty($ban['ban_end']) ? $this->user->format_date($ban['ban_end']) : '';
+ $message = !empty($ban['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
+
+ $contact_link = phpbb_get_board_contact_link($this->config, $this->phpbb_root_path, $this->php_ext);
+ $message = $this->user->lang($message, $till_date, '<a href="' . $contact_link . '">', '</a>');
+ $message .= !empty($ban['ban_give_reason']) ? '<br /><br />' . $this->user->lang('BOARD_BAN_REASON', $ban['ban_give_reason']) : '';
+ $message .= !empty($ban['ban_triggered_by']) ? '<br /><br /><em>' . $this->user->lang('BAN_TRIGGERED_BY_' . strtoupper($ban['ban_triggered_by'])) . '</em>' : '';
+
+ return array(
+ 'status' => LOGIN_BREAK,
+ 'error_msg' => $message,
+ 'user_row' => $row,
+ );
+ }
+
// Update token storage to store the user_id
$storage->set_user_id($row['user_id']);
/**
- * Event is triggered after user is successfuly logged in via OAuth.
+ * Event is triggered after user is successfully logged in via OAuth.
*
* @event core.auth_oauth_login_after
* @var array row User row
@@ -268,7 +330,15 @@ class oauth extends \phpbb\auth\provider\base
}
else
{
- $url = $service->getAuthorizationUri();
+ if ($service::OAUTH_VERSION === 1)
+ {
+ $token = $service->requestRequestToken();
+ $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
+ }
+ else
+ {
+ $url = $service->getAuthorizationUri();
+ }
header('Location: ' . $url);
}
}
@@ -358,7 +428,7 @@ class oauth extends \phpbb\auth\provider\base
if ($credentials['key'] && $credentials['secret'])
{
$actual_name = str_replace('auth.provider.oauth.service.', '', $service_name);
- $redirect_url = build_url(false) . '&login=external&oauth_service=' . $actual_name;
+ $redirect_url = generate_board_url() . '/ucp.' . $this->php_ext . '?mode=login&login=external&oauth_service=' . $actual_name;
$login_data['BLOCK_VARS'][$service_name] = array(
'REDIRECT_URL' => redirect($redirect_url, true),
'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
@@ -483,7 +553,7 @@ class oauth extends \phpbb\auth\provider\base
*/
protected function link_account_login_link(array $link_data, $service_name)
{
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table);
+ $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
// Check for an access token, they should have one
if (!$storage->has_access_token_by_session($service_name))
@@ -526,13 +596,14 @@ class oauth extends \phpbb\auth\provider\base
*/
protected function link_account_auth_link(array $link_data, $service_name)
{
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table);
+ $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
$query = 'i=ucp_auth_link&mode=auth_link&link=1&oauth_service=' . strtolower($link_data['oauth_service']);
$service_credentials = $this->service_providers[$service_name]->get_service_credentials();
$scopes = $this->service_providers[$service_name]->get_auth_scope();
$service = $this->get_service(strtolower($link_data['oauth_service']), $storage, $service_credentials, $query, $scopes);
- if ($this->request->is_set('code', \phpbb\request\request_interface::GET))
+ if (($service::OAUTH_VERSION === 2 && $this->request->is_set('code', \phpbb\request\request_interface::GET))
+ || ($service::OAUTH_VERSION === 1 && $this->request->is_set('oauth_token', \phpbb\request\request_interface::GET)))
{
$this->service_providers[$service_name]->set_external_service_provider($service);
$unique_id = $this->service_providers[$service_name]->perform_auth_login();
@@ -548,7 +619,15 @@ class oauth extends \phpbb\auth\provider\base
}
else
{
- $url = $service->getAuthorizationUri();
+ if ($service::OAUTH_VERSION === 1)
+ {
+ $token = $service->requestRequestToken();
+ $url = $service->getAuthorizationUri(array('oauth_token' => $token->getRequestToken()));
+ }
+ else
+ {
+ $url = $service->getAuthorizationUri();
+ }
header('Location: ' . $url);
}
}
@@ -560,6 +639,21 @@ class oauth extends \phpbb\auth\provider\base
*/
protected function link_account_perform_link(array $data)
{
+ // Check if the external account is already associated with other user
+ $sql = 'SELECT user_id
+ FROM ' . $this->auth_provider_oauth_token_account_assoc . "
+ WHERE provider = '" . $this->db->sql_escape($data['provider']) . "'
+ AND oauth_provider_id = '" . $this->db->sql_escape($data['oauth_provider_id']) . "'";
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if ($row)
+ {
+ trigger_error('AUTH_PROVIDER_OAUTH_ERROR_ALREADY_LINKED');
+ }
+
+ // Link account
$sql = 'INSERT INTO ' . $this->auth_provider_oauth_token_account_assoc . '
' . $this->db->sql_build_array('INSERT', $data);
$this->db->sql_query($sql);
@@ -583,7 +677,7 @@ class oauth extends \phpbb\auth\provider\base
public function logout($data, $new_session)
{
// Clear all tokens belonging to the user
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table);
+ $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
$storage->clearAllTokens();
return;
@@ -608,7 +702,7 @@ class oauth extends \phpbb\auth\provider\base
$oauth_user_ids = array();
- if ($rows !== false && sizeof($rows))
+ if ($rows !== false && count($rows))
{
foreach ($rows as $row)
{
@@ -631,6 +725,7 @@ class oauth extends \phpbb\auth\provider\base
'oauth_service' => $actual_name,
),
+ 'SERVICE_ID' => $actual_name,
'SERVICE_NAME' => $this->user->lang['AUTH_PROVIDER_OAUTH_SERVICE_' . strtoupper($actual_name)],
'UNIQUE_ID' => (isset($oauth_user_ids[$actual_name])) ? $oauth_user_ids[$actual_name] : null,
);
@@ -664,9 +759,9 @@ class oauth extends \phpbb\auth\provider\base
AND user_id = " . (int) $user_id;
$this->db->sql_query($sql);
- // Clear all tokens belonging to the user on this servce
+ // Clear all tokens belonging to the user on this service
$service_name = 'auth.provider.oauth.service.' . strtolower($link_data['oauth_service']);
- $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table);
+ $storage = new \phpbb\auth\provider\oauth\token_storage($this->db, $this->user, $this->auth_provider_oauth_token_storage_table, $this->auth_provider_oauth_state_table);
$storage->clearToken($service_name);
}
}
diff --git a/phpBB/phpbb/auth/provider/oauth/service/twitter.php b/phpBB/phpbb/auth/provider/oauth/service/twitter.php
new file mode 100644
index 0000000000..06beac51e2
--- /dev/null
+++ b/phpBB/phpbb/auth/provider/oauth/service/twitter.php
@@ -0,0 +1,102 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\auth\provider\oauth\service;
+
+/**
+* Twitter OAuth service
+*/
+class twitter extends \phpbb\auth\provider\oauth\service\base
+{
+ /**
+ * phpBB config
+ *
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
+ * phpBB request
+ *
+ * @var \phpbb\request\request_interface
+ */
+ protected $request;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\config\config $config
+ * @param \phpbb\request\request_interface $request
+ */
+ public function __construct(\phpbb\config\config $config, \phpbb\request\request_interface $request)
+ {
+ $this->config = $config;
+ $this->request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_service_credentials()
+ {
+ return array(
+ 'key' => $this->config['auth_oauth_twitter_key'],
+ 'secret' => $this->config['auth_oauth_twitter_secret'],
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function perform_auth_login()
+ {
+ if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter))
+ {
+ throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ }
+
+ $storage = $this->service_provider->getStorage();
+ $token = $storage->retrieveAccessToken('Twitter');
+ $tokensecret = $token->getRequestTokenSecret();
+
+ // This was a callback request from twitter, get the token
+ $this->service_provider->requestAccessToken(
+ $this->request->variable('oauth_token', ''),
+ $this->request->variable('oauth_verifier', ''),
+ $tokensecret
+ );
+
+ // Send a request with it
+ $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true);
+
+ // Return the unique identifier returned from twitter
+ return $result['id'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function perform_token_auth()
+ {
+ if (!($this->service_provider instanceof \OAuth\OAuth1\Service\Twitter))
+ {
+ throw new \phpbb\auth\provider\oauth\service\exception('AUTH_PROVIDER_OAUTH_ERROR_INVALID_SERVICE_TYPE');
+ }
+
+ // Send a request with it
+ $result = json_decode($this->service_provider->request('account/verify_credentials.json'), true);
+
+ // Return the unique identifier returned from twitter
+ return $result['id'];
+ }
+}
diff --git a/phpBB/phpbb/auth/provider/oauth/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php
index 9b6afae255..b0c2fd0d62 100644
--- a/phpBB/phpbb/auth/provider/oauth/token_storage.php
+++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php
@@ -17,6 +17,7 @@ use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\Common\Token\TokenInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\Common\Storage\Exception\TokenNotFoundException;
+use OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException;
/**
* OAuth storage wrapper for phpbb's cache
@@ -42,7 +43,14 @@ class token_storage implements TokenStorageInterface
*
* @var string
*/
- protected $auth_provider_oauth_table;
+ protected $oauth_token_table;
+
+ /**
+ * OAuth state table
+ *
+ * @var string
+ */
+ protected $oauth_state_table;
/**
* @var object|TokenInterface
@@ -50,17 +58,24 @@ class token_storage implements TokenStorageInterface
protected $cachedToken;
/**
+ * @var string
+ */
+ protected $cachedState;
+
+ /**
* Creates token storage for phpBB.
*
* @param \phpbb\db\driver\driver_interface $db
* @param \phpbb\user $user
- * @param string $auth_provider_oauth_table
+ * @param string $oauth_token_table
+ * @param string $oauth_state_table
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $auth_provider_oauth_table)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\user $user, $oauth_token_table, $oauth_state_table)
{
$this->db = $db;
$this->user = $user;
- $this->auth_provider_oauth_table = $auth_provider_oauth_table;
+ $this->oauth_token_table = $oauth_token_table;
+ $this->oauth_state_table = $oauth_state_table;
}
/**
@@ -98,15 +113,31 @@ class token_storage implements TokenStorageInterface
$this->cachedToken = $token;
$data = array(
- 'user_id' => (int) $this->user->data['user_id'],
- 'provider' => $service,
'oauth_token' => $this->json_encode_token($token),
- 'session_id' => $this->user->data['session_id'],
);
- $sql = 'INSERT INTO ' . $this->auth_provider_oauth_table . '
- ' . $this->db->sql_build_array('INSERT', $data);
+ $sql = 'UPDATE ' . $this->oauth_token_table . '
+ SET ' . $this->db->sql_build_array('UPDATE', $data) . '
+ WHERE user_id = ' . (int) $this->user->data['user_id'] . '
+ ' . ((int) $this->user->data['user_id'] === ANONYMOUS ? "AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'" : '') . "
+ AND provider = '" . $this->db->sql_escape($service) . "'";
$this->db->sql_query($sql);
+
+ if (!$this->db->sql_affectedrows())
+ {
+ $data = array(
+ 'user_id' => (int) $this->user->data['user_id'],
+ 'provider' => $service,
+ 'oauth_token' => $this->json_encode_token($token),
+ 'session_id' => $this->user->data['session_id'],
+ );
+
+ $sql = 'INSERT INTO ' . $this->oauth_token_table . $this->db->sql_build_array('INSERT', $data);
+
+ $this->db->sql_query($sql);
+ }
+
+ return $this;
}
/**
@@ -143,7 +174,7 @@ class token_storage implements TokenStorageInterface
$this->cachedToken = null;
- $sql = 'DELETE FROM ' . $this->auth_provider_oauth_table . '
+ $sql = 'DELETE FROM ' . $this->oauth_token_table . '
WHERE user_id = ' . (int) $this->user->data['user_id'] . "
AND provider = '" . $this->db->sql_escape($service) . "'";
@@ -153,6 +184,8 @@ class token_storage implements TokenStorageInterface
}
$this->db->sql_query($sql);
+
+ return $this;
}
/**
@@ -162,7 +195,7 @@ class token_storage implements TokenStorageInterface
{
$this->cachedToken = null;
- $sql = 'DELETE FROM ' . $this->auth_provider_oauth_table . '
+ $sql = 'DELETE FROM ' . $this->oauth_token_table . '
WHERE user_id = ' . (int) $this->user->data['user_id'];
if ((int) $this->user->data['user_id'] === ANONYMOUS)
@@ -171,6 +204,124 @@ class token_storage implements TokenStorageInterface
}
$this->db->sql_query($sql);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function storeAuthorizationState($service, $state)
+ {
+ $service = $this->get_service_name_for_db($service);
+
+ $this->cachedState = $state;
+
+ $data = array(
+ 'user_id' => (int) $this->user->data['user_id'],
+ 'provider' => $service,
+ 'oauth_state' => $state,
+ 'session_id' => $this->user->data['session_id'],
+ );
+
+ $sql = 'INSERT INTO ' . $this->oauth_state_table . '
+ ' . $this->db->sql_build_array('INSERT', $data);
+ $this->db->sql_query($sql);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasAuthorizationState($service)
+ {
+ $service = $this->get_service_name_for_db($service);
+
+ if ($this->cachedState)
+ {
+ return true;
+ }
+
+ $data = array(
+ 'user_id' => (int) $this->user->data['user_id'],
+ 'provider' => $service,
+ );
+
+ if ((int) $this->user->data['user_id'] === ANONYMOUS)
+ {
+ $data['session_id'] = $this->user->data['session_id'];
+ }
+
+ return (bool) $this->get_state_row($data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function retrieveAuthorizationState($service)
+ {
+ $service = $this->get_service_name_for_db($service);
+
+ if ($this->cachedState)
+ {
+ return $this->cachedState;
+ }
+
+ $data = array(
+ 'user_id' => (int) $this->user->data['user_id'],
+ 'provider' => $service,
+ );
+
+ if ((int) $this->user->data['user_id'] === ANONYMOUS)
+ {
+ $data['session_id'] = $this->user->data['session_id'];
+ }
+
+ return $this->get_state_row($data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clearAuthorizationState($service)
+ {
+ $service = $this->get_service_name_for_db($service);
+
+ $this->cachedState = null;
+
+ $sql = 'DELETE FROM ' . $this->oauth_state_table . '
+ WHERE user_id = ' . (int) $this->user->data['user_id'] . "
+ AND provider = '" . $this->db->sql_escape($service) . "'";
+
+ if ((int) $this->user->data['user_id'] === ANONYMOUS)
+ {
+ $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
+ }
+
+ $this->db->sql_query($sql);
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clearAllAuthorizationStates()
+ {
+ $this->cachedState = null;
+
+ $sql = 'DELETE FROM ' . $this->oauth_state_table . '
+ WHERE user_id = ' . (int) $this->user->data['user_id'];
+
+ if ((int) $this->user->data['user_id'] === ANONYMOUS)
+ {
+ $sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'";
+ }
+
+ $this->db->sql_query($sql);
+
+ return $this;
}
/**
@@ -185,7 +336,7 @@ class token_storage implements TokenStorageInterface
return;
}
- $sql = 'UPDATE ' . $this->auth_provider_oauth_table . '
+ $sql = 'UPDATE ' . $this->oauth_token_table . '
SET ' . $this->db->sql_build_array('UPDATE', array(
'user_id' => (int) $user_id
)) . '
@@ -218,6 +369,29 @@ class token_storage implements TokenStorageInterface
}
/**
+ * Checks to see if a state exists solely by the session_id of the user
+ *
+ * @param string $service The name of the OAuth service
+ * @return bool true if they have state, false if they don't
+ */
+ public function has_state_by_session($service)
+ {
+ $service = $this->get_service_name_for_db($service);
+
+ if ($this->cachedState)
+ {
+ return true;
+ }
+
+ $data = array(
+ 'session_id' => $this->user->data['session_id'],
+ 'provider' => $service,
+ );
+
+ return (bool) $this->get_state_row($data);
+ }
+
+ /**
* A helper function that performs the query for has access token functions
*
* @param array $data
@@ -245,6 +419,23 @@ class token_storage implements TokenStorageInterface
return $this->_retrieve_access_token($data);
}
+ public function retrieve_state_by_session($service)
+ {
+ $service = $this->get_service_name_for_db($service);
+
+ if ($this->cachedState)
+ {
+ return $this->cachedState;
+ }
+
+ $data = array(
+ 'session_id' => $this->user->data['session_id'],
+ 'provider' => $service,
+ );
+
+ return $this->_retrieve_state($data);
+ }
+
/**
* A helper function that performs the query for retrieve access token functions
* Also checks if the token is a valid token
@@ -276,6 +467,26 @@ class token_storage implements TokenStorageInterface
}
/**
+ * A helper function that performs the query for retrieve state functions
+ *
+ * @param array $data
+ * @return mixed
+ * @throws \OAuth\Common\Storage\Exception\AuthorizationStateNotFoundException
+ */
+ protected function _retrieve_state($data)
+ {
+ $row = $this->get_state_row($data);
+
+ if (!$row)
+ {
+ throw new AuthorizationStateNotFoundException();
+ }
+
+ $this->cachedState = $row['oauth_state'];
+ return $this->cachedState;
+ }
+
+ /**
* A helper function that performs the query for retrieving an access token
*
* @param array $data
@@ -283,7 +494,24 @@ class token_storage implements TokenStorageInterface
*/
protected function get_access_token_row($data)
{
- $sql = 'SELECT oauth_token FROM ' . $this->auth_provider_oauth_table . '
+ $sql = 'SELECT oauth_token FROM ' . $this->oauth_token_table . '
+ WHERE ' . $this->db->sql_build_array('SELECT', $data);
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ return $row;
+ }
+
+ /**
+ * A helper function that performs the query for retrieving a state
+ *
+ * @param array $data
+ * @return mixed
+ */
+ protected function get_state_row($data)
+ {
+ $sql = 'SELECT oauth_state FROM ' . $this->oauth_state_table . '
WHERE ' . $this->db->sql_build_array('SELECT', $data);
$result = $this->db->sql_query($sql);
$row = $this->db->sql_fetchrow($result);