diff options
Diffstat (limited to 'phpBB/phpbb/auth/provider')
| -rw-r--r-- | phpBB/phpbb/auth/provider/oauth/oauth.php | 21 | ||||
| -rw-r--r-- | phpBB/phpbb/auth/provider/oauth/token_storage.php | 232 | 
2 files changed, 238 insertions, 15 deletions
diff --git a/phpBB/phpbb/auth/provider/oauth/oauth.php b/phpBB/phpbb/auth/provider/oauth/oauth.php index be0fbf5831..bfeac2dd32 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 @@ -120,6 +127,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 @@ -127,7 +135,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_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_root_path, $php_ext)  	{  		$this->db = $db;  		$this->config = $config; @@ -135,6 +143,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; @@ -188,7 +197,7 @@ 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()); @@ -456,7 +465,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)) @@ -499,7 +508,7 @@ 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(); @@ -544,7 +553,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; @@ -627,7 +636,7 @@ class oauth extends \phpbb\auth\provider\base  		// Clear all tokens belonging to the user on this servce  		$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/token_storage.php b/phpBB/phpbb/auth/provider/oauth/token_storage.php index 9b6afae255..e922342ef6 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;  	}  	/** @@ -104,9 +119,11 @@ class token_storage implements TokenStorageInterface  			'session_id'	=> $this->user->data['session_id'],  		); -		$sql = 'INSERT INTO ' . $this->auth_provider_oauth_table . ' +		$sql = 'INSERT INTO ' . $this->oauth_token_table . '  			' . $this->db->sql_build_array('INSERT', $data);  		$this->db->sql_query($sql); + +		return $this;  	}  	/** @@ -143,7 +160,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 +170,8 @@ class token_storage implements TokenStorageInterface  		}  		$this->db->sql_query($sql); + +		return $this;  	}  	/** @@ -162,7 +181,123 @@ 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) +		{ +			$sql .= " AND session_id = '" . $this->db->sql_escape($this->user->data['session_id']) . "'"; +		} + +		$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) @@ -171,6 +306,8 @@ class token_storage implements TokenStorageInterface  		}  		$this->db->sql_query($sql); + +		return $this;  	}  	/** @@ -185,7 +322,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 +355,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 +405,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 +453,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 +480,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);  | 
