| | |
| | | |
| | | const JS_OBJECT_NAME = 'rcmail'; |
| | | |
| | | const ERROR_STORAGE = -2; |
| | | const ERROR_INVALID_REQUEST = 1; |
| | | const ERROR_INVALID_HOST = 2; |
| | | const ERROR_COOKIES_DISABLED = 3; |
| | | |
| | | |
| | | /** |
| | | * This implements the 'singleton' design pattern |
| | | * |
| | |
| | | |
| | | // create user object |
| | | $this->set_user(new rcube_user($_SESSION['user_id'])); |
| | | |
| | | // configure session (after user config merge!) |
| | | $this->session_configure(); |
| | | |
| | | // set task and action properties |
| | | $this->set_task(rcube_utils::get_input_value('_task', rcube_utils::INPUT_GPC)); |
| | |
| | | $this->config->set_user_prefs((array)$this->user->get_prefs()); |
| | | } |
| | | |
| | | $_SESSION['language'] = $this->user->language = $this->language_prop($this->config->get('language', $_SESSION['language'])); |
| | | $lang = $this->language_prop($this->config->get('language', $_SESSION['language'])); |
| | | $_SESSION['language'] = $this->user->language = $lang; |
| | | |
| | | // set localization |
| | | setlocale(LC_ALL, $_SESSION['language'] . '.utf8', 'en_US.utf8'); |
| | | setlocale(LC_ALL, $lang . '.utf8', $lang . '.UTF-8', 'en_US.utf8', 'en_US.UTF-8'); |
| | | |
| | | // workaround for http://bugs.php.net/bug.php?id=18556 |
| | | if (in_array($_SESSION['language'], array('tr_TR', 'ku', 'az_AZ'))) |
| | | setlocale(LC_CTYPE, 'en_US' . '.utf8'); |
| | | if (in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) { |
| | | setlocale(LC_CTYPE, 'en_US.utf8', 'en_US.UTF-8'); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Return instance of the internal address book class |
| | | * |
| | | * @param string Address book identifier |
| | | * @param string Address book identifier (-1 for default addressbook) |
| | | * @param boolean True if the address book needs to be writeable |
| | | * |
| | | * @return rcube_contacts Address book object |
| | |
| | | { |
| | | $contacts = null; |
| | | $ldap_config = (array)$this->config->get('ldap_public'); |
| | | $abook_type = strtolower($this->config->get('address_book_type')); |
| | | |
| | | // 'sql' is the alias for '0' used by autocomplete |
| | | if ($id == 'sql') |
| | | $id = '0'; |
| | | $id = '0'; |
| | | else if ($id == -1) { |
| | | $id = $this->config->get('default_addressbook'); |
| | | $default = true; |
| | | } |
| | | |
| | | // use existing instance |
| | | if (isset($this->address_books[$id]) && is_object($this->address_books[$id]) |
| | | && is_a($this->address_books[$id], 'rcube_addressbook') |
| | | && (!$writeable || !$this->address_books[$id]->readonly) |
| | | ) { |
| | | if (isset($this->address_books[$id]) && ($this->address_books[$id] instanceof rcube_addressbook)) { |
| | | $contacts = $this->address_books[$id]; |
| | | } |
| | | else if ($id && $ldap_config[$id]) { |
| | |
| | | if ($plugin['instance'] instanceof rcube_addressbook) { |
| | | $contacts = $plugin['instance']; |
| | | } |
| | | // get first source from the list |
| | | else if (!$id) { |
| | | $source = reset($this->get_address_sources($writeable)); |
| | | if (!empty($source)) { |
| | | $contacts = $this->get_address_book($source['id']); |
| | | if ($contacts) |
| | | $id = $source['id']; |
| | | } |
| | | } |
| | | |
| | | // Get first addressbook from the list if configured default doesn't exist |
| | | // This can happen when user deleted the addressbook (e.g. Kolab folder) |
| | | if (!$contacts && (!$id || $default)) { |
| | | $source = reset($this->get_address_sources($writeable)); |
| | | if (!empty($source)) { |
| | | $contacts = $this->get_address_book($source['id']); |
| | | if ($contacts) |
| | | $id = $source['id']; |
| | | } |
| | | } |
| | | |
| | |
| | | 'file' => __FILE__, 'line' => __LINE__, |
| | | 'message' => "Addressbook source ($id) not found!"), |
| | | true, true); |
| | | } |
| | | |
| | | if ($writeable && $contacts->readonly) { |
| | | return null; |
| | | } |
| | | |
| | | // set configured sort order |
| | |
| | | $autocomplete = (array) $this->config->get('autocomplete_addressbooks'); |
| | | $list = array(); |
| | | |
| | | // We are using the DB address book |
| | | if ($abook_type != 'ldap') { |
| | | // We are using the DB address book or a plugin address book |
| | | if ($abook_type != 'ldap' && $abook_type != '') { |
| | | if (!isset($this->address_books['0'])) |
| | | $this->address_books['0'] = new rcube_contacts($this->db, $this->get_user_id()); |
| | | $list['0'] = array( |
| | |
| | | } |
| | | $list[$id] = array( |
| | | 'id' => $id, |
| | | 'name' => $prop['name'], |
| | | 'name' => html::quote($prop['name']), |
| | | 'groups' => is_array($prop['groups']), |
| | | 'readonly' => !$prop['writable'], |
| | | 'hidden' => $prop['hidden'], |
| | |
| | | |
| | | /** |
| | | * Init output object for GUI and add common scripts. |
| | | * This will instantiate a rcmail_template object and set |
| | | * This will instantiate a rcube_output_html object and set |
| | | * environment vars according to the current session and configuration |
| | | * |
| | | * @param boolean True if this request is loaded in a (i)frame |
| | |
| | | if (!($this->output instanceof rcube_output_html)) |
| | | $this->output = new rcube_output_html($this->task, $framed); |
| | | |
| | | // set keep-alive/check-recent interval |
| | | if ($this->session && ($keep_alive = $this->session->get_keep_alive())) { |
| | | $this->output->set_env('keep_alive', $keep_alive); |
| | | } |
| | | // set keep-alive interval |
| | | $this->output->set_env('keep_alive', $this->config->get('keep_alive', 0)); |
| | | $this->output->set_env('session_lifetime', $this->config->get('session_lifetime', 0) * 60); |
| | | |
| | | if ($framed) { |
| | | $this->comm_path .= '&_framed=1'; |
| | |
| | | $this->output->set_charset(RCMAIL_CHARSET); |
| | | |
| | | // add some basic labels to client |
| | | $this->output->add_label('loading', 'servererror', 'requesttimedout'); |
| | | $this->output->add_label('loading', 'servererror', 'requesttimedout', 'refreshing'); |
| | | |
| | | return $this->output; |
| | | } |
| | |
| | | * @param string Mail storage (IMAP) user name |
| | | * @param string Mail storage (IMAP) password |
| | | * @param string Mail storage (IMAP) host |
| | | * @param bool Enables cookie check |
| | | * |
| | | * @return boolean True on success, False on failure |
| | | */ |
| | | function login($username, $pass, $host=NULL) |
| | | function login($username, $pass, $host = null, $cookiecheck = false) |
| | | { |
| | | $this->login_error = null; |
| | | |
| | | if (empty($username)) { |
| | | return false; |
| | | } |
| | | |
| | | if ($cookiecheck && empty($_COOKIE)) { |
| | | $this->login_error = self::ERROR_COOKIES_DISABLED; |
| | | return false; |
| | | } |
| | | |
| | |
| | | break; |
| | | } |
| | | } |
| | | if (!$allowed) |
| | | return false; |
| | | if (!$allowed) { |
| | | $host = null; |
| | | } |
| | | else if (!empty($config['default_host']) && $host != rcube_utils::parse_host($config['default_host'])) |
| | | } |
| | | else if (!empty($config['default_host']) && $host != rcube_utils::parse_host($config['default_host'])) { |
| | | $host = null; |
| | | } |
| | | |
| | | if (!$host) { |
| | | $this->login_error = self::ERROR_INVALID_HOST; |
| | | return false; |
| | | } |
| | | |
| | | // parse $host URL |
| | | $a_host = parse_url($host); |
| | |
| | | $username .= '@'.rcube_utils::parse_host($config['username_domain'], $host); |
| | | } |
| | | |
| | | if (!isset($config['login_lc'])) { |
| | | $config['login_lc'] = 2; // default |
| | | } |
| | | |
| | | // Convert username to lowercase. If storage backend |
| | | // is case-insensitive we need to store always the same username (#1487113) |
| | | if ($config['login_lc']) { |
| | | $username = mb_strtolower($username); |
| | | if ($config['login_lc'] == 2 || $config['login_lc'] === true) { |
| | | $username = mb_strtolower($username); |
| | | } |
| | | else if (strpos($username, '@')) { |
| | | // lowercase domain name |
| | | list($local, $domain) = explode('@', $username); |
| | | $username = $local . '@' . mb_strtolower($domain); |
| | | } |
| | | } |
| | | |
| | | // try to resolve email address from virtuser table |
| | |
| | | |
| | | // Here we need IDNA ASCII |
| | | // Only rcube_contacts class is using domain names in Unicode |
| | | $host = rcube_utils::idn_to_ascii($host); |
| | | if (strpos($username, '@')) { |
| | | // lowercase domain name |
| | | list($local, $domain) = explode('@', $username); |
| | | $username = $local . '@' . mb_strtolower($domain); |
| | | $username = rcube_utils::idn_to_ascii($username); |
| | | } |
| | | $host = rcube_utils::idn_to_ascii($host); |
| | | $username = rcube_utils::idn_to_ascii($username); |
| | | |
| | | // user already registered -> overwrite username |
| | | if ($user = rcube_user::query($username, $host)) |
| | | if ($user = rcube_user::query($username, $host)) { |
| | | $username = $user->data['username']; |
| | | } |
| | | |
| | | $storage = $this->get_storage(); |
| | | |
| | | // try to log in |
| | | if (!($login = $storage->connect($host, $username, $pass, $port, $ssl))) { |
| | | // try with lowercase |
| | | $username_lc = mb_strtolower($username); |
| | | if ($username_lc != $username) { |
| | | // try to find user record again -> overwrite username |
| | | if (!$user && ($user = rcube_user::query($username_lc, $host))) |
| | | $username_lc = $user->data['username']; |
| | | |
| | | if ($login = $storage->connect($host, $username_lc, $pass, $port, $ssl)) |
| | | $username = $username_lc; |
| | | } |
| | | } |
| | | |
| | | // exit if login failed |
| | | if (!$login) { |
| | | if (!$storage->connect($host, $username, $pass, $port, $ssl)) { |
| | | return false; |
| | | } |
| | | |
| | |
| | | // Configure environment |
| | | $this->set_user($user); |
| | | $this->set_storage_prop(); |
| | | $this->session_configure(); |
| | | |
| | | // fix some old settings according to namespace prefix |
| | | $this->fix_namespace_settings($user); |
| | |
| | | $_SESSION['login_time'] = time(); |
| | | |
| | | if (isset($_REQUEST['_timezone']) && $_REQUEST['_timezone'] != '_default_') |
| | | $_SESSION['timezone'] = floatval($_REQUEST['_timezone']); |
| | | if (isset($_REQUEST['_dstactive']) && $_REQUEST['_dstactive'] != '_default_') |
| | | $_SESSION['dst_active'] = intval($_REQUEST['_dstactive']); |
| | | $_SESSION['timezone'] = rcube_utils::get_input_value('_timezone', rcube_utils::INPUT_GPC); |
| | | |
| | | // force reloading complete list of subscribed mailboxes |
| | | $storage->clear_cache('mailboxes', true); |
| | |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Returns error code of last login operation |
| | | * |
| | | * @return int Error code |
| | | */ |
| | | public function login_error() |
| | | { |
| | | if ($this->login_error) { |
| | | return $this->login_error; |
| | | } |
| | | |
| | | if ($this->storage && $this->storage->get_error_code() < -1) { |
| | | return self::ERROR_STORAGE; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | |
| | | |
| | | if (is_array($default_host)) { |
| | | $post_host = rcube_utils::get_input_value('_host', rcube_utils::INPUT_POST); |
| | | $post_user = rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST); |
| | | |
| | | list($user, $domain) = explode('@', $post_user); |
| | | |
| | | // direct match in default_host array |
| | | if ($default_host[$post_host] || in_array($post_host, array_values($default_host))) { |
| | | $host = $post_host; |
| | | } |
| | | |
| | | // try to select host by mail domain |
| | | list($user, $domain) = explode('@', rcube_utils::get_input_value('_user', rcube_utils::INPUT_POST)); |
| | | if (!empty($domain)) { |
| | | else if (!empty($domain)) { |
| | | foreach ($default_host as $storage_host => $mail_domains) { |
| | | if (is_array($mail_domains) && in_array_nocase($domain, $mail_domains)) { |
| | | $host = $storage_host; |
| | |
| | | */ |
| | | public function url($p) |
| | | { |
| | | if (!is_array($p)) |
| | | if (!is_array($p)) { |
| | | if (strpos($p, 'http') === 0) |
| | | return $p; |
| | | |
| | | $p = array('_action' => @func_get_arg(0)); |
| | | } |
| | | |
| | | $task = $p['_task'] ? $p['_task'] : ($p['task'] ? $p['task'] : $this->task); |
| | | $p['_task'] = $task; |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Registers action aliases for current task |
| | | * |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Returns current action filename |
| | | * |
| | |
| | | |
| | | return strtr($this->action, '-', '_') . '.inc'; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Fixes some user preferences according to namespace handling change. |
| | |
| | | } |
| | | else { |
| | | if (!empty($date)) { |
| | | $timestamp = rcube_strtotime($date); |
| | | $timestamp = rcube_utils::strtotime($date); |
| | | } |
| | | |
| | | if (empty($timestamp)) { |
| | |
| | | $err_code = $this->storage->get_error_code(); |
| | | $res_code = $this->storage->get_response_code(); |
| | | |
| | | if ($err_code < 0) { |
| | | $this->output->show_message('storageerror', 'error'); |
| | | } |
| | | else if ($res_code == rcube_storage::NOPERM) { |
| | | if ($res_code == rcube_storage::NOPERM) { |
| | | $this->output->show_message('errornoperm', 'error'); |
| | | } |
| | | else if ($res_code == rcube_storage::READONLY) { |
| | |
| | | else { |
| | | $this->output->show_message('servererrormsg', 'error', array('msg' => $err_str)); |
| | | } |
| | | } |
| | | else if ($err_code < 0) { |
| | | $this->output->show_message('storageerror', 'error'); |
| | | } |
| | | else if ($fallback) { |
| | | $this->output->show_message($fallback, 'error', $fallback_args); |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Returns real size (calculated) of the message part |
| | | * |
| | | * @param rcube_message_part Message part |
| | | * |
| | | * @return string Part size (and unit) |
| | | */ |
| | | public function message_part_size($part) |
| | | { |
| | | if (isset($part->d_parameters['size'])) { |
| | | $size = $this->show_bytes((int)$part->d_parameters['size']); |
| | | } |
| | | else { |
| | | $size = $part->size; |
| | | if ($part->encoding == 'base64') { |
| | | $size = $size / 1.33; |
| | | } |
| | | |
| | | $size = '~' . $this->show_bytes($size); |
| | | } |
| | | |
| | | return $size; |
| | | } |
| | | |
| | | |
| | | /************************************************************************ |
| | | ********* Deprecated methods (to be removed) ********* |
| | | ***********************************************************************/ |
| | |
| | | |
| | | if (!$storage->connect($host, $user, $pass, $port, $ssl)) { |
| | | if (is_object($this->output)) { |
| | | $error = $storage->get_error_code() == -1 ? 'storageerror' : 'sessionerror'; |
| | | $this->output->show_message($error, 'error'); |
| | | $this->output->show_message('storageerror', 'error'); |
| | | } |
| | | } |
| | | else { |
| | | $this->set_storage_prop(); |
| | | return $storage->is_connected(); |
| | | } |
| | | } |
| | | |
| | | return false; |
| | | return $storage->is_connected(); |
| | | } |
| | | } |