aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/phpbb
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/phpbb')
-rw-r--r--phpBB/phpbb/auth/oauth/token_storage.php220
-rw-r--r--phpBB/phpbb/auth/provider/oauth.php304
2 files changed, 524 insertions, 0 deletions
diff --git a/phpBB/phpbb/auth/oauth/token_storage.php b/phpBB/phpbb/auth/oauth/token_storage.php
new file mode 100644
index 0000000000..fcc277053c
--- /dev/null
+++ b/phpBB/phpbb/auth/oauth/token_storage.php
@@ -0,0 +1,220 @@
+<?php
+/**
+*
+* @package auth
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+
+use OAuth\Common\Token\TokenInterface;
+use OAuth\Common\Storage\TokenStorageInterface;
+use OAuth\Common\Storage\Exception\StorageException;
+use OAuth\Common\Storage\Exception\TokenNotFoundException;
+
+/**
+* OAuth storage wrapper for phpbb's cache
+*
+* @package auth
+*/
+class phpbb_auth_oauth_token_storage implements TokenStorageInterface
+{
+ /**
+ * Cache driver.
+ *
+ * @var phpbb_db_driver
+ */
+ protected $db;
+
+ /**
+ * phpBB user
+ *
+ * @var phpbb_user
+ */
+ protected $user;
+
+ /**
+ * Name of the OAuth provider
+ *
+ * @var string
+ */
+ protected $service_name;
+
+ /**
+ * OAuth token table
+ *
+ * @var string
+ */
+ protected $auth_provider_oauth_table;
+
+ /**
+ * @var object|TokenInterface
+ */
+ protected $cachedToken;
+
+ /**
+ * Creates token storage for phpBB.
+ *
+ * @param phpbb_db_driver $db
+ * @param phpbb_user $user
+ * @param string $service_name
+ * @param string $auth_provider_oauth_table
+ */
+ public function __construct(phpbb_db_driver $db, phpbb_user $user, $service_name, $auth_provider_oauth_table)
+ {
+ $this->db = $db;
+ $this->user = $user;
+ $this->service_name = $service_name;
+ $this->auth_provider_oauth_table = $auth_provider_oauth_table;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function retrieveAccessToken()
+ {
+ if( $this->cachedToken instanceOf TokenInterface ) {
+ return $this->token;
+ }
+
+ $data = array(
+ 'user_id' => $this->user->data['user_id'],
+ 'oauth_provider' => $this->service_name,
+ );
+
+ if ($this->user->data['user_id'] == ANONYMOUS)
+ {
+ $data['session_id'] = $this->user->data['session_id'];
+ }
+
+ $sql = 'SELECT oauth_token FROM ' . $this->auth_provider_oauth_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);
+
+ if (!$row)
+ {
+ // TODO: translate
+ throw new TokenNotFoundException('Token not stored');
+ }
+
+ $token = unserialize($row['oauth_token']);
+
+ // Ensure that the token was serialized/unserialized correctly
+ if (!($token instanceof TokenInterface))
+ {
+ $this->clearToken();
+ // TODO: translate
+ throw new TokenNotFoundException('Token not stored correctly');
+ }
+
+ $this->cachedToken = $token;
+ return $token;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function storeAccessToken(TokenInterface $token)
+ {
+ $this->cachedToken = $token;
+
+ $data = array(
+ 'user_id' => $this->user->data['user_id'],
+ 'oauth_provider' => $this->service_name,
+ 'oauth_token' => serialize($token),
+ );
+
+ if ($this->user->data['user_id'] == ANONYMOUS)
+ {
+ $data['session_id'] = $this->user->data['session_id'];
+ }
+
+ $sql = 'INSERT INTO ' . $this->auth_provider_oauth_table . '
+ WHERE ' . $this->db->sql_build_array('INSERT', $data);
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasAccessToken()
+ {
+ if( $this->cachedToken ) {
+ return true;
+ }
+
+ $data = array(
+ 'user_id' => $this->user->data['user_id'],
+ 'oauth_provider' => $this->service_name,
+ );
+
+ if ($this->user->data['user_id'] == ANONYMOUS)
+ {
+ $data['session_id'] = $this->user->data['session_id'];
+ }
+
+ $sql = 'SELECT oauth_token FROM ' . $this->auth_provider_oauth_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);
+
+ if (!$row)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function clearToken()
+ {
+ $this->cachedToken = null;
+
+ $sql = 'DELETE FROM ' . $this->auth_provider_oauth_table . '
+ WHERE user_id = ' . $this->user->data['user_id'] . '
+ AND oauth_provider = ' . $this->db->sql_escape($this->oauth_provider);
+
+ if ($this->user->data['user_id'] == ANONYMOUS)
+ {
+ $sql .= ' AND session_id = ' . $this->user->data['session_id'];
+ }
+
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * Updates the user_id field in the database assosciated with the token
+ *
+ * @param int $user_id
+ */
+ public function set_user_id($user_id)
+ {
+ if (!$this->cachedToken)
+ {
+ return;
+ }
+
+ $sql = 'UPDATE ' . $this->auth_provider_oauth_table . '
+ SET ' . $db->sql_build_array('UPDATE', array(
+ 'user_id' => (int) $user_id
+ )) . '
+ WHERE user_id = ' . $this->user->data['user_id'] . '
+ AND session_id = ' . $this->user->data['session_id'];
+ $this->db->sql_query($sql);
+ }
+}
diff --git a/phpBB/phpbb/auth/provider/oauth.php b/phpBB/phpbb/auth/provider/oauth.php
new file mode 100644
index 0000000000..aeca2a4869
--- /dev/null
+++ b/phpBB/phpbb/auth/provider/oauth.php
@@ -0,0 +1,304 @@
+<?php
+/**
+*
+* @package auth
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+use OAuth\Common\Consumer\Credentials;
+use OAuth\Common\Http\Uri\Uri;
+
+/**
+* OAuth authentication provider for phpBB3
+*
+* @package auth
+*/
+class phpbb_auth_provider_oauth extends phpbb_auth_provider_base
+{
+ /**
+ * Database driver
+ *
+ * @var phpbb_db_driver
+ */
+ protected $db;
+
+ /**
+ * phpBB config
+ *
+ * @var phpbb_config
+ */
+ protected $config;
+
+ /**
+ * phpBB request object
+ *
+ * @var phpbb_request
+ */
+ protected $request;
+
+ /**
+ * phpBB user
+ *
+ * @var phpbb_user
+ */
+ protected $user;
+
+ /**
+ * OAuth token table
+ *
+ * @var string
+ */
+ protected $auth_provider_oauth_table;
+
+ /**
+ * Cached services once they has been created
+ *
+ * @var array Contains \OAuth\Common\Service\ServiceInterface or null
+ */
+ protected $services;
+
+ /**
+ * Cached current uri object
+ *
+ * @var \OAuth\Common\Http\Uri\UriInterface|null
+ */
+ protected $current_uri;
+
+ /**
+ * OAuth Authentication Constructor
+ *
+ * @param phpbb_db_driver $db
+ * @param phpbb_config $config
+ * @param phpbb_request $request
+ * @param phpbb_user $user
+ * @param string $auth_provider_oauth_table
+ */
+ public function __construct(phpbb_db_driver $db, phpbb_config $config, phpbb_request $request, phpbb_user $user, $auth_provider_oauth_table)
+ {
+ $this->db = $db;
+ $this->config = $config;
+ $this->request = $request;
+ $this->user = $user;
+ $this->auth_provider_oauth_table = $auth_provider_oauth_table;
+ $this->services = array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function login($username, $password)
+ {
+ // Requst the name of the OAuth service
+ $service_name = $this->request->variable('oauth_service', '', false, phpbb_request_interface::POST);
+ if ($service_name === '')
+ {
+ return array(
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ // TODO: change error message
+ 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ // Get the service credentials for the given service
+ $service_credentials = $this->get_credentials($service_name);
+
+ // Check that the service has settings
+ if ($service_credentials['key'] == false || $service_credentials['secret'] == false)
+ {
+ return array(
+ 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
+ // TODO: change error message
+ 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE',
+ 'user_row' => array('user_id' => ANONYMOUS),
+ );
+ }
+
+ $storage = new phpbb_auth_oauth_token_storage($this->db, $this->user, $service_name, $this->auth_provider_oauth_table);
+ $service = $this->get_service($service_name, $storage, $service_credentials, $this->get_scopes($service_name));
+
+ if ($this->request->is_set('code', phpbb_request_interface::GET))
+ {
+ // This was a callback request from the service provider
+ $service->requestAccessToken( $_GET['code'] );
+
+ // Send a request with it
+ $path = $this->get_path($service_name);
+ if ($path)
+ {
+ $result = json_decode( $service->request($path), true );
+ }
+
+ // Perform authentication
+ } else {
+ $url = $service->getAuthorizationUri();
+ // TODO: modify $url for the appropriate return points
+ header('Location: ' . $url);
+ }
+ }
+
+ /**
+ * Returns an array containing the service credentials belonging to requested
+ * service.
+ *
+ * @param string $service_name The name of the service
+ * @return array An array containing the 'key' and the 'secret' of the
+ * service in the form:
+ * array(
+ * 'key' => string
+ * 'secret' => string
+ * )
+ */
+ protected function get_service_credentials($service_name)
+ {
+ return array(
+ 'key' => $this->config['auth_oauth_' . $service_name . '_key'],
+ 'secret' => $this->config['auth_oauth_' . $service_name . '_secret'],
+ );
+ }
+
+ /**
+ * Returns the cached current_uri object or creates and caches it if it is
+ * not already created
+ *
+ * @return \OAuth\Common\Http\Uri\UriInterface
+ */
+ protected function get_current_uri()
+ {
+ if ($this->current_uri)
+ {
+ return $this->current_uri;
+ }
+
+ $uri_factory = new \OAuth\Common\Http\Uri\UriFactory();
+ $current_uri = $uri_factory->createFromSuperGlobalArray($this->request->get_super_global(phpbb_request_interface::SERVER));
+ $current_uri->setQuery('');
+
+ $this->current_uri = $current_uri;
+ return $current_uri;
+ }
+
+ /**
+ * Returns the cached service object or creates a new one
+ *
+ * @param string $service_name The name of the service
+ * @param phpbb_auth_oauth_token_storage $storage
+ * @param array $service_credentials {@see phpbb_auth_provider_oauth::get_service_credentials}
+ * @param array $scope The scope of the request against
+ * the api.
+ * @return \OAuth\Common\Service\ServiceInterface
+ */
+ protected function get_service($service_name, phpbb_auth_oauth_token_storage $storage, array $service_credentials, array $scopes = array())
+ {
+ if ($this->services[$service_name])
+ {
+ return $this->services[$service_name];
+ }
+
+ $current_uri = $this->get_current_uri();
+
+ // Setup the credentials for the requests
+ $credentials = new Credentials(
+ $service_credentials['key'],
+ $service_credentials['secret'],
+ $current_uri->getAbsoluteUri()
+ );
+
+ $service_factory = new \OAuth\ServiceFactory();
+ $this->service[$service_name] = $service_factory->createService($service_name, $credentials, $storage, $scopes);
+
+ return $this->service[$service_name];
+ }
+
+ /**
+ * Returns the scopes of the service required for authentication
+ *
+ * @param string $service_name
+ * @return array An array of the scopes required from the service
+ */
+ protected function get_scopes($service_name)
+ {
+ $scopes = array();
+
+ switch ($service_name)
+ {
+ case 'GitHub':
+ $scopes[] = 'user';
+ break;
+ case 'google':
+ $scopes[] = 'userinfo_email';
+ $scopes[] = 'userinfo_profile';
+ break;
+ case 'instagram':
+ case 'microsoft':
+ $scopes[] = 'basic';
+ break;
+ case 'linkedin':
+ $scopes[] = 'r_basicprofile';
+ break;
+ }
+
+ return $scopes;
+ }
+
+ /**
+ * Returns the path desired of the service
+ *
+ * @param string $service_name
+ * @return string|UriInterface|null A null return means do not
+ * request additional information.
+ */
+ protected function get_path($service_name)
+ {
+ switch ($service_name)
+ {
+ case 'bitly':
+ case 'tumblr':
+ $path = 'user/info';
+ break;
+ case 'box':
+ $path = '/users/me';
+ break;
+ case 'facebook':
+ $path = '/me';
+ break;
+ case 'FitBit':
+ $path = 'user/-/profile.json';
+ break;
+ case 'foursquare':
+ case 'instagram':
+ $path = 'users/self';
+ break;
+ case 'GitHub':
+ $path = 'user/emails';
+ break;
+ case 'google':
+ $path = 'https://www.googleapis.com/oauth2/v1/userinfo';
+ break;
+ case 'linkedin':
+ $path = '/people/~?format=json';
+ break;
+ case 'soundCloud':
+ $path = 'me.json';
+ break;
+ case 'twitter':
+ $path = 'account/verify_credentials.json';
+ break;
+ default:
+ $path = null;
+ break;
+ }
+
+ return $path;
+ }
+}