From 52352ed01e112bd6ae1eb124cef79c5f533faf18 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 25 May 2010 17:10:09 -0600 Subject: [PATCH] Moved Auth signup code to horde/Core --- folks/account/signup.php | 4 +- framework/Auth/lib/Horde/Auth/Signup.php | 303 ----------------- framework/Auth/lib/Horde/Auth/Signup/Sql.php | 362 --------------------- framework/Auth/package.xml | 9 +- framework/Core/lib/Horde/Core/Auth/Signup.php | 42 +++ framework/Core/lib/Horde/Core/Auth/Signup/Base.php | 165 ++++++++++ framework/Core/lib/Horde/Core/Auth/Signup/Form.php | 83 +++++ framework/Core/lib/Horde/Core/Auth/Signup/Null.php | 70 ++++ framework/Core/lib/Horde/Core/Auth/Signup/Sql.php | 162 +++++++++ .../Core/lib/Horde/Core/Auth/Signup/SqlObject.php | 87 +++++ .../Core/lib/Horde/Core/Binder/AuthSignup.php | 22 ++ framework/Core/lib/Horde/Registry.php | 1 + framework/Core/package.xml | 25 +- horde/admin/signup_confirm.php | 8 +- horde/admin/user.php | 2 +- horde/signup.php | 10 +- 16 files changed, 671 insertions(+), 684 deletions(-) delete mode 100644 framework/Auth/lib/Horde/Auth/Signup.php delete mode 100644 framework/Auth/lib/Horde/Auth/Signup/Sql.php create mode 100644 framework/Core/lib/Horde/Core/Auth/Signup.php create mode 100644 framework/Core/lib/Horde/Core/Auth/Signup/Base.php create mode 100644 framework/Core/lib/Horde/Core/Auth/Signup/Form.php create mode 100644 framework/Core/lib/Horde/Core/Auth/Signup/Null.php create mode 100644 framework/Core/lib/Horde/Core/Auth/Signup/Sql.php create mode 100644 framework/Core/lib/Horde/Core/Auth/Signup/SqlObject.php create mode 100644 framework/Core/lib/Horde/Core/Binder/AuthSignup.php diff --git a/folks/account/signup.php b/folks/account/signup.php index 77c3aa6bc..4764ccf7b 100644 --- a/folks/account/signup.php +++ b/folks/account/signup.php @@ -21,14 +21,14 @@ if ($conf['signup']['allow'] !== true || Horde_Auth::authenticateFailure('folks'); } -$signup = Horde_Auth_Signup::factory(); +$signup = $injector->getInstance('Horde_Core_Auth_Signup'); if ($signup instanceof PEAR_Error) { $notification->push($signup, 'horde.error'); Horde_Auth::authenticateFailure('folks'); } $vars = Horde_Variables::getDefaultVariables(); -$form = new HordeSignupForm($vars); +$form = new Horde_Core_Auth_Signup_Form($vars); if ($form->validate()) { $form->getInfo(null, $info); try { diff --git a/framework/Auth/lib/Horde/Auth/Signup.php b/framework/Auth/lib/Horde/Auth/Signup.php deleted file mode 100644 index 34533b09a..000000000 --- a/framework/Auth/lib/Horde/Auth/Signup.php +++ /dev/null @@ -1,303 +0,0 @@ - - * @package Horde_Auth - */ -class Horde_Auth_Signup -{ - /** - * Attempts to return a concrete Auth_Signup instance based on $driver. - * - * @param string $driver The type of the concrete Auth_Signup subclass - * to return. The class name is based on the - * storage driver ($driver). The code is - * dynamically included. - * @param array $params A hash containing any additional configuration or - * connection parameters a subclass might need. - * - * @return Auth_Signup The newly created concrete Auth_Signup instance, - * or false on an error. - */ - static public function factory($driver = null, $params = null) - { - if ($driver === null) { - if (!empty($GLOBALS['conf']['signup']['driver'])) { - $driver = $GLOBALS['conf']['signup']['driver']; - } else { - $driver = 'datatree'; - } - } else { - $driver = basename($driver); - } - - if ($params === null) { - $params = Horde::getDriverConfig('signup', $driver); - } - - $class = 'Horde_Auth_Signup_' . $driver; - if (!class_exists($class)) { - include dirname(__FILE__) . '/Signup/' . $driver . '.php'; - } - if (class_exists($class)) { - return new $class($params); - } else { - return PEAR::raiseError(_("You must configure a backend to use Signups.")); - } - } - - /** - * Adds a new user to the system and handles any extra fields that may have - * been compiled, relying on the hooks.php file. - * - * @params mixed $info Reference to array of parameters to be passed - * to hook. - * - * @throws Horde_Exception - */ - public function addSignup(&$info) - { - global $auth; - - // Perform any preprocessing if requested. - $this->_preSignup($info); - - // Attempt to add the user to the system. - $auth->addUser($info['user_name'], array('password' => $info['password'])); - - // Attempt to add/update any extra data handed in. - if (!empty($info['extra'])) { - try { - Horde::callHook('signup_addextra', array($info['user_name'], $info['extra'], $info['password'])); - } catch (Horde_Exception_HookNotSet $e) {} - } - } - - /** - * Queues the user's submitted registration info for later admin approval. - * - * @params mixed $info Reference to array of parameters to be passed - * to hook - * - * @throws Horde_Exception - * @throws Horde_Mime_Exception - */ - public function queueSignup(&$info) - { - global $conf; - - // Perform any preprocessing if requested. - $this->_preSignup($info); - - // If it's a unique username, go ahead and queue the request. - $signup = $this->newSignup($info['user_name']); - if (!empty($info['extra'])) { - $signup->data = array_merge($info['extra'], - array('password' => $info['password'], - 'dateReceived' => time())); - } else { - $signup->data = array('password' => $info['password'], - 'dateReceived' => time()); - } - - $result = $this->_queueSignup($signup); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - try { - Horde::callHook('signup_queued', array($info['user_name'], $info)); - } catch (Horde_Exception_HookNotSet $e) {} - - if (!empty($conf['signup']['email'])) { - $link = Horde_Util::addParameter(Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/admin/signup_confirm.php', true, -1), - array('u' => $signup->name, - 'h' => hash_hmac('sha1', $signup->name, $conf['secret_key'])), - null, false); - $message = sprintf(_("A new account for the user \"%s\" has been requested through the signup form."), $signup->name) - . "\n\n" - . _("Approve the account:") - . "\n" . Horde_Util::addParameter($link, 'a', 'approve') . "\n" - . _("Deny the account:") - . "\n" . Horde_Util::addParameter($link, 'a', 'deny'); - $mail = new Horde_Mime_Mail(array( - 'subject' => sprintf(_("Account signup request for \"%s\""), $signup->name), - 'body' => $message, - 'to' => $conf['signup']['email'], - 'from' => $conf['signup']['email'], - 'subject' => Horde_Nls::getCharset())); - $mail->send($GLOBALS['injector']->getInstance('Horde_Mail')); - } - } - - /** - * Perform common presignup actions. - * - * @param array $info Reference to array of parameters. - * - * @throws Horde_Exception - */ - protected function _preSignup(&$info) - { - global $auth; - - try { - $info = Horde::callHook('signup_preprocess', array($info)); - } catch (Horde_Exception_HookNotSet $e) {} - - // Check to see if the username already exists in auth backend. - if ($auth->exists($info['user_name'])) { - throw new Horde_Exception(sprintf(_("Username \"%s\" already exists."), $info['user_name'])); - } - - // Check to see if the username already exists in signup queue. - if ($this->exists($info['user_name'])) { - throw new Horde_Exception(sprintf(_("Username \"%s\" already exists."), $info['user_name'])); - } - } - - /** - * Queues the user's submitted registration info for later admin approval. - * - * @params mixed $info Reference to array of parameters to be passed - * to hook - * - * @throws Horde_Exception - */ - protected function _queueSignup(&$info) - { - throw new Horde_Exception('Not implemented'); - } - - /** - * Get a user's queued signup information. - * - * @param string $username The username to retrieve the queued info for. - * - * @return object The object for the requested signup. - * @throws Horde_Exception - */ - public function getQueuedSignup($username) - { - throw new Horde_Exception('Not implemented'); - } - - /** - * Get the queued information for all pending signups. - * - * @return array An array of objects, one for each signup in the queue. - * @throws Horde_Exception - */ - public function getQueuedSignups() - { - throw new Horde_Exception('Not implemented'); - } - - /** - * Remove a queued signup. - * - * @param string $username The user to remove from the signup queue. - * @throws Horde_Exception - */ - public function removeQueuedSignup($username) - { - throw new Horde_Exception('Not implemented'); - } - - /** - * Return a new signup object. - * - * @param string $name The signups's name. - * - * @return object A new signup object. - * @throws Horde_Exception - */ - public function newSignup($name) - { - throw new Horde_Exception('Not implemented'); - } - -} - -/** - * Horde Signup Form. - * - * Copyright 2003-2010 The Horde Project (http://www.horde.org/) - * - * See the enclosed file COPYING for license information (LGPL). If you did - * not receive this file, see http://opensource.org/licenses/lgpl-2.1.php - * - * @author Marko Djukic - * @package Horde_Auth - */ -class HordeSignupForm extends Horde_Form { - - var $_useFormToken = true; - - function HordeSignupForm(&$vars) - { - global $registry; - - parent::Horde_Form($vars, sprintf(_("%s Sign Up"), $registry->get('name'))); - - $this->setButtons(_("Sign up"), true); - - $this->addHidden('', 'url', 'text', false); - - /* Use hooks get any extra fields required in signing up. */ - try { - $extra = Horde::callHook('signup_getextra'); - } catch (Horde_Exception_HookNotSet $e) {} - - if (!empty($extra)) { - if (!isset($extra['user_name'])) { - $this->addVariable(_("Choose a username"), 'user_name', 'text', true); - } - if (!isset($extra['password'])) { - $this->addVariable(_("Choose a password"), 'password', 'passwordconfirm', true, false, _("type the password twice to confirm")); - } - foreach ($extra as $field_name => $field) { - $readonly = isset($field['readonly']) ? $field['readonly'] : null; - $desc = isset($field['desc']) ? $field['desc'] : null; - $required = isset($field['required']) ? $field['required'] : false; - $field_params = isset($field['params']) ? $field['params'] : array(); - - $this->addVariable($field['label'], 'extra[' . $field_name . ']', - $field['type'], $required, $readonly, - $desc, $field_params); - } - } else { - $this->addVariable(_("Choose a username"), 'user_name', 'text', true); - $this->addVariable(_("Choose a password"), 'password', 'passwordconfirm', true, false, _("type the password twice to confirm")); - } - } - - /** - * Fetch the field values of the submitted form. - * - * @param Variables $vars A Variables instance, optional since Horde 3.2. - * @param array $info Array to be filled with the submitted field - * values. - */ - function getInfo($vars, &$info) - { - parent::getInfo($vars, $info); - - if (!isset($info['user_name']) && isset($info['extra']['user_name'])) { - $info['user_name'] = $info['extra']['user_name']; - } - - if (!isset($info['password']) && isset($info['extra']['password'])) { - $info['password'] = $info['extra']['password']; - } - } - -} diff --git a/framework/Auth/lib/Horde/Auth/Signup/Sql.php b/framework/Auth/lib/Horde/Auth/Signup/Sql.php deleted file mode 100644 index b9c0ce264..000000000 --- a/framework/Auth/lib/Horde/Auth/Signup/Sql.php +++ /dev/null @@ -1,362 +0,0 @@ - - * @package Horde_Auth - */ -class Horde_Auth_Signup_Sql extends Horde_Auth_Signup -{ - /** - * Handle for the current database connection. - * - * @var DB - */ - protected $_db; - - /** - * Handle for the current database connection, used for writing. Defaults - * to the same handle as $db if a separate write database is not required. - * - * @var DB - */ - protected $_write_db; - - /** - * SQL connection parameters - */ - protected $_params = array(); - - /** - * Connect to DB. - */ - public function __construct($params) - { - $this->_params = $params; - $this->_connect(); - } - - /** - * Stores the signup data in the backend. - * - * @params SQLObject_Signup $signup Signup data. - */ - protected function _queueSignup($signup) - { - $query = 'INSERT INTO ' . $this->_params['table'] - . ' (user_name, signup_date, signup_host, signup_data) VALUES (?, ?, ?, ?) '; - $values = array($signup->name, - time(), - $_SERVER['REMOTE_ADDR'], - serialize($signup->data)); - Horde::logMessage('SQL query by Auth_Signup_sql::_queueSignup(): ' . $query, 'DEBUG'); - $stmt = $this->_write_db->prepare($query, null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute($values); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - $stmt->free(); - } - - /** - * Checks if a user exists in the system. - * - * @param string $user The user to check. - * - * @return boolean True if the user exists. - */ - public function exists($user) - { - if (empty($GLOBALS['conf']['signup']['queue'])) { - return false; - } - - $stmt = $this->_db->prepare('SELECT 1 FROM ' . $this->_params['table'] - . ' WHERE user_name = ?'); - - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute(array($user)); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - $exists = (bool)$result->fetchOne(); - $stmt->free(); - $result->free(); - - return $exists; - } - - /** - * Get a user's queued signup information. - * - * @param string $username The username to retrieve the queued info for. - * - * @return SQLObject_Signup The SQLObject for the requested - * signup. - */ - public function getQueuedSignup($username) - { - $stmt = $this->_db->prepare('SELECT * FROM ' . $this->_params['table'] . ' WHERE user_name = ?'); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $results = $stmt->execute(array($username)); - if (is_a($results, 'PEAR_Error')) { - Horde::logMessage($results, 'ERR'); - return $results; - } - $data = $results->fetchRow(MDB2_FETCHMODE_ASSOC); - if (is_a($data, 'PEAR_Error')) { - Horde::logMessage($data, 'ERR'); - return $data; - } elseif (empty($data)) { - return PEAR::RaiseError(sprintf(_("User \"%s\" does not exist."), $name)); - } - $stmt->free(); - $results->free(); - - $object = new SQLObject_Signup($data['user_name']); - $object->setData($data); - - return $object; - } - - /** - * Get the queued information for all pending signups. - * - * @return array An array of SQLObject_Signup objects, one for - * each signup in the queue. - */ - public function getQueuedSignups() - { - $query = 'SELECT * FROM ' . $this->_params['table'] . ' ORDER BY signup_date'; - $result = $this->_db->query($query); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } elseif (empty($result)) { - return array(); - } - - $signups = array(); - while ($signup = $result->fetchRow(MDB2_FETCHMODE_ASSOC)) { - $object = new SQLObject_Signup($signup['user_name']); - $object->setData($signup); - $signups[] = $object; - } - - $result->free(); - - return $signups; - } - - /** - * Remove a queued signup. - * - * @param string $username The user to remove from the signup queue. - */ - public function removeQueuedSignup($username) - { - $stmt = $this->_write_db->prepare('DELETE FROM ' . $this->_params['table'] . ' WHERE user_name = ?', null, MDB2_PREPARE_MANIP); - if (is_a($stmt, 'PEAR_Error')) { - Horde::logMessage($stmt, 'ERR'); - return $stmt; - } - $result = $stmt->execute(array($username)); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - $stmt->free(); - - return true; - } - - /** - * Return a new signup object. - * - * @param string $name The signups's name. - * - * @return SQLObject_Signup A new signup object. - */ - public function newSignup($name) - { - if (empty($name)) { - return PEAR::raiseError('Signup names must be non-empty'); - } - return new SQLObject_Signup($name); - } - - /** - * Attempts to open a connection to the sql server. - * - * @return boolean True on success. - * @throws Horde_Exception - */ - protected function _connect() - { - if (!isset($this->_params['database'])) { - $this->_params['database'] = ''; - } - if (!isset($this->_params['username'])) { - $this->_params['username'] = ''; - } - if (!isset($this->_params['hostspec'])) { - $this->_params['hostspec'] = ''; - } - if (!isset($this->_params['table'])) { - $this->_params['table'] = 'horde_signups'; - } - - /* Connect to the sql server using the supplied parameters. */ - $params = $this->_params; - unset($params['charset']); - $this->_write_db = MDB2::factory($params); - if (is_a($this->_write_db, 'PEAR_Error')) { - throw new Horde_Exception_Prior($this->_write_db); - } - - /* Set DB portability options. */ - switch ($this->_write_db->phptype) { - case 'mssql': - $this->_write_db->setOption('field_case', CASE_LOWER); - $this->_write_db->setOption('portability', MDB2_PORTABILITY_FIX_CASE | MDB2_PORTABILITY_ERRORS | MDB2_PORTABILITY_RTRIM | MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES); - break; - default: - $this->_write_db->setOption('field_case', CASE_LOWER); - $this->_write_db->setOption('portability', MDB2_PORTABILITY_FIX_CASE | MDB2_PORTABILITY_ERRORS | MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES); - } - - /* Check if we need to set up the read DB connection seperately. */ - if (!empty($this->_params['splitread'])) { - $params = array_merge($params, $this->_params['read']); - $this->_db = MDB2::factory($params); - if (is_a($this->_db, 'PEAR_Error')) { - throw new Horde_Exception_Prior($this->_db); - } - - /* Set DB portability options. */ - switch ($this->_db->phptype) { - case 'mssql': - $this->_db->setOption('field_case', CASE_LOWER); - $this->_db->setOption('portability', MDB2_PORTABILITY_FIX_CASE | MDB2_PORTABILITY_ERRORS | MDB2_PORTABILITY_RTRIM | MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES); - break; - default: - $this->_db->setOption('portability', MDB2_PORTABILITY_FIX_CASE | MDB2_PORTABILITY_ERRORS | MDB2_PORTABILITY_FIX_ASSOC_FIELD_NAMES); - } - } else { - /* Default to the same DB handle as the writer for reading too */ - $this->_db = $this->_write_db; - } - - return true; - } - -} - -/** - * Extension of the SQLObject class for storing Signup - * information in the SQL driver. If you want to store - * specialized Signup information, you should extend this class - * instead of extending SQLObject directly. - * - * @author Duck - * @package Horde_Auth - */ -class SQLObject_Signup { - - /** - * Key-value hash that will be serialized. - * - * @see getData() - * @var array - */ - var $data = array(); - - /** - * The unique name of this object. - * These names have the same requirements as other object names - they must - * be unique, etc. - * - * @var string - */ - var $name; - - /** - * The SQLObject_Signup constructor. Just makes sure to call - * the parent constructor so that the signup's is is set - * properly. - * - * @param string $id The id of the signup. - */ - function SQLObject_Signup($id) - { - if (is_null($this->data)) { - $this->data = array(); - } - - $this->name = $id; - } - - /** - * Gets the data array. - * - * @return array The internal data array. - */ - function getData() - { - return $this->data; - } - - /** - * Sets the data array. - * - * @param array The data array to store internally. - */ - function setData($data) - { - $part = unserialize($data['signup_data']); - if (!empty($part) && is_array($part)) { - if (!empty($part['extra'])) { - $extra = $part['extra']; - unset($part['extra']); - $part = array_merge($part, $extra); - } - $this->data = array_merge($data, $part); - } else { - $this->data = $data; - } - - unset($this->data['signup_data']); - $this->data['dateReceived'] = $data['signup_date']; - } - - /** - * Gets the name of this object. - * - * @return string The object name. - */ - function getName() - { - return $this->name; - } - -} diff --git a/framework/Auth/package.xml b/framework/Auth/package.xml index 4e07865d1..db2039f1c 100644 --- a/framework/Auth/package.xml +++ b/framework/Auth/package.xml @@ -30,7 +30,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> beta LGPL - * Replaced Horde_Auth::addHook() and Horde_Auth::removeHook() with + * Moved signup code to horde/Core. + * Replaced Horde_Auth::addHook() and Horde_Auth::removeHook() with Horde_Auth::convertUsername(). * Add ability to retrieve app-specific credentials via Horde_Auth::getCredential(). @@ -46,9 +47,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> - - - @@ -72,7 +70,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> - @@ -183,8 +180,6 @@ http://pear.php.net/dtd/package-2.0.xsd"> - - diff --git a/framework/Core/lib/Horde/Core/Auth/Signup.php b/framework/Core/lib/Horde/Core/Auth/Signup.php new file mode 100644 index 000000000..bba7e4093 --- /dev/null +++ b/framework/Core/lib/Horde/Core/Auth/Signup.php @@ -0,0 +1,42 @@ + + * @category Horde + * @license http://opensource.org/licenses/lgpl-2.1.php LGPL + * @package Core + */ +class Horde_Core_Auth_Signup +{ + /** + * Attempts to return a concrete instance based on $driver. + * + * @param string $driver The type of the concrete subclass to return. + * @param array $params A hash containing any additional configuration + * or connection parameters a subclass might need. + * + * @return Horde_Core_Auth_Signup_Base The newly created concrete + * instance. + * @throws Horde_Exception + */ + static public function factory($driver, $params = array()) + { + $driver = Horde_String::ucfirst(basename($driver)); + $class = __CLASS__ . '_' . $driver; + + if (class_exists($class)) { + return new $class($params); + } + + throw new Horde_Exception(__CLASS__ . ' driver (' . $class . ') not found.'); + } + +} diff --git a/framework/Core/lib/Horde/Core/Auth/Signup/Base.php b/framework/Core/lib/Horde/Core/Auth/Signup/Base.php new file mode 100644 index 000000000..ddff4ccc1 --- /dev/null +++ b/framework/Core/lib/Horde/Core/Auth/Signup/Base.php @@ -0,0 +1,165 @@ + + * @author Michael Slusarz + * @category Horde + * @license http://opensource.org/licenses/lgpl-2.1.php LGPL + * @package Core + */ +abstract class Horde_Core_Auth_Signup_Base +{ + /** + * Adds a new user to the system and handles any extra fields that may have + * been compiled, relying on the hooks.php file. + * + * @params mixed $info Reference to array of parameters to be passed + * to hook. + * + * @throws Horde_Exception + */ + public function addSignup(&$info) + { + // Perform any preprocessing if requested. + $this->_preSignup($info); + + // Attempt to add the user to the system. + $GLOBALS['auth']->addUser($info['user_name'], array('password' => $info['password'])); + + // Attempt to add/update any extra data handed in. + if (!empty($info['extra'])) { + try { + Horde::callHook('signup_addextra', array($info['user_name'], $info['extra'], $info['password'])); + } catch (Horde_Exception_HookNotSet $e) {} + } + } + + /** + * Queues the user's submitted registration info for later admin approval. + * + * @params mixed $info Reference to array of parameters to be passed + * to hook + * + * @throws Horde_Exception + * @throws Horde_Mime_Exception + */ + public function queueSignup(&$info) + { + global $conf; + + // Perform any preprocessing if requested. + $this->_preSignup($info); + + // If it's a unique username, go ahead and queue the request. + $signup = $this->newSignup($info['user_name']); + $signup->data = empty($info['extra']) + ? array() + : $info['extra']; + $signup->data = array_merge($signup->data, array( + 'dateReceived' => time(), + 'password' => $info['password'] + )); + + $this->_queueSignup($signup); + + try { + Horde::callHook('signup_queued', array($info['user_name'], $info)); + } catch (Horde_Exception_HookNotSet $e) {} + + if (!empty($conf['signup']['email'])) { + $link = Horde::url($GLOBALS['registry']->get('webroot', 'horde') . '/admin/signup_confirm.php', true, -1)->setRaw(true)->add(array( + 'u' => $signup->name, + 'h' => hash_hmac('sha1', $signup->name, $conf['secret_key']) + )); + $message = sprintf(_("A new account for the user \"%s\" has been requested through the signup form."), $signup->name) + . "\n\n" + . _("Approve the account:") + . "\n" . Horde_Util::addParameter($link, 'a', 'approve') . "\n" + . _("Deny the account:") + . "\n" . Horde_Util::addParameter($link, 'a', 'deny'); + $mail = new Horde_Mime_Mail(array( + 'subject' => sprintf(_("Account signup request for \"%s\""), $signup->name), + 'body' => $message, + 'to' => $conf['signup']['email'], + 'from' => $conf['signup']['email'], + 'subject' => Horde_Nls::getCharset())); + $mail->send($GLOBALS['injector']->getInstance('Horde_Mail')); + } + } + + /** + * Perform common presignup actions. + * + * @param array $info Reference to array of parameters. + * + * @throws Horde_Exception + */ + protected function _preSignup(&$info) + { + try { + $info = Horde::callHook('signup_preprocess', array($info)); + } catch (Horde_Exception_HookNotSet $e) {} + + // Check to see if the username already exists in the auth backend or + // the signup queue. + if ($GLOBALS['auth']->exists($info['user_name']) || + $this->exists($info['user_name'])) { + throw new Horde_Exception(sprintf(_("Username \"%s\" already exists."), $info['user_name'])); + } + } + + /** + * Queues the user's submitted registration info for later admin approval. + * + * @params mixed $info Reference to array of parameters to be passed + * to hook + * + * @throws Horde_Exception + */ + abstract protected function _queueSignup(&$info); + + /** + * Get a user's queued signup information. + * + * @param string $username The username to retrieve the queued info for. + * + * @return object The object for the requested signup. + * @throws Horde_Exception + */ + abstract public function getQueuedSignup($username); + + /** + * Get the queued information for all pending signups. + * + * @return array An array of objects, one for each signup in the queue. + * @throws Horde_Exception + */ + abstract public function getQueuedSignups(); + + /** + * Remove a queued signup. + * + * @param string $username The user to remove from the signup queue. + * + * @throws Horde_Exception + */ + abstract public function removeQueuedSignup($username); + + /** + * Return a new signup object. + * + * @param string $name The signups's name. + * + * @return object A new signup object. + * @throws Horde_Exception + */ + abstract public function newSignup($name); + +} diff --git a/framework/Core/lib/Horde/Core/Auth/Signup/Form.php b/framework/Core/lib/Horde/Core/Auth/Signup/Form.php new file mode 100644 index 000000000..7b5ce9d31 --- /dev/null +++ b/framework/Core/lib/Horde/Core/Auth/Signup/Form.php @@ -0,0 +1,83 @@ + + * @category Horde + * @license http://opensource.org/licenses/lgpl-2.1.php LGPL + * @package Core + */ +class Horde_Core_Auth_Signup_Form extends Horde_Form +{ + /** + * @var boolean + */ + protected $_useFormToken = true; + + /** + * Constructor + * + * @var params Horde_Variables TODO + */ + public function __construct(&$vars) + { + parent::__construct($vars, sprintf(_("%s Sign Up"), $GLOBALS['registry']->get('name'))); + + $this->setButtons(_("Sign up"), true); + + $this->addHidden('', 'url', 'text', false); + + /* Use hooks get any extra fields required in signing up. */ + try { + $extra = Horde::callHook('signup_getextra'); + } catch (Horde_Exception_HookNotSet $e) {} + + if (!empty($extra)) { + if (!isset($extra['user_name'])) { + $this->addVariable(_("Choose a username"), 'user_name', 'text', true); + } + if (!isset($extra['password'])) { + $this->addVariable(_("Choose a password"), 'password', 'passwordconfirm', true, false, _("type the password twice to confirm")); + } + foreach ($extra as $field_name => $field) { + $readonly = isset($field['readonly']) ? $field['readonly'] : null; + $desc = isset($field['desc']) ? $field['desc'] : null; + $required = isset($field['required']) ? $field['required'] : false; + $field_params = isset($field['params']) ? $field['params'] : array(); + + $this->addVariable($field['label'], 'extra[' . $field_name . ']', + $field['type'], $required, $readonly, + $desc, $field_params); + } + } else { + $this->addVariable(_("Choose a username"), 'user_name', 'text', true); + $this->addVariable(_("Choose a password"), 'password', 'passwordconfirm', true, false, _("type the password twice to confirm")); + } + } + + /** + * Fetch the field values of the submitted form. + * + * @param Variables $vars A Variables instance (Needed?). + * @param array $info Array to be filled with the submitted field + * values. + */ + public function getInfo($vars, &$info) + { + parent::getInfo($vars, $info); + + if (!isset($info['user_name']) && isset($info['extra']['user_name'])) { + $info['user_name'] = $info['extra']['user_name']; + } + + if (!isset($info['password']) && isset($info['extra']['password'])) { + $info['password'] = $info['extra']['password']; + } + } + +} diff --git a/framework/Core/lib/Horde/Core/Auth/Signup/Null.php b/framework/Core/lib/Horde/Core/Auth/Signup/Null.php new file mode 100644 index 000000000..6a10f8f81 --- /dev/null +++ b/framework/Core/lib/Horde/Core/Auth/Signup/Null.php @@ -0,0 +1,70 @@ + + * @category Horde + * @license http://opensource.org/licenses/lgpl-2.1.php LGPL + * @package Core + */ +class Horde_Core_Auth_Signup_Null extends Horde_Core_Auth_Signup_Base +{ + /** + * Queues the user's submitted registration info for later admin approval. + * + * @params mixed $info Reference to array of parameters to be passed + * to hook + */ + protected function _queueSignup(&$info) + { + } + + /** + * Get a user's queued signup information. + * + * @param string $username The username to retrieve the queued info for. + * + * @return object The object for the requested signup. + */ + public function getQueuedSignup($username) + { + return new Horde_Support_Stub(); + } + + /** + * Get the queued information for all pending signups. + * + * @return array An array of objects, one for each signup in the queue. + */ + public function getQueuedSignups() + { + return array(); + } + + /** + * Remove a queued signup. + * + * @param string $username The user to remove from the signup queue. + */ + public function removeQueuedSignup($username) + { + } + + /** + * Return a new signup object. + * + * @param string $name The signups's name. + * + * @return object A new signup object. + */ + public function newSignup($name) + { + return new Horde_Support_Stub(); + } + +} diff --git a/framework/Core/lib/Horde/Core/Auth/Signup/Sql.php b/framework/Core/lib/Horde/Core/Auth/Signup/Sql.php new file mode 100644 index 000000000..63c834962 --- /dev/null +++ b/framework/Core/lib/Horde/Core/Auth/Signup/Sql.php @@ -0,0 +1,162 @@ + + * @category Horde + * @license http://opensource.org/licenses/lgpl-2.1.php LGPL + * @package Core + */ +class Horde_Core_Auth_Signup_Sql extends Horde_Core_Auth_Signup_Base +{ + /** + * Configuration parameters. + * + * @var array + */ + protected $_params = array(); + + /** + * Constructor. + */ + public function __construct() + { + $this->_params = array_merge($this->_params, array( + 'table' => 'horde_signups' + ), Horde::getDriverConfig('signup', 'Sql')); + } + + /** + * Stores the signup data in the backend. + * + * @params Horde_Core_Auth_Signup_SqlObject $signup Signup data. + * + * @throws Horde_Db_Exception + */ + protected function _queueSignup($signup) + { + $query = 'INSERT INTO ' . $this->_params['table'] + . ' (user_name, signup_date, signup_host, signup_data) VALUES (?, ?, ?, ?) '; + $values = array( + $signup->getName(), + time(), + $_SERVER['REMOTE_ADDR'], + serialize($signup->getData()) + ); + + $GLOBALS['injector']->getInstance('Horde_Db_Adapter_Base')->insert($query, $values); + } + + /** + * Checks if a user exists in the system. + * + * @param string $user The user to check. + * + * @return boolean True if the user exists. + * @throws Horde_Db_Exception + */ + public function exists($user) + { + if (empty($GLOBALS['conf']['signup']['queue'])) { + return false; + } + + $query = 'SELECT 1 FROM ' . $this->_params['table'] . + ' WHERE user_name = ?'; + $values = array($user); + + return (bool)$GLOBALS['injector']->getInstance('Horde_Db_Adapter_Base')->selectValue($query, $values); + } + + /** + * Get a user's queued signup information. + * + * @param string $username The username to retrieve the queued info for. + * + * @return Horde_Core_Auth_Signup_SqlObject $signup The object for the + * requested signup. + * @throws Horde_Exception + * @throws Horde_Db_Exception + */ + public function getQueuedSignup($username) + { + $query = 'SELECT * FROM ' . $this->_params['table'] . + ' WHERE user_name = ?'; + $values = array($username); + + $result = $GLOBALS['injector']->getInstance('Horde_Db_Adapter_Base')->selectOne($query, $values); + if (empty($result)) { + throw new Horde_Exception(sprintf(_("User \"%s\" does not exist."), $username)); + } + $object = new Horde_Core_Auth_Signup_SqlObject($data['user_name']); + $object->setData($data); + + return $object; + } + + /** + * Get the queued information for all pending signups. + * + * @return array An array of signup objects, one for each signup in the + * queue. + * @throws Horde_Db_Exception + */ + public function getQueuedSignups() + { + $query = 'SELECT * FROM ' . $this->_params['table'] . + ' ORDER BY signup_date'; + + $result = $GLOBALS['injector']->getInstance('Horde_Db_Adapter_Base')->selectAll($query); + if (empty($result)) { + return array(); + } + + $signups = array(); + foreach ($result as $signup) { + $object = new Horde_Core_Auth_Signup_SqlObject($signup['user_name']); + $object->setData($signup); + $signups[] = $object; + } + + return $signups; + } + + /** + * Remove a queued signup. + * + * @param string $username The user to remove from the signup queue. + * + * @throws Horde_Db_Exception + */ + public function removeQueuedSignup($username) + { + $query = 'DELETE FROM ' . $this->_params['table'] . + ' WHERE user_name = ?'; + $values = array($username); + + $GLOBALS['injector']->getInstance('Horde_Db_Adapter_Base')->delete($query, $values); + } + + /** + * Return a new signup object. + * + * @param string $name The signups's name. + * + * @return Horde_Core_Auth_Signup_SqlObject A new signup object. + * @throws InvalidArgumentException + */ + public function newSignup($name) + { + if (empty($name)) { + throw new InvalidArgumentException('Signup names must be non-empty.'); + } + + return new Horde_Core_Auth_Signup_SqlObject($name); + } + +} diff --git a/framework/Core/lib/Horde/Core/Auth/Signup/SqlObject.php b/framework/Core/lib/Horde/Core/Auth/Signup/SqlObject.php new file mode 100644 index 000000000..bed1c8036 --- /dev/null +++ b/framework/Core/lib/Horde/Core/Auth/Signup/SqlObject.php @@ -0,0 +1,87 @@ + + * @category Horde + * @license http://opensource.org/licenses/lgpl-2.1.php LGPL + * @package Core + */ +class Horde_Core_Auth_Signup_SQLObject +{ + /** + * Key-value hash that will be serialized. + * + * @see getData() + * @var array + */ + protected $_data = array(); + + /** + * The unique name of this object. + * These names have the same requirements as other object names - they + * must be unique, etc. + * + * @var string + */ + protected $name; + + /** + * Constructor. + * + * @param string $id The id of the signup. + */ + public function __construct($id) + { + $this->_name = $id; + } + + /** + * Gets the data array. + * + * @return array The internal data array. + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the data array. + * + * @param array The data array to store internally. + */ + public function setData($data) + { + $part = unserialize($data['signup_data']); + if (!empty($part) && is_array($part)) { + if (!empty($part['extra'])) { + $extra = $part['extra']; + unset($part['extra']); + $part = array_merge($part, $extra); + } + $this->_data = array_merge($data, $part); + } else { + $this->_data = $data; + } + + unset($this->_data['signup_data']); + $this->_data['dateReceived'] = $data['signup_date']; + } + + /** + * Gets the name of this object. + * + * @return string The object name. + */ + public function getName() + { + return $this->_name; + } + +} diff --git a/framework/Core/lib/Horde/Core/Binder/AuthSignup.php b/framework/Core/lib/Horde/Core/Binder/AuthSignup.php new file mode 100644 index 000000000..0e1fe3002 --- /dev/null +++ b/framework/Core/lib/Horde/Core/Binder/AuthSignup.php @@ -0,0 +1,22 @@ + new Horde_Core_Binder_Alarm(), // 'Horde_Browser' - initialized below 'Horde_Cache' => new Horde_Core_Binder_Cache(), + 'Horde_Core_Auth_Signup' => new Horde_Core_Binder_AuthSignup(), 'Horde_Data' => new Horde_Core_Binder_Data(), 'Horde_Db_Adapter_Base' => new Horde_Core_Binder_Db(), 'Horde_Db_Pear' => new Horde_Core_Binder_DbPear(), diff --git a/framework/Core/package.xml b/framework/Core/package.xml index e014fa0df..f4598e02b 100644 --- a/framework/Core/package.xml +++ b/framework/Core/package.xml @@ -37,7 +37,8 @@ Application Framework. beta LGPL - * Import Horde backend driver from horde/LoginTasks. + * Import signup code from horde/Auth. + * Import Horde backend driver from horde/LoginTasks. * Import perms UI handling class from horde/Perms. * Import prefs UI handling class from horde/Prefs. * Convert from PEAR Log to Horde_Log for logging. @@ -60,6 +61,16 @@ Application Framework. + + + + + + + + + + @@ -68,6 +79,7 @@ Application Framework. + @@ -174,6 +186,10 @@ Application Framework. 1.5.4 + Auth + pear.horde.org + + Autoloader pear.horde.org @@ -241,9 +257,16 @@ Application Framework. + + + + + + + diff --git a/horde/admin/signup_confirm.php b/horde/admin/signup_confirm.php index e3e9081b1..6faad98ee 100644 --- a/horde/admin/signup_confirm.php +++ b/horde/admin/signup_confirm.php @@ -17,9 +17,11 @@ if ($conf['signup']['allow'] !== true || !$auth->hasCapability('add')) { throw new Horde_Exception(_("User Registration has been disabled for this site.")); } -$signup = Horde_Auth_Signup::factory(); -if (is_a($signup, 'PEAR_Error')) { - Horde::logMessage($signup, 'ERR'); + +try { + $signup = $injector->getInstance('Horde_Core_Auth_Signup'); +} catch (Horde_Exception $e) { + Horde::logMessage($e, 'ERR'); throw new Horde_Exception(_("User Registration is not properly configured for this site.")); } diff --git a/horde/admin/user.php b/horde/admin/user.php index 9387fc72e..5217162e8 100644 --- a/horde/admin/user.php +++ b/horde/admin/user.php @@ -14,7 +14,7 @@ Horde_Registry::appInit('horde', array('admin' => true)); $auth = Horde_Auth::singleton($conf['auth']['driver']); if ($conf['signup']['allow'] && $conf['signup']['approve']) { - $signup = Horde_Auth_Signup::factory(); + $signup = $injector->getInstance('Horde_Core_Auth_Signup'); } $vars = Horde_Variables::getDefaultVariables(); diff --git a/horde/signup.php b/horde/signup.php index 74ecf5305..6411db64e 100644 --- a/horde/signup.php +++ b/horde/signup.php @@ -21,17 +21,17 @@ if ($conf['signup']['allow'] !== true || exit; } -$signup = Horde_Auth_Signup::factory(); -if (is_a($signup, 'PEAR_Error')) { - Horde::logMessage($signup, 'ERR'); +try { + $signup = $injector->getInstance('Horde_Core_Auth_Signup'); +} catch (Horde_Exception $e) { + Horde::logMessage($e, 'ERR'); $notification->push(_("User Registration is not properly configured for this site."), 'horde.error'); header('Location: ' . Horde::getServiceLink('login')->setRaw(true)); exit; } $vars = Horde_Variables::getDefaultVariables(); -require_once 'Horde/Auth/Signup.php'; -$formsignup = new HordeSignupForm($vars); +$formsignup = new Horde_Core_Auth_Signup_Form($vars); if ($formsignup->validate()) { $formsignup->getInfo($vars, $info); $success_message = null; -- 2.11.0