322 lines
10 KiB
PHP
322 lines
10 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2002 Ronnie Garcia <ronnie@mk2.net>
|
|
* Copyright 2002-2017 Horde LLC (http://www.horde.org/)
|
|
*
|
|
* See the enclosed file COPYING for license information (LGPL). If you did
|
|
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
|
*
|
|
* @author Ronnie Garcia <ronnie@mk2.net>
|
|
* @author Chuck Hagenbuch <chuck@horde.org>
|
|
* @author Joel Vandal <joel@scopserv.com>
|
|
* @category Horde
|
|
* @license http://opensource.org/licenses/lgpl-2.1.php LGPL-2.1
|
|
* @package Auth
|
|
*/
|
|
|
|
/**
|
|
* The Horde_Auth_Customsql class provides a sql implementation of the Horde
|
|
* authentication system with the possibility to set custom-made queries.
|
|
*
|
|
* @author Ronnie Garcia <ronnie@mk2.net>
|
|
* @author Chuck Hagenbuch <chuck@horde.org>
|
|
* @author Joel Vandal <joel@scopserv.com>
|
|
* @category Horde
|
|
* @copyright 2002 Ronnie Garcia <ronnie@mk2.net>
|
|
* @copyright 2002-2017 Horde LLC
|
|
* @license http://opensource.org/licenses/lgpl-2.1.php LGPL-2.1
|
|
* @package Auth
|
|
*/
|
|
class Horde_Auth_Customsql extends Horde_Auth_Sql
|
|
{
|
|
/**
|
|
* An array of capabilities, so that the driver can report which
|
|
* operations it supports and which it doesn't.
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $_capabilities = array(
|
|
'add' => true,
|
|
'list' => true,
|
|
'remove' => true,
|
|
'resetpassword' => true,
|
|
'update' => true,
|
|
'authenticate' => true,
|
|
);
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* Some special tokens can be used in the SQL query. They are replaced
|
|
* at the query stage:
|
|
* '\L' will be replaced by the user's login
|
|
* '\P' will be replaced by the user's password.
|
|
* '\O' will be replaced by the old user's login (required for update)
|
|
*
|
|
* Eg: "SELECT * FROM users WHERE uid = \L
|
|
* AND passwd = \P
|
|
* AND billing = 'paid'"
|
|
*
|
|
* @param array $params Configuration parameters:
|
|
* - query_auth: (string) Authenticate the user. ('\L' & '\P')
|
|
* - query_add: (string) Add user. ('\L' & '\P')
|
|
* - query_getpw: (string) Get one user's password. ('\L')
|
|
* - query_update: (string) Update user. ('\O', '\L' & '\P')
|
|
* - query_resetpassword: (string) Reset password. ('\L', & '\P')
|
|
* - query_remove: (string) Remove user. ('\L')
|
|
* - query_list: (string) List user.
|
|
* - query_exists: (string) Check for existance of user. ('\L')
|
|
*/
|
|
public function __construct(array $params = array())
|
|
{
|
|
foreach (array('query_auth', 'query_add',
|
|
'query_update', 'query_resetpassword', 'query_remove',
|
|
'query_list') as $val) {
|
|
if (empty($params[$val])) {
|
|
switch($val) {
|
|
case 'query_auth':
|
|
$this->_capabilities['authenticate'] = false;
|
|
break;
|
|
case 'query_add':
|
|
$this->_capabilities['add'] = false;
|
|
break;
|
|
case 'query_update':
|
|
$this->_capabilities['update'] = false;
|
|
break;
|
|
case 'query_resetpassword':
|
|
$this->_capabilities['resetpassword'] = false;
|
|
break;
|
|
case 'query_remove':
|
|
$this->_capabilities['remove'] = false;
|
|
break;
|
|
case 'query_list':
|
|
$this->_capabilities['list'] = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
parent::__construct($params);
|
|
}
|
|
|
|
/**
|
|
* Find out if a set of login credentials are valid.
|
|
*
|
|
* @param string $userId The userId to check.
|
|
* @param array $credentials The credentials to use.
|
|
*
|
|
* @throws Horde_Auth_Exception
|
|
*/
|
|
protected function _authenticate($userId, $credentials)
|
|
{
|
|
/* Build a custom query, based on the config file. */
|
|
$query = str_replace(
|
|
array('\L', '\P'),
|
|
array(
|
|
$this->_db->quote($userId),
|
|
$this->_db->quote(Horde_Auth::getCryptedPassword($credentials['password'], $this->_getPassword($userId), $this->_params['encryption'], $this->_params['show_encryption']))
|
|
),
|
|
$this->_params['query_auth']
|
|
);
|
|
|
|
try {
|
|
if ($this->_db->selectValue($query)) {
|
|
return;
|
|
}
|
|
throw new Horde_Auth_Exception('', Horde_Auth::REASON_BADLOGIN);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Horde_Auth_Exception('', Horde_Auth::REASON_FAILED);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a set of authentication credentials.
|
|
*
|
|
* @param string $userId The userId to add.
|
|
* @param array $credentials The credentials to add.
|
|
*
|
|
* @throws Horde_Auth_Exception
|
|
*/
|
|
public function addUser($userId, $credentials)
|
|
{
|
|
/* Build a custom query, based on the config file. */
|
|
$query = str_replace(
|
|
array('\L', '\P'),
|
|
array(
|
|
$this->_db->quote($userId),
|
|
$this->_db->quote(Horde_Auth::getCryptedPassword($credentials['password'], '', $this->_params['encryption'], $this->_params['show_encryption']))
|
|
),
|
|
$this->_params['query_add']
|
|
);
|
|
|
|
try {
|
|
$this->_db->insert($query);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Horde_Auth_Exception($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update a set of authentication credentials.
|
|
*
|
|
* @param string $oldId The old userId.
|
|
* @param string $newId The new userId.
|
|
* @param array $credentials The new credentials
|
|
*
|
|
* @throws Horde_Auth_Exception
|
|
*/
|
|
public function updateUser($oldId, $newId, $credentials)
|
|
{
|
|
/* Build a custom query, based on the config file. */
|
|
$query = str_replace(
|
|
array('\O', '\L', '\P'),
|
|
array(
|
|
$this->_db->quote($oldId),
|
|
$this->_db->quote($newId),
|
|
$this->_db->quote(Horde_Auth::getCryptedPassword($credentials['password'], $this->_getPassword($oldId), $this->_params['encryption'], $this->_params['show_encryption']))
|
|
),
|
|
$this->_params['query_update']
|
|
);
|
|
|
|
try {
|
|
$this->_db->update($query);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Horde_Auth_Exception($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resets a user's password. Used for example when the user does not
|
|
* remember the existing password.
|
|
*
|
|
* @param string $userId The user id for which to reset the password.
|
|
*
|
|
* @return string The new password on success.
|
|
* @throws Horde_Auth_Exception
|
|
*/
|
|
public function resetPassword($userId)
|
|
{
|
|
/* Get a new random password. */
|
|
$password = Horde_Auth::genRandomPassword();
|
|
|
|
/* Build the SQL query. */
|
|
$query = str_replace(
|
|
array('\L', '\P'),
|
|
array(
|
|
$this->_db->quote($userId),
|
|
$this->_db->quote(Horde_Auth::getCryptedPassword($password, '', $this->_params['encryption'], $this->_params['show_encryption']))
|
|
),
|
|
$this->_params['query_resetpassword']
|
|
);
|
|
|
|
try {
|
|
$this->_db->update($query);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Horde_Auth_Exception($e);
|
|
}
|
|
|
|
return $password;
|
|
}
|
|
|
|
/**
|
|
* Delete a set of authentication credentials.
|
|
*
|
|
* @param string $userId The userId to delete.
|
|
*
|
|
* @throws Horde_Auth_Exception
|
|
*/
|
|
public function removeUser($userId)
|
|
{
|
|
/* Build a custom query, based on the config file. */
|
|
$query = str_replace(
|
|
'\L',
|
|
$this->_db->quote($userId),
|
|
$this->_params['query_remove']
|
|
);
|
|
|
|
try {
|
|
$this->_db->delete($query);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Horde_Auth_Exception($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Lists all users in the system.
|
|
*
|
|
* @param boolean $sort Sort the users?
|
|
*
|
|
* @return array The array of userIds.
|
|
* @throws Horde_Auth_Exception
|
|
*/
|
|
public function listUsers($sort = false)
|
|
{
|
|
/* Build a custom query, based on the config file. */
|
|
$query = str_replace(
|
|
'\L',
|
|
$this->_db->quote($this->_params['default_user']),
|
|
$this->_params['query_list']
|
|
);
|
|
|
|
try {
|
|
$users = $this->_db->selectValues($query);
|
|
// Find a way to sort in database with portable SQL
|
|
return $this->_sort($users, $sort);
|
|
} catch (Horde_Db_Exception $e) {
|
|
throw new Horde_Auth_Exception($e);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if a userId exists in the system.
|
|
*
|
|
* @param string $userId User ID for which to check
|
|
*
|
|
* @return boolean Whether or not the userId already exists.
|
|
*/
|
|
public function exists($userId)
|
|
{
|
|
if (empty($this->_params['query_exists'])) {
|
|
return parent::exists($userId);
|
|
}
|
|
|
|
/* Build a custom query, based on the config file. */
|
|
$query = str_replace(
|
|
'\L',
|
|
$this->_db->quote($userId),
|
|
$this->_params['query_exists']
|
|
);
|
|
|
|
try {
|
|
return (bool)$this->_db->selectValue($query);
|
|
} catch (Horde_Db_Exception $e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fetch $userId's current password - needed for the salt with some
|
|
* encryption schemes when doing authentication or updates.
|
|
*
|
|
* @param string $userId The userId to query.
|
|
*
|
|
* @return string $userId's current password.
|
|
*/
|
|
protected function _getPassword($userId)
|
|
{
|
|
/* Retrieve the old password in case we need the salt. */
|
|
$query = str_replace(
|
|
'\L',
|
|
$this->_db->quote($userId),
|
|
$this->_params['query_getpw']
|
|
);
|
|
|
|
try {
|
|
return $this->_db->selectValue($query);
|
|
} catch (Horde_Db_Exception $e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
}
|