From: Jan Schneider Date: Fri, 10 Dec 2010 17:32:25 +0000 (+0100) Subject: PHP5/H4-ify X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=006e1347e2b8daa6766f675ab0374b0dd9db63e3;p=horde.git PHP5/H4-ify --- diff --git a/vilma/config/hooks.php.dist b/vilma/config/hooks.php.dist index 927602c94..062ebd19a 100644 --- a/vilma/config/hooks.php.dist +++ b/vilma/config/hooks.php.dist @@ -19,7 +19,7 @@ // "control/locals" file on an interval from cron(8) using some kind of script // to pull a list of domains from Horde using (for example) XML-RPC. -// if (!function_exists('_vilma_hook_savedomain')) { +// if (!function_exists('_vilma_hook_saveDomain')) { // function _vilma_hook_savedomain($info = null) // { // if ($info === null || !isset($info['domain_name'])) { @@ -55,7 +55,7 @@ // This hook does the opposite of the above: Remove a domain from the // "control/locals" file. -// if (!function_exists('_vilma_hook_deletedomain')) { +// if (!function_exists('_vilma_hook_deleteDomain')) { // function _vilma_hook_deletedomain($domain = null) // { // if ($domain === null) { @@ -89,7 +89,7 @@ // This function will turn an array of additional LDAP attributes that will be // added to the attributes created by the LDAP driver. -//if (!function_exists('_vilma_hook_getldapattrs')) { +//if (!function_exists('_vilma_hook_getLDAPAttrs')) { // function _vilma_hook_getldapattrs($attrs) // { // $attrs['deliverymode'] = 'nolocal'; diff --git a/vilma/domains/delete.php b/vilma/domains/delete.php index 838298a42..2a0b66de4 100644 --- a/vilma/domains/delete.php +++ b/vilma/domains/delete.php @@ -11,45 +11,45 @@ require_once dirname(__FILE__) . '/../lib/Application.php'; $vilma = Horde_Registry::appInit('vilma'); -require_once VILMA_BASE . '/lib/Forms/DeleteDomainForm.php'; - /* Only admin should be using this. */ if (!Vilma::hasPermission($domain)) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } $vars = Horde_Variables::getDefaultVariables(); -$form = new DeleteDomainForm($vars); +try { + $form = new Vilma_Form_DeleteDomain($vars); +} catch (Exception $e) { + $notification->push($e); + Horde::url('domains/index.php', true)->redirect(); +} + +if ($vars->get('submitbutton') == _("Do not delete")) { + $notification->push(_("Domain not deleted."), 'horde.message'); + Horde::url('domains/index.php', true)->redirect(); +} if ($vars->get('submitbutton') == _("Delete")) { if ($form->validate($vars)) { $form->getInfo($vars, $info); - $delete = $vilma->driver->deleteDomain($info['domain_id']); - if (is_a($delete, 'PEAR_Error')) { - Horde::logMessage($delete, 'ERR'); - $notification->push(sprintf(_("Error deleting domain. %s."), $delete->getMessage()), 'horde.error'); - } else { + try { + $delete = $vilma->driver->deleteDomain($info['domain_id']); $notification->push(_("Domain deleted."), 'horde.success'); Horde::url('domains/index.php', true)->redirect(); + } catch (Exception $e) { + $notification->push(sprintf(_("Error deleting domain. %s."), $e->getMessage()), 'horde.error'); } } -} elseif ($vars->get('submitbutton') == _("Do not delete")) { - $notification->push(_("Domain not deleted."), 'horde.message'); - Horde::url('domains/index.php', true)->redirect(); } /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; $renderer = new Horde_Form_Renderer(); +$template = $injector->createInstance('Horde_Template'); Horde::startBuffer(); $form->renderActive($renderer, $vars, 'delete.php', 'post'); -$main = Horde::endBuffer(); - -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); - +$template->set('main', Horde::endBuffer()); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); $template->set('notify', Horde::endBuffer()); diff --git a/vilma/domains/edit.php b/vilma/domains/edit.php index ec2646376..3199151c4 100644 --- a/vilma/domains/edit.php +++ b/vilma/domains/edit.php @@ -11,42 +11,39 @@ require_once dirname(__FILE__) . '/../lib/Application.php'; $vilma = Horde_Registry::appInit('vilma'); -require_once VILMA_BASE . '/lib/Forms/EditDomainForm.php'; - /* Only admin should be using this. */ if (!Vilma::hasPermission($domain)) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } -//$domain_id = Horde_Util::getFormData('domain_id'); $vars = Horde_Variables::getDefaultVariables(); -$form = new EditDomainForm($vars); +try { + $form = new Vilma_Form_EditDomain($vars); +} catch (Exception $e) { + $notification->push($e); + Horde::url('domains/index.php', true)->redirect(); +} if ($form->validate($vars)) { $form->getInfo($vars, $info); $info['name'] = Horde_String::lower($info['name']); - $domain_id = $vilma->driver->saveDomain($info); - if (is_a($domain_id, 'PEAR_Error')) { - Horde::logMessage($domain_id, 'ERR'); - $notification->push(sprintf(_("Error saving domain: %s."), $domain_id->getMessage()), 'horde.error'); - } else { + try { + $domain_id = $vilma->driver->saveDomain($info); $notification->push(_("Domain saved."), 'horde.success'); Horde::url('domains/index.php', true)->redirect(); + } catch (Exception $e) { + $notification->push(sprintf(_("Error saving domain: %s."), $e->getMessage()), 'horde.error'); } } /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; $renderer = new Horde_Form_Renderer(); +$template = $injector->createInstance('Horde_Template'); Horde::startBuffer(); $form->renderActive($renderer, $vars, 'edit.php', 'post'); -$main = Horde::endBuffer(); - -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); - +$template->set('main', Horde::endBuffer()); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); $template->set('notify', Horde::endBuffer()); diff --git a/vilma/domains/index.php b/vilma/domains/index.php index f7042c162..1d90ff2d0 100644 --- a/vilma/domains/index.php +++ b/vilma/domains/index.php @@ -17,28 +17,29 @@ if (!Vilma::hasPermission()) { } // Having a current domain doesn't make sense on this page -Vilma::setCurDomain(false); +Vilma::setCurDomain(); -$domains = $vilma->driver->getDomains(); -if (is_a($domains, 'PEAR_Error')) { - $notification->push($domains, 'horde.error'); +try { + $domains = $vilma->driver->getDomains(); +} catch (Exception $e) { + $notification->push($e, 'horde.error'); $domains = array(); } -foreach ($domains as $id => $domain) { - $url = Horde::url('domains/edit.php'); - $domains[$id]['edit_url'] = Horde_Util::addParameter($url, 'domain_id', $domain['domain_id']); - $url = Horde::url('domains/delete.php'); - $domains[$id]['del_url'] = Horde_Util::addParameter($url, 'domain_id', $domain['domain_id']); - $url = Horde::url('users/index.php'); - $domains[$id]['view_url'] = Horde_Util::addParameter($url, 'domain_id', $domain['domain_id']); + +$editurl = Horde::url('domains/edit.php'); +$deleteurl = Horde::url('domains/delete.php'); +$userurl = Horde::url('users/index.php'); +foreach ($domains as &$domain) { + $domain['edit_url'] = $editurl->copy()->add('domain_id', $domain['domain_id']); + $domain['del_url'] = $deleteurl->copy()->add('domain_id', $domain['domain_id']); + $domain['view_url'] = $userurl->copy()->add('domain_id', $domain['domain_id']); } /* Set up the template fields. */ $template = $injector->createInstance('Horde_Template'); $template->setOption('gettext', true); -$template->set('domains', $domains, true); +$template->set('domains', $domains); $template->set('menu', Horde::menu()); - Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); $template->set('notify', Horde::endBuffer()); diff --git a/vilma/lib/Application.php b/vilma/lib/Application.php index 732b6d343..53fe8c55f 100644 --- a/vilma/lib/Application.php +++ b/vilma/lib/Application.php @@ -49,7 +49,7 @@ class Vilma_Application extends Horde_Registry_Application protected function _init() { - $this->driver = Vilma_Driver::singleton(); + $this->driver = Vilma_Driver::factory(); // Get the currently active domain, possibly storing a change into the // session. diff --git a/vilma/lib/Driver.php b/vilma/lib/Driver.php index c90459593..276cd1118 100644 --- a/vilma/lib/Driver.php +++ b/vilma/lib/Driver.php @@ -5,8 +5,8 @@ * See the enclosed file LICENSE for license information (BSD). If you did not * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. * - * @author Marko Djukic - * @author Daniel Collins + * @author Marko Djukic + * @author Daniel Collins * @package Vilma */ abstract class Vilma_Driver @@ -16,133 +16,218 @@ abstract class Vilma_Driver * * @var array */ - var $_params = array(); + protected $_params = array(); /** - * Constructor + * Constructor. * * @param array $params Any parameters needed for this driver. */ - function Vilma_Driver($params) + public function __construct(array $params) { $this->_params = $params; } /** - * Returns a list of all users, aliases, or groups and forwards for a - * domain. + * Returns the list of domains from the backend. * - * @param string $domain Domain on which to search. - * @param string $type Only return a specific type. One of 'all', - * 'user', 'alias','forward', or 'group'. - * @param string $key Sort list by this key. - * @param integer $direction Sort direction. + * @return array All the domains and their data in an array. + */ + abstract public function getDomains(); + + /** + * Returns the specified domain information from the backend. * - * @return array Account information for this domain + * @param integer $domain_id The id of the domain to fetch. + * + * @return array The domain's information in an array. */ - public function getAddresses($domain, $type = 'all', $key = 'user_name', - $direction = 0) - { - $addresses = $this->_getAddresses($domain, $type); - Horde_Array::arraySort($addresses, $key, $direction, true); - return $addresses; - } + abstract public function getDomain($domain_id); /** - * Returns a list of all users, aliases, or groups and forwards for a - * domain. + * Given a domain name returns the information from the backend. * - * @param string $domain Domain on which to search. - * @param string $type Only return a specific type. One of 'all', - * 'user', 'alias','forward', or 'group'. - * @param string $key Sort list by this key. - * @param integer $direction Sort direction. + * @param string $name The name of the domain to fetch. * - * @return array Account information for this domain + * @return array The domain's information in an array. */ - abstract protected function _getAddresses($domain, $type = 'all'); + abstract public function getDomainByName($domain_name); /** - * Returns all the users sorted by domain and as arrays of each domain. + * Saves a domain with the provided information. * - * @return array An array of domains then users for each domain. + * @param array $info Array of details to save the domain. + * + * @throws Vilma_Exception */ - function getAllUsers() + public function saveDomain($info) { - /* Get all users from backend. */ - $users = &$this->getUsers(); + $this->_saveDomain($info); + Horde::callHook('saveDomain', array($info), 'vilma'); + } - /* Determine the domain for each user and plug into array by domain. */ - $users_by_domain = array(); + /** + * Saves a domain with the provided information. + * + * @param array $info Array of details to save the domain. + */ + abstract protected function _saveDomain($info); + + /** + * Deletes a domain and all the users and virtuals within it. + * + * @param integer $domain_id The id of the domain to delete. + * + * @throws Vilma_Exception + */ + public function deleteDomain($domain_id) + { + $domain_record = $this->getDomain($domain_id); + $users = $this->getUsers($domain_record['domain_name']); foreach ($users as $user) { - $domain_name = Vilma::stripDomain($user['user_name']); - $users_by_domain[$domain_name][] = $user; + $this->_deleteUser($user['user_id']); } + $this->_deleteDomain($domain_id); + Horde::callHook('deleteDomain', array($domain_record['domain_name']), 'vilma'); + } - /* Sort by domain. */ - ksort($users_by_domain); - /* Sort each domain's users by user name. */ - require_once 'Horde/Array.php'; - foreach ($users_by_domain as $key => $val) { - Horde_Array::arraySort($users_by_domain[$key], 'user_name'); - } + /** + * Deletes a domain. + * + * @param integer $domain_id The id of the domain to delete. + * + * @throws Vilma_Exception + */ + abstract protected function _deleteDomain($domain_id); - return $users_by_domain; + /** + * Returns the user who is the domain administrator. + * + * @todo This should be replaced by moving all permissions into Horde + * permissions. + * + * @param string $domain_name The name of the domain for which to + * return the administrator. + * + * @return string The domain adminstrator. + * @throws Vilma_Exception + */ + public function getDomainAdmin($domain_name) + { + $domain = $this->getDomainByName($domain_name); + return $domain['domain_admin']; } /** + * Returns the configured quota for this domain. + * + * @param string $domain_name The name of the domain for which to + * return the quota. + * + * @return integer The domain quota. + * @throws Vilma_Exception + */ + public function getDomainQuota($domain_name) + { + $domain = $this->getDomainByName($domain_name); + return $domain['domain_quota']; + } + + /** + * Returns the maximum number of users allowed for a given domain. + * + * @param string $domain_name The name of the domain for which to + * return the maximum users. + * + * @return integer The maximum number of allowed users. + * @throws Vilma_Exception + */ + public function getDomainMaxUsers($domain_name) + { + $domain = $this->getDomainByName($domain_name); + return $domain['max_users']; + } + + /** + * Returns the current number of users for a domain. + * + * @param string $domain_name The name of the domain for which to + * get the current number of users. + * + * @return integer The current number of users. + */ + abstract public function getDomainNumUsers($domain_name); + + /** * Checks if the given domain is below the maximum allowed users. * * @param string $domain The domain name to check. * * @return boolean True if the domain does not have a maximum limit (0) or * current number of users is below the maximum number - * allowed. Otherwise false. + * allowed. */ - function isBelowMaxUsers($domain) + public function isBelowMaxUsers($domain) { /* Get the maximum number of users for this domain. */ $max_users = $this->getDomainMaxUsers($domain); - if ($max_users == '0') { + if (!$max_users) { /* No maximum. */ return true; } /* Get the current number of users. */ - $num_users = $this->getDomainNumUsers($domain); - - return ($num_users < $max_users); + return $this->getDomainNumUsers($domain) < $max_users; } /** - * Gets an array of information related to the address passed in. - * This method may be overridden by the backend driver if there is a more - * efficient way to do this than a linear array search + * Returns all available users, if a domain name is passed then limit the + * list of users only to those users. * - * @param string $address Address for which information will be pulled - * @param string $type Address type to request - * One of 'user', 'alias', 'grpfwd' or 'any' - * Defaults to 'any' + * @param string $domain The name of the domain for which to fetch the + * users. * - * @return mixed Array of user information on success, empty array - * if the user does not exist, PEAR_Error on failure + * @return array The available users and their stored information. + * @throws Vilma_Exception + */ + abstract public function getUsers($domain = null); + + /** + * Returns all the users sorted by domain and as arrays of each domain. + * + * @return array An array of domains then users for each domain. */ - function getAddressInfo($address, $type = 'all') + public function getAllUsers() { - Horde::logMessage("Get Addresses Called for $domain with type $type and key $key", 'DEBUG'); - $domain = Vilma::stripDomain($address); - $addresses = $this->getAddresses($domain, $type); - foreach($addresses as $addrinfo) { - if ($addrinfo['id'] == $address) { - return $addrinfo; - } else if ($addrinfo['address'] == $address) { - return $addrinfo; - } + /* Determine the domain for each user and plug into array by domain. */ + $users = array(); + foreach ($this->getUsers() as $user) { + $domain = Vilma::stripDomain($user['user_name']); + $users[$domain][] = $user; } - throw new Vilma_Exception(sprintf(_("No such address %s of type %s found."), $address, $type)); + + /* Sort by domain. */ + ksort($users); + + /* Sort each domain's users by user name. */ + foreach ($users as $key => $val) { + Horde_Array::arraySort($users[$key], 'user_name'); + } + + return $users; } /** + * Returns the user information for a given user id. + * + * @param integer $user_id The id of the user for which to fetch + * information. + * + * @return array The user information. + */ + abstract public function getUser($user_id); + + /** * Does a series of checks for a given user to determine the status. * * @param array $user The user's details in an array as returned by the @@ -151,33 +236,28 @@ abstract class Vilma_Driver * @return array Either an array of error messages found during the checks * or an array with a single element stating that the user * is ready. + * @throws Vilma_Exception if an error occurs looking up the user status. */ - function getUserStatus($user) + public function getUserStatus($user) { /* Some needed vars. */ - $no_error = true; + $error = false; $status = array(); $domain_name = Vilma::stripDomain($user['user_name']); $user_name = Vilma::stripUser($user['user_name']); /* Check if user enabled. */ if ($user['user_enabled'] !== 'active') { - $no_error = false; + $error = true; $err_msg = _("User disabled."); $status[] = Horde::img('alerts/error.png', $err_msg) . ' ' . $err_msg; } /* Check if mailbox exists. */ - $mailboxes = &Vilma::getMailboxDriver(); - if (is_a($mailboxes, 'PEAR_Error')) { - $no_error = false; - $err_msg = $mailboxes->getMessage(); - $status[] = Horde::img('alerts/warning.png', $err_msg) . ' ' . $err_msg; - } try { - $mailboxes->checkMailbox($user_name, $domain_name); + Vilma_MailboxDriver::factory()->checkMailbox($user_name, $domain_name); } catch (Exception $result) { - $no_error = false; + $error = true; $err_msg = $result->getMessage(); $status[] = Horde::img('alerts/warning.png', $err_msg) . ' ' . $err_msg; } @@ -186,112 +266,30 @@ abstract class Vilma_Driver /* If no errors have been found output a success message for this * user's status. */ - if ($no_error) { + if (!$error) { $msg = _("User ready."); $status = array(Horde::img('alerts/success.png', $msg) . ' ' . $msg); } - return $status; - } - - /* Saves or creates alias records for a given user. - * - * @param array info The info used to store the information. - * Required fields are: - * 'address' => The destination address (used for LDAP ID lookup) - * 'alias_address' => The alias to create or the new data for the modified entry - * 'alias' => The alias we are modifying, if we are modifying an existing one. - */ - function saveAlias(&$info) - { - Horde::logMessage("saveAlias called with info: " . print_r($info, true), 'DEBUG'); - $result = $this->_saveAlias($info); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - return true; - } - - /* Deletes alias records for a given user. - * - * @param array info The info used to store the information. - * Required fields are: - * 'address' => The destination address (used for LDAP ID lookup) - * 'alias' => The alias we are deleting. - */ - function deleteAlias(&$info) - { - Horde::logMessage("deleteAlias called with info: " . print_r($info, true), 'DEBUG'); - $result = $this->_deleteAlias($info); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - return true; - } - /* Saves or creates forward records for a given user. - * - * @param array info The info used to store the information. - * Required fields are: - * 'address' => The destination address (used for LDAP ID lookup) - * 'forward_address' => The forward to create or the new data for the modified entry - * 'forward' => The forward we are modifying, if we are modifying an existing one. - */ - function saveForward(&$info) - { - Horde::logMessage("saveForward called with info: " . print_r($info, true), 'DEBUG'); - $result = $this->_saveForward($info); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - return true; + return $status; } - /* Deletes forward records for a given user. - * - * @param array info The info used to store the information. - * Required fields are: - * 'address' => The destination address (used for LDAP ID lookup) - * 'forward' => The forward we are deleting. + /** + * @throws Vilma_Exception */ - function deleteForward(&$info) + public function saveUser($info) { - Horde::logMessage("deleteForward called with info: " . print_r($info, true), 'DEBUG'); - $result = $this->_deleteForwrd($info); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - return true; - } - - function saveUser(&$info) - { - $create = false; - if (empty($info['user_id'])) { - $create = true; - } - - $result = $this->_saveUser($info); - if (is_a($result, 'PEAR_Error')) { - return $result; - } + $create = empty($info['user_id']); + $info['user_id'] = $this->_saveUser($info); if ($create) { - $mailboxes = &Vilma::getMailboxDriver(); - if (is_a($mailboxes, 'PEAR_Error')) { - $this->_deleteUser($result['user_id']); - return $mailboxes; - } - - $mailbox = $mailboxes->createMailbox(Vilma::stripUser($info['user_name']), Vilma::stripDomain($info['user_name'])); - if (is_a($mailbox, 'PEAR_Error')) { - //echo $mailbox->getMessage() . '
'; - //No 'system_user' parameter specified to maildrop driver. - //$this->_deleteUser($result['user_id']); - return $mailbox; + try { + Vilma_MailboxDriver::factory() + ->createMailbox(Vilma::stripUser($info['user_name']), + Vilma::stripDomain($info['user_name'])); + } catch (Exception $e) { + $this->_deleteUser($info['user_id']); + throw $e; } } @@ -306,232 +304,235 @@ abstract class Vilma_Driver throw new Vilma_Exception(_("Error running authentication update script.")); } if ($ec != 0) { - if (empty($msg)) { - $msg = _("Unknown error running authentication update script."); - } - throw new Vilma_Exception($msg); + throw new Vilma_Exception(_("Unknown error running authentication update script.")); } } - - return true; } - function deleteUser($user_id) + /** + * Saves a user to the backend. + * + * @param array $info The user information to save. + * + * @return string The user ID. + * @throws Vilma_Exception + */ + abstract protected function _saveUser($info); + + /** + * Deletes a user. + * + * @param integer $user_id The id of the user to delete. + * + * @throws Vilma_Exception + */ + abstract public function deleteUser($user_id); + + public function getUserFormAttributes() { - throw new Vilma_Exception(_("Vilma_Driver::deleteUser(): Method Not Implemented.")); } /** - * Saves a given domain with the provided information. + * Returns a list of all users, aliases, or groups and forwards for a + * domain. * - * @param array $info Array of details to save the domain + * @param string $domain Domain on which to search. + * @param string $type Only return a specific type. One of 'all', + * 'user', 'alias', 'forward', or 'group'. + * @param string $key Sort list by this key. + * @param integer $direction Sort direction. * - * @return mixed True on success, or PEAR_Error on failure. + * @return array Account information for this domain. */ - function saveDomain(&$info) + public function getAddresses($domain, $type = 'all', $key = 'user_name', + $direction = 0) { - $domain_id = $this->_saveDomain($info); - if (is_a($domain_id, 'PEAR_Error')) { - return $domain_id; - } + $addresses = $this->_getAddresses($domain, $type); + Horde_Array::arraySort($addresses, $key, $direction, true); + return $addresses; + } - $ret = Horde::callHook('_vilma_hook_savedomain', array($info), 'vilma'); - if (!$ret) { - throw new Vilma_Exception(_("Domain added but an error was encountered while calling the configured hook. Contact your administrator for futher assistance.")); - } + /** + * Returns a list of all users, aliases, or groups and forwards for a + * domain. + * + * @param string $domain Domain on which to search. + * @param string $type Only return a specific type. One of 'all', + * 'user', 'alias','forward', or 'group'. + * @param string $key Sort list by this key. + * @param integer $direction Sort direction. + * + * @return array Account information for this domain. + */ + abstract protected function _getAddresses($domain, $type = 'all'); - return $domain_id; + /** + * Returns an array of information related to the address passed in. + * + * This method may be overridden by the backend driver if there is a more + * efficient way to do this than a linear array search. + * + * @param string $address Address for which information will be pulled. + * @param string $type Address type to request. + * One of 'all', 'user', 'alias', 'forward' or + * 'group'. + * + * @return array Array of user information on success or empty array + * if the user does not exist. + * @throws Vilma_Exception if address of that type doesn't exist. + */ + public function getAddressInfo($address, $type = 'all') + { + $domain = Vilma::stripDomain($address); + $addresses = $this->getAddresses($domain, $type); + foreach ($addresses as $addrinfo) { + if ($addrinfo['id'] == $address || + $addrinfo['address'] == $address) { + return $addrinfo; + } + } + throw new Vilma_Exception(sprintf(_("No such address %s of type %s found."), $address, $type)); } /** - * Saves the domain record. + * Returns available virtual emails. * - * @abstract - * @param array $info Information to save the domain + * @param string $filter If passed a domain then return all virtual emails + * for the domain, otherwise if passed a user name + * return all virtual emails for that user. * - * @return mixed True on success, or PEAR_Error on failure. + * @return array The available virtual emails. */ - function _saveDomain(&$info) + public function getVirtuals($filter) { - throw new Vilma_Exception(_("Not implemented.")); } /** - * Deletes a given domain and all the users and virtuals under it. + * Returns information for a virtual id. * - * @param integer $domain_id The id of the domain to delete. + * @param integer $virtual_id The virtual id for which to return + * information. * - * @return mixed True on success, or PEAR_Error on failure. + * @return array The virtual email information. */ - function deleteDomain($domain_id) + public function getVirtual($virtual_id) { - $domain_record = $this->getDomain($domain_id); - if (is_a($domain_record, 'PEAR_Error')) { - return $domain_record; - } - - $users = $this->getUsers($domain_record['domain_name']); - if (is_a($users, 'PEAR_Error')) { - return $users; - } - - foreach ($users as $user) { - $this->_deleteUser($user['user_id']); - } - - $ret = $this->_deleteDomain($domain_id); - if (is_a($ret, 'PEAR_Error')) { - return $ret; - } - - $ret = Horde::callHook('_vilma_hook_deletedomain', - array($domain_record['domain_name']), - 'vilma'); - if (!$ret) { - throw new Vilma_Exception(_("Error while calling hook to delete domain.")); - } } /** - * Deletes the domain record. + * Saves virtual email address to the backend. * - * @abstract - * @param integer $domain_id The ID of the domain to delete. + * @param array $info The virtual email data. + * @param string $domain The name of the domain for this virtual email. * - * @return mixed True on success, or PEAR_Error on failure. + * @throws Vilma_Exception */ - function _deleteDomain($domain_id) + public function saveVirtual($info, $domain) { - throw new Vilma_Exception(_("Not implemented.")); } /** - * Get the user who is the domain admin. + * Deletes a virtual email. * - * @todo This should be replaced by moving all permissions into Horde - * permissions. + * @param integer $virtual_id The id of the virtual email to delete. */ - function getDomainAdmin($domain_name) + public function deleteVirtual($virtual_id) { - $domain = $this->getDomainByName($domain_name); - if (is_a($domain, 'PEAR_Error')) { - return $domain; - } - return $domain['domain_admin']; } /** - * Returns the configured quota for this domain. + * Saves or creates alias records for a user. * - * @param string $domain_name The name of the domain for which to - * return the quota. + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'alias_address': The alias to create or the new + * data for the modified entry. + * - 'alias': The alias we are modifying, if we are + * modifying an existing one. * - * @return integer The domain's quota. + * @throws Vilma_Exception */ - function getDomainQuota($domain_name) + public function saveAlias($info) { - $domain = $this->getDomainByName($domain_name); - if (is_a($domain, 'PEAR_Error')) { - return $domain; - } - return $domain['domain_quota']; } /** - * Returns the maximum number of users allowed for a given domain. + * Deletes alias records for a given user. * - * @param string $domain_name The name of the domain for which to - * return the maximum users. + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'alias': The alias we are deleting. * - * @return integer The maximum number of allowed users or PEAR_Error on - * failure. + * @throws Vilma_Exception */ - function getDomainMaxUsers($domain_name) + public function deleteAlias($info) { - $domain = $this->getDomainByName($domain_name); - if (is_a($domain, 'PEAR_Error')) { - return $domain; - } - return $domain['max_users']; } - public function getUserFormAttributes() + /** + * Saves or creates forward records for a given user. + * + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'forward_address': The forward to create or the + * new data for the modified entry. + * - 'forward': The forward we are modifying, if we are + * modifying an existing one. + * + * @throws Vilma_Exception + */ + public function saveForward($info) { } /** - * Attempts to return a concrete Vilma_Driver instance based on $driver. + * Deletes forward records for a given user. * - * @param string $driver The type of concrete Vilma_Driver subclass to - * return. - * @param array $params A hash containing any additional configuration or - * connection parameters a subclass might need. + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'forward': The forward we are deleting. * - * @return Vilma_Driver The newly created concrete Vilma_Driver instance, - * or false on error. * @throws Vilma_Exception */ - function factory($driver = null, $params = null) + public function deleteForward($info) { - if (is_null($driver)) { - $driver = $GLOBALS['conf']['storage']['driver']; - } - $driver = basename($driver); - - if (is_null($params)) { - $params = Horde::getDriverConfig('storage', $driver); - } - - include_once dirname(__FILE__) . '/Driver/' . $driver . '.php'; - $class = 'Vilma_Driver_' . $driver; - if (class_exists($class)) { - return new $class($params); - } - - throw new Vilma_Exception(sprintf(_("No such backend \"%s\" found"), $driver)); } /** - * Attempts to return a reference to a concrete Vilma_Driver instance - * based on $driver. - * - * It will only create a new instance if no Vilma_Driver instance with the - * same parameters currently exists. - * - * This should be used if multiple storage sources are required. - * - * This method must be invoked as: $var = &Vilma_Driver::singleton() + * Attempts to return a concrete Vilma_Driver instance based on $driver. * * @param string $driver The type of concrete Vilma_Driver subclass to * return. * @param array $params A hash containing any additional configuration or * connection parameters a subclass might need. * - * @return mixed The created concrete Vilma_Driver instance, or false on - * error. + * @return Vilma_Driver The newly created concrete Vilma_Driver instance. + * @throws Vilma_Exception */ - function &singleton($driver = null, $params = null) + static public function factory($driver = null, $params = null) { - static $instances; - if (is_null($driver)) { $driver = $GLOBALS['conf']['storage']['driver']; } + $driver = Horde_String::ucfirst(basename($driver)); if (is_null($params)) { $params = Horde::getDriverConfig('storage', $driver); } - if (!isset($instances)) { - $instances = array(); - } - - $signature = serialize(array($driver, $params)); - if (!isset($instances[$signature])) { - $instances[$signature] = Vilma_Driver::factory($driver, $params); + $class = 'Vilma_Driver_' . $driver; + if (class_exists($class)) { + return new $class($params); } - return $instances[$signature]; + throw new Vilma_Exception(sprintf(_("No such backend \"%s\" found"), $driver)); } - } diff --git a/vilma/lib/Driver/Qmailldap.php b/vilma/lib/Driver/Qmailldap.php new file mode 100644 index 000000000..9de822575 --- /dev/null +++ b/vilma/lib/Driver/Qmailldap.php @@ -0,0 +1,1020 @@ + + * + * See the enclosed file LICENSE for license information (BSD). If you did + * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. + * + * @author Ben Klang + * @author David Cummings + * @package Vilma + * @todo - Convert to Horde_Ldap + */ +class Vilma_Driver_Qmailldap extends Vilma_Driver_Sql +{ + /** + * Reference to initialized LDAP driver. + * + * @var resource + */ + protected $_ldap; + + /** + * Cache for retrieved getUsers() results. + * + * @var array + */ + protected $_users = array(); + + /** + * Map of internal field names to LDAP attribute names. + * + * @var array + */ + protected $_fieldmap = array( + 'address' => 'mail', + 'user_name' => 'uid', + 'user_crypt' => 'userpassword', + 'user_full_name' => 'cn', + 'user_uid' => 'qmailuid', + 'user_gid' => 'qmailgid', + 'user_home_dir' => 'homedirectory', + 'user_mail_dir' => 'mailmessagestore', + 'user_mail_quota_bytes' => 'mailquotasize', + 'user_mail_quota_count' => 'mailquotacount', + 'user_enabled' => 'accountstatus', + ); + + /** + * Constructor. + * + * @param array $params Any parameters needed for this driver. + */ + public function __construct($params) + { + $params = array_merge( + Horde::getDriverConfig('storage', 'sql'), + $params); + parent::__construct($params); + $this->_connect(); + } + + /** + * Deletes a domain. + * + * @todo Add logic to remove all users, aliases, and grpfwds for this + * domain. + * @todo Use parent::_deleteDomain() + * + * @param integer $domain_id The id of the domain to delete. + * + * @throws Vilma_Exception + */ + protected function _deleteDomain($domain_id) + { + $domain_record = $this->getDomain($domain_id); + $domain_name = $domain_record['domain_name']; + + /* Finally delete the domain. */ + $sql = 'DELETE FROM vilma_domains WHERE domain_id=?'; + $values = array((int)$domain_id); + + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->query($sql, $values); + } + + /** + * Returns the current number of users for a domain. + * + * @param string $domain_name The name of the domain for which to + * get the current number of users. + * + * @return integer The current number of users. + */ + public function getDomainNumUsers($domain_name) + { + return count($this->_getUsers($domain_name)); + } + + /** + * Returns all available users, if a domain name is passed then limit the + * list of users only to those users. + * + * @param string $domain The name of the domain for which to fetch the + * users. + * + * @return array The available users and their stored information. + * @throws Vilma_Exception + */ + public function getUsers($domain = null) + { + // Cache for multiple calls. + if (is_null($domain) && isset($this->_users['_all'])) { + return $this->_users['_all']; + } + + if (!is_null($domain) && isset($this->_users[$domain])) { + return $this->_users[$domain]; + } + + $filter = '(&'; + if (!is_null($domain)) { + $filter .= '(mail=*@' . $domain . ')'; + } else { + $domain = '_all'; + } + + // Make sure we don't get any forwards. + $filter .= '(!(mailForwardingAddress=*))'; + + // FIXME: Check/add configured filter instead of objectclasses + foreach ($this->_params['ldap']['objectclass'] as $objectclass) { + $filter .= '(objectClass=' . $objectclass . ')'; + } + $filter .= ')'; + + Horde::logMessage($filter, 'DEBUG'); + $res = ldap_search($this->_ldap, $this->_params['ldap']['basedn'], $filter); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error in LDAP search: %s"), ldap_error($this->LDAP))); + } + + $res = ldap_get_entries($this->_ldap, $res); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error in LDAP search: %s"), ldap_error($this->LDAP))); + } + + $this->_users[$domain] = array(); + // Can't use foreach because of the array format returned by LDAP driver + for ($i = 0; isset($res[$id]); $user = $res[$i++]) { + $info = array( + 'id' => $user['dn'], + 'address' => $user[$this->_fieldmap['address']][0], + 'type' => 'user', + 'user_name' => $user[$this->_fieldmap['user_name']][0]); + + // We likely don't have read permission on the crypted password so + // avoid any warnings/errors about missing array elements. + if (isset($user[$this->_fieldmap['user_crypt']])) { + $info['user_crypt'] = $user[$this->_fieldmap['user_crypt']][0]; + } else { + $info['user_crypt'] = ''; + } + $info['user_full_name'] = $user[$this->_fieldmap['user_full_name']][0]; + // Mute assignment errors on the following optional fields. + // These may not be present if the mail is only forwarded. + $info['user_uid'] = @$user[$this->_fieldmap['user_uid']][0]; + $info['user_gid'] = @$user[$this->_fieldmap['user_gid']][0]; + $info['user_home_dir'] = @$user[$this->_fieldmap['user_home_dir']][0]; + $info['user_mail_dir'] = @$user[$this->_fieldmap['user_mail_dir']][0]; + $info['user_mail_quota_bytes'] = @$user[$this->_fieldmap['user_mail_quota_bytes']][0]; + $info['user_mail_quota_count'] = @$user[$this->_fieldmap['user_mail_quota_count']][0]; + + // If accountStatus is blank it's the same as active. + if (!isset($user[$this->_fieldmap['user_enabled']][0]) || + $user[$this->_fieldmap['user_enabled']][0] == 'active') { + $info['user_enabled'] = 'active'; + } else { + // accountStatus can also be: + // noaccess (receives but cannot pick up mail) + // disabled (bounce incoming and deny pickup) + // deleted (bounce incoming but allow pickup) + $info['user_enabled'] = $user[$this->_fieldmap['user_enabled']][0]; + } + + $this->_users[$domain][$i] = $info; + } + + return $this->_users[$domain]; + } + + /** + * Returns the user information for a given user id. + * + * @param integer $user_id The id of the user for which to fetch + * information. + * + * @return array The user information. + */ + public function getUser($user_id) + { + $user = $this->getUserStatus($user_id); + if (is_array($user)) { + return $user; + } + throw new Vilma_Exception(_("Unable to qualify address.")); + } + + /** + * Saves a user to the backend. + * + * @param array $info The user information to save. + * + * @return array The user information. + * @throws Vilma_Exception + */ + protected function _saveUser($info) + { + switch ($info['mode']) { + case 'edit': + return $this->_updateUser($info); + case 'new': + return $this->_createUser($info); + } + + throw new Vilma_Exception(_("Unable to save user information.")); + } + + /** + * Updates a user in the backend. + * + * @param array $info The user information to save. + * + * @return array The user information. + * @throws Vilma_Exception + */ + protected function _updateUser($info) + { + $address = $info['address']; + if (empty($address)) { + $user_name = $info['user_name']; + $domain = $info['domain']; + if (empty($user_name)) { + throw new Vilma_Exception(_("Unable to acquire handle on address.")); + } + $address = $info['user_name'] . $info['domain']; + } + $addrinfo = $this->getAddressInfo($address); + $type = $addrinfo['type']; + if ($type != 'user') { + throw new Vilma_Exception(sprintf(_("Unable to save account of type \"%s\""), $type)); + } + + $user_info = $this->_searchForUser($address); + if ($res['count'] === 0) { + throw new Vilma_Exception(_("Error reading address information from backend.")); + } + + $objectClassData = null; + if (isset($user_info[0]['objectclass'])) { + $objectClassData = $user_info[0]['objectclass']; + } + + // Don't want to save this to LDAP. + unset($info['mode']); + + // Special case for the password: If it was provided, it needs + // to be crypted. Otherwise, ignore it. + if (isset($info['password'])) { + if (!empty($user['password'])) { + // FIXME: Allow choice of hash + $info['user_password'] = Horde_Auth::getCryptedPassowrd($info['password'], '', 'ssha', true); + } + unset($info['password']); + } + + $tmp['dn'] = $addrinfo['id']; + foreach ($info as $key => $val) { + $attr = $this->_fieldmap[$key]; + $tmp[$attr] = $val; + } + + // Bind with appropriate dn to give update access. + $res = ldap_bind($this->_ldap, $this->_params['ldap']['binddn'], + $this->_params['ldap']['bindpw']); + if (!$res) { + throw new Vilma_Exception(_("Unable to bind to the LDAP server. Check authentication credentials.")); + } + + // Prepare data. + $entry['cn'] = $info['user_full_name']; + // sn is not used operationally but we make an effort to be + // something sensical. No guarantees, though. + $entry['sn'] = array_pop(explode(' ', $info['user_full_name'])); + $entry['mail'] = $info['user_name'] . $info['domain']; + $entry['uid'] = $entry['mail']; + $entry['homeDirectory'] = '/srv/vhost/mail/' . $info['domain'] .'/' . $info['user_name']; + if ($type != 'group' && $type != 'forward') { + $entry['qmailUID'] = $entry['qmailGID'] = 8; + } + $entry['accountstatus'] = $info['user_enabled']; + if (isset($info['password']) && !empty($info['password'])) { + // FIXME: Allow choice of hash + $entry['userPassword'] = Horde_Auth::getCryptedPassword($info['password'], '', 'ssha', true); + } + if (isset($objectClassData)) { + array_shift($objectClassData); + $entry['objectclass'] = $objectClassData; + } else { + $entry['objectclass'] = array( + 'top', + 'person', + 'organizationalPerson', + 'inetOrgPerson', + 'hordePerson', + 'qmailUser'); + } + + // Stir in any site-local custom LDAP attributes. + $entry = Horde::callHook('getLDAPAttrs', array($entry), 'vilma'); + $rdn = 'mail=' . $entry['mail']; + $dn = $rdn . ',' . $this->_params['ldap']['basedn']; + $res = @ldap_modify($this->_ldap, $dn, $entry); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); + } + + return $dn; + } + + /** + * Creates a user in the backend. + * + * @param array $info The user information to save. + * + * @return array The user information. + * @throws Vilma_Exception + */ + protected function _createUser($info) + { + // Bind with appropriate dn to give update access. + $res = ldap_bind($this->_ldap, $this->_params['ldap']['binddn'], + $this->_params['ldap']['bindpw']); + if (!$res) { + throw new Vilma_Exception(_("Unable to bind to the LDAP server. Check authentication credentials.")); + } + + // Prepare data. + $entry['cn'] = $info['user_full_name']; + // sn is not used operationally but we make an effort to be + // something sensical. No guarantees, though. + $entry['sn'] = array_pop(explode(' ', $info['user_full_name'])); + $entry['mail'] = $info['user_name'] . '@' . $info['domain']; + // uid must match mail or SMTP auth fails. + $entry['uid'] = $entry['mail']; + $entry['homeDirectory'] = '/srv/vhost/mail/' . $info['domain'] .'/' . $info['user_name']; + $entry['qmailUID'] = $entry['qmailGID'] = 8; + $entry['objectclass'] = array( + 'top', + 'person', + 'organizationalPerson', + 'inetOrgPerson', + 'hordePerson', + 'qmailUser'); + $entry['accountstatus'] = $info['user_enabled']; + // FIXME: Allow choice of hash + $entry['userPassword'] = Horde_Auth::getCryptedPassword($info['password'], '', 'ssha', true); + + // Stir in any site-local custom LDAP attributes. + $entry = Horde::callHook('getLDAPAttrs', array($entry), 'vilma'); + $rdn = 'mail=' . $entry['mail']; + $dn = $rdn . ',' . $this->_params['ldap']['basedn']; + $res = @ldap_add($this->_ldap, $dn, $entry); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error adding account to LDAP: %s"), @ldap_error($this->_ldap))); + } + + return $dn; + } + + /** + * Deletes a user. + * + * @param integer $user_id The id of the user to delete. + * + * @throws Vilma_Exception + */ + public function deleteUser($user_id) + { + // Get the user's DN. + $filter = '(&'; + foreach ($this->_params['ldap']['objectclass'] as $objectclass) { + // Add each objectClass from parameters. + $filter .= '(objectclass=' . $objectclass . ')'; + } + $filter .= '(mail=' . $user_id . ')'; + $filter .= ')'; + + Horde::logMessage($filter, 'DEBUG'); + $res = @ldap_search($this->_ldap, $this->_params['ldap']['basedn'], $filter); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error searching LDAP: %s"), @ldap_error($this->_ldap))); + } + $res = @ldap_get_entries($this->_ldap, $res); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap))); + } + + if ($res['count'] === 0) { + throw new Vilma_Exception(_("Unable to acquire handle on DN. Aborting delete operation.")); + } + if ($res['count'] !== 1) { + throw new Vilma_Exception(_("More than one DN returned. Aborting delete operation.")); + } + + // We now have one unique DN to delete. + $res = @ldap_delete($this->_ldap, $res[0]['dn']); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error deleting account from LDAP: %s"), @ldap_error($this->_ldap))); + } + } + + public function getUserFormAttributes() + { + return array(array( + 'label' => _("Account Status"), + 'name' => 'user_enabled', + 'type' => 'enum', + 'required' => true, + 'readonly' => false, + 'description' => null, + 'params' => array( + array( + 'active' => _("Account is active"), + 'noaccess' => _("Disable Delivery Only"), + 'disabled' => _("Bounce Incoming Only"), + 'deleted' => _("Account is disabled"), + ), + ), + 'default' => 'active', + )); + } + + /** + * Returns a list of all users, aliases, or groups and forwards for a + * domain. + * + * @param string $domain Domain on which to search. + * @param string $type Only return a specific type. One of 'all', + * 'user', 'alias','forward', or 'group'. + * @param string $key Sort list by this key. + * @param integer $direction Sort direction. + * + * @return array Account information for this domain + */ + protected function _getAddresses($domain, $type = 'all') + { + $addresses = array(); + if ($type == 'all' || $type == 'user') { + $addresses += $this->_getUsers($domain); + } + if ($type == 'all' || $type == 'alias') { + $addresses += $this->_getAliases($domain); + } + if ($type == 'all' || $type == 'forward') { + $addresses += $this->_getGroupsAndForwards('forward', $domain); + } + if ($type == 'all' || $type == 'group') { + $addresses += $this->_getGroupsAndForwards('group', $domain); + } + return $addresses; + } + + /** + * Returns available email address aliases. + * + * @param string $target If passed a domain then return all alias emails + * for the domain, otherwise if passed a user name + * return all virtual emails for that user. + * + * @return array The used email aliases. + */ + protected function _getAliases($target = null) + { + // FIXME: Add static cache + + // FIXME: Add preconfigured filter from $this->_params['ldap'] + // Begin filter (cumulative AND). + $filter = '(&'; + foreach ($this->_params['ldap']['objectclass'] as $objectclass) { + // Add each objectClass from parameters + $filter .= '(objectClass=' . $objectclass . ')'; + } + + // Check if filtering only for domain. + if (strpos($target, '@') === false && !empty($target)) { + $filter .= '(mailAlternateAddress=*@' . $target . ')'; + } else { + // Otherwise filter for all aliases. + $filter .= '(mailAlternateAddress=*)'; + // Restrict the results to $target. + if (!empty($target)) { + // Add user's email. + $filter .= '(mail=' . $target . ')'; + } + } + // End filter. + $filter .= ')'; + + Horde::logMessage($filter, 'DEBUG'); + $res = @ldap_search($this->_ldap, $this->_params['ldap']['basedn'], $filter); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error searching LDAP: %s"), @ldap_error($this->_ldap))); + } + + $res = @ldap_get_entries($this->_ldap, $res); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap))); + } + + $aliases = array(); + // Can't use foreach because of the array format returned by LDAP driver + for ($e = 0; isset($res[$e]); $entry = $res[$e++]) { + // If accountStatus is blank it's the same as active + if (!isset($entry[$this->_fieldmap['user_enabled']][0]) || + $entry[$this->_fieldmap['user_enabled']][0] == 'active') { + $curstatus = 'active'; + } else { + // accountStatus can also be: + // noaccess (receives but cannot pick up mail) + // disabled (bounce incoming and deny pickup) + // deleted (bounce incoming but allow pickup) + $curstatus = $entry[$this->_fieldmap['user_enabled']][0]; + } + for ($a = 0; isset($entry['mailalternateaddress'][$a]); $mail = @$entry['mailalternateaddress'][$a++]) { + $aliases[] = array( + 'id' => $mail, + 'type' => 'alias', + 'user_name' => $mail, + 'user_full_name' => sprintf(_("Alias for %s"), $entry['mail'][0]), + 'destination' => $entry['mail'][0], + 'user_enabled' => $curstatus); + } + } + + return $aliases; + } + + /** + * Returns all available groups and forwards unless otherwise specified. + * + * If a domain name is passed then limit the results to groups or forwards + * in that domain. + * + * @param string $acquire The default behavior is to acquire both + * groups and forwards; a value of 'group' + * will return only groups and a value of + * 'forward' will return only forwards. + * @param string $domain The name of the domain from which to fetch. + * + * @return array The available groups and forwards with details. + */ + protected function _getGroupsAndForwards($acquire = null, $domain = null) + { + // FIXME: Add preconfigured filter from $this->_params['ldap'] + // Begin filter (cumulative AND). + $filter = '(&'; + foreach ($this->_params['ldap']['objectclass'] as $objectclass) { + // Add each objectClass from parameters. + $filter .= '(objectClass=' . $objectclass . ')'; + } + + // Only return results which have a forward configured. + $filter .= '(mailForwardingAddress=*)'; + + if (!empty($domain)) { + // mail or mailAlternateAddress. + $filter .= '(|'; + $filter .= '(mail=*@' . $domain . ')'; + $filter .= '(mailAlternateAddress=*@' . $domain . ')'; + $filter .= ')'; + } else { + $domain = '_all'; + } + + // End filter + $filter .= ')'; + + Horde::logMessage($filter, 'DEBUG'); + $res = @ldap_search($this->_ldap, $this->_params['ldap']['basedn'], $filter); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error searching LDAP: %s"), @ldap_error($this->_ldap))); + } + + $res = @ldap_get_entries($this->_ldap, $res); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap))); + } + + $grpfwds[$domain] = array(); + // Can't use foreach because of the array format returned by LDAP driver + for ($e = 0; isset($res[$e]); $entry = $res[$e++]) { + $targets = array(); + for ($a = 0; isset($res[$e]['mailforwardingaddress'][$a]); $attr = $res[$e]['mailforwardingaddress'][$a++]) { + $targets[] = $attr; + } + $type = $entry['mailforwardingaddress']['count']; + if ($type > 1) { + $type = 'group'; + } else { + $type = 'forward'; + } + if ($acquire == 'all' || $type == $acquire) { + $grpfwds[$domain][$e] = array( + 'id' => $entry['dn'], + 'type' => $type, + 'address' => $entry[$this->_fieldmap['address']][0], + 'targets' => $targets, + 'user_name' => $entry[$this->_fieldmap['user_name']][0], + 'user_full_name' => @$entry[$this->_fieldmap['user_name']][0], + ); + // If accountStatus is blank it's the same as active + if (!isset($entry[$this->_fieldmap['user_enabled']][0]) || + $entry[$this->_fieldmap['user_enabled']][0] == 'active') { + $grpfwds[$domain][$e]['user_enabled'] = 'active'; + } else { + // accountStatus can also be: + // noaccess (receives but cannot pick up mail) + // disabled (bounce incoming and deny pickup) + // deleted (bounce incoming but allow pickup) + $grpfwds[$domain][$e]['user_enabled'] = + $entry[$this->_fieldmap['user_enabled']][0]; + } + } + } + + return $grpfwds[$domain]; + } + + /** + * Returns an array of information related to the address passed in. + * + * @param string $address Address for which information will be pulled. + * @param string $type Address type to request. + * One of 'all', 'user', 'alias', 'forward' or + * 'group'. + * + * @return array Array of user information on success or empty array + * if the user does not exist. + * @throws Vilma_Exception if address of that type doesn't exist. + */ + public function getAddressInfo($address, $type = 'all') + { + if ($type != 'alias') { + return parent::getAddressInfo($address, $type); + } + + // FIXME: Which is faster? A linear array search or an LDAP search? + // I think LDAP in this case because we can't assume the domain. + // Begin filter (cumulative AND). + $filter = '(&'; + foreach ($this->_params['ldap']['objectclass'] as $objectclass) { + // Add each objectClass from parameters. + $filter .= '(objectClass=' . $objectclass . ')'; + } + $filter .= '(mailAlternateAddress=' . $address . ')'; + // End filter. + $filter .= ')'; + + Horde::logMessage($filter, 'DEBUG'); + $res = @ldap_search($this->_ldap, $this->_params['ldap']['basedn'], $filter); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error searching LDAP: %s"), @ldap_error($this->_ldap))); + } + $res = @ldap_get_entries($this->_ldap, $res); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap))); + } + + if ($res['count'] !== 1) { + throw new Vilma_Exception(_("More than one DN returned for this alias. Please contact an administrator to resolve this error.")); + } + + return array( + 'id' => $res[0]['dn'], + 'address' => $address, + 'destination' => $res[0]['mail'][0], + ); + } + + /** + * Saves or creates alias records for a user. + * + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'alias_address': The alias to create or the new + * data for the modified entry. + * - 'alias': The alias we are modifying, if we are + * modifying an existing one. + * + * @throws Vilma_Exception + */ + public function saveAlias($info) + { + $address = $info['address']; + if (!empty($info['alias'])) { + $alias = $info['alias']; + $create = false; + } else { + $create = true; + } + $alias_address = $info['alias_address']; + + $user_res = $this->_searchForUser($address); + if ($res['count'] === 0) { + throw new Vilma_Exception(_("Error reading address information from backend.")); + } + $user = $user_res[0]; + + // Retrieve the current MAA values. + if (isset($user_res[0]['mailalternateaddress'])) { + $maa = $user['mailalternateaddress']; + unset($maa['count']); + } else { + $maa = array(); + } + + $oldmaa = $maa; + if ($create) { + // Verify that it does not already exist. + if (in_array($alias_address, $maa)) { + throw new Vilma_Exception(_("That alias already exists!")); + } + + // Not there, we create it. + $maa[] = $alias_address; + } elseif ($alias != $alias_address) { + $key = array_search($alias, $maa); + if ($key === false) { + throw new Vilma_Exception(sprintf(_("Existing entry \"%s\" could not be found."), $alias)); + } + $maa[$key] = $alias_address; + } else { + return; + } + sort($maa); + + $dn = $user['dn']; + Horde::logMessage("UPDATING: $dn \nOld MAA: " . print_r($oldmaa, true) . "\nNew MAA: " . print_r($maa, true), 'DEBUG'); + + // Bind with appropriate dn to give update access. + $res = ldap_bind($this->_ldap, $this->_params['ldap']['binddn'], + $this->_params['ldap']['bindpw']); + if (!$res) { + throw new Vilma_Exception(_("Unable to bind to the LDAP server. Check authentication credentials.")); + } + + $entry['mailAlternateAddress'] = $maa; + $res = @ldap_modify($this->_ldap, $dn, $entry); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); + } + } + + /** + * Deletes alias records for a given user. + * + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'alias': The alias we are deleting. + * + * @throws Vilma_Exception + */ + public function deleteAlias($info) + { + $address = $info['address']; + $alias = $info['alias']; + + $user_res = $this->_searchForUser($address); + if ($res['count'] === 0) { + throw new Vilma_Exception(_("Error reading address information from backend.")); + } + $user = $user_res[0]; + + // Retrieve the current MAA values. + if (!isset($user['mailalternateaddress'])) { + return; + } + + $maa = $user['mailalternateaddress']; + unset($maa['count']); + $oldmaa = $maa; + $key = array_search($alias, $maa); + if ($key === false) { + return; + } + + unset($maa[$key]); + sort($maa); + + $dn = $user['dn']; + Horde::logMessage("UPDATING: $dn \nOld MAA: " . print_r($oldmaa, true) . "\nNew MAA: " . print_r($maa, true), 'DEBUG'); + + // Bind with appropriate dn to give update access. + $res = ldap_bind($this->_ldap, $this->_params['ldap']['binddn'], + $this->_params['ldap']['bindpw']); + if (!$res) { + throw new Vilma_Exception(_("Unable to bind to the LDAP server. Check authentication credentials.")); + } + + $entry['mailAlternateAddress'] = $maa; + $res = @ldap_modify($this->_ldap, $dn, $entry); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); + } + } + + /** + * Saves or creates forward records for a given user. + * + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'forward_address': The forward to create or the + * new data for the modified entry. + * - 'forward': The forward we are modifying, if we are + * modifying an existing one. + * + * @throws Vilma_Exception + */ + public function saveForward($info) + { + $address = $info['address']; + if (!empty($info['forward'])) { + $forward = $info['forward']; + $create = false; + } else { + $create = true; + } + $forward_address = $info['forward_address']; + + $user_res = $this->_searchForUser($address); + if ($res['count'] === 0) { + throw new Vilma_Exception(_("Error reading address information from backend.")); + } + $user = $user_res[0]; + + // Retrieve the current MAA values. + if (isset($user['mailforwardingaddress'])) { + $mfa = $user['mailforwardingaddress']; + unset($mfa['count']); + } else { + $mfa = array(); + } + + $oldmfa = $mfa; + if ($create) { + // Verify that it does not already exist + if (in_array($forward_address, $mfa)) { + throw new Vilma_Exception(sprintf(_("That forward, \"%s\", already exists!"), $forward_address)); + } + + // Not there, we create it. + $mfa[] = $forward_address; + } elseif ($forward != $forward_address) { + $key = array_search($forward, $mfa); + if ($key === false) { + throw new Vilma_Exception(sprintf(_("Existing entry \"%s\" could not be found."), $forward)); + } + $mfa[$key] = $forward_address; + } else { + return; + } + sort($mfa); + + $dn = $user['dn']; + Horde::logMessage("UPDATING: $dn \nOld MFA: " . print_r($oldmfa, true) . "\nNew MFA: " . print_r($mfa, true), 'DEBUG'); + + // Bind with appropriate dn to give update access. + $res = ldap_bind($this->_ldap, $this->_params['ldap']['binddn'], + $this->_params['ldap']['bindpw']); + if (!$res) { + throw new Vilma_Exception(_("Unable to bind to the LDAP server. Check authentication credentials.")); + } + + $entry['mailForwardingAddress'] = $mfa; + $res = @ldap_modify($this->_ldap, $dn, $entry); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); + } + } + + /** + * Deletes forward records for a given user. + * + * @param array $info The info used to store the information. + * Required fields are: + * - 'address': The destination address (used for LDAP + * ID lookup). + * - 'forward': The forward we are deleting. + * + * @throws Vilma_Exception + */ + public function deleteForward($info) + { + $address = $info['address']; + $forward = $info['forward']; + + $user_res = $this->_searchForUser($address); + if ($res['count'] === 0) { + throw new Vilma_Exception(_("Error reading address information from backend.")); + } + $user = $user_res[0]; + + // Retrieve the current MFA values. + if (!isset($user['mailforwardingaddress'])) { + return; + } + + $mfa = $user['mailforwardingaddress']; + unset($mfa['count']); + $oldmfa = $mfa; + $key = array_search($forward, $mfa); + if ($key === false) { + return; + } + unset($mfa[$key]); + sort($mfa); + + $dn = $user['dn']; + Horde::logMessage("UPDATING: $dn \nOld MFA: " . print_r($oldmfa, true) . "\nNew MFA: " . print_r($mfa, true), 'DEBUG'); + // Bind with appropriate dn to give update access. + $res = ldap_bind($this->_ldap, $this->_params['ldap']['binddn'], + $this->_params['ldap']['bindpw']); + if (!$res) { + throw new Vilma_Exception(_("Unable to bind to the LDAP server. Check authentication credentials.")); + } + + $entry['mailForwardingAddress'] = $mfa; + $res = @ldap_modify($this->_ldap, $dn, $entry); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); + } + } + + /** + * Searchs for a given email account. + * + * @param string $email_id The id of the account to be searched for. + * + * @return array Data for given email account on success or no + * information found. + */ + protected function _searchForUser($email_id) + { + // Get the user's DN + $filter = '(&'; + foreach ($this->_params['ldap']['objectclass'] as $objectclass) { + // Add each objectClass from parameters. + $filter .= '(objectclass=' . $objectclass . ')'; + } + $filter .= '(mail=' . $email_id . '))'; + + Horde::logMessage($filter, 'DEBUG'); + $res = @ldap_search($this->_ldap, $this->_params['ldap']['basedn'], $filter); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error searching LDAP: %s"), @ldap_error($this->_ldap))); + } + $res = @ldap_get_entries($this->_ldap, $res); + if ($res === false) { + throw new Vilma_Exception(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap))); + } + + if ($res['count'] === 0) { + throw new Vilma_Exception(_("Unable to acquire handle on DN. Aborting delete operation.")); + } + if($res['count'] !== 1) { + throw new Vilma_Exception(_("More than one DN returned. Aborting delete operation.")); + } + + return $res; + } + + function _connect() + { + if (!is_null($this->_ldap)) { + return; + } + + Horde::assertDriverConfig($this->_params['ldap'], 'storage', + array('ldaphost', 'basedn', 'binddn', 'dn')); + + if (!isset($this->_params['ldap']['bindpw'])) { + $this->_params['ldap']['bindpw'] = ''; + } + + $port = isset($this->_params['ldap']['port']) + ? $this->_params['ldap']['port'] + : 389; + + $this->_ldap = ldap_connect($this->_params['ldap']['ldaphost'], $port); + if (!$this->_ldap) { + throw new Vilma_Exception("Unable to connect to LDAP server $hostname on $port"); + } + $res = ldap_set_option($this->_ldap, LDAP_OPT_PROTOCOL_VERSION, + $this->_params['ldap']['version']); + if (!$res) { + throw new Vilma_Exception(_("Unable to set LDAP protocol version")); + } + $res = ldap_bind($this->_ldap, $this->_params['ldap']['binddn'], + $this->_params['ldap']['bindpw']); + if (!$res) { + throw new Vilma_Exception(_("Unable to bind to the LDAP server. Check authentication credentials.")); + } + } +} diff --git a/vilma/lib/Driver/Sql.php b/vilma/lib/Driver/Sql.php new file mode 100644 index 000000000..fb4d999f8 --- /dev/null +++ b/vilma/lib/Driver/Sql.php @@ -0,0 +1,615 @@ + + * @package Vilma + */ +class Vilma_Driver_sql extends Vilma_Driver +{ + /** + * @var DB + */ + protected $_db; + + /** + * Constructor. + * + * @param array $params Any parameters needed for this driver. + */ + public function __construct($params) + { + parent::__construct($params); + $this->_initialize(); + } + + /** + * Returns the list of domains from the backend. + * + * @return array All the domains and their data in an array. + */ + public function getDomains() + { + $binds = $this->_getDomainKeyFilter(); + $sql = 'SELECT ' . $this->_getTableFields('domains') + . ' FROM ' . $this->_params['tables']['domains'] + . $binds[0] . ' ORDER BY domain_name'; + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->getAll($sql, $binds[1], DB_FETCHMODE_ASSOC); + } + + /** + * Returns the specified domain information from the backend. + * + * @param integer $domain_id The id of the domain to fetch. + * + * @return array The domain's information in an array. + */ + public function getDomain($domain_id) + { + $binds = $this->_getDomainKeyFilter('AND'); + $sql = 'SELECT ' . $this->_getTableFields('domains') + . ' FROM ' . $this->_params['tables']['domains'] + . ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?' . $binds[0]; + array_unshift($binds[1], (int)$domain_id); + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); + } + + /** + * Given a domain name returns the information from the backend. + * + * @param string $name The name of the domain to fetch. + * + * @return array The domain's information in an array. + */ + public function getDomainByName($domain_name) + { + $binds = $this->_getDomainKeyFilter('AND'); + $sql = 'SELECT ' . $this->_getTableFields('domains') + . ' FROM ' . $this->_params['tables']['domains'] + . ' WHERE ' . $this->_getTableField('domains', 'domain_name') . ' = ?' . $binds[0]; + array_unshift($binds[1], $domain_name); + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); + } + + /** + * Saves a domain with the provided information. + * + * @param array $info Array of details to save the domain. + */ + protected function _saveDomain($info) + { + $record = array('domain_name' => $info['name'], + 'domain_transport' => $info['transport'], + 'domain_max_users' => (int)$info['max_users'], + 'domain_quota' => (int)$info['quota']); + + if (empty($info['domain_id'])) { + $record['domain_id'] = $this->_db->nextId($this->_params['tables']['domains']); + if (!empty($this->_params['tables']['domainkey'])) { + $record['domain_key'] = $this->_params['tables']['domainkey']; + } + + $sql = 'INSERT INTO ' . $this->_params['tables']['domains'] . ' ' + . Horde_SQL::insertValues($this->_db, $this->_prepareRecord('domains', $record)); + $values = array(); + } else { + $binds = $this->_getDomainKeyFilter('AND'); + $sql = 'UPDATE ' . $this->_params['tables']['domains'] + . ' SET ' . Horde_SQL::updateValues($this->_db, $this->_prepareRecord('domains', $record)) + . ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?' . $binds[0]; + array_unshift($binds[1], $info['domain_id']); + $values = $binds[1]; + } + + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->query($sql, $values); + } + + /** + * Deletes a domain. + * + * @param integer $domain_id The id of the domain to delete. + * + * @throws Vilma_Exception + */ + protected function _deleteDomain($domain_id) + { + $domain_record = $this->getDomain($domain_id); + $domain_name = $domain_record['domain_name']; + + /* Delete all virtual emails for this domain. */ + $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] . + ' WHERE ' . $this->_getTableField('virtuals', 'virtual_email') . ' LIKE ?'; + $values = array('%@' . $domain_name); + $delete = $this->_db->query($sql, $values); + if (is_a($delete, 'PEAR_Error')) { + throw new Vilma_Exception($delete); + } + + /* Delete all users for this domain. */ + $sql = 'DELETE FROM ' . $this->_params['tables']['users'] . + ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?'; + $values = array('%@' . $domain_name); + $delete = $this->_db->query($sql, $values); + if (is_a($delete, 'PEAR_Error')) { + throw new Vilma_Exception($delete); + } + + /* Finally delete the domain. */ + $sql = 'DELETE FROM ' . $this->_params['tables']['domains'] . + ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?'; + $values = array((int)$domain_id); + + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->query($sql, $values); + } + + /** + * Returns the current number of users for a domain. + * + * @param string $domain_name The name of the domain for which to + * get the current number of users. + * + * @return integer The current number of users. + */ + public function getDomainNumUsers($domain_name) + { + $binds = $this->_getUserKeyFilter('AND'); + $sql = 'SELECT count(' . $this->_getTableField('users', 'user_name') . ')' + . ' FROM ' . $this->_params['tables']['users'] + . ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?' . $binds[0]; + array_unshift($binds[1], '%@' . $domain_name); + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->getOne($sql, $binds[1]); + } + + /** + * Returns all available users, if a domain name is passed then limit the + * list of users only to those users. + * + * @param string $domain The name of the domain for which to fetch the + * users. + * + * @return array The available users and their stored information. + */ + public function getUsers($domain = null) + { + /* Put together the SQL statement. */ + if (is_null($domain)) { + /* Fetch all users. */ + $binds = $this->_getUserKeyFilter(); + $sql = 'SELECT ' . $this->_getTableFields('users') + . ' FROM ' . $this->_params['tables']['users'] . $binds[0]; + $values = $binds[1]; + } else { + /* Fetch only users for a domain. */ + $binds = $this->_getUserKeyFilter('AND'); + $user_field = $this->_getTableField('users', 'user_name'); + $sql = 'SELECT ' . $this->_getTableFields('users') + . ' FROM ' . $this->_params['tables']['users'] + . ' WHERE ' . $user_field . ' LIKE ?' . $binds[0] + . ' ORDER BY ' . $user_field; + array_unshift($binds[1], '%@' . $domain); + $values = $binds[1]; + } + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC); + } + + /** + * Returns the user information for a given user id. + * + * @param integer $user_id The id of the user for which to fetch + * information. + * + * @return array The user information. + */ + public function getUser($user_id) + { + $binds = $this->_getUserKeyFilter('AND'); + $sql = 'SELECT ' . $this->_getTableFields('users') + . ' FROM ' . $this->_params['tables']['users'] + . ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?' . $binds[0]; + array_unshift($binds[1], (int)$user_id); + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); + } + + /** + * Saves a user to the backend. + * + * @param array $info The user information to save. + * + * @return string The user ID. + * @throws Vilma_Exception + */ + protected function _saveUser($info) + { + /* Access check (for domainkey). */ + $domain = Vilma::stripDomain($info['user_name']); + $this->getDomainByName($domain); + + if (empty($info['user_id'])) { + $info['user_id'] = $this->_db->nextId($this->_params['tables']['users']); + $create = true; + } else { + $create = false; + } + + // Slightly hackish. + $mailboxes = Vilma_MailboxDriver::factory(); + $mail_dir_base = isset($mailboxes->_params['mail_dir_base']) + ? $mailboxes->_params['mail_dir_base'] + : '?'; + + $tuple = array( + 'user_id' => (int)$info['user_id'], + 'user_name' => $info['user_name'], + 'user_full_name' => $info['user_full_name'], + 'user_home_dir' => $mail_dir_base, + 'user_mail_dir' => $domain . '/' . Vilma::stripUser($info['user_name']) . '/', + 'user_mail_quota' => $this->getDomainQuota($domain) * 1024 * 1024, + 'user_enabled' => (int)$info['user_enabled']); + + // UID and GID are slightly hackish (specific to maildrop driver), too. + if (!isset($mailboxes->_params['uid'])) { + $tuple['user_uid'] = -1; + } else { + $tuple['user_uid'] = $mailboxes->_params['uid']; + } + if (!isset($mailboxes->_params['gid'])) { + $tuple['user_gid'] = -1; + } else { + $tuple['user_gid'] = $mailboxes->_params['gid']; + } + + if (!empty($info['password'])) { + $tuple['user_clear'] = $info['password']; + $tuple['user_crypt'] = crypt($info['password'], + substr($info['password'], 0, 2)); + } elseif ($create) { + throw new Vilma_Exception(_("Password must be supplied when creating a new user.")); + } + + if ($create) { + $sql = 'INSERT INTO ' . $this->_params['tables']['users'] . ' ' + . Horde_SQL::insertValues($this->_db, $this->_prepareRecord('users', $tuple)); + } else { + $sql = sprintf('UPDATE %s SET %s WHERE ' . $this->_getTableField('users', 'user_id') . ' = %d', + $this->_params['tables']['users'], + Horde_SQL::updateValues($this->_db, $this->_prepareRecord('users', $tuple)), + (int)$info['user_id']); + } + + Horde::logMessage($sql, 'DEBUG'); + $result = $this->_db->query($sql); + if (is_a($result, 'PEAR_Error')) { + Horde::logMessage($result, 'ERR'); + throw new Vilma_Exception($result); + } + + return $info['user_id']; + } + + /** + * Deletes a user. + * + * @param integer $user_id The id of the user to delete. + * + * @throws Vilma_Exception + */ + public function deleteUser($user_id) + { + $user = $this->getUser($user_id); + + /* Delete all virtual emails for this user. */ + $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] . + ' WHERE ' . $this->_getTableField('virtuals', 'virtual_destination') . ' = ?'; + $values = array($user['user_name']); + + Horde::logMessage($sql, 'DEBUG'); + $delete = $this->_db->query($sql, $values); + if (is_a($delete, 'PEAR_Error')) { + throw new Vilma_Exception($delete); + } + + /* Delete the actual user. */ + $sql = 'DELETE FROM ' . $this->_params['tables']['users'] . + ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?'; + $values = array((int)$user_id); + + Horde::logMessage($sql, 'DEBUG'); + $result = $this->_db->query($sql, $values); + if (is_a($result, 'PEAR_Error')) { + throw new Vilma_Exception($result); + } + + Vilma_MailboxDriver::factory() + ->deleteMailbox(Vilma::stripUser($user['user_name']), + Vilma::stripDomain($user['user_name'])); + } + + /** + * Returns a list of all users, aliases, or groups and forwards for a + * domain. + * + * @param string $domain Domain on which to search. + * @param string $type Only return a specific type. One of 'all', + * 'user', 'alias','forward', or 'group'. + * @param string $key Sort list by this key. + * @param integer $direction Sort direction. + * + * @return array Account information for this domain + */ + protected function _getAddresses($domain, $type = 'all') + { + $addresses = array(); + if ($type == 'all' || $type == 'user') { + $addresses += $this->getUsers($domain); + } + if ($type == 'all' || $type == 'alias') { + $addresses += $this->getVirtuals($domain); + } + return $addresses; + } + + /** + * Returns available virtual emails. + * + * @param string $filter If passed a domain then return all virtual emails + * for the domain, otherwise if passed a user name + * return all virtual emails for that user. + * + * @return array The available virtual emails. + */ + public function getVirtuals($filter) + { + $email_field = $this->_getTableField('virtuals', 'virtual_email'); + $destination_field = $this->_getTableField('virtuals', 'virtual_destination'); + + /* Check if filtering only for domain. */ + if (strpos($filter, '@') === false) { + $where = $email_field . ' LIKE ?'; + $values = array('%@' . $filter); + } else { + $where = $destination_field . ' = ?'; + $values = array($filter); + } + + $binds = $this->_getVirtualKeyFilter('AND'); + $sql = 'SELECT ' . $this->_getTableFields('virtuals') + . ' FROM ' . $this->_params['tables']['virtuals'] + . ' WHERE ' . $where . $binds[0] + . ' ORDER BY ' . $destination_field . ', ' . $email_field; + $values = array_merge($values, $binds[1]); + + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC); + } + + /** + * Returns information for a virtual id. + * + * @param integer $virtual_id The virtual id for which to return + * information. + * + * @return array The virtual email information. + */ + public function getVirtual($virtual_id) + { + $binds = $this->_getVirtualKeyFilter('AND'); + $sql = 'SELECT ' . $this->_getTableFields('virtuals') + . ' FROM ' . $this->_params['tables']['virtuals'] + . ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?' . $binds[0]; + array_unshift($binds[1], (int)$virtual_id); + + Horde::logMessage($sql, 'DEBUG'); + $virtual = $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); + $virtual['stripped_email'] = Vilma::stripUser($virtual['virtual_email']); + + return $virtual; + } + + /** + * Saves virtual email address to the backend. + * + * @param array $info The virtual email data. + * @param string $domain The name of the domain for this virtual email. + * + * @throws Vilma_Exception + */ + public function saveVirtual($info, $domain) + { + /* Access check (for domainkey) */ + $this->getDomainByName($domain); + + if (empty($info['virtual_id'])) { + $info['virtual_id'] = $this->_db->nextId($this->_params['tables']['virtuals']); + $sql = 'INSERT INTO ' . $this->_params['tables']['virtuals'] + . ' (' . $this->_getTableField('virtuals', 'virtual_email') . ', ' + . $this->_getTableField('virtuals', 'virtual_destination') . ', ' + . $this->_getTableField('virtuals', 'virtual_id') . ') VALUES (?, ?, ?)'; + } else { + $sql = 'UPDATE ' . $this->_params['tables']['virtuals'] + . ' SET ' . $this->_getTableField('virtuals', 'virtual_email') . ' = ?, ' + . $this->_getTableField('virtuals', 'virtual_destination') . ' = ?' + . ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?'; + } + $values = array($info['stripped_email'] . '@' . $domain, + $info['virtual_destination'], + $info['virtual_id']); + + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->query($sql, $values); + } + + /** + * Deletes a virtual email. + * + * @param integer $virtual_id The id of the virtual email to delete. + */ + public function deleteVirtual($virtual_id) + { + $binds = $this->_getVirtualKeyFilter('AND'); + $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] + . ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?' . $binds[0]; + array_unshift($binds[1], $virtual_id); + Horde::logMessage($sql, 'DEBUG'); + return $this->_db->query($sql, $binds[1]); + } + + /** + * Constructs an SQL WHERE fragment to filter domains by domain key. + * + * @param string $join Keyword to join expression to rest of SQL statement + * (e.g. 'WHERE' or 'AND'). + * + * @return array An SQL fragment and a list of values suitable for + * binding. + */ + protected function _getDomainKeyFilter($join = 'WHERE') + { + if (empty($this->_params['tables']['domainkey'])) { + return array('', array()); + } + + return array(' ' . $join . ' domain_key = ?', + array($this->_params['tables']['domainkey'])); + } + + /** + * Constructs an SQL WHERE fragment to filter users by domain key. + * + * @param string $join Keyword to join expression to rest of SQL statement + * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'. + * + * @return array An SQL fragment and a list of values suitable for + * binding. + */ + protected function _getUserKeyFilter($join = 'WHERE') + { + if (empty($this->_params['tables']['domainkey'])) { + return array('', array()); + } + + $binds = $this->_getDomainKeyFilter('AND'); + return array(' ' . $join . ' EXISTS (SELECT domain_name' . + ' FROM ' . $this->_params['tables']['domains'] . + ' WHERE ' . $this->_getTableField('users', 'user_name') . + ' LIKE ? || ' . $this->_getTableField('domains', 'domain_name') . + ' ' . $binds[0] . ' )', + array_unshift($binds[1], '%@')); + } + + /** + * Constructs an SQL WHERE fragment to filter virtuals by domain key. + * + * @param string $join Keyword to join expression to rest of SQL statement + * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'. + * + * @return array An SQL fragment and a list of values suitable for + * binding. + */ + protected function _getVirtualKeyFilter($join = 'WHERE') + { + if (empty($this->_params['tables']['domainkey'])) { + return array('', array()); + } + + $binds = $this->_getDomainKeyFilter('AND'); + return array(' ' . $join . ' EXISTS (SELECT domain_name' . + ' FROM ' . $this->_params['tables']['domains'] . + ' WHERE ' . $this->_getTableField('virtuals', 'virtual_email') . + ' LIKE ? || ' . $this->_getTableField('domains', 'domain_name') . + ' ' . $binds[0] . ' )', + array_unshift($binds[1], '%@')); + } + + /** + * Returns the list of fields from a specific table for SQL statements. + * + * @return string + */ + protected function _getTableFields($table) + { + if (empty($this->_params['tables'][$table . '_fields'])) { + switch ($table) { + case 'domains': + return 'domain_id, domain_name, domain_transport, domain_max_users, domain_quota'; + default: + return '*'; + } + } + + $domainsFields = $this->_params['tables'][$table . '_fields']; + foreach ($domainsFields as $defaultName => $customName) { + $fields[] = $customName . ' AS ' . $defaultName; + } + + return implode(', ', $fields); + } + + /** + * Returns the real name of a field from a specific table for SQL + * statements. + * + * @return string + */ + protected function _getTableField($table, $field) + { + if (empty($this->_params['tables'][$table . '_fields'])) { + return $field; + } + return $this->_params['tables'][$table . '_fields'][$field]; + } + + /** + * + * + * @return array + */ + protected function _prepareRecord($table, $record) + { + if (empty($this->_params['tables'][$table . '_fields'])) { + return $record; + } + + $domainsFields = $this->_params['tables'][$table . '_fields']; + $newRecord = array(); + foreach ($record as $defaultName => $value) { + $newRecord[$domainsFields[$defaultName]] = $record[$defaultName]; + } + return $newRecord; + } + + /** + * Initializes this backend, connects to the SQL database. + * + * @throws Vilma_Exception + */ + protected function _initialize() + { + try { + $this->_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('rw', 'vilma', 'storage'); + } catch (Exception $e) { + throw Vilma_Exception($e); + } + + /* Use default table names if these are not set. */ + if (!isset($this->_params['tables']['domains'])) { + $this->_params['tables']['domains'] = 'vilma_domains'; + } + if (!isset($this->_params['tables']['users'])) { + $this->_params['tables']['users'] = 'vilma_users'; + } + if (!isset($this->_params['tables']['virtuals'])) { + $this->_params['tables']['virtuals'] = 'vilma_virtuals'; + } + } +} diff --git a/vilma/lib/Driver/qmailldap.php b/vilma/lib/Driver/qmailldap.php deleted file mode 100644 index 31bef06bc..000000000 --- a/vilma/lib/Driver/qmailldap.php +++ /dev/null @@ -1,1261 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you did - * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. - * - * @author Ben Klang - * @author David Cummings - * @package Vilma - */ -class Vilma_Driver_qmailldap extends Vilma_Driver { - - /** - * @var _LDAP Reference to initialized LDAP driver - */ - var $_ldap; - - /** - * @var _dbparams Configuration parameters for the LDAP driver - */ - var $_ldapparams; - - /** - * @var _db Reference to the initialized database driver - */ - var $_db; - - /** - * @var _dbparams Configuration parameters for the database driver - */ - var $_dbparams; - - function Vilma_Driver_qmailldap($params) - { - parent::Vilma_Driver($params); - $this->_ldapparams = $this->_params['ldap']; - $this->_sqlparams = Horde::getDriverConfig('storage', 'sql'); - $res = $this->_connect(); - if (is_a($res, 'PEAR_Error')) { - return $res; - } - - /* Connect to the backend for tracking domains. */ - $this->_dbinit(); - } - - /** - * Gets the list of domains from the backend. - * - * @return array All the domains and their data in an array. - */ - function getDomains() - { - $sql = 'SELECT domain_id, domain_name, domain_transport, ' . - 'domain_max_users, domain_quota FROM vilma_domains ' . - 'ORDER BY domain_name'; - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC); - } - - /** - * Gets the specified domain information from the backend. - * - * @param integer $domain_id The id of the domain to fetch. - * - * @return array The domain's information in an array. - */ - function getDomain($domain_id) - { - $sql = 'SELECT domain_id, domain_name, domain_transport, ' . - 'domain_max_users, domain_quota FROM vilma_domains ' . - 'WHERE domain_id=? ORDER BY domain_name'; - $values = array($domain_id); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getRow($sql, $values, DB_FETCHMODE_ASSOC); - } - - /** - * Given a domain name returns the information from the backend. - * - * @param string $name The name of the domain to fetch. - * - * @return array The domain's information in an array. - */ - function getDomainByName($domain_name) - { - $sql = 'SELECT domain_id, domain_name, domain_transport, ' . - 'domain_max_users, domain_quota FROM vilma_domains ' . - 'WHERE domain_name=?'; - $values = array($domain_name); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getRow($sql, $values, DB_FETCHMODE_ASSOC); - } - - /** - * Returns a list of all users, aliases, or groups and forwards for a - * domain. - * - * @param string $domain Domain on which to search. - * @param string $type Only return a specific type. One of 'all', - * 'user', 'alias','forward', or 'group'. - * @param string $key Sort list by this key. - * @param integer $direction Sort direction. - * - * @return array Account information for this domain - */ - protected function _getAddresses($domain, $type = 'all') - { - Horde::logMessage("Get Addresses Called for $domain with type $type and key $key", 'DEBUG'); - $addresses = array(); - if ($type == 'all' || $type == 'user') { - $addresses += $this->_getUsers($domain); - } - if ($type == 'all' || $type == 'alias') { - $addresses += $this->_getAliases($domain); - } - if ($type == 'all' || $type == 'forward') { - $addresses += $this->_getGroupsAndForwards('forward', $domain); - } - if ($type == 'all' || $type == 'group') { - $addresses += $this->_getGroupsAndForwards('group', $domain); - } - return $addresses; - } - - function getUser($user_id) { - $user = $this->getUserStatus($user_id); - - if (is_a($user, 'PEAR_Error')) { - return PEAR::raiseError(sprintf(_("Unable to qualify address: %s"), $user->getMessage())); - } - if(isset($user) && is_array($user)) { - return $user; - } else { - return PEAR::raiseError(_("Unable to qualify address.")); - } - } - - /** - * Returns an array of all users, aliases, groups and forwards for this - * domain. - * - * @param string $domain Domain on which to search - * @param optional string $type Only return a specific type - * - * @return array Account information for this domain - */ - function _getUsers($domain = null) - { - //$domain = $domain['domain_name']; - // Cache for multiple calls - static $users = array(); - if (is_null($domain) && isset($users['_all'])) { - return $users['_all']; - } - - if (!is_null($domain) - && isset($users[$domain])) { - return $users[$domain]; - } - - $filter = '(&'; - if (!is_null($domain)) { - $filter .= '(mail=*@' . $domain . ')'; - } else { - $domain = '_all'; - } - - // Make sure we don't get any forwards - $filter .= '(!(mailForwardingAddress=*))'; - - // FIXME: Check/add configured filter instead of objectclasses - foreach ($this->_ldapparams['objectclass'] as $objectclass) { - $filter .= '(objectClass=' . $objectclass . ')'; - } - $filter .= ')'; - - Horde::logMessage($filter, 'DEBUG'); - $res = ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error in LDAP search: %s"), ldap_error($this->LDAP))); - } - - $res = ldap_get_entries($this->_ldap, $res); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error in LDAP search: %s"), ldap_error($this->LDAP))); - } - - $users[$domain] = array(); - $i = 0; - // Can't use foreach because of the array format returned by LDAP driver - while ($user = @$res[$i]) { - $users[$domain][$i]['id'] = $user['dn']; - $users[$domain][$i]['address'] = $user[$this->_getAttrByField('address')][0]; - $users[$domain][$i]['type'] = 'user'; - $users[$domain][$i]['user_name'] = - $user[$this->_getAttrByField('user_name')][0]; - // We likely don't have read permission on the crypted password so - // avoid any warnings/errors about missing array elements - if (isset($user[$this->_getAttrByField('user_crypt')])) { - $users[$domain][$i]['user_crypt'] = - $user[$this->_getAttrByField('user_crypt')][0]; - } else { - $users[$domain][$i]['user_crypt'] = ''; - } - $users[$domain][$i]['user_full_name'] = - $user[$this->_getAttrByField('user_full_name')][0]; - // Mute assignment errors on the following optional fields - // These may not be present if the mail is only forwarded - $users[$domain][$i]['user_uid'] = - @$user[$this->_getAttrByField('user_uid')][0]; - $users[$domain][$i]['user_gid'] = - @$user[$this->_getAttrByField('user_gid')][0]; - $users[$domain][$i]['user_home_dir'] = - @$user[$this->_getAttrByField('user_home_dir')][0]; - $users[$domain][$i]['user_mail_dir'] = - @$user[$this->_getAttrByField('user_mail_dir')][0]; - $users[$domain][$i]['user_mail_quota_bytes'] = - @$user[$this->_getAttrByField('user_mail_quota_bytes')][0]; - $users[$domain][$i]['user_mail_quota_count'] = - @$user[$this->_getAttrByField('user_mail_quota_count')][0]; - - // If accountStatus is blank it's the same as active - if (!isset($user[$this->_getAttrByField('user_enabled')][0]) || - ($user[$this->_getAttrByField('user_enabled')][0] == 'active')) { - $users[$domain][$i]['user_enabled'] = 'active'; - } else { - // accountStatus can also be: - // noaccess (receives but cannot pick up mail) - // disabled (bounce incoming and deny pickup) - // deleted (bounce incoming but allow pickup) - $users[$domain][$i]['user_enabled'] = - $user[$this->_getAttrByField('user_enabled')][0]; - } - - $i++; - } - - return $users[$domain]; - } - - function _getFields() - { - // LDAP attributes are always returned lower case! - static $fields = array( - 'address' => 'mail', - 'user_name' => 'uid', - 'user_crypt' => 'userpassword', - 'user_full_name' => 'cn', - 'user_uid' => 'qmailuid', - 'user_gid' => 'qmailgid', - 'user_home_dir' => 'homedirectory', - 'user_mail_dir' => 'mailmessagestore', - 'user_mail_quota_bytes' => 'mailquotasize', - 'user_mail_quota_count' => 'mailquotacount', - 'user_enabled' => 'accountstatus', - ); - - return $fields; - - } - - function _getAttrByField($field) { - $fields = $this->_getFields(); - return $fields[$field]; - } - - function _getFieldByAttr($attr) { - $attrs = array_flip($this->_getFields()); - return $attrs[$attr]; - } - - /** - * Returns available email address aliases. This method should not be - * called directly but rather by way of getAddresses(). - * - * @access private - * - * @param string $target If passed a domain then return all alias emails - * for the domain, otherwise if passed a user name - * return all virtual emails for that user. - * - * @return array The used email aliases - */ - function _getAliases($target = null) - { - // FIXME: Add static cache - - $filter = '(&'; // Begin filter (cumulative AND) - foreach ($this->_ldapparams['objectclass'] as $objectclass) { - // Add each objectClass from parameters - $filter .= '(objectClass=' . $objectclass . ')'; - } - // FIXME: Add preconfigured filter from $this->_ldapparams - - // Check if filtering only for domain. - if (($pos = strpos($target, '@')) === false && !empty($target)) { - $filter .= '(mailAlternateAddress=*@' . $target . ')'; - // Otherwise filter for all aliases - } else { - $filter .= '(mailAlternateAddress=*)'; - // Restrict the results to $target - if (!empty($target)) { - $filter .= '(mail=' . $target . ')'; // Add user's email - } - } - $filter .= ')'; // End filter - - Horde::logMessage($filter, 'DEBUG'); - $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"), - @ldap_error($this->_ldap))); - } - - $res = @ldap_get_entries($this->_ldap, $res); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap))); - } - - $aliases = array(); - // Can't use foreach because of the array format returned by LDAP driver - $i = 0; // Virtual address index - $e = 0; // Entry counter - while ($entry = @$res[$e]) { - // If accountStatus is blank it's the same as active - if (!isset($entry[$this->_getAttrByField('user_enabled')][0]) || - ($entry[$this->_getAttrByField('user_enabled')][0] == 'active')) { - $curstatus = 'active'; - } else { - // accountStatus can also be: - // noaccess (receives but cannot pick up mail) - // disabled (bounce incoming and deny pickup) - // deleted (bounce incoming but allow pickup) - $curstatus = $entry[$this->_getAttrByField('user_enabled')][0]; - } - $a = 0; // Attribute counter - while ($mail = @$entry['mailalternateaddress'][$a]) { - $aliases[$i]['id'] = $mail; - $aliases[$i]['type'] = 'alias'; - $aliases[$i]['user_name'] = $mail; - $aliases[$i]['user_full_name'] = sprintf(_("Alias for %s"), $entry['mail'][0]); - $aliases[$i]['destination'] = $entry['mail'][0]; - $aliases[$i]['user_enabled'] = $curstatus; - $a++; - $i++; - } - $e++; - } - - return $aliases; - } - - /** - * Returns all available groups and forwards unless otherwise specified. - * If a domain name is passed then limit the results to groups or forwards - * in that domain. This method should not be called directly, but rather by - * way of getAddresses() - * - * @access private - * - * @param string $acquire The default behavior is to acquire both - * groups and forwards; a value of 'group' - * will return only groups and a value of - * 'forward' will return only forwards. - * @param string $domain The name of the domain from which to fetch - * - * @return array The available groups and forwards with details - */ - function _getGroupsAndForwards($acquire = null, $domain = null) - { - // Cache - static $grpfwds; - // TODO ? - /* - if (is_null($domain) && isset($grpfwds['_all'])) { - return $grpfwds['_all']; - } - if (!is_null($domain) && isset($grpfwds[$domain])) { - return $grpfwds[$domain]; - } - */ - $filter = '(&'; // Begin filter (cumulative AND) - foreach ($this->_ldapparams['objectclass'] as $objectclass) { - // Add each objectClass from parameters - $filter .= '(objectClass=' . $objectclass . ')'; - } - // FIXME: Add preconfigured filter from $this->_ldapparams - - // Only return results which have a forward configured - $filter .= '(mailForwardingAddress=*)'; - - if (!empty($domain)) { - $filter .= '(|'; // mail or mailAlternateAddress - $filter .= '(mail=*@' . $domain . ')'; - $filter .= '(mailAlternateAddress=*@' . $domain . ')'; - $filter .= ')'; // end mail or mailAlternateAddress - } else { - $domain = '_all'; - } - $filter .= ')'; // End filter - Horde::logMessage($filter, 'DEBUG'); - $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"), - @ldap_error($this->_ldap))); - } - - $res = @ldap_get_entries($this->_ldap, $res); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap))); - } - - $grpfwds[$domain] = array(); - // Can't use foreach because of the array format returned by LDAP driver - $i = 0; // Address index - $e = 0; // Entry counter - - while ($entry = @$res[$e]) { - $targets = array(); - $a = 0; // Attribute counter - while ($attr = @$res[$e]['mailforwardingaddress'][$a]) { - $targets[] = $attr; - $a++; - } - $type = $entry['mailforwardingaddress']["count"]; - if($type > 1) { - $type = 'group'; - } else { - $type = 'forward'; - } - if(($acquire == 'all') || ($type == $acquire)) { - $grpfwds[$domain][$i] = array( - 'id' => $entry['dn'], - 'type' => $type, - 'address' => $entry[$this->_getAttrByField('address')][0], - 'targets' => $targets, - 'user_name' => $entry[$this->_getAttrByField('user_name')][0], - 'user_full_name' => @$entry[$this->_getAttrByField('user_name')][0], - ); - // If accountStatus is blank it's the same as active - if (!isset($entry[$this->_getAttrByField('user_enabled')][0]) || - ($entry[$this->_getAttrByField('user_enabled')][0] == 'active')) { - $grpfwds[$domain][$i]['user_enabled'] = 'active'; - } else { - // accountStatus can also be: - // noaccess (receives but cannot pick up mail) - // disabled (bounce incoming and deny pickup) - // deleted (bounce incoming but allow pickup) - $grpfwds[$domain][$i]['user_enabled'] = - $entry[$this->_getAttrByField('user_enabled')][0]; - } - } else { - $e++; - continue; - } - $e++; - $i++; - } - return $grpfwds[$domain]; - } - - /** - * Returns information for an email alias - * - * @param string $id The email alias id for which to return information. - * - * @return array The virtual email information. - */ - function getAddressInfo($address, $type = 'all') - { - Horde::logMessage("Get Addresses Called for $address with type $type and key $key", 'DEBUG'); - if ($type != 'alias') { - return parent::getAddressInfo($address, $type); - } else { - // FIXME: Which is faster? A linear array search or an LDAP search? - // I think LDAP in this case because we can't assume the domain. - $filter = '(&'; // Begin filter (cumulative AND) - foreach ($this->_ldapparams['objectclass'] as $objectclass) { - // Add each objectClass from parameters - $filter .= '(objectClass=' . $objectclass . ')'; - } - $filter .= '(mailAlternateAddress=' . $address . ')'; - $filter .= ')'; // End filter - Horde::logMessage($filter, 'DEBUG'); - $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"), - @ldap_error($this->_ldap))); - } - $res = @ldap_get_entries($this->_ldap, $res); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error returning LDAP results: %s"), @ldap_error($this->_ldap))); - } - - if ($res['count'] !== 1) { - return PEAR::raiseError(_("More than one DN returned for this alias. Please contact an administrator to resolve this error.")); - } - - return array( - 'id' => $res[0]['dn'], - 'address' => $address, - 'destination' => $res[0]['mail'][0], - ); - } - } - - /** - * Returns the current number of set up users for a domain. - * - * @param string $domain_name The name of the domain for which to - * get the current number of users. - * - * @return integer The current number of users. - */ - function getDomainNumUsers($domain_name) - { - return count($this->_getUsers($domain_name)); - } - - /** - * Saves a domain to the backend. - * - * @param array $info The domain information to save to the backend. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _saveDomain(&$info) - { - // We store the records within Horde's configured SQL database for - // Vilma because LDAP has no mechanism for tracking domains - // that are valid for this system. - $values = array($info['name'], $info['transport'], - (int)$info['max_users'], (int)$info['quota']); - - if (empty($info['domain_id'])) { - $nextid = $this->_db->nextId('vilma_domains'); - $sql = 'INSERT INTO vilma_domains (domain_id, domain_name, ' . - 'domain_transport, domain_max_users, domain_quota) VALUES ' . - '(?, ?, ?, ?, ?)'; - array_unshift($values, $nextid); - } else { - $sql = 'UPDATE vilma_domains SET domain_name=?, ' . - 'domain_transport=?, domain_max_users=?, domain_quota=? ' . - 'WHERE domain_id=?'; - array_push($values, $info['domain_id']); - } - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->query($sql, $values); - } - - /** - * Deletes a given domain. - * - * @param string $domain_id The id of the domain to delete. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _deleteDomain($domain_id) - { - $domain_record = $this->getDomain($domain_id); - if (is_a($domain_record, 'PEAR_Error')) { - return $domain_record; - } - - $domain_name = $domain_record['domain_name']; - - // FIXME: Add logic to remove all users, aliases, and grpfwds for this - // domain - - /* Finally delete the domain. */ - $sql = 'DELETE FROM vilma_domains WHERE domain_id=?'; - $values = array((int)$domain_id); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->query($sql, $values); - } - - /** - * Searchs for a given email account. - * - * @param string $email_id The id of the account to be searched for. - * - * @return Array of data for given email account on success or no - * information found; and for an error a PEAR::Error otherwise. - */ - function searchForAliases($email_id) { - // Get the user's DN - $filter = '(&'; // Begin filter (cumulative AND) - foreach ($this->_ldapparams['objectclass'] as $objectclass) { - // Add each objectClass from parameters - $filter .= '(objectClass=' . $objectclass . ')'; - } - /* - // Check if filtering only for domain. - if (($pos = strpos($target, '@')) === false && !empty($email_id)) { - $filter .= '(mailAlternateAddress=*@' . $email_id . ')'; - // Otherwise filter for all aliases - } else { - $filter .= '(mailAlternateAddress=*)'; - // Restrict the results to $target - if (!empty($email_id)) { - $filter .= '(mail=' . $email_id . ')'; // Add user's email - } - } - */ - $filter .= '(mailAlternateAddress=' . $email_id . ')'; - $filter .= ')'; // End filter - - //echo $filter; - Horde::logMessage($filter, 'DEBUG'); - $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"), - @ldap_error($this->_ldap))); - } - $res = @ldap_get_entries($this->_ldap, $res); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap))); - } - - return $res; - } - - /** - * Searchs for a given email account. - * - * @param string $email_id The id of the account to be searched for. - * - * @return Array of data for given email account on success or no - * information found; and for an error a PEAR::Error otherwise. - */ - function searchForUser($email_id) - { - // Get the user's DN - $filter = '(&'; - foreach ($this->_ldapparams['objectclass'] as $objectclass) { - // Add each objectClass from parameters - $filter .= '(objectclass=' . $objectclass . ')'; - } - $filter .= '(mail=' . $email_id . '))'; - - Horde::logMessage($filter, 'DEBUG'); - $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"), - @ldap_error($this->_ldap))); - } - $res = @ldap_get_entries($this->_ldap, $res); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap))); - } - - if ($res['count'] === 0) { - return PEAR::raiseError(_("Unable to acquire handle on DN. Aborting delete operation.")); - } else if($res['count'] !== 1) { - return PEAR::raiseError(_("More than one DN returned. Aborting delete operation.")); - } - return $res; - } - - /** - * Deletes a given email account. - * - * @param string $email_id The id of the account to delete (not an alias) - * - * @return mixed True on success or PEAR::Error otherwise. - */ - function deleteUser($email_id) - { - // Get the user's DN - $filter = '(&'; - foreach ($this->_ldapparams['objectclass'] as $objectclass) { - // Add each objectClass from parameters - $filter .= '(objectclass=' . $objectclass . ')'; - } - $filter .= '(mail=' . $email_id . ')'; - //echo $email_id . '
'; - $filter .= ')'; - Horde::logMessage($filter, 'DEBUG'); - $res = @ldap_search($this->_ldap, $this->_ldapparams['basedn'], $filter); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error searching LDAP: %s"), - @ldap_error($this->_ldap))); - } - $res = @ldap_get_entries($this->_ldap, $res); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error retrieving LDAP results: %s"), @ldap_error($this->_ldap))); - } - - if ($res['count'] === 0) { - return PEAR::raiseError(_("Unable to acquire handle on DN. Aborting delete operation.")); - } else if($res['count'] !== 1) { - return PEAR::raiseError(_("More than one DN returned. Aborting delete operation.")); - } - // We now have one unique DN to delete. - $res = @ldap_delete($this->_ldap, $res[0]['dn']); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error deleting account from LDAP: %s"), @ldap_error($this->_ldap))); - } - - return true; - } - - /** - * Modifies alias data on the backend. See Driver::saveAlias() for parameter info. - * - * @param mixed $info The alias, or an array containing the alias and supporting data. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _saveAlias($info) - { - Horde::logMessage("_saveAlias called with info: " . print_r($info, true), 'DEBUG'); - $address = $info['address']; - if (!empty($info['alias'])) { - $alias = $info['alias']; - $create = false; - } else { - $create = true; - } // if - $alias_address = $info['alias_address']; - - $user_res = $this->searchForUser($address); - if (is_a($user_res, 'PEAR_Error') || ($res['count'] === 0) ) { - return PEAR::raiseError(_("Error reading address information from backend.")); - } // if - $user = $user_res[0]; - - // Retrieve the current MAA values - if (array_key_exists('mailalternateaddress', $user_res[0])) { - $maa = $user['mailalternateaddress']; - unset($maa['count']); - } else { - $maa = array(); - } // if - - Horde::logMessage("Resource contains: " . print_r($maa, true), 'DEBUG'); - - $update = false; - $oldmaa = $maa; - if ($create) { - // Verify that it does not already exist - if (in_array($alias_address, $maa) === false) { - // Not there, we create it - // return PEAR::raiseError(_("We would create a new entry here.")); - $maa[] = $alias_address; - // usort($maa, "compareEmailSort"); - sort($maa); - $update = true; - } else { - // Already exists, throw a notification - return PEAR::raiseError(_("That alias already exists!")); - } // if - - } else { - if ($alias == $alias_address) { - /* do nothing */; - } else { - $key = array_search($alias, $maa); - if ($key > 0 || $key === 0) { - $maa[$key] = $alias_address; - // usort($maa, "compareEmailSort"); - sort($maa); - $update = true; - } else { - return PEAR::raiseError(sprintf(_("Existing entry \"%s\" could not be found: " . print_r($key, true)), $alias)); - } // if - } - } // if - - - if ($update) { - $dn = $user['dn']; - Horde::logMessage("UPDATING: $dn \nOld MAA: " . print_r($oldmaa, true) . "\nNew MAA: " . print_r($maa, true), 'DEBUG'); - // return PEAR::raiseError(sprintf(_("Update Code Not Written."), $alias)); - if ($this->_ldap) { - // bind with appropriate dn to give update access - $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'], - $this->_ldapparams['bindpw']); - if (!$res) { - return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials.")); - } - $entry["mailAlternateAddress"] = $maa; - - $res = @ldap_modify($this->_ldap, $dn, $entry); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); - } else { - return TRUE; - } // if - } // if - } // if - - return true; - } - - function _deleteAlias($info) - { - Horde::logMessage("_deleteAlias called with info: " . print_r($info, true), 'DEBUG'); - $address = $info['address']; - $alias = $info['alias']; - - $user_res = $this->searchForUser($address); - if (is_a($user_res, 'PEAR_Error') || ($res['count'] === 0) ) { - return PEAR::raiseError(_("Error reading address information from backend.")); - } // if - $user = $user_res[0]; - - // Retrieve the current MAA values - if (array_key_exists('mailalternateaddress', $user_res[0])) { - $maa = $user['mailalternateaddress']; - unset($maa['count']); - } else { - $maa = array(); - } // if - - Horde::logMessage("Resource contains: " . print_r($maa, true), 'DEBUG'); - - $update = false; - $oldmaa = $maa; - $key = array_search($alias, $maa); - if ($key > 0 || $key === 0) { - unset($maa[$key]); - sort($maa); - $update = true; - } else { - /* skip */; - } // if - - if ($update) { - $dn = $user['dn']; - Horde::logMessage("UPDATING: $dn \nOld MAA: " . print_r($oldmaa, true) . "\nNew MAA: " . print_r($maa, true), 'DEBUG'); - // return PEAR::raiseError(sprintf(_("Update Code Not Written."), $alias)); - if ($this->_ldap) { - // bind with appropriate dn to give update access - $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'], - $this->_ldapparams['bindpw']); - if (!$res) { - return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials.")); - } - $entry["mailAlternateAddress"] = $maa; - - $res = @ldap_modify($this->_ldap, $dn, $entry); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); - } else { - return TRUE; - } // if - } // if - } // if - - return true; - } - - /** - * Modifies forward data on the backend. See Driver::saveForward() for parameter info. - * - * @param mixed $info An array containing the alias and supporting data. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _saveForward($info) - { - Horde::logMessage("_saveForward called with info: " . print_r($info, true), 'DEBUG'); - $address = $info['address']; - if (!empty($info['forward'])) { - $forward = $info['forward']; - $create = false; - } else { - $create = true; - } // if - $forward_address = $info['forward_address']; - - $user_res = $this->searchForUser($address); - if (is_a($user_res, 'PEAR_Error') || ($res['count'] === 0) ) { - return PEAR::raiseError(_("Error reading address information from backend.")); - } // if - $user = $user_res[0]; - - // Retrieve the current MAA values - if (array_key_exists('mailforwardingaddress', $user_res[0])) { - $mfa = $user['mailforwardingaddress']; - unset($mfa['count']); - } else { - $mfa = array(); - } // if - - Horde::logMessage("Resource contains: " . print_r($mfa, true), 'DEBUG'); - - $update = false; - $oldmfa = $mfa; - if ($create) { - // Verify that it does not already exist - if (in_array($forward_address, $mfa) === false) { - // Not there, we create it - // return PEAR::raiseError(_("We would create a new entry here.")); - $mfa[] = $forward_address; - // usort($mfa, "compareEmailSort"); - sort($mfa); - $update = true; - } else { - // Already exists, throw a notification - return PEAR::raiseError(sprintf(_("That forward, \"%s\", already exists!"), $forward_address)); - } // if - - } else { - if ($forward == $forward_address) { - /* do nothing */; - } else { - $key = array_search($forward, $mfa); - if ($key > 0 || $key === 0) { - $mfa[$key] = $forward_address; - // usort($mfa, "compareEmailSort"); - sort($mfa); - $update = true; - } else { - return PEAR::raiseError(sprintf(_("Existing entry \"%s\" could not be found: " . print_r($key, true)), $forward)); - } // if - } - } // if - - - if ($update) { - $dn = $user['dn']; - Horde::logMessage("UPDATING: $dn \nOld MFA: " . print_r($oldmfa, true) . "\nNew MFA: " . print_r($mfa, true), 'DEBUG'); - // return PEAR::raiseError(sprintf(_("Update Code Not Written."), $alias)); - if ($this->_ldap) { - // bind with appropriate dn to give update access - $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'], - $this->_ldapparams['bindpw']); - if (!$res) { - return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials.")); - } - $entry["mailForwardingAddress"] = $mfa; - - $res = @ldap_modify($this->_ldap, $dn, $entry); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); - } else { - return TRUE; - } // if - } // if - } // if - - return true; - } - - /** - * Deletes forward data on the backend. See Driver::deleteForward() for parameter info. - * - * @param mixed $info An array containing the forward and supporting data. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _deleteForward($info) - { - Horde::logMessage("_deleteForward called with info: " . print_r($info, true), 'DEBUG'); - $address = $info['address']; - $forward = $info['forward']; - - $user_res = $this->searchForUser($address); - if (is_a($user_res, 'PEAR_Error') || ($res['count'] === 0) ) { - return PEAR::raiseError(_("Error reading address information from backend.")); - } // if - $user = $user_res[0]; - - // Retrieve the current MFA values - if (array_key_exists('mailforwardingaddress', $user_res[0])) { - $mfa = $user['mailforwardingaddress']; - unset($mfa['count']); - } else { - $mfa = array(); - } // if - - Horde::logMessage("Resource contains: " . print_r($mfa, true), 'DEBUG'); - - $update = false; - $oldmfa = $mfa; - $key = array_search($forward, $mfa); - if ($key > 0 || $key === 0) { - unset($mfa[$key]); - sort($mfa); - $update = true; - } else { - /* skip */; - } // if - - if ($update) { - $dn = $user['dn']; - Horde::logMessage("UPDATING: $dn \nOld MFA: " . print_r($oldmfa, true) . "\nNew MFA: " . print_r($mfa, true), 'DEBUG'); - // return PEAR::raiseError(sprintf(_("Update Code Not Written."), $alias)); - if ($this->_ldap) { - // bind with appropriate dn to give update access - $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'], - $this->_ldapparams['bindpw']); - if (!$res) { - return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials.")); - } - $entry["mailForwardingAddress"] = $mfa; - - $res = @ldap_modify($this->_ldap, $dn, $entry); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); - } else { - return TRUE; - } // if - } // if - } // if - - return true; - } - - /* Sorting function to sort aliases, forwards, and accounts by domain name first, - * then by user component. - */ - function compareEmailSort($a, $b) { - $a_comp = split("@", $a); - $b_comp = split("@", $b); - // not finished. - } - - function _saveUser(&$info) - { - if ($info['mode'] == 'edit') { - $address = $info['address']; - if(!isset($address) || empty($address)) { - $user_name = $info['user_name']; - $domain = $info['domain']; - if(!(!isset($user_name) || empty($user_name)) && !(!isset($user_name) || empty($user_name))) { - $address = $info['user_name'] . $info['domain']; - } else { - return PEAR::raiseError(_("Unable to acquire handle on address.")); - } - } - $addrinfo = $this->getAddressInfo($address); - if (is_a($addrinfo, 'PEAR_Error')) { - return $addrinfo; - } - $type = $addrinfo['type']; - if($type == 'user') { - //continue, this is a user. - } else { - //return PEAR::raiseError(_("Unable to save account of type " . $type)); - } - - $user_info = $this->searchForUser($address); - if (is_a($user_info, 'PEAR_Error') || ($res['count'] === 0) ) { - return PEAR::raiseError(_("Error reading address information from backend.")); - } - - $objectClassData = null; - if(isset($user_info[0]['objectclass'])) { - $objectClassData = $user_info[0]['objectclass']; - } - - unset($info['mode']); // Don't want to save this to LDAP - // Special case for the password: If it was provided, it needs - // to be crypted. Otherwise, ignore it. - if (isset($info['password'])) { - if (!empty($user['password'])) { - // FIXME: Allow choice of hash - $info['user_password'] = Horde_Auth::getCryptedPassowrd($info['password'], '', 'ssha', true); - } - unset($info['password']); - } - - $tmp['dn'] = $addrinfo['id']; - foreach ($info as $key => $val) { - $attr = $this->_getAttrByField($key); - $tmp[$attr] = $val; - } - - if ($this->_ldap) { - // bind with appropriate dn to give update access - $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'], - $this->_ldapparams['bindpw']); - if (!$res) { - return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials.")); - } - - // prepare data - $entry['cn'] = $info['user_full_name']; - // sn is not used operationally but we make an effort to be - // something sensical. No guarantees, though. - $entry['sn'] = array_pop(explode(' ', $info['user_full_name'])); -// The next two lines were reversed: which is right? - $entry['mail'] = $info['user_name'] . $info['domain']; - // $tmp['mail']; - $entry['uid'] = $entry['mail']; - $entry['homeDirectory'] = '/srv/vhost/mail/' . $info['domain'] .'/' . $info['user_name']; - if(($type != 'group') && ($type != 'forward')) { - $entry["qmailUID"] = 8; - $entry["qmailGID"] = 8; - } - $entry["accountstatus"] = $info["user_enabled"]; - if(isset($info['password']) && !empty($info['password'])) { - // FIXME: Allow choice of hash - $entry["userPassword"] = Horde_Auth::getCryptedPassword($info['password'], '', 'ssha', true); - } - if(isset($objectClassData)) { - array_shift($objectClassData); - $entry['objectclass'] = $objectClassData; - } else { - $entry['objectclass'] = array(); - $entry['objectclass'][] = 'top'; - $entry['objectclass'][] = 'person'; - $entry['objectclass'][] = 'organizationalPerson'; - $entry['objectclass'][] = 'inetOrgPerson'; - $entry['objectclass'][] = 'hordePerson'; - $entry['objectclass'][] = 'qmailUser'; - } - - // Stir in any site-local custom LDAP attributes - $entry = Horde::callHook('_vilma_hook_getldapattrs', - array($entry), 'vilma'); - - $rdn = 'mail=' . $entry['mail']; - $dn = $rdn . ',' . $this->_ldapparams['basedn']; - $res = @ldap_modify($this->_ldap, $dn, $entry); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error modifying account: %s"), @ldap_error($this->_ldap))); - } else { - return TRUE; - } - } - } else if($info['mode'] == 'new') { - if ($this->_ldap) { - // bind with appropriate dn to give update access - $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'], - $this->_ldapparams['bindpw']); - if (!$res) { - return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials.")); - } - - // prepare data - $entry['cn'] = $info['user_full_name']; - // sn is not used operationally but we make an effort to be - // something sensical. No guarantees, though. - $entry['sn'] = array_pop(explode(' ', $info['user_full_name'])); - $entry['mail'] = $info['user_name'] . '@' . $info['domain']; - // uid must match mail or SMTP auth fails - $entry['uid'] = $entry['mail']; - $entry['homeDirectory'] = '/srv/vhost/mail/' . $info['domain'] .'/' . $info['user_name']; - $entry['qmailUID'] = 8; - $entry['qmailGID'] = 8; - $entry['objectclass'] = array(); - $entry['objectclass'][] = 'top'; - $entry['objectclass'][] = 'person'; - $entry['objectclass'][] = 'organizationalPerson'; - $entry['objectclass'][] = 'inetOrgPerson'; - $entry['objectclass'][] = 'hordePerson'; - $entry['objectclass'][] = 'qmailUser'; - $entry["accountstatus"] = $info["user_enabled"]; - // FIXME: Allow choice of hash - $entry["userPassword"] = Horde_Auth::getCryptedPassword($info['password'], '', 'ssha', true); - - // Stir in any site-local custom LDAP attributes - $entry = Horde::callHook('_vilma_hook_getldapattrs', - array($entry), 'vilma'); - - $rdn = 'mail=' . $entry['mail']; - $dn = $rdn . ',' . $this->_ldapparams['basedn']; - $res = @ldap_add($this->_ldap, $dn, $entry); - if ($res === false) { - return PEAR::raiseError(sprintf(_("Error adding account to LDAP: %s"), @ldap_error($this->_ldap))); - } else { - return TRUE; - } - } else { - return PEAR::raiseError(_("Unable to connect to LDAP server")); - } - } - - return PEAR::raiseError(_("Unable to save user information.")); - } - - /** - * Deletes a virtual email. - * - * @param integer $virtual_id The id of the virtual email to delete. - */ - function deleteVirtual($virtual_id) - { - die("deleteVirtual()"); - } - - public function getUserFormAttributes() - { - return array(array( - 'label' => _("Account Status"), - 'name' => 'user_enabled', - 'type' => 'enum', - 'required' => true, - 'readonly' => false, - 'description' => null, - 'params' => array( - array( - 'active' => _("Account is active"), - 'noaccess' => _("Disable Delivery Only"), - 'disabled' => _("Bounce Incoming Only"), - 'deleted' => _("Account is disabled"), - ), - ), - 'default' => 'active', - )); - } - - function _connect() - { - if (!is_null($this->_ldap)) { - return true; - } - - Horde::assertDriverConfig($this->_ldapparams, 'storage', - array('ldaphost', 'basedn', 'binddn', 'dn')); - - if (!isset($this->_ldapparams['bindpw'])) { - $this->_ldapparams['bindpw'] = ''; - } - - $port = (isset($this->_ldapparams['port'])) ? - $this->_ldapparams['port'] : 389; - - $this->_ldap = ldap_connect($this->_ldapparams['ldaphost'], $port); - if (!$this->_ldap) { - throw new Vilma_Exception("Unable to connect to LDAP server $hostname on $port"); - } - $res = ldap_set_option($this->_ldap, LDAP_OPT_PROTOCOL_VERSION, - $this->_ldapparams['version']); - if (!$res) { - return PEAR::raiseError(_("Unable to set LDAP protocol version")); - } - $res = ldap_bind($this->_ldap, $this->_ldapparams['binddn'], - $this->_ldapparams['bindpw']); - if (!$res) { - return PEAR::raiseError(_("Unable to bind to the LDAP server. Check authentication credentials.")); - } - - } - - /** - * Initialise this backend, connect to the SQL database. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _dbinit() - { - global $registry; - - try { - $this->_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('rw', 'vilma', 'storage'); - } catch (Horde_Exception $e) { - return PEAR::raiseError($e->getMessage()); - } - } -} diff --git a/vilma/lib/Driver/sql.php b/vilma/lib/Driver/sql.php deleted file mode 100644 index 2aafc8b4b..000000000 --- a/vilma/lib/Driver/sql.php +++ /dev/null @@ -1,635 +0,0 @@ - - * @package Vilma - */ -class Vilma_Driver_sql extends Vilma_Driver { - - /** - * @var DB - */ - var $_db; - - function Vilma_Driver_sql($params) - { - parent::Vilma_Driver($params); - $this->initialise(); - } - - /** - * Construct an SQL WHERE fragment to filter domains by domain key. - * - * @access private - * - * @param string $join Keyword to join expression to rest of SQL statement - * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'. - * - * @return array An SQL fragment and a list of values suitable for - * binding. - */ - function _getDomainKeyFilter($join = 'WHERE') - { - if (empty($this->_params['tables']['domainkey'])) { - return array('', array()); - } - - return array(' ' . $join . ' domain_key = ?', - array($this->_params['tables']['domainkey'])); - } - - /** - * Construct an SQL WHERE fragment to filter users by domain key. - * - * @access private - * - * @param string $join Keyword to join expression to rest of SQL statement - * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'. - * - * @return array An SQL fragment and a list of values suitable for - * binding. - */ - function _getUserKeyFilter($join = 'WHERE') - { - if (empty($this->_params['tables']['domainkey'])) { - return array('', array()); - } - $binds = $this->_getDomainKeyFilter('AND'); - - return array(' ' . $join . ' EXISTS (SELECT domain_name' . - ' FROM ' . $this->_params['tables']['domains'] . - ' WHERE ' . $this->_getTableField('users', 'user_name') . - ' LIKE ? || ' . $this->_getTableField('domains', 'domain_name') . - ' ' . $binds[0] . ' )', - array_unshift($binds[1], '%@')); - } - - /** - * Construct an SQL WHERE fragment to filter virtuals by domain key. - * - * @access private - * - * @param string $join Keyword to join expression to rest of SQL statement - * (e.g. 'WHERE' or 'AND'). Default: 'WHERE'. - * - * @return string An SQL fragment. - */ - function _getVirtualKeyFilter($join = 'WHERE') - { - if (empty($this->_params['tables']['domainkey'])) { - return array('', array()); - } - $binds = $this->_getDomainKeyFilter('AND'); - - return array(' ' . $join . ' EXISTS (SELECT domain_name' . - ' FROM ' . $this->_params['tables']['domains'] . - ' WHERE ' . $this->_getTableField('virtuals', 'virtual_email') . - ' LIKE ? || ' . $this->_getTableField('domains', 'domain_name') . - ' ' . $binds[0] . ' )', - array_unshift($binds[1], '%@')); - } - - /** - * Gets the list of fields from specific table for sql statement. - * - * @return string - */ - function _getTableFields($table) - { - if (empty($this->_params['tables'][$table . '_fields'])){ - return '*'; - } - - $domainsFields = $this->_params['tables'][$table . '_fields']; - foreach ($domainsFields as $defaultName => $customName) { - $fields[] = $customName . ' as ' . $defaultName; - } - return implode(', ', $fields); - } - - /** - * Gets the real name of the field from specific table for sql statement. - * - * @return string - */ - function _getTableField($table, $field) - { - if (empty($this->_params['tables'][$table . '_fields'])) { - return $field; - } else { - return $this->_params['tables'][$table . '_fields'][$field]; - } - } - - /** - * - * - * @return array - */ - function _prepareRecord($table, $record) - { - if (empty($this->_params['tables'][$table . '_fields'])){ - return $record; - } - - $domainsFields = $this->_params['tables'][$table . '_fields']; - $newRecord = array(); - foreach ($record as $defaultName => $value) { - $newRecord[$domainsFields[$defaultName]] = $record[$defaultName]; - } - return $newRecord; - } - - /** - * Gets the list of domains from the backend. - * - * @return array All the domains and their data in an array. - */ - function getDomains() - { - $binds = $this->_getDomainKeyFilter(); - $sql = 'SELECT '. $this->_getTableFields('domains') . ' FROM ' . $this->_params['tables']['domains'] . - $binds[0] . ' ORDER BY domain_name'; - $values = $binds[1]; - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC); - } - - /** - * Gets the specified domain information from the backend. - * - * @param integer $domain_id The id of the domain to fetch. - * - * @return array The domain's information in an array. - */ - function getDomain($domain_id) - { - $binds = $this->_getDomainKeyFilter('AND'); - $sql = 'SELECT '. $this->_getTableFields('domains') . ' FROM ' . $this->_params['tables']['domains'] . - ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?' . $binds[0]; - array_unshift($binds[1], (int)$domain_id); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); - } - - /** - * Given a domain name returns the information from the backend. - * - * @param string $name The name of the domain to fetch. - * - * @return array The domain's information in an array. - */ - function getDomainByName($domain_name) - { - $binds = $this->_getDomainKeyFilter('AND'); - $sql = 'SELECT '. $this->_getTableFields('domains') . ' FROM ' . $this->_params['tables']['domains'] . - ' WHERE ' . $this->_getTableField('domains', 'domain_name') . ' = ?' . $binds[0]; - array_unshift($binds[1], $domain_name); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); - } - - /** - * Returns a list of all users, aliases, or groups and forwards for a - * domain. - * - * @param string $domain Domain on which to search. - * @param string $type Only return a specific type. One of 'all', - * 'user', 'alias','forward', or 'group'. - * @param string $key Sort list by this key. - * @param integer $direction Sort direction. - * - * @return array Account information for this domain - */ - protected function _getAddresses($domain, $type = 'all') - { - $addresses = array(); - if ($type == 'all' || $type == 'user') { - $addresses += $this->getUsers($domain); - } - if ($type == 'all' || $type == 'alias') { - $addresses += $this->getVirtuals($domain); - } - return $addresses; - } - - /** - * Returns all available users, if a domain name is passed then limit the - * list of users only to those users. - * - * @param string $domain The name of the domain for which to fetch the - * users. - * - * @return array The available users and their stored information. - */ - function getUsers($domain = null) - { - /* Put together the SQL statement. */ - if (is_null($domain)) { - /* Fetch all users. */ - $binds = $this->_getUserKeyFilter(); - $sql = 'SELECT '. $this->_getTableFields('users') . ' FROM ' . $this->_params['tables']['users'] . - $binds[0]; - $values = $binds[1]; - } else { - /* Fetch only users for a domain. */ - $binds = $this->_getUserKeyFilter('AND'); - $sql = 'SELECT '. $this->_getTableFields('users') . ' FROM ' . $this->_params['tables']['users'] . - ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?' . $binds[0] . - ' ORDER BY user_name'; - array_unshift($binds[1], '%@' . $domain); - $values = $binds[1]; - } - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC); - } - - /** - * Returns the user information for a given user id. - * - * @param integer $user_id The id of the user for which to fetch - * information. - * - * @return array The user information. - */ - function getUser($user_id) - { - $binds = $this->_getUserKeyFilter('AND'); - $sql = 'SELECT '. $this->_getTableFields('users') . ' FROM ' . $this->_params['tables']['users'] . - ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?' . $binds[0]; - array_unshift($binds[1], (int)$user_id); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); - } - - /** - * Returns available virtual emails. - * - * @param string $filter If passed a domain then return all virtual emails - * for the domain, otherwise if passed a user name - * return all virtual emails for that user. - * - * @return array The available virtual emails. - */ - function getVirtuals($filter) - { - /* Check if filtering only for domain. */ - if (($pos = strpos($filter, '@')) === false) { - $where = $this->_getTableField('virtuals', 'virtual_email') . ' LIKE ?'; - $values = array('%@' . $filter); - } else { - $where = $this->_getTableField('virtuals', 'virtual_destination') . ' = ?'; - $values = array($filter); - } - - $binds = $this->_getVirtualKeyFilter('AND'); - $sql = 'SELECT '. $this->_getTableFields('virtuals') . ' FROM ' . $this->_params['tables']['virtuals'] . - ' WHERE ' . $where . $binds[0] . - ' ORDER BY virtual_destination, virtual_email'; - $values = array_merge($values, $binds[1]); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC); - } - - /** - * Returns information for a virtual id. - * - * @param integer $virtual_id The virtual id for which to return - * information. - * - * @return array The virtual email information. - */ - function getVirtual($virtual_id) - { - $binds = $this->_getVirtualKeyFilter('AND'); - $sql = 'SELECT '. $this->_getTableFields('virtuals') . ' FROM ' . $this->_params['tables']['virtuals'] . - ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?' . $binds[0]; - array_unshift($binds[1], (int)$virtual_id); - - Horde::logMessage($sql, 'DEBUG'); - $virtual = $this->_db->getRow($sql, $binds[1], DB_FETCHMODE_ASSOC); - $virtual['stripped_email'] = Vilma::stripUser($virtual['virtual_email']); - - return $virtual; - } - - /** - * Returns the current number of set up users for a domain. - * - * @param string $domain_name The name of the domain for which to - * get the current number of users. - * - * @return integer The current number of users. - */ - function getDomainNumUsers($domain_name) - { - $binds = $this->_getUserKeyFilter('AND'); - $sql = 'SELECT count(' . $this->_getTableField('users', 'user_name') . ')' . - ' FROM ' . $this->_params['tables']['users'] . - ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?' . $binds[0]; - array_unshift($binds[1], '%@' . $domain_name); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->getOne($sql, $binds[1]); - } - - /** - * Saves a domain to the backend. - * - * @param array $info The domain information to save to the backend. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _saveDomain($info) - { - require_once 'Horde/SQL.php'; - - $record = array('domain_name' => $info['name'], - 'domain_transport' => $info['transport'], - 'domain_max_users' => (int)$info['max_users'], - 'domain_quota' => (int)$info['quota']); - - if (empty($info['domain_id'])) { - $record['domain_id'] = $this->_db->nextId($this->_params['tables']['domains']); - if (!empty($this->_params['tables']['domainkey'])) { - $record['domain_key'] = $this->_params['tables']['domainkey']; - } - - $sql = 'INSERT INTO ' . $this->_params['tables']['domains'] . - ' ' . Horde_SQL::insertValues($this->_db, $this->_prepareRecord('domains', $record)); - $values = array(); - } else { - $binds = $this->_getDomainKeyFilter('AND'); - $sql = 'UPDATE ' . $this->_params['tables']['domains'] . - ' SET ' . Horde_SQL::updateValues($this->_db, $this->_prepareRecord('domains', $record)) . - ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?' . $binds[0]; - array_unshift($binds[1], $info['domain_id']); - $values = $binds[1]; - } - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->query($sql, $values); - } - - /** - * Deletes a given domain. - * - * @param integer $domain_id The id of the domain to delete. - * - * @return mixed True on success or PEAR error otherwise. - */ - function _deleteDomain($domain_id) - { - $domain_record = $this->getDomain($domain_id); - if (is_a($domain_record, 'PEAR_Error')) { - return $domain_record; - } - - $domain_name = $domain_record['domain_name']; - - /* Delete all virtual emails for this domain. */ - $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] . - ' WHERE ' . $this->_getTableField('virtuals', 'virtual_email') . ' LIKE ?'; - $values = array('%@' . $domain_name); - $delete = $this->_db->query($sql, $values); - if (is_a($delete, 'PEAR_Error')) { - return $delete; - } - - /* Delete all users for this domain. */ - $sql = 'DELETE FROM ' . $this->_params['tables']['users'] . - ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?'; - $values = array('%@' . $domain_name); - $delete = $this->_db->query($sql, $values); - if (is_a($delete, 'PEAR_Error')) { - return $delete; - } - - /* Finally delete the domain. */ - $sql = 'DELETE FROM ' . $this->_params['tables']['domains'] . - ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?'; - $values = array((int)$domain_id); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->query($sql, $values); - } - - /** - * Saves a user to the backend. - * - * @param array $info The user information to save. - * - * @return array The user information. - */ - function _saveUser($info) - { - global $conf; - - require_once 'Horde/SQL.php'; - - /* Access check (for domainkey). */ - $res = $this->getDomainByName(Vilma::stripDomain($info['user_name'])); - if (is_a($res, 'PEAR_Error')) { - return $res; - } - - $mailboxes = &Vilma::getMailboxDriver(); - if (is_a($mailboxes, 'PEAR_Error')) { - return $mailboxes; - } - - if (empty($info['user_id'])) { - $info['user_id'] = $this->_db->nextId($this->_params['tables']['users']); - $create = true; - } else { - $create = false; - } - - // Slightly hackish. - $mail_dir_base = isset($mailboxes->_params['mail_dir_base']) ? - $mailboxes->_params['mail_dir_base'] : '?'; - - $tuple = array('user_id' => (int)$info['user_id'], - 'user_name' => $info['user_name'], - 'user_full_name' => $info['user_full_name'], - 'user_home_dir' => $mail_dir_base, - 'user_mail_dir' => Vilma::stripDomain($info['user_name']) . '/' . Vilma::stripUser($info['user_name']) . '/', - 'user_mail_quota' => $this->getDomainQuota(Vilma::stripDomain($info['user_name'])) * 1024 * 1024, - 'user_enabled' => (int)$info['user_enabled']); - - // UID and GID are slightly hackish (specific to maildrop driver), too - if (!isset($mailboxes->_params['uid'])) { - $tuple['user_uid'] = -1; - } else { - $tuple['user_uid'] = $mailboxes->_params['uid']; - } - if (!isset($mailboxes->_params['gid'])) { - $tuple['user_gid'] = -1; - } else { - $tuple['user_gid'] = $mailboxes->_params['gid']; - } - - if (!empty($info['password'])) { - $tuple['user_clear'] = $info['password']; - $tuple['user_crypt'] = crypt($info['password'], - substr($info['password'], 0, 2)); - } elseif ($create) { - return PEAR::raiseError(_("Password must be supplied when creating a new user.")); - } - - if ($create) { - $sql = 'INSERT INTO ' . - $this->_params['tables']['users'] . ' ' . - Horde_SQL::insertValues($this->_db, $this->_prepareRecord('users', $tuple)); - } else { - $sql = sprintf('UPDATE %s SET %s WHERE ' . $this->_getTableField('users', 'user_id') . ' = %d', - $this->_params['tables']['users'], - Horde_SQL::updateValues($this->_db, $this->_prepareRecord('users', $tuple)), - (int)$info['user_id']); - } - - Horde::logMessage($sql, 'DEBUG'); - $result = $this->_db->query($sql); - if (is_a($result, 'PEAR_Error')) { - Horde::logMessage($result, 'ERR'); - return $result; - } - - return $info; - } - - /** - * Deletes a requested user. - * - * @param integer $user_id The id of the user to delete. - * - * @return mixed True, or PEAR_Error on failure. - */ - function _deleteUser($user_id) - { - $user = $this->getUser($user_id); - if (is_a($user, 'PEAR_Error')) { - return $user; - } - - /* Delete all virtual emails for this user. */ - $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] . - ' WHERE ' . $this->_getTableField('virtuals', 'virtual_destination') . ' = ?'; - $values = array($user['user_name']); - - Horde::logMessage($sql, 'DEBUG'); - $delete = $this->_db->query($sql, $values); - if (is_a($delete, 'PEAR_Error')) { - return $delete; - } - - /* Delete the actual user. */ - $sql = 'DELETE FROM ' . $this->_params['tables']['users'] . - ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?'; - $values = array((int)$user_id); - - Horde::logMessage($sql, 'DEBUG'); - $result = $this->_db->query($sql, $values); - if (is_a($result, 'PEAR_Error')) { - return $result; - } - - $mailboxes = &Vilma::getMailboxDriver(); - if (is_a($mailboxes, 'PEAR_Error')) { - return $mailboxes; - } - - return $mailboxes->deleteMailbox(Vilma::stripUser($user['user_name']), - Vilma::stripDomain($user['user_name'])); - } - - /** - * Saves virtual email address to the backend. - * - * @param array $info The virtual email data. - * @param string $domain The name of the domain for this virtual email. - * - * @return mixed True on success or PEAR error otherwise. - */ - function saveVirtual(&$info, $domain) - { - /* Access check (for domainkey) */ - $res = $this->getDomainByName($domain); - if (is_a($res, 'PEAR_Error')) { - return $res; - } - - if (empty($info['virtual_id'])) { - $info['virtual_id'] = $this->_db->nextId($this->_params['tables']['virtuals']); - $sql = 'INSERT INTO ' . $this->_params['tables']['virtuals'] . - ' (' . $this->_getTableField('virtuals', 'virtual_email') . ', ' . - $this->_getTableField('virtuals', 'virtual_destination') . ', ' . - $this->_getTableField('virtuals', 'virtual_id') . ') VALUES (?, ?, ?)'; - } else { - $sql = 'UPDATE ' . $this->_params['tables']['virtuals'] . - ' SET ' . $this->_getTableField('virtuals', 'virtual_email') . ' = ?, '. - $this->_getTableField('virtuals', 'virtual_destination') . ' = ?' . - ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?'; - } - $values = array($info['stripped_email'] . '@' . $domain, - $info['virtual_destination'], - $info['virtual_id']); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->query($sql, $values); - } - - /** - * Deletes a virtual email. - * - * @param integer $virtual_id The id of the virtual email to delete. - */ - function deleteVirtual($virtual_id) - { - $binds = $this->_getVirtualKeyFilter('AND'); - $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] . - ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?' . $binds[0]; - array_unshift($binds[1], $virtual_id); - - Horde::logMessage($sql, 'DEBUG'); - return $this->_db->query($sql, $binds[1]); - } - - /** - * Initialise this backend, connect to the SQL database. - * - * @return mixed True on success or PEAR error otherwise. - */ - function initialise() - { - try { - $this->_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('rw', 'vilma', 'storage'); - } catch (Horde_Exception $e) { - return PEAR::raiseError($e->getMessage()); - } - - /* Use default table names if these are not set. */ - if (!isset($this->_params['tables']['domains'])) { - $this->_params['tables']['domains'] = 'vilma_domains'; - } - if (!isset($this->_params['tables']['users'])) { - $this->_params['tables']['users'] = 'vilma_users'; - } - if (!isset($this->_params['tables']['virtuals'])) { - $this->_params['tables']['virtuals'] = 'vilma_virtuals'; - } - - return true; - } - -} diff --git a/vilma/lib/Form/DeleteDomain.php b/vilma/lib/Form/DeleteDomain.php new file mode 100644 index 000000000..0532b6c92 --- /dev/null +++ b/vilma/lib/Form/DeleteDomain.php @@ -0,0 +1,25 @@ + + * + * See the enclosed file LICENSE for license information (BSD). If you did + * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. + * + * @author Ben Klang + * @package Vilma + */ +class Vilma_Form_DeleteDomain extends Horde_Form +{ + public function __construct($vars) + { + parent::Horde_Form($vars, _("Delete Domain")); + + $domain_record = $GLOBALS['vilma']->driver->getDomain($vars->get('domain_id')); + $domain = $domain_record['domain_name']; + + /* Set up the form. */ + $this->setButtons(array(_("Delete"), _("Do not delete"))); + $this->addHidden('', 'domain_id', 'text', false); + $this->addVariable(sprintf(_("Delete domain \"%s\" and all associated email addresses?"), $domain), 'description', 'description', false); + } +} diff --git a/vilma/lib/Form/EditAlias.php b/vilma/lib/Form/EditAlias.php new file mode 100644 index 000000000..9d8db863b --- /dev/null +++ b/vilma/lib/Form/EditAlias.php @@ -0,0 +1,36 @@ + + * + * See the enclosed file LICENSE for license information (BSD). If you did + * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. + * + * @author Ben Klang + * @package Vilma + */ +class Vilma_Form_EditAlias extends Horde_Form +{ + public function __construct($vars) + { + $editing = $vars->get('mode') == 'edit'; + if ($editing) { + $title = sprintf(_("Edit Alias \"%s\" for \"%s\""), + $vars->get('alias_address'), + $vars->get('address')); + } else { + $title = sprintf(_("New Alias for %s"), + $vars->get('address')); + } + parent::Horde_Form($vars, $title); + + /* Set up the form. */ + $this->setButtons(true, true); + $this->addHidden('', 'address', 'text', false); + $this->addHidden('', 'mode', 'text', false); + $this->addHidden('', 'id', 'text', false); + if ($editing) { + $this->addHidden('', 'alias', 'text', false); + } + $this->addVariable(_("Alias Address"), 'alias_address', 'email', true, false, _("The email address to add as an alias for this user. Note that the server must be configured to receive mail for the domain contained in this address.")); + } +} diff --git a/vilma/lib/Form/EditDomain.php b/vilma/lib/Form/EditDomain.php new file mode 100644 index 000000000..bf88faea5 --- /dev/null +++ b/vilma/lib/Form/EditDomain.php @@ -0,0 +1,36 @@ + + * + * See the enclosed file LICENSE for license information (BSD). If you did + * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. + * + * @author Ben Klang + * @package Vilma + */ +class Vilma_Form_EditDomain extends Horde_Form +{ + public function __construct($vars) + { + /* Check if a form is being edited. */ + $editing = $vars->exists('domain_id'); + $domain = $GLOBALS['session']->get('vilma', 'domain'); + parent::Horde_Form($vars, $editing ? _("Edit Domain") : _("New Domain")); + if ($editing && !$this->isSubmitted()) { + $domain = $GLOBALS['vilma']->driver->getDomain($vars->get('domain_id')); + $vars = new Horde_Variables($domain); + } + $vars->add('name', $domain['domain_name']); + $vars->add('transport', $domain['domain_transport']); + $vars->add('max_users', $domain['domain_max_users']); + $vars->add('quota', $domain['domain_quota']); + + /* Set up the form. */ + $this->setButtons(true, true); + $this->addHidden('', 'domain_id', 'text', false); + $this->addVariable(_("Domain"), 'name', 'text', true); + $this->addVariable(_("Transport"), 'transport', 'enum', false, false, null, array(Horde_Array::valuesToKeys($GLOBALS['conf']['mta']['transports']))); + $this->addVariable(_("Max users"), 'max_users', 'int', false); + $this->addVariable(_("Quota"), 'quota', 'int', false, false, _("Value in MB")); + } +} diff --git a/vilma/lib/Form/EditForward.php b/vilma/lib/Form/EditForward.php new file mode 100644 index 000000000..53ff7bb5f --- /dev/null +++ b/vilma/lib/Form/EditForward.php @@ -0,0 +1,36 @@ + + * + * See the enclosed file LICENSE for license information (BSD). If you did + * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. + * + * @author Daniel Collins + * @package Vilma + */ +class Vilma_Form_EditForward extends Horde_Form +{ + public function __construct($vars) + { + $editing = $vars->get('mode') == 'edit'; + if ($editing) { + $title = sprintf(_("Edit Forward \"%s\" for \"%s\""), + $vars->get('forward_address'), + $vars->get('address')); + } else { + $title = sprintf(_("New Forward for %s"), + $vars->get('address')); + } + parent::Horde_Form($vars, $title); + + /* Set up the form. */ + $this->setButtons(true, true); + $this->addHidden('', 'address', 'text', false); + $this->addHidden('', 'mode', 'text', false); + $this->addHidden('', 'id', 'text', false); + if ($editing) { + $this->addHidden('', 'forward', 'text', false); + } + $this->addVariable(_("Forward Address"), 'forward_address', 'email', true, false, _("The email address to add as an forward for this user. Note that the server must be configured to receive mail for the domain contained in this address.")); + } +} diff --git a/vilma/lib/Form/EditUser.php b/vilma/lib/Form/EditUser.php new file mode 100644 index 000000000..71b37be14 --- /dev/null +++ b/vilma/lib/Form/EditUser.php @@ -0,0 +1,63 @@ + + * + * See the enclosed file LICENSE for license information (BSD). If you did + * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. + * + * @author Ben Klang + * @package Vilma + */ +class Vilma_Form_EditUser extends Horde_Form +{ + public function __construct($vars) + { + $type = $vars->get('type'); + $editing = $vars->get('mode') == 'edit'; + switch ($type) { + case 'group': + $title = sprintf(_("Edit Group for \"%s\""), $vars->get('domain')); + $name = _("Group Name"); + break; + case 'forward': + $title = sprintf(_("Edit Forward for \"%s\""), $vars->get('domain')); + $name = _("Forward Name"); + break; + default: + $title = sprintf(_("Edit User for \"%s\""), $vars->get('domain')); + $name = _("User Name"); + break; + } + if (!$editing) { + $title = sprintf(_("New User @%s"), $vars->get('domain')); + } + parent::Horde_Form($vars, $title); + + /* Set up the form. */ + $this->setButtons(true, true); + $this->addHidden('', 'address', 'text', false); + $this->addHidden('', 'mode', 'text', false); + $this->addHidden('', 'domain', 'text', false); + $this->addHidden('', 'id', 'text', false); + if ($editing) { + $this->addHidden('', 'user_name', 'text', false); + } + $this->addVariable($name, 'user_name', 'text', true, $editing, _("Name must begin with an alphanumeric character, must contain only alphanumeric and '._-' characters, and must end with an alphanumeric character."), array('~^[a-zA-Z0-9]{1,1}[a-zA-Z0-9._-]*[a-zA-Z0-9]$~')); + if ($editing) { + $this->addVariable(_("Password"), 'password', 'passwordconfirm', false, false, _("Only enter a password if you wish to change this user's password")); + } else { + $this->addVariable(_("Password"), 'password', 'passwordconfirm', true); + } + $this->addVariable(_("Full Name"), 'user_full_name', 'text', true); + $attrs = $GLOBALS['vilma']->driver->getUserFormAttributes(); + foreach ($attrs as $attr) { + $v = $this->addVariable($attr['label'], $attr['name'], + $attr['type'], $attr['required'], + $attr['readonly'], $attr['description'], + $attr['params']); + if (isset($attr['default'])) { + $v->setDefault($attr['default']); + } + } + } +} diff --git a/vilma/lib/Forms/DeleteDomainForm.php b/vilma/lib/Forms/DeleteDomainForm.php deleted file mode 100644 index ff50da74d..000000000 --- a/vilma/lib/Forms/DeleteDomainForm.php +++ /dev/null @@ -1,29 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you did - * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. - * - * @author Ben Klang - * @package Vilma - */ -class DeleteDomainForm extends Horde_Form { - - function DeleteDomainForm(&$vars) - { - parent::Horde_Form($vars, _("Delete Domain")); - - $domain_record = $GLOBALS['vilma']->driver->getDomain($vars->get('domain_id')); - if (is_a($domain_record, 'PEAR_Error')) { - return $domain_record; - } - - $domain = $domain_record['domain_name']; - - /* Set up the form. */ - $this->setButtons(array(_("Delete"), _("Do not delete"))); - $this->addHidden('', 'domain_id', 'text', false); - $this->addVariable(sprintf(_("Delete domain \"%s\" and all associated email addresses?"), $domain), 'description', 'description', false); - } -} diff --git a/vilma/lib/Forms/EditAliasForm.php b/vilma/lib/Forms/EditAliasForm.php deleted file mode 100644 index f3e1ddf48..000000000 --- a/vilma/lib/Forms/EditAliasForm.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you did - * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. - * - * @author Ben Klang - * @package Vilma - */ - -class EditAliasForm extends Horde_Form { - - function EditAliasForm(&$vars) - { - $type = $vars->get('type'); - $editing = ($vars->get('mode') == 'edit'); - if ($editing) { - $title = sprintf(_("Edit Alias \"%s\" for \"%s\""), $vars->get('alias_address'), $vars->get('address')); - } else { - $title = sprintf(_("New Alias for %s"), $vars->get('address')); - } - parent::Horde_Form($vars, $title); - - /* Set up the form. */ - $this->setButtons(true, true); - $this->addHidden('', 'address', 'text', false); - $this->addHidden('', 'mode', 'text', false); - $this->addHidden('', 'id', 'text', false); - if ($editing) { - $this->addHidden('', 'alias', 'text', false); - } - $name = "Alias Address"; - $type = $vars->get('type'); - $this->addVariable(_($name), 'alias_address', 'email', true, false, _("The email address to add as an alias for this user. Note that the server must be configured to receive mail for the domain contained in this address.")); - } - -} diff --git a/vilma/lib/Forms/EditDomainForm.php b/vilma/lib/Forms/EditDomainForm.php deleted file mode 100644 index 550ba2aa6..000000000 --- a/vilma/lib/Forms/EditDomainForm.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you did - * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. - * - * @author Ben Klang - * @package Vilma - */ - -class EditDomainForm extends Horde_Form { - - function EditDomainForm(&$vars) - { - /* Check if a form is being edited. */ - $editing = $vars->exists('domain_id'); - $domain = $GLOBALS['session']->get('vilma', 'domain'); - parent::Horde_Form($vars, $editing ? _("Edit Domain") : _("New Domain")); - if ($editing && !$this->isSubmitted()) { - $domain = $GLOBALS['vilma']->driver->getDomain($vars->get('domain_id')); - if (is_a($domain, 'PEAR_Error')) { - return $domain; - } - $vars = new Horde_Variables($domain); - } - $vars->add('name', $domain['domain_name']); - $vars->add('transport', $domain['domain_transport']); - $vars->add('max_users', $domain['domain_max_users']); - $vars->add('quota', $domain['domain_quota']); - /* Set up the form. */ - $this->setButtons(true, true); - $this->addHidden('', 'domain_id', 'text', false); - $this->addVariable(_("Domain"), 'name', 'text', true); - require_once 'Horde/Array.php'; - $this->addVariable(_("Transport"), 'transport', 'enum', false, false, null, array(Horde_Array::valuesToKeys($GLOBALS['conf']['mta']['transports']))); - $this->addVariable(_("Max users"), 'max_users', 'int', false); - $this->addVariable(_("Quota"), 'quota', 'int', false, false, _("Value in MB")); - } - -} diff --git a/vilma/lib/Forms/EditForwardForm.php b/vilma/lib/Forms/EditForwardForm.php deleted file mode 100644 index cd3a4f3f4..000000000 --- a/vilma/lib/Forms/EditForwardForm.php +++ /dev/null @@ -1,38 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you did - * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. - * - * @author Daniel Collins - * @package Vilma - */ - -class EditForwardForm extends Horde_Form { - - function EditForwardForm(&$vars) - { - $type = $vars->get('type'); - $editing = ($vars->get('mode') == 'edit'); - if ($editing) { - $title = sprintf(_("Edit Forward \"%s\" for \"%s\""), $vars->get('forward_address'), $vars->get('address')); - } else { - $title = sprintf(_("New Forward for %s"), $vars->get('address')); - } - parent::Horde_Form($vars, $title); - - /* Set up the form. */ - $this->setButtons(true, true); - $this->addHidden('', 'address', 'text', false); - $this->addHidden('', 'mode', 'text', false); - $this->addHidden('', 'id', 'text', false); - if ($editing) { - $this->addHidden('', 'forward', 'text', false); - } - $name = "Forward Address"; - $type = $vars->get('type'); - $this->addVariable(_($name), 'forward_address', 'email', true, false, _("The email address to add as an forward for this user. Note that the server must be configured to receive mail for the domain contained in this address.")); - } - -} diff --git a/vilma/lib/Forms/EditUserForm.php b/vilma/lib/Forms/EditUserForm.php deleted file mode 100644 index e04f30127..000000000 --- a/vilma/lib/Forms/EditUserForm.php +++ /dev/null @@ -1,68 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you did - * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. - * - * @author Ben Klang - * @package Vilma - */ - -class EditUserForm extends Horde_Form { - - function EditUserForm(&$vars) - { - $type = $vars->get('type'); - $editing = ($vars->get('mode') == 'edit'); - if ($editing) { - if($type == 'group') { - $title = sprintf(_("Edit Group for \"%s\""), $vars->get('domain')); - } else if($type == 'forward') { - $title = sprintf(_("Edit Forward for \"%s\""), $vars->get('domain')); - } else { - $title = sprintf(_("Edit User for \"%s\""), $vars->get('domain')); - } - } else { - $title = sprintf(_("New User @%s"), $vars->get('domain')); - } - parent::Horde_Form($vars, $title); - - /* Set up the form. */ - $this->setButtons(true, true); - $this->addHidden('', 'address', 'text', false); - $this->addHidden('', 'mode', 'text', false); - $this->addHidden('', 'domain', 'text', false); - $this->addHidden('', 'id', 'text', false); - if ($editing) { - $this->addHidden('', 'user_name', 'text', false); - } - $name = "User Name"; - $type = $vars->get('type'); - if($type == 'group') { - $name = "Group Name"; - } else if($type == 'forward') { - $name = "Forward Name"; - } - $this->addVariable(_($name), 'user_name', 'text', true, $editing, _("Name must begin with an alphanumeric character, must contain only alphanumeric and '._-' characters, and must end with an alphanumeric character."), array('~^[a-zA-Z0-9]{1,1}[a-zA-Z0-9._-]*[a-zA-Z0-9]$~')); - if ($editing) { - $this->addVariable(_("Password"), 'password', 'passwordconfirm', false, false, _("Only enter a password if you wish to change this user's password")); - } else { - $this->addVariable(_("Password"), 'password', 'passwordconfirm', true); - } - $this->addVariable(_("Full Name"), 'user_full_name', 'text', true); - $attrs = $GLOBALS['vilma']->driver->getUserFormAttributes(); - foreach ($attrs as $attr) { - $v = &$this->addVariable($attr['label'], $attr['name'], - $attr['type'], $attr['required'], - $attr['readonly'], $attr['description'], - $attr['params']); - - if (!isset($attr['default'])) { - $v->setDefault($attr['default']); - } - } - //$this->addVariable(_("Target(s)"), 'target', 'text', false); - } - -} diff --git a/vilma/lib/MailboxDriver.php b/vilma/lib/MailboxDriver.php index 0897bd92f..d9865ae2c 100644 --- a/vilma/lib/MailboxDriver.php +++ b/vilma/lib/MailboxDriver.php @@ -8,101 +8,83 @@ * @author Jason M. Felice * @package Vilma */ -class Vilma_MailboxDriver { - - var $_params; - +abstract class Vilma_MailboxDriver +{ /** - * Constructor. + * A hash containing any parameters for the current driver. * - * @access private + * @var array */ - function Vilma_MailboxDriver($params = array()) - { - $this->_params = $params; - } + protected $_params = array(); /** - * Creates a new mailbox driver instance. - * - * @param string $driver The name of the driver to create an instance of. - * @param array $params Driver-specific parameters. + * Constructor. * - * @return Vilma_MailboxDriver The new driver instance or a PEAR_Error. + * @param array $params Any parameters needed for this driver. */ - function &factory($driver, $params = array()) + public function __construct(array $params = array()) { - require_once VILMA_BASE . '/lib/MailboxDriver/' . $driver . '.php'; - $class = 'Vilma_MailboxDriver_' . $driver; - $mailbox = &new $class($params); - return $mailbox; + $this->_params = $params; } /** - * Returns a mailbox driver instance with the specified params, creating - * it if necessary. + * Creates a new mailbox. * - * @param string $driver The name of the driver to create an instance of. - * @param array $params Driver-specific parameters. + * @param string $user The name of the mailbox to create. + * @param string $domain The name of the domain in which to create the + * mailbox. * - * @return Vilma_MailboxDriver The new driver instance or a PEAR_Error. + * @throws Vilma_Exception */ - function &singleton($driver, $params = array()) - { - static $cache; - $key = serialize(array($driver, $params)); - if (!isset($cache[$key])) { - $ret = &Vilma_MailboxDriver::factory($driver, $params); - if (is_a($ret, 'PEAR_Error')) { - return $ret; - } - $cache[$key] = &$ret; - } - return $cache[$key]; - } + abstract public function createMailbox($user, $domain); /** - * Creates a new mailbox. + * Deletes an existing mailbox. * - * This default implementation only returns an error. + * @param string $user The name of the mailbox to delete. + * @param string $domain The name of the domain in which to delete the + * mailbox. * - * @param string $user The name of the mailbox to create - * @param string $domain The name of the domain in which to create the - * mailbox - * @return mixed True or PEAR_Error:: instance. + * @throws Vilma_Exception */ - function createMailbox($user, $domain) - { - return PEAR::raiseError(_("This driver cannot create mailboxes.")); - } + abstract public function deleteMailbox($user, $domain); /** - * Deletes an existing mailbox. - * - * This default implementation only returns an error. + * Checks whether a mailbox exists and is set up properly. * - * @param string $user The name of the mailbox to delete - * @param string $domain The name of the domain in which to delete the - * mailbox + * @param string $user The name of the mailbox to check. + * @param string $domain The mailbox' domain. * - * @return mixed True or PEAR_Error:: instance. + * @return boolean True if the mailbox exists. + * @throws Vilma_Exception if the mailbox doesn't exist. */ - function deleteMailbox($user, $domain) - { - return PEAR::raiseError(_("This driver cannot delete mailboxes.")); - } + abstract public function checkMailbox($user, $domain); /** - * Checks whether a mailbox exists and is set up properly. + * Creates a new mailbox driver instance. * - * @param string $user The name of the mailbox to check - * @param string $domain The mailbox's domain + * @param string $driver The name of the driver to create an instance of. + * @param array $params Driver-specific parameters. * - * @return mixed True or PEAR_Error:: instance. + * @return Vilma_MailboxDriver The new driver instance. + * @throws Vilma_Exception */ - function checkMailbox($user, $domain) + static public function factory($driver = null, $params = null) { - return true; - } + if (is_null($driver)) { + $driver = $GLOBALS['conf']['mailboxes']['driver']; + } + $driver = Horde_String::ucfirst(basename($driver)); + if (is_null($params)) { + $params = $GLOBALS['conf']['mailboxes']['params']; + } + + $class = 'Vilma_MailboxDriver_' . $driver; + if (class_exists($class)) { + return new $class($params); + } + + throw new Vilma_Exception(sprintf(_("No such mailbox driver \"%s\" found"), $driver)); + } } diff --git a/vilma/lib/MailboxDriver/Hooks.php b/vilma/lib/MailboxDriver/Hooks.php new file mode 100644 index 000000000..4ba2b3e8a --- /dev/null +++ b/vilma/lib/MailboxDriver/Hooks.php @@ -0,0 +1,69 @@ + + * + * See the enclosed file LICENSE for license information (BSD). If you did not + * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. + * + * @author Ben Klang + * @package Vilma + */ + +class Vilma_MailboxDriver_hooks extends Vilma_MailboxDriver +{ + /** + * Creates a new mailbox. + * + * @param string $user The name of the mailbox to create. + * @param string $domain The name of the domain in which to create the + * mailbox. + * + * @throws Vilma_Exception + */ + public function createMailbox($user, $domain) + { + try { + return Horde::callHook('createMailbox', array($user, $domain), 'vilma'); + } catch (Exception $e) { + throw new Vilma_Exception($e); + } + } + + /** + * Deletes an existing mailbox. + * + * @todo + * + * @param string $user The name of the mailbox to delete. + * @param string $domain The name of the domain in which to delete the + * mailbox. + * + * @throws Vilma_Exception + */ + public function deleteMailbox($user, $domain) + { + try { + return Horde::callHook('deleteMailbox', array($user, $domain), 'vilma'); + } catch (Exception $e) { + throw new Vilma_Exception($e); + } + } + + /** + * Checks whether a mailbox exists and is set up properly. + * + * @param string $user The name of the mailbox to check. + * @param string $domain The mailbox' domain. + * + * @return boolean True if the mailbox exists. + * @throws Vilma_Exception if the mailbox doesn't exist. + */ + public function checkMailbox($user, $domain) + { + try { + return Horde::callHook('checkMailbox', array($user, $domain), 'vilma'); + } catch (Exception $e) { + throw new Vilma_Exception($e); + } + } +} diff --git a/vilma/lib/MailboxDriver/Imap.php b/vilma/lib/MailboxDriver/Imap.php new file mode 100644 index 000000000..69ed9d046 --- /dev/null +++ b/vilma/lib/MailboxDriver/Imap.php @@ -0,0 +1,90 @@ + + * @author Jan Schneider + * @package Vilma + */ +class Vilma_MailboxDriver_imap extends Vilma_MailboxDriver +{ + /** + * An IMAP client. + * + * @var Horde_Imap_Client_Base + */ + protected $_imap; + + /** + * Constructor. + * + * @param array $params Any parameters needed for this driver. + */ + public function __construct(array $params = array()) + { + parent::__construct($params); + $params = array('username' => $this->_params['admin_user'], + 'password' => $this->_params['admin_password'], + 'hostspec' => $this->_params['hostspec'], + 'port' => $this->_params['port']); + $this->_imap = Horde_Imap_Client::factory('Socket', $params); + } + + /** + * Creates a new mailbox. + * + * @param string $user The name of the mailbox to create. + * @param string $domain The name of the domain in which to create the + * mailbox. + * + * @throws Vilma_Exception + */ + public function createMailbox($user, $domain) + { + try { + $this->_imap->createMailbox($this->_params['userhierarchy'] . $user . '@' . $domain); + } catch (Exception $e) { + throw new Vilma_Exception($e); + } + } + + /** + * Deletes an existing mailbox. + * + * @todo + * + * @param string $user The name of the mailbox to delete. + * @param string $domain The name of the domain in which to delete the + * mailbox. + * + * @throws Vilma_Exception + */ + public function deleteMailbox($user, $domain) + { + try { + $this->_imap->deleteMailbox($this->_params['userhierarchy'] . $user . '@' . $domain); + } catch (Exception $e) { + throw new Vilma_Exception($e); + } + } + + /** + * Checks whether a mailbox exists and is set up properly. + * + * @param string $user The name of the mailbox to check. + * @param string $domain The mailbox' domain. + * + * @return boolean True if the mailbox exists. + * @throws Vilma_Exception if the mailbox doesn't exist. + */ + public function checkMailbox($user, $domain) + { + if (!$this->_imap->listMailboxes($this->_params['userhierarchy'] . $user . '@' . $domain)) { + throw new Vilma_Exception(sprintf(_("Mailbox \"%s\" does not exist."), $user . '@' . $domain)); + } + return true; + } +} diff --git a/vilma/lib/MailboxDriver/Maildrop.php b/vilma/lib/MailboxDriver/Maildrop.php new file mode 100644 index 000000000..db1d53221 --- /dev/null +++ b/vilma/lib/MailboxDriver/Maildrop.php @@ -0,0 +1,86 @@ + + * @package Vilma + */ +class Vilma_MailboxDriver_maildrop extends Vilma_MailboxDriver +{ + /** + * Creates a new mailbox. + * + * @param string $user The name of the mailbox to create. + * @param string $domain The name of the domain in which to create the + * mailbox. + * + * @throws Vilma_Exception + */ + public function createMailbox($user, $domain) + { + if (empty($this->_params['system_user'])) { + throw new Vilma_Exception(_("No 'system_user' parameter specified to maildrop driver.")); + } + + $shell = sprintf('sudo -u %s maildirmake %s', + escapeshellarg($this->_params['system_user']), + escapeshellarg($this->_getMailboxDir($user, $domain))); + exec($shell); + } + + /** + * Deletes an existing mailbox. + * + * @todo + * + * @param string $user The name of the mailbox to delete. + * @param string $domain The name of the domain in which to delete the + * mailbox. + * + * @throws Vilma_Exception + */ + public function deleteMailbox($user, $domain) + { + } + + /** + * Checks whether a mailbox exists and is set up properly. + * + * @param string $user The name of the mailbox to check. + * @param string $domain The mailbox' domain. + * + * @return boolean True if the mailbox exists. + * @throws Vilma_Exception if the mailbox doesn't exist or a parameter is + * missing + */ + public function checkMailbox($user, $domain) + { + $dir = $this->_getMailboxDir($user, $domain); + + if (!is_dir($dir)) { + throw new Vilma_Exception(sprintf(_("Maildrop directory \"%s\" does not exist."), $dir)); + } + + return true; + } + + /** + * @throws Vilma_Exception + */ + protected function _getMailboxDir($user, $domain) + { + if (empty($this->_params['mail_dir_base'])) { + throw new Vilma_Exception(_("No 'mail_dir_base' parameter specified to maildrop driver.")); + } + + $dir = $this->_params['mail_dir_base']; + if (!empty($this->_params['usedomain'])) { + $dir .= '/' . $domain; + } + + return $dir . '/' . $user; + } +} diff --git a/vilma/lib/MailboxDriver/Null.php b/vilma/lib/MailboxDriver/Null.php new file mode 100644 index 000000000..bcd5a3417 --- /dev/null +++ b/vilma/lib/MailboxDriver/Null.php @@ -0,0 +1,47 @@ + + * @package Vilma + */ +class Vilma_MailboxDriver_null extends Vilma_MailboxDriver +{ + /** + * Creates a new mailbox. + * + * @param string $user The name of the mailbox to create. + * @param string $domain The name of the domain in which to create the + * mailbox. + */ + public function createMailbox($user, $domain) + { + } + + /** + * Deletes an existing mailbox. + * + * @param string $user The name of the mailbox to delete. + * @param string $domain The name of the domain in which to delete the + * mailbox. + */ + public function deleteMailbox($user, $domain) + { + } + + /** + * Checks whether a mailbox exists and is set up properly. + * + * @param string $user The name of the mailbox to check. + * @param string $domain The mailbox' domain. + * + * @return boolean True if the mailbox exists. + */ + public function checkMailbox($user, $domain) + { + return true; + } +} diff --git a/vilma/lib/MailboxDriver/hooks.php b/vilma/lib/MailboxDriver/hooks.php deleted file mode 100644 index ff158e239..000000000 --- a/vilma/lib/MailboxDriver/hooks.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * See the enclosed file LICENSE for license information (BSD). If you did not - * did not receive this file, see http://cvs.horde.org/co.php/vilma/LICENSE. - * - * @author Ben Klang - * @package Vilma - */ - -class Vilma_MailboxDriver_hooks extends Vilma_MailboxDriver { - - function Vilma_MailboxDriver_hooks($params) - { - Horde::loadConfiguration('hooks.php', null, 'vilma'); - } - - - function checkMailbox($user, $domain) - { - if (function_exists('_vilma_hook_checkMailbox')) { - return call_user_func('_vilma_hook_checkMailbox', $user, $domain); - } else { - return true; - } - } - - function createMailbox($user, $domain) - { - if (function_exists('_vilma_hook_createMailbox')) { - return call_user_func('_vilma_hook_createMailbox', $user, $domain); - } else { - return true; - } - } - - function deleteMailbox($user, $domain) - { - if (function_exists('_vilma_hook_deleteMailbox')) { - return call_user_func('_vilma_hook_deleteMailbox', $user, $domain); - } else { - return true; - } - } - -} diff --git a/vilma/lib/MailboxDriver/imap.php b/vilma/lib/MailboxDriver/imap.php deleted file mode 100644 index f3e59fde5..000000000 --- a/vilma/lib/MailboxDriver/imap.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @author Jan Schneider - * @package Vilma - */ -class Vilma_MailboxDriver_imap extends Vilma_MailboxDriver -{ - protected $_imap = null; - - protected function _connect() - { - if ($this->_imap) { - return; - } - $params = array('username' => $this->_params['admin_user'], - 'password' => $this->_params['admin_password'], - 'hostspec' => $this->_params['hostspec'], - 'port' => $this->_params['port']); - $this->_imap = Horde_Imap_Client::factory('Socket', $params); - } - - public function checkMailbox($user, $domain) - { - $this->_connect(); - if (!$this->_imap->listMailboxes($this->_params['userhierarchy'] . $user . '@' . $domain)) { - throw new Vilma_Exception(sprintf(_("Mailbox \"%s\" does not exist."), $user . '@' . $domain)); - } - } - - public function createMailbox($user, $domain) - { - $this->_connect(); - $this->_imap->createMailbox($this->_params['userhierarchy'] . $user . '@' . $domain); - } - - public function deleteMailbox($user, $domain) - { - $this->_connect(); - $this->_imap->deleteMailbox($this->_params['userhierarchy'] . $user . '@' . $domain); - } - -} diff --git a/vilma/lib/MailboxDriver/maildrop.php b/vilma/lib/MailboxDriver/maildrop.php deleted file mode 100644 index 734e547db..000000000 --- a/vilma/lib/MailboxDriver/maildrop.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @package Vilma - */ -class Vilma_MailboxDriver_maildrop extends Vilma_MailboxDriver { - - function _getMailboxDir($user, $domain) - { - if (empty($this->_params['mail_dir_base'])) { - throw new Vilma_Exception(_("No 'mail_dir_base' parameter specified to maildrop driver.")); - } - $dir = $this->_params['mail_dir_base']; - $usedomain = isset($this->_params['usedomain']) ? $this->_params['usedomain'] : false; - if ($usedomain) { - $dir .= '/' . $domain; - } - - return $dir . '/' . $user; - } - - function checkMailbox($user, $domain) - { - static $exists; - - $dir = $this->_getMailboxDir($user, $domain); - if (is_a($dir, 'PEAR_Error')) { - return $dir; - } - - if (!isset($exists[$dir])) { - $exists[$dir] = is_dir($dir); - } - - if (!$exists[$dir]) { - throw new Vilma_Exception(sprintf(_("Maildrop directory \"%s\" does not exist."), $dir)); - } - - return true; - } - - function createMailbox($user, $domain) - { - $dir = $this->_getMailboxDir($user, $domain); - if (is_a($dir, 'PEAR_Error')) { - return $dir; - } - if (empty($this->_params['system_user'])) { - throw new Vilma_Exception(_("No 'system_user' parameter specified to maildrop driver.")); - } - - $create_function = sprintf('sudo -u %s maildirmake %s', - escapeshellarg($this->_params['system_user']), - escapeshellarg($dir)); - exec($create_function); - return true; - } - - /** - * @TODO: Implement - */ - function deleteMailbox($user, $domain) - { - return true; - } - -} diff --git a/vilma/lib/MailboxDriver/null.php b/vilma/lib/MailboxDriver/null.php deleted file mode 100644 index 093fb812c..000000000 --- a/vilma/lib/MailboxDriver/null.php +++ /dev/null @@ -1,28 +0,0 @@ - - * @package Vilma - */ -class Vilma_MailboxDriver_null extends Vilma_MailboxDriver { - - public function checkMailbox($user, $domain) - { - return true; - } - - public function createMailbox($user, $domain) - { - return true; - } - - public function deleteMailbox($user, $domain) - { - return true; - } - -} diff --git a/vilma/lib/Vilma.php b/vilma/lib/Vilma.php index b9d137dc4..5d9a04b1a 100644 --- a/vilma/lib/Vilma.php +++ b/vilma/lib/Vilma.php @@ -12,7 +12,7 @@ class Vilma { /** - * Check whether the current user has administrative permissions over the + * Checks whether the current user has administrative permissions over the * requested domain at the given permissions level. * * Also checks to see if the user is a Vilma superadmin. If the user is a @@ -23,7 +23,7 @@ class Vilma * * @return boolean True if the user has the requested permission. */ - public function hasPermission($domain = null, $permmask = null) + static public function hasPermission($domain = null, $permmask = null) { if ($GLOBALS['registry']->isAdmin()) { return true; @@ -45,35 +45,32 @@ class Vilma return false; } - function getUserMgrTypes() + static public function getUserMgrTypes() { return array( 'all' => array( 'singular' => _("All"), - 'plural' => _("All") ), + 'plural' => _("All")), 'user' => array( 'singular' => _("User"), - 'plural' => _("Users"), ), + 'plural' => _("Users")), 'alias' => array( 'singular' => _("Alias"), - 'plural' => _("Aliases"), ), - //'grpfwd' => array( - // 'singular' => _("Group/Forward"), - // 'plural' => _("Groups and Forwards"), ), ); + 'plural' => _("Aliases")), 'group' => array( 'singular' => _("Group"), - 'plural' => _("Groups"), ), + 'plural' => _("Groups")), 'forward' => array( 'singular' => _("Forward"), - 'plural' => _("Forwards"),), ); + 'plural' => _("Forwards"))); } /** - * Create tabs to navigate the user manager area + * Creates tabs to navigate the user manager area. * - * return object Horde_Core_Ui_Tabs object + * @return Horde_Core_Ui_Tabs */ - function getUserMgrTabs(&$vars) + static public function getUserMgrTabs(Variables $vars) { $url = Horde::url('users/index.php'); $tabs = new Horde_Core_Ui_Tabs('section', $vars); @@ -84,34 +81,38 @@ class Vilma } /** - * Set the current domain + * Set the current domain. */ - function setCurDomain($domain) + static public function setCurDomain($domain = null) { - $GLOBALS['session']->set('vilma', 'domain', $domain); + if ($domain) { + $GLOBALS['session']->set('vilma', 'domain', $domain); + } else { + $GLOBALS['session']->unset('vilma', 'domain'); + } } /** - * Strip the domain from an email address (leaving the Username) + * Strips the domain from an email address (leaving the user name). * - * @param string $email Email address to strip (leaving the Username) + * @param string $email Email address to strip. * - * @return string Username portion of supplied email address + * @return string User name portion of the email address. */ - function stripUser($email) + static public function stripUser($email) { list($user, $domain) = explode('@', $email); return $user; } /** - * Strip the username from an email address (leaving the domain) + * Strip the user name from an email address (leaving the domain). * - * @param string $email Email address to strip (leaving the domain) + * @param string $email Email address to strip. * - * @return string Domain portion of supplied email address + * @return string Domain portion of the email address. */ - function stripDomain($email) + static public function stripDomain($email) { $parts = explode('@', $email); if (count($parts) == 2) { @@ -120,14 +121,4 @@ class Vilma } return null; } - - function &getMailboxDriver() - { - global $conf; - - require_once VILMA_BASE . '/lib/MailboxDriver.php'; - $driver = &Vilma_MailboxDriver::singleton($conf['mailboxes']['driver'], - $conf['mailboxes']['params']); - return $driver; - } } diff --git a/vilma/lib/tests/driver.phpt b/vilma/lib/tests/driver.phpt index 01f9a9413..7ed2eade3 100644 --- a/vilma/lib/tests/driver.phpt +++ b/vilma/lib/tests/driver.phpt @@ -32,7 +32,7 @@ function checkConstruction() unset($unfiltered_params['tables']['domainkey']); } - $GLOBALS['unfiltered'] = &Vilma_Driver::singleton('sql', $unfiltered_params); + $GLOBALS['unfiltered'] = Vilma_Driver::factory('sql', $unfiltered_params); if (is_a($GLOBALS['unfiltered'], 'PEAR_Error')) { printf(_("ERROR(1): %s\n"), $GLOBALS['unfiltered']->getMessage()); return; @@ -41,7 +41,7 @@ function checkConstruction() $filtered_params = $conf['storage']['params']; $filtered_params['tables']['domainkey'] = '__FOO'; - $GLOBALS['filtered'] = &Vilma_Driver::singleton('sql', $filtered_params); + $GLOBALS['filtered'] = Vilma_Driver::factory('sql', $filtered_params); if (is_a($GLOBALS['filtered'], 'PEAR_Error')) { printf(_("ERROR(2): %s\n"), $GLOBALS['filtered']->getMessage()); return; diff --git a/vilma/scripts/create_mailboxes.php b/vilma/scripts/create_mailboxes.php index b3199f009..ab222818b 100644 --- a/vilma/scripts/create_mailboxes.php +++ b/vilma/scripts/create_mailboxes.php @@ -17,12 +17,7 @@ if (!Horde_Cli::runningFromCLI()) { // some variables, etc. Horde_Cli::init(); -/* Make sure there's no compression. */ -@ob_end_clean(); - -$users_by_domain = $vilma->driver->getAllUsers(); - -foreach ($users_by_domain as $domain => $users) { +foreach ($vilma->driver->getAllUsers() as $domain => $users) { foreach ($users as $user) { /* Check for user's home dir. */ if (!file_exists($user['user_home_dir'])) { diff --git a/vilma/users/delete.php b/vilma/users/delete.php index 91f30afa3..f64de0b83 100644 --- a/vilma/users/delete.php +++ b/vilma/users/delete.php @@ -13,166 +13,148 @@ $vilma = Horde_Registry::appInit('vilma'); /* Only admin should be using this. */ if (!Vilma::hasPermission($domain)) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } $vars = Horde_Variables::getDefaultVariables(); -$address = $vars->get('address'); -$section = Horde_Util::getFormData('section','all'); +$user_id = $vars->address; +$section = $vars->get('section', 'all'); -//$addrInfo = $vilma->driver->getAddressInfo($address, 'all'); -/* -$user_id = $vars->get('address'); -$formname = $vars->get('formname'); -$user = $vilma->driver->getUser($user_id); -print_r($vars) . '
'; -echo $user_id . '
'; -echo $fromname . '
'; -print_r($user) . '
'; -$domain = Vilma::stripDomain($user['name']); -$domain = $vilma->driver->getDomainByName($domain); -*/ -$address = $vilma->driver->getAddressInfo($address); -$type = $address['type']; -if(($section == 'all') && ($type == 'alias')) { - $address = $vilma->driver->getAddressInfo($vars->get('address'),$type); +try { + $address = $vilma->driver->getAddressInfo($user_id); + $type = $address['type']; + if ($section == 'all' && $type == 'alias') { + $address = $vilma->driver->getAddressInfo($user_id, $type); + } +} catch (Exception $e) { + $notification->push(sprintf(_("Error reading address information from backend: %s"), $address->getMessage()), 'horde.error'); + Horde::url('users/index.php', true)->redirect(); } -$user_id = $vars->get('address'); + $user = $vilma->driver->getUser($user_id); +/* $aliases = $vilma->driver->_getAliases($user_id); $aliasesCount = 0; -if(is_array($aliases)) { +if (is_array($aliases)) { $aliasesCount = sizeof($aliases); } +*/ + $domain = Vilma::stripDomain($user_id); -$forwards = $vilma->driver->_getGroupsAndForwards('forwards',$domain); +$forwards = $vilma->driver->_getGroupsAndForwards('forwards', $domain); $forwardsCount = 0; -foreach($forwards as $entry) { - foreach($entry['targets'] as $target) { - if($user_id === $target) { +foreach ($forwards as $entry) { + foreach ($entry['targets'] as $target) { + if ($user_id === $target) { $forwardsCount++; } } } -$groups = $vilma->driver->_getGroupsAndForwards('groups',$domain); +$groups = $vilma->driver->_getGroupsAndForwards('groups', $domain); $groupsCount = 0; -foreach($groups as $entry) { - foreach($entry['targets'] as $target) { - if($user_id === $target) { +foreach ($groups as $entry) { + foreach ($entry['targets'] as $target) { + if ($user_id === $target) { $groupsCount++; } } } -if (is_a($address, 'PEAR_Error')) { - $notification->push(sprintf(_("Error reading address information from backend: %s"), $address->getMessage()), 'horde.error'); - $url = '/users/index.php'; - require VILMA_BASE . $url; - exit; -} + $user_name = $address['user_name']; -if(!isset($user_name) || empty($user_name)) { +if (empty($user_name)) { $user_name = $address['address']; } -$vars->set('user_name', Vilma::stripUser($user_name)); +$vars->user_name = Vilma::stripUser($user_name); $domain = Vilma::stripDomain($address); $domain = $vilma->driver->getDomainByName($domain); -$vars->set('domain', $domain); -$vars->set('mode', 'edit'); +$vars->domain = $domain; +$vars->mode = 'edit'; -$form = new Horde_Form($vars, sprintf(_("Delete %s"), $type)); /* Set up the form. */ +$form = new Horde_Form($vars, sprintf(_("Delete %s"), $type)); $form->setButtons(array(_("Delete"), _("Do not delete"))); //$form->addHidden($user_id, 'user_id', 'text', false); $form->addHidden($address['address'], 'address', 'text', false); $form->addHidden($section, 'section', 'text', false); -$desc = "Delete $type \"%s\""; -$sub = " and all dependencies?"; -$tot = $aliasesCount + $groupsCount + $forwardsCount; -if($tot > 0) { - $desc .= $sub; +if ($aliasesCount + $groupsCount + $forwardsCount) { + $desc = _("Delete %s \"%s\" and all dependencies?"); } else { - $desc .= "?"; + $desc = _("Delete %s \"%s\"?"); } -if($aliasesCount > 0) { - $desc .= " Account has " . $aliasesCount . " aliases."; +$desc = sprintf($desc, $type, $user_name); +if ($aliasesCount) { + $desc .= ' ' . sprintf(ngettext("Account has %d alias.", "Account has %d aliases.", $aliasesCount), $aliasesCount); } -if($forwardsCount > 0) { - $desc .= " Account is the target of " . $forwardsCount . " forward(s)."; +if ($forwardsCount) { + $desc .= ' ' . sprintf(ngettext("Account is the target of %d forward.", "Account is the target of %d forwards.", $forwardsCount), $forwardsCount); } -if($groupsCount > 0) { - $desc .= " Account belongs to " . $groupsCount . " group(s)."; +if ($groupsCount) { + $desc .= ' ' . sprintf(ngettext("Account belongs to %d group.", "Account belongs to %d groups.", $groupsCount), $groupsCount); } -$form->addVariable(sprintf(_($desc), $user_name), 'description', 'description', false); -if ($vars->get('submitbutton') == _("Delete")) { - if ($type == 'alias') { - if ($form->validate($vars)) { - $form->getInfo($vars, $info); - $deleteInfo = array(); - $deleteInfo['address'] = $address['destination']; - $deleteInfo['alias'] = $user_id; - $delete = $vilma->driver->deleteAlias($deleteInfo); - if (is_a($delete, 'PEAR_Error')) { - Horde::logMessage($delete, 'ERR'); - $notification->push(sprintf(_("Error deleting alias. %s."), $delete->getMessage()), 'horde.error'); - } else { - $notification->push(_("Alias deleted."), 'horde.success'); - } - Horde::url('users/index.php') - ->add('domain_id', $domain['id']) - ->redirect(); +$form->addVariable($desc, 'description', 'description', false); + +if ($vars->get('submitbutton') == _("Do not delete")) { + $notification->push(_("User not deleted."), 'horde.message'); + Horde::url('users/index.php', true) + ->add('domain_id', $domain['id']) + ->redirect(); +} + +if ($vars->get('submitbutton') == _("Delete") && + $form->validate($vars)) { + $form->getInfo($vars, $info); + + switch ($type) { + case 'alias': + $deleteInfo = array('address' => $address['destination'], + 'alias' => $user_id); + try { + $vilma->driver->deleteAlias($deleteInfo); + $notification->push(_("Alias deleted."), 'horde.success'); + } catch (Exception $e) { + $notification->push(sprintf(_("Error deleting alias. %s."), $e->getMessage()), 'horde.error'); } - } elseif ($type == 'forward') { - if ($form->validate($vars)) { - $form->getInfo($vars, $info); - $deleteInfo = array(); - $deleteInfo['address'] = $address['destination']; - $deleteInfo['forward'] = $user_id; - $delete = $vilma->driver->deleteForward($deleteInfo); - if (is_a($delete, 'PEAR_Error')) { - Horde::logMessage($delete, 'ERR'); - $notification->push(sprintf(_("Error deleting forward. %s."), $delete->getMessage()), 'horde.error'); - } else { - $notification->push(_("Forward deleted."), 'horde.success'); - } - Horde::url('users/index.php') - ->add('domain_id', $domain['id']) - ->redirect(); + Horde::url('users/index.php', true) + ->add('domain_id', $domain['id']) + ->redirect(); + + case 'forward': + $deleteInfo = array('address' => $address['destination'], + 'forward' => $user_id); + try { + $vilma->driver->deleteForward($deleteInfo); + $notification->push(_("Forward deleted."), 'horde.success'); + } catch (Exception $e) { + $notification->push(sprintf(_("Error deleting forward. %s."), $e->getMessage()), 'horde.error'); } - } else { - if ($form->validate($vars)) { - $form->getInfo($vars, $info); - //$delete = $vilma->driver->deleteUser($info['user_id']); - $delete = $vilma->driver->deleteUser($address['address']); - if (is_a($delete, 'PEAR_Error')) { - Horde::logMessage($delete, 'ERR'); - $notification->push(sprintf(_("Error deleting user. %s."), $delete->getMessage()), 'horde.error'); - } else { - $notification->push(_("$type deleted."), 'horde.success'); - } - Horde::url('users/index.php') - ->add('domain_id', $domain['id']) - ->redirect(); + Horde::url('users/index.php', true) + ->add('domain_id', $domain['id']) + ->redirect(); + + default: + try { + $vilma->driver->deleteUser($address['address']); + $notification->push(_("$type deleted."), 'horde.success'); + } catch (Exception $e) { + $notification->push(sprintf(_("Error deleting user. %s."), $e->getMessage()), 'horde.error'); } + Horde::url('users/index.php', true) + ->add('domain_id', $domain['id']) + ->redirect(); } -} elseif ($vars->get('submitbutton') == _("Do not delete")) { - $notification->push(_("User not deleted."), 'horde.message'); - Horde::url('users/index.php') - ->add('domain_id', $domain['id']) - ->redirect(); } /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; -$renderer = &new Horde_Form_Renderer(); +$renderer = new Horde_Form_Renderer(); + +$template = $injector->createInstance('Horde_Template'); Horde::startBuffer(); $form->renderActive($renderer, $vars, 'delete.php', 'post'); -$main = Horde::endBuffer(); +$template->set('main', Horde::endBuffer()); -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); diff --git a/vilma/users/edit.php b/vilma/users/edit.php index 3a7d180a7..3868b060e 100644 --- a/vilma/users/edit.php +++ b/vilma/users/edit.php @@ -14,68 +14,61 @@ require_once dirname(__FILE__) . '/../lib/Application.php'; $vilma = Horde_Registry::appInit('vilma'); -require_once VILMA_BASE . '/lib/Forms/EditUserForm.php'; - /* Only admin should be using this. */ if (!Vilma::hasPermission($domain)) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } -$vars = Horde_Variables::getDefaultVariables(); -$address = $vars->get('address'); -$section = Horde_Util::getFormData('section','all'); -//$addrInfo = $vilma->driver->getAddressInfo($address, 'all'); +$vars = Horde_Variables::getDefaultVariables(); +$address = $vars->address; +$section = $vars->get('section', 'all'); $domain = Vilma::stripDomain($address); /* Check if a form is being edited. */ -if (!$vars->exists('mode')) { +if (!isset($vars->mode)) { if ($address) { - $address = $vilma->driver->getAddressInfo($address,$section); - if (is_a($address, 'PEAR_Error')) { - $notification->push(sprintf(_("Error reading address information from backend: %s"), $address->getMessage()), 'horde.error'); - $url = '/users/index.php'; - require VILMA_BASE . $url; - exit; + try { + $address = $vilma->driver->getAddressInfo($address, $section); + } catch (Exception $e) { + $notification->push(sprintf(_("Error reading address information from backend: %s"), $e->getMessage()), 'horde.error'); + Horde::url('users/index.php', true)->redirect(); } $vars = new Horde_Variables($address); - $user_name = //$vars->get('address'); - $vars->get('user_name'); - $vars->set('user_name', Vilma::stripUser($user_name)); + $user_name = $vars->get('user_name'); + $vars->user_name = Vilma::stripUser($user_name); $domain = Vilma::stripDomain($user_name); - $vars->set('domain', $domain); - $vars->set('type', $address['type']); - $vars->set('target', 'test'); //$address['target']); - $vars->set('mode', 'edit'); + $vars->domain = $domain; + $vars->type = $address['type']; + $vars->target = 'test'; //$address['target']); + $vars->mode = 'edit'; } else { - $vars->set('mode', 'new'); + $vars->mode = 'new'; $domain_info = $session->get('vilma', 'domain'); $domain = $domain_info['domain_name']; $domain_id = $domain_info['domain_id']; - $vars->set('domain', $domain); - $vars->set('id', $domain_id); - $vars->add('user_name', Horde_Util::getFormData('user_name','')); + $vars->domain = $domain; + $vars->id = $domain_id; + $vars->add('user_name', Horde_Util::getFormData('user_name', '')); } } $domain = Vilma::stripDomain($address['address']); -$tmp = $vars->get('domain'); -if(!isset($tmp)) { - $vars->set('domain', $domain); +$tmp = $vars->domain; +if (!$tmp) { + $vars->domain = $domain; } -$form = &new EditUserForm($vars); -if (!$vars->exists('id') && !$vilma->driver->isBelowMaxUsers($domain)) { + +if (!isset($vars->id) && !$vilma->driver->isBelowMaxUsers($domain)) { $notification->push(sprintf(_("\"%s\" already has the maximum number of users allowed."), $domain), 'horde.error'); - require VILMA_BASE . '/users/index.php'; - exit; + Horde::url('users/index.php', true)->redirect(); } + +$form = new Vilma_Form_EditUser($vars); if ($form->validate($vars)) { $form->getInfo($vars, $info); $info['user_name'] = Horde_String::lower($info['user_name']) . '@' . $domain; - $user_id = $vilma->driver->saveUser($info); - if (is_a($user_id, 'PEAR_Error')) { - Horde::logMessage($user_id, 'ERR'); - $notification->push(sprintf(_("Error saving user. %s"), $user_id->getMessage()), 'horde.error'); - } else { + try { + $vilma->driver->saveUser($info); $notification->push(_("User details saved."), 'horde.success'); /* $virtuals = $vilma->driver->getVirtuals($info['name']); @@ -92,20 +85,21 @@ if ($form->validate($vars)) { } */ //exit; + } catch (Exception $e) { + $notification->push(sprintf(_("Error saving user. %s"), $e->getMessage()), 'horde.error'); } } /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; -$renderer = &new Horde_Form_Renderer(); +$renderer = new Horde_Form_Renderer(); + +$template = $injector->createInstance('Horde_Template'); Horde::startBuffer(); $form->renderActive($renderer, $vars, 'edit.php', 'post'); -$main = Horde::endBuffer(); +$template->set('main', Horde::endBuffer()); -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); diff --git a/vilma/users/editAlias.php b/vilma/users/editAlias.php index 9bd8d66ce..790ab16cb 100644 --- a/vilma/users/editAlias.php +++ b/vilma/users/editAlias.php @@ -13,77 +13,69 @@ require_once dirname(__FILE__) . '/../lib/Application.php'; $vilma = Horde_Registry::appInit('vilma'); -require_once VILMA_BASE . '/lib/Forms/EditAliasForm.php'; - /* Only admin should be using this. */ if (!Vilma::hasPermission($domain)) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } $vars = Variables::getDefaultVariables(); -/* If the form is submitted, $vars['mode'] will be set. Catch this and process the submission so that the displayed form accurately indicates the result of the transaction. */ -if ($vars->exists('mode')) { - Horde::logMessage("Submit Detected: " . print_r(serialize($vars), true), 'DEBUG'); - $form = &new EditAliasForm($vars); - +/* If the form is submitted, $vars['mode'] will be set. Catch this and process + * the submission so that the displayed form accurately indicates the result of + * the transaction. */ +if (isset($vars->mode)) { + $form = new Vilma_Form_EditAlias($vars); if ($form->validate($vars)) { $form->getInfo($vars, $info); - $alias_id = $vilma->driver->saveAlias($info); - if (is_a($alias_id, 'PEAR_Error')) { - Horde::logMessage($user_id, 'ERR'); - $notification->push(sprintf(_("Error saving alias. %s"), $alias_id->getMessage()), 'horde.error'); - // remove the mode, and rearrange the alias information to clean - // up the form. - $vars->remove('mode'); - $vars->add('retry', true); - if ($vars->exists('alias')) { - $vars->remove('alias_address'); - } elseif ($vars->exists('address')) { - $vars->remove('alias_address'); - $vars->remove('alias'); - } - } else { + try { + $alias_id = $vilma->driver->saveAlias($info); $notification->push(_("Alias saved."), 'horde.success'); - Horde::url('users/index.php') + Horde::url('users/index.php', true) ->add('domain_id', $domain['id']) ->redirect(); + } catch (Exception $e) { + Horde::logMessage($e); + $notification->push(sprintf(_("Error saving alias. %s"), $e->getMessage()), 'horde.error'); + // Remove the mode, and rearrange the alias information to clean + // up the form. + unset($vars->mode); + $vars->add('retry', true); + if (isset($vars->alias)) { + unset($vars->alias_address); + } elseif (isset($vars->address)) { + unset($vars->alias_address, $vars->alias); + } } } } /* Check if a form is being edited. */ -if (!$vars->exists('mode') || $vars->getExists('retry')) { - Horde::logMessage("No-Submit Detected: " . print_r(serialize($vars), true), 'DEBUG'); - if ($vars->exists("alias")) { - $alias = $vars->get("alias"); - Horde::logMessage("Alias Detected: $alias", 'DEBUG'); - - $addrInfo = $vilma->driver->getAddressInfo($alias,'alias'); - Horde::logMessage("addrInfo contains: " . print_r($addrInfo, true), 'DEBUG'); - if (is_a($addrInfo, 'PEAR_Error')) { - $notification->push(sprintf(_("Error reading address information from backend: %s"), $addrInfo->getMessage()), 'horde.error'); - $url = '/users/index.php'; - require VILMA_BASE . $url; - exit; +if (!isset($vars->mode) || $vars->retry) { + if (isset($vars->alias)) { + $alias = $vars->alias; + try { + $addrInfo = $vilma->driver->getAddressInfo($alias, 'alias'); + $address = $vilma->driver->getAddressInfo($addrInfo['destination']); + } catch (Exception $e) { + $notification->push(sprintf(_("Error reading address information from backend: %s"), $e->getMessage()), 'horde.error'); + Horde::url('users/index.php', true)->redirect(); } - $address = $vilma->driver->getAddressInfo($addrInfo['destination']); - Horde::logMessage("address Info contains: " . print_r($address, true), 'DEBUG'); $vars = new Variables($address); - $vars->set('mode', 'edit'); + $vars->mode = 'edit'; $vars->add('alias_address', $alias); $vars->add('alias', $alias); $vars->add('address', $address['address']); - } elseif ($vars->exists("address")) { - $tmp_address = $vars->get("address"); - Horde::logMessage("Address Detected: $tmp_address", 'DEBUG'); - - $address = $vilma->driver->getAddressInfo($tmp_address, 'all'); - Horde::logMessage("addrInfo contains: " . print_r($addrInfo, true), 'DEBUG'); + } elseif (isset($vars->address)) { + try { + $address = $vilma->driver->getAddressInfo($vars->address, 'all'); + } catch (Exception $e) { + $notification->push(sprintf(_("Error reading address information from backend: %s"), $e->getMessage()), 'horde.error'); + Horde::url('users/index.php', true)->redirect(); + } $vars = new Variables($address); - $vars->set('mode', 'new'); + $vars->mode = 'new'; } - $form = &new EditAliasForm($vars); + $form = new Vilma_Form_EditAlias($vars); /* if ($form->validate($vars)) { $form->getInfo($vars, $info); @@ -98,18 +90,16 @@ if (!$vars->exists('mode') || $vars->getExists('retry')) { */ } - /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; -$renderer = &new Horde_Form_Renderer(); +$renderer = new Horde_Form_Renderer(); + +$template = $injector->createInstance('Horde_Template'); Horde::startBuffer(); $form->renderActive($renderer, $vars, 'editAlias.php', 'post'); -$main = Horde::endBuffer(); +$template->set('main', Horde::endBuffer()); -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); diff --git a/vilma/users/editForward.php b/vilma/users/editForward.php index 4822db8e9..6ee88da15 100644 --- a/vilma/users/editForward.php +++ b/vilma/users/editForward.php @@ -13,73 +13,62 @@ require_once dirname(__FILE__) . '/../lib/Application.php'; $vilma = Horde_Registry::appInit('vilma'); -require_once VILMA_BASE . '/lib/Forms/EditForwardForm.php'; - /* Only admin should be using this. */ if (!Vilma::hasPermission($domain)) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } -$vars = Variables::getDefaultVariables(); -/* If the form is submitted, $vars['mode'] will be set. Catch this and process the submission so that the displayed form accurately indicates the result of the transaction. */ -if ($vars->exists('mode')) { - Horde::logMessage("Submit Detected: " . print_r(serialize($vars), true), 'DEBUG'); - $form = &new EditForwardForm($vars); +$vars = Variables::getDefaultVariables(); - if ($form->validate($vars)) { - $form->getInfo($vars, $info); - $forward_id = $vilma->driver->saveForward($info); - if (is_a($forward_id, 'PEAR_Error')) { - Horde::logMessage($user_id, 'ERR'); - $notification->push(sprintf(_("Error saving forward. %s"), $forward_id->getMessage()), 'horde.error'); - // remove the mode, and rearrange the forward information to clean up the form. - $vars->remove('mode'); - $vars->add('retry', true); - if ($vars->exists('forward')) { - $vars->remove('forward_address'); - } elseif ($vars->exists('address')) { - $vars->remove('forward_address'); - $vars->remove('forward'); - } - } else { - $notification->push(_("forward saved."), 'horde.success'); - } - } -} // if +/* If the form is submitted, $vars['mode'] will be set. Catch this and process + * the submission so that the displayed form accurately indicates the result of + * the transaction. */ +if (isset($vars->mode)) { + $form = new Vilma_Form_EditForward($vars); + if ($form->validate($vars)) { + $form->getInfo($vars, $info); + try { + $forward_id = $vilma->driver->saveForward($info); + $notification->push(_("forward saved."), 'horde.success'); + } catch (Exception $e) { + Horde::logMessage($e); + $notification->push(sprintf(_("Error saving forward. %s"), $e->getMessage()), 'horde.error'); + // Remove the mode, and rearrange the forward information to clean + // up the form. + unset($vars->mode); + $vars->add('retry', true); + if (isset($vars->forward)) { + unset($vars->forward_address); + } elseif (isset($vars->address)) { + unset($vars->forward_address, $vars->forward); + } + } + } +} /* Check if a form is being edited. */ -if (!$vars->exists('mode') || $vars->getExists('retry')) { - Horde::logMessage("No-Submit Detected: " . print_r(serialize($vars), true), 'DEBUG'); - if ($vars->exists("forward")) { - $forward = $vars->get("forward"); - Horde::logMessage("Forward Detected: $forward", 'DEBUG'); - - $addrInfo = $vilma->driver->getAddressInfo($forward,'forward'); - Horde::logMessage("addrInfo contains: " . print_r($addrInfo, true), 'DEBUG'); - if (is_a($addrInfo, 'PEAR_Error')) { - $notification->push(sprintf(_("Error reading address information from backend: %s"), $addrInfo->getMessage()), 'horde.error'); - $url = '/users/index.php'; - require VILMA_BASE . $url; - exit; +if (!isset($vars->mode) || $vars->retry) { + if (isset($vars->forward)) { + try { + $addrInfo = $vilma->driver->getAddressInfo($vars->forward, 'forward'); + $address = $vilma->driver->getAddressInfo($addrInfo['destination']); + } catch (Exception $e) { + Horde::logMessage($e); + $notification->push(sprintf(_("Error reading address information from backend: %s"), $e->getMessage()), 'horde.error'); + Horde::url('users/index.php', true)->redirect(); } - $address = $vilma->driver->getAddressInfo($addrInfo['destination']); - Horde::logMessage("address Info contains: " . print_r($address, true), 'DEBUG'); $vars = new Variables($address); - $vars->set('mode', 'edit'); + $vars->mode = 'edit'; $vars->add('forward_address', $forward); $vars->add('forward', $forward); $vars->add('address', $address['address']); - } elseif ($vars->exists("address")) { - $tmp_address = $vars->get("address"); - Horde::logMessage("Address Detected: $tmp_address", 'DEBUG'); - - $address = $vilma->driver->getAddressInfo($tmp_address, 'all'); - Horde::logMessage("addrInfo contains: " . print_r($addrInfo, true), 'DEBUG'); + } elseif (isset($vars->address)) { + $address = $vilma->driver->getAddressInfo($vars->address, 'all'); $vars = new Variables($address); - $vars->set('mode', 'new'); + $vars->mode = 'new'; } - $form = &new EditforwardForm($vars); + $form = new EditforwardForm($vars); /* if ($form->validate($vars)) { $form->getInfo($vars, $info); @@ -94,18 +83,16 @@ if (!$vars->exists('mode') || $vars->getExists('retry')) { */ } - /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; -$renderer = &new Horde_Form_Renderer(); +$renderer = new Horde_Form_Renderer(); + +$template = $injector->createInstance('Horde_Template'); Horde::startBuffer(); $form->renderActive($renderer, $vars, 'editForward.php', 'post'); -$main = Horde::endBuffer(); +$template->set('main', Horde::endBuffer()); -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); diff --git a/vilma/users/index.php b/vilma/users/index.php index 22607bd0f..6da905322 100644 --- a/vilma/users/index.php +++ b/vilma/users/index.php @@ -15,117 +15,93 @@ $vilma = Horde_Registry::appInit('vilma'); /* Only admin should be using this. */ if (!Vilma::hasPermission($curdomain)) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } -// Input validation: make sure we have a valid section +// Input validation: make sure we have a valid section. $vars = Horde_Variables::getDefaultVariables(); -$section = $vars->get('section'); -$tmp = Vilma::getUserMgrTypes(); -if (!array_key_exists($section, Vilma::getUserMgrTypes())) { - $section = 'all'; - $vars->set('section', $section); +$section = $vars->section; +$types = Vilma::getUserMgrTypes(); +if (!isset($types[$section])) { + $vars->section = $section = 'all'; } $tabs = Vilma::getUserMgrTabs($vars); -$addresses = $vilma->driver->getAddresses($curdomain['domain_name'], $section); -if (is_a($addresses, 'PEAR_Error')) { - $notification->push($addresses); - Horde::url('index.php')->redirect(); +try { + $addresses = $vilma->driver->getAddresses($curdomain['domain_name'], $section); +} catch (Exception $e) { + $notification->push($e); + Horde::url('index.php', true)->redirect(); } // Page results -$page = Horde_Util::getGet('page', 0); $perpage = $prefs->getValue('addresses_perpage'); -$url = 'users/index.php'; -$url = Horde_Util::addParameter($url, 'section', $section); +$url = Horde::url('users/index.php')->add('section', $section); $pager = new Horde_Core_Ui_Pager('page', - Horde_Variables::getDefaultVariables(), - array('num' => count($addresses), - 'url' => $url, - 'page_count' => 10, - 'perpage' => $perpage)); -$addresses = array_slice($addresses, $page*$perpage, $perpage); + $vars, + array('num' => count($addresses), + 'url' => $url, + 'page_count' => 10, + 'perpage' => $perpage)); +$addresses = array_slice($addresses, $vars->page * $perpage, $perpage); -$types = Vilma::getUserMgrTypes(); -foreach ($addresses as $i => $address) { +foreach ($addresses as &$address) { $type = $address['type']; $id = $address['id']; - if($type === 'alias') { - $url = Horde::url('users/editAlias.php'); - $url = Horde_Util::addParameter($url, 'alias', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['edit_url'] = $url; - $addresses[$i]['add_alias_url'] = false; - $addresses[$i]['add_forward_url'] = false; - } elseif($type === 'forward') { - $url = Horde::url('users/editForward.php'); - $url = Horde_Util::addParameter($url, 'forward', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['edit_url'] = $url; - $addresses[$i]['add_alias_url'] = false; - $addresses[$i]['add_forward_url'] = false; - } else { - $url = Horde::url('users/edit.php'); - $url = Horde_Util::addParameter($url, 'address', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['edit_url'] = $url; - $url = Horde::url('users/editAlias.php'); - $url = Horde_Util::addParameter($url, 'address', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['add_alias_url'] = $url; - $url = Horde::url('users/editForward.php'); - $url = Horde_Util::addParameter($url, 'address', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['add_forward_url'] = $url; + switch ($type) { + case 'alias': + $address['edit_url'] = Horde::url('users/editAlias.php') + ->add(array('alias' => $id, 'section' => $section)); + $address['add_alias_url'] = $address['add_forward_url'] = false; + break; + case 'forward': + $address['edit_url'] = Horde::url('users/editForward.php') + ->add(array('forward' => $id, 'section' => $section)); + $address['add_alias_url'] = $address['add_forward_url'] = false; + break; + default: + $params = array('address' => $id, 'section' => $section); + $address['edit_url'] = Horde::url('users/edit.php') + ->add($params); + $address['add_alias_url'] = Horde::url('users/editAlias.php') + ->add($params); + $address['add_forward_url'] = Horde::url('users/editForward.php') + ->add($params); + break; } - $url = Horde::url('users/delete.php'); $currentAddress = $address['address']; - if(!isset($currentAddress) || empty($currentAddress)) { + if (empty($currentAddress)) { $currentAddress = $address['user_name'] . $address['domain']; } - $url = Horde_Util::addParameter($url, 'address', $currentAddress); - //$addresses[$i]['del_url'] = Horde_Util::addParameter($url, 'address', $id); - $addresses[$i]['del_url'] = Horde_Util::addParameter($url, 'section', $section); - //$url = Horde::url('users/edit.php'); - //$addresses[$i]['view_url'] = Horde_Util::addParameter($url, 'address', $address['user_name']); + $address['del_url'] = $url = Horde::url('users/delete.php') + ->add(array('address' => $currentAddress, 'section' => $section)); - if($type === 'alias') { - $url = Horde::url('users/editAlias.php'); - $url = Horde_Util::addParameter($url, 'alias', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['view_url'] = $url; - } elseif ($type === 'forward') { - $url = Horde::url('users/editForward.php'); - $url = Horde_Util::addParameter($url, 'forward', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['view_url'] = $url; - } else { - $url = Horde::url('users/edit.php'); - $url = Horde_Util::addParameter($url, 'address', $id); - $url = Horde_Util::addParameter($url, 'section', $section); - $addresses[$i]['view_url'] = $url; + switch ($type) { + case 'alias': + $address['view_url'] = Horde::url('users/editAlias.php') + ->add(array('alias' => $id, 'section' => $section)); + break; + case 'forward': + $address['view_url'] = Horde::url('users/editForward.php') + ->add(array('forward' => $id, 'section' => $section)); + break; + default: + $address['view_url'] = Horde::url('users/edit.php') + ->add(array('address' => $id, 'section' => $section)); + break; } - $addresses[$i]['type'] = $types[$address['type']]['singular']; - $addresses[$i]['status'] = $vilma->driver->getUserStatus($address); -} - -/* Set up the template action links. */ -if ($vilma->driver->isBelowMaxUsers($curdomain['domain_name'])) { - $url = Horde::url('users/edit.php'); - $maxusers = ''; -} else { - $maxusers = _("Maximum Users"); + $address['type'] = $types[$address['type']]['singular']; + $address['status'] = $vilma->driver->getUserStatus($address); } -$url = Horde::url('virtuals/edit.php'); - /* Set up the template fields. */ $template = $injector->createInstance('Horde_Template'); $template->setOption('gettext', true); -$template->set('addresses', $addresses, true); -$template->set('maxusers', $maxusers, true); +$template->set('addresses', $addresses); +if (!$vilma->driver->isBelowMaxUsers($curdomain['domain_name'])) { + $template->set('maxusers', _("Maximum Users")); +} $template->set('menu', Horde::menu()); $template->set('tabs', $tabs->render()); diff --git a/vilma/virtuals/delete.php b/vilma/virtuals/delete.php index 725330794..d80dc82e2 100644 --- a/vilma/virtuals/delete.php +++ b/vilma/virtuals/delete.php @@ -13,17 +13,24 @@ $vilma = Horde_Registry::appInit('vilma'); /* Only admin should be using this. */ if (!$registry->isAdmin()) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } $vars = Horde_Variables::getDefaultVariables(); -$virtual_id = $vars->get('virtual_id'); -$formname = $vars->get('formname'); +$virtual_id = $vars->virtual_id; +$formname = $vars->formname; $virtual = $vilma->driver->getVirtual($virtual_id); $domain = Vilma::stripDomain($virtual['virtual_email']); $domain = $vilma->driver->getDomainByName($domain); +if ($vars->submitbutton == _("Do not delete")) { + $notification->push(_("Virtual email not deleted."), 'horde.message'); + Horde::url('virtuals/index.php') + ->add('domain_id', $domain['domain_id']) + ->redirect(); +} + $form = new Horde_Form($vars, _("Delete Virtual Email Address")); /* Set up the form. */ @@ -31,38 +38,30 @@ $form->setButtons(array(_("Delete"), _("Do not delete"))); $form->addHidden('', 'virtual_id', 'text', false); $form->addVariable(sprintf(_("Delete the virtual email address \"%s\" => \"%s\"?"), $virtual['virtual_email'], $virtual['virtual_destination']), 'description', 'description', false); -if ($vars->get('submitbutton') == _("Delete")) { - if ($form->validate($vars)) { - $form->getInfo($vars, $info); +if ($vars->submitbutton == _("Delete") && + $form->validate($vars)) { + $form->getInfo($vars, $info); + try { $delete = $vilma->driver->deleteVirtual($info['virtual_id']); - if (is_a($delete, 'PEAR_Error')) { - Horde::logMessage($delete, 'ERR'); - $notification->push(sprintf(_("Error deleting virtual email. %s."), $delete->getMessage()), 'horde.error'); - } else { - $notification->push(_("Virtual email deleted."), 'horde.success'); - Horde::url('virtuals/index.php') - ->add('domain_id', $domain['domain_id']) - ->redirect(); - } + $notification->push(_("Virtual email deleted."), 'horde.success'); + Horde::url('virtuals/index.php', true) + ->add('domain_id', $domain['domain_id']) + ->redirect(); + } catch (Exception $e) { + Horde::logMessage($e); + $notification->push(sprintf(_("Error deleting virtual email. %s."), $e->getMessage()), 'horde.error'); } -} elseif ($vars->get('submitbutton') == _("Do not delete")) { - $notification->push(_("Virtual email not deleted."), 'horde.message'); - Horde::url('virtuals/index.php') - ->add('domain_id', $domain['domain_id']) - ->redirect(); } /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; -$renderer = &new Horde_Form_Renderer(); +$renderer = new Horde_Form_Renderer(); + +$template = $injector->createInstance('Horde_Template'); Horde::startBuffer(); $form->renderActive($renderer, $vars, 'delete.php', 'post'); -$main = Horde::endBuffer(); - -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); +$template->set('main', Horde::endBuffer()); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); diff --git a/vilma/virtuals/edit.php b/vilma/virtuals/edit.php index f1cd4b0a7..1c0323b97 100644 --- a/vilma/virtuals/edit.php +++ b/vilma/virtuals/edit.php @@ -13,14 +13,14 @@ $vilma = Horde_Registry::appInit('vilma'); /* Only admin should be using this. */ if (!$registry->isAdmin() && !Vilma::isDomainAdmin()) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } $domain = Vilma::getDomain(); $vars = Horde_Variables::getDefaultVariables(); -$virtual_id = $vars->get('virtual_id'); -$user = $vars->get('user'); -$formname = $vars->get('formname'); +$virtual_id = $vars->virtual_id; +$user = $vars->user; +$formname = $vars->formname; /* Check if a form is being edited. */ $editing = false; @@ -30,7 +30,7 @@ if ($virtual_id && !$formname) { } if (empty($domain)) { - $domain = Vilma::stripDomain($vars->get('virtual_destination')); + $domain = Vilma::stripDomain($vars->virtual_destination); } $users = $vilma->driver->getUsers($domain); $user_list = array(); @@ -39,7 +39,7 @@ foreach ($users as $user) { $user_list[$user['user_name']] = $virtual_destination; } -$form = new Horde_Form($vars, ($editing) ? _("Edit Virtual Email Address") : _("New Virtual Email Address")); +$form = new Horde_Form($vars, $editing ? _("Edit Virtual Email Address") : _("New Virtual Email Address")); /* Set up the form. */ $form->setButtons(true, true); @@ -50,9 +50,8 @@ $var = &$form->addVariable(_("Destination type"), 'destination_type', 'enum', true, false, null, array(array('local' => _("Local user"), 'remote' => _("Remote address")))); -$action = Horde_Form_Action::factory('reload'); -$var->setAction($action); -if ($vars->get('destination_type') == 'remote') { +$var->setAction(Horde_Form_Action::factory('reload')); +if ($vars->destination_type == 'remote') { $form->addVariable(_("Remote e-mail address"), 'virtual_destination', 'email', true, false); } else { @@ -66,29 +65,28 @@ if ($form->validate($vars)) { if ($info['destination_type'] == 'remote') { $info['virtual_destination'] = Horde_String::lower($info['virtual_destination']); } - $virtual_id = $vilma->driver->saveVirtual($info, $domain); - if (is_a($virtual_id, 'PEAR_Error')) { - Horde::logMessage($virtual_id, 'ERR'); - $notification->push(sprintf(_("Error saving virtual email. %s."), $virtual_id->getMessage()), 'horde.error'); - } else { + try { + $virtual_id = $vilma->driver->saveVirtual($info, $domain); $notification->push(_("Virtual email saved."), 'horde.success'); - Horde::url('virtuals/index.php') + Horde::url('virtuals/index.php', true) ->add('user', $info['virtual_destination']) ->redirect(); + } catch (Exception $e) { + Horde::logMessage($e); + $notification->push(sprintf(_("Error saving virtual email. %s."), $e->getMessage()), 'horde.error'); } } /* Render the form. */ -require_once 'Horde/Form/Renderer.php'; $renderer = new Horde_Form_Renderer(); +$template = $injector->createInstance('Horde_Template'); + Horde::startBuffer(); $form->renderActive($renderer, $vars, 'edit.php', 'post'); -$main = Horde::endBuffer(); +$template->set('main', Horde::endBuffer()); -$template = $injector->createInstance('Horde_Template'); -$template->set('main', $main); -$template->set('menu', Vilma::getMenu('string')); +$template->set('menu', Horde::menu()); Horde::startBuffer(); $notification->notify(array('listeners' => 'status')); diff --git a/vilma/virtuals/index.php b/vilma/virtuals/index.php index 73a4ffec4..e49ce90e1 100644 --- a/vilma/virtuals/index.php +++ b/vilma/virtuals/index.php @@ -13,28 +13,28 @@ $vilma = Horde_Registry::appInit('vilma'); /* Only admin should be using this. */ if (!$registry->isAdmin() && !Vilma::isDomainAdmin()) { - $registry->authenticateFailure('vilma', $e); + $registry->authenticateFailure('vilma'); } $user = Horde_Util::getFormData('user'); -if (!empty($user)) { - $virtuals = $vilma->driver->getVirtuals($user); - $domain = Vilma::stripDomain($user); -} else { - $domain = Vilma::getDomain(); - $virtuals = $vilma->driver->getVirtuals($domain); -} - -if (is_a($virtuals, 'PEAR_Error')) { - $notification->push($virtuals); - Horde::url('index.php')->redirect(); +try { + if (!empty($user)) { + $virtuals = $vilma->driver->getVirtuals($user); + $domain = Vilma::stripDomain($user); + } else { + $domain = Vilma::getDomain(); + $virtuals = $vilma->driver->getVirtuals($domain); + } +} catch (Exception $e) { + $notification->push($e); + Horde::url('index.php', true)->redirect(); } foreach ($virtuals as $id => $virtual) { - $url = Horde::url('virtuals/edit.php'); - $virtuals[$id]['edit_url'] = Horde_Util::addParameter($url, 'virtual_id', $virtual['virtual_id']); - $url = Horde::url('virtuals/delete.php'); - $virtuals[$id]['del_url'] = Horde_Util::addParameter($url, 'virtual_id', $virtual['virtual_id']); + $virtuals[$id]['edit_url'] = Horde::url('virtuals/edit.php') + ->add('virtual_id', $virtual['virtual_id']); + $virtuals[$id]['del_url'] = Horde::url('virtuals/delete.php') + ->add('virtual_id', $virtual['virtual_id']); } $template = $injector->createInstance('Horde_Template'); @@ -44,10 +44,16 @@ $template->set('virtuals', $virtuals, true); /* Set up the template action links. */ $actions = array(); $url = Horde::url('virtuals/edit.php'); -$actions['new_url'] = (Vilma::isDomainAdmin() ? $url : Horde_Util::addParameter($url, 'domain', $domain)); +if (!Vilma::isDomainAdmin()) { + $url->add('domain', $domain); +} +$actions['new_url'] = $url; $actions['new_text'] = _("New Virtual Email"); $url = Horde::url('users/index.php'); -$actions['users_url'] = (Vilma::isDomainAdmin() ? $url : Horde_Util::addParameter($url, 'domain', $domain)); +if (!Vilma::isDomainAdmin()) { + $url->add('domain', $domain); +} +$actions['users_url'] = $url; $actions['users_text'] = _("Users"); $template->set('actions', $actions);