From 33d1d19f9775242a260adbb33b0bfa4b5324dedf Mon Sep 17 00:00:00 2001 From: Jakub Senko Date: Sun, 22 May 2016 15:05:49 +0200 Subject: [ticket/14586] Add OAuth1 support PHPBB3-14586 --- phpBB/config/default/container/services_auth.yml | 8 ++ phpBB/language/en/common.php | 1 + phpBB/phpbb/auth/provider/oauth/oauth.php | 26 +++++- .../phpbb/auth/provider/oauth/service/twitter.php | 102 +++++++++++++++++++++ phpBB/phpbb/auth/provider/oauth/token_storage.php | 24 ++++- 5 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 phpBB/phpbb/auth/provider/oauth/service/twitter.php diff --git a/phpBB/config/default/container/services_auth.yml b/phpBB/config/default/container/services_auth.yml index 5306644256..a0f9fbd8ef 100644 --- a/phpBB/config/default/container/services_auth.yml +++ b/phpBB/config/default/container/services_auth.yml @@ -99,3 +99,11 @@ services: - '@request' tags: - { name: auth.provider.oauth.service } + + auth.provider.oauth.service.twitter: + class: phpbb\auth\provider\oauth\service\twitter + arguments: + - @config + - @request + tags: + - { name: auth.provider.oauth.service } diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php index f501dc074d..c66f728c06 100644 --- a/phpBB/language/en/common.php +++ b/phpBB/language/en/common.php @@ -98,6 +98,7 @@ $lang = array_merge($lang, array( 'AUTH_PROVIDER_OAUTH_SERVICE_BITLY' => 'Bitly', 'AUTH_PROVIDER_OAUTH_SERVICE_FACEBOOK' => 'Facebook', 'AUTH_PROVIDER_OAUTH_SERVICE_GOOGLE' => 'Google', + 'AUTH_PROVIDER_OAUTH_SERVICE_TWITTER' => 'Twitter', 'AUTH_PROVIDER_OAUTH_TOKEN_ERROR_NOT_STORED' => 'OAuth token not stored.', 'AUTH_PROVIDER_OAUTH_TOKEN_ERROR_INCORRECTLY_STORED' => 'OAuth token incorrectly stored.', 'AVATAR_DISALLOWED_CONTENT' => 'The upload was rejected because the uploaded file was identified as a possible attack vector.', diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index dd7736db4e..04729d8453 100644 --- a/phpBB/phpbb/auth/provider/oauth/oauth.php +++ b/phpBB/phpbb/auth/provider/oauth/oauth.php @@ -201,7 +201,8 @@ class oauth extends \phpbb\auth\provider\base $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(); @@ -256,7 +257,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); } } @@ -520,7 +529,8 @@ class oauth extends \phpbb\auth\provider\base $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(); @@ -536,7 +546,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); } } 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 @@ + +* @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 e922342ef6..b0c2fd0d62 100644 --- a/phpBB/phpbb/auth/provider/oauth/token_storage.php +++ b/phpBB/phpbb/auth/provider/oauth/token_storage.php @@ -113,16 +113,30 @@ 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->oauth_token_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; } -- cgit v1.2.1