diff --git a/modules/core/functions.php b/modules/core/functions.php index d1bc61fc43..9ade1c45e6 100644 --- a/modules/core/functions.php +++ b/modules/core/functions.php @@ -608,3 +608,17 @@ function get_special_folders($mod, $id) { } return array(); } + +/** + * @subpackage core/functions + */ +if (!hm_exists('check_file_upload')) { +function check_file_upload($request, $key) { + if (!is_array($request->files) || !array_key_exists($key, $request->files)) { + return false; + } + if (!is_array($request->files[$key]) || !array_key_exists('tmp_name', $request->files[$key])) { + return false; + } + return true; +}} diff --git a/modules/imap/functions.php b/modules/imap/functions.php index d80bf67687..0ff29302ab 100644 --- a/modules/imap/functions.php +++ b/modules/imap/functions.php @@ -1518,7 +1518,7 @@ function parse_sieve_config_host($host) { }} if (!hm_exists('connect_to_imap_server')) { - function connect_to_imap_server($address, $name, $port, $user, $pass, $tls, $imap_sieve_host, $enableSieve, $type, $context, $hidden = false, $server_id = false) { + function connect_to_imap_server($address, $name, $port, $user, $pass, $tls, $imap_sieve_host, $enableSieve, $type, $context, $hidden = false, $server_id = false, $show_errors = true) { $imap_list = array( 'name' => $name, 'server' => $address, @@ -1567,11 +1567,16 @@ function connect_to_imap_server($address, $name, $port, $user, $pass, $tls, $ima $sieveClientFactory = new Hm_Sieve_Client_Factory(); $client = $sieveClientFactory->init(null, $server); - if (!$client) { + if (!$client && $show_errors) { Hm_Msgs::add("ERRFailed to authenticate to the Sieve host"); } } catch (Exception $e) { - Hm_Msgs::add("ERRFailed to authenticate to the Sieve host"); + if ($show_errors) { + Hm_Msgs::add("ERRFailed to authenticate to the Sieve host"); + } + if (! $server_id) { + Hm_IMAP_List::del($imap_server_id); + } return; } } @@ -1580,9 +1585,11 @@ function connect_to_imap_server($address, $name, $port, $user, $pass, $tls, $ima if (imap_authed($imap)) { return $imap_server_id; - }else { + } else { Hm_IMAP_List::del($imap_server_id); - Hm_Msgs::add('ERRAuthentication failed'); + if ($show_errors) { + Hm_Msgs::add('ERRAuthentication failed'); + } return null; } } diff --git a/modules/nux/assets/data/server_accounts_sample.csv b/modules/nux/assets/data/server_accounts_sample.csv index 2cd5a1cf03..06b08ad8dd 100644 --- a/modules/nux/assets/data/server_accounts_sample.csv +++ b/modules/nux/assets/data/server_accounts_sample.csv @@ -1,2 +1,3 @@ -server_name;jmap_server;jmap_hide_from_combined_view;username;password;imap_port;imap_tls;imap_hide_from_combined_view;imap_server;smtp_server;smtp_port;smtp_tls;sieve_host;sieve_port -Exemple;;FALSE;email@exemple.org;secret;993;TRUE;FALSE;imap.exemple.org;smtp.exemple.org;465;TRUE;tls://imap.exemple.org;4190 \ No newline at end of file +server_name;username;password;jmap_server;jmap_hide_from_combined_view;imap_server;imap_port;imap_tls;imap_hide_from_combined_view;smtp_server;smtp_port;smtp_tls;sieve_host;sieve_port;profile_reply_to;profile_signature;profile_is_default +Mailbox 1;email@example.org;secret;;FALSE;imap.example.org;993;TRUE;FALSE;smtp.example.org;465;TRUE;tls://imap.exemple.org;4190;email@example.org;;FALSE +Mailbox 2;test@example2.org;secret2;jmap.example2.org;FALSE;;;;;smtp.example2.org;465;TRUE;tls://jmap.example2.org;4190;test@example2.org;my-signature;TRUE \ No newline at end of file diff --git a/modules/nux/assets/data/server_accounts_sample.yaml b/modules/nux/assets/data/server_accounts_sample.yaml index 44c9cdb30e..951c3a9504 100644 --- a/modules/nux/assets/data/server_accounts_sample.yaml +++ b/modules/nux/assets/data/server_accounts_sample.yaml @@ -1,15 +1,14 @@ -Test1: +Mailbox 1: + username: email@example.org + password: secret jmap: server: - hide_from_combined_view: false - user: - username: email@example.org - password: secret + hide_from_combined_view: imap: + server: imap.example.org port: 993 tls: true hide_from_combined_view: false - server: imap.example.org smtp: server: smtp.example.org port: 465 @@ -17,20 +16,29 @@ Test1: sieve: host: tls://imap.example.org port: 4190 -Test2: + profile: + reply_to: email@example.org + signature: + is_default: false +Mailbox 2: + username: test@example2.org + password: secret2 jmap: - server: - user: - username: email@example.org - password: secret + server: jmap.example2.org + hide_from_combined_view: false imap: - port: 993 - tls: true - server: mail.example.org + server: + port: + tls: + hide_from_combined_view: smtp: - server: mail.example.org + server: smtp.example2.org port: 465 tls: true sieve: - host: tls://mail.example.org + host: tls://jmap.example2.org port: 4190 + profile: + reply_to: test@example2.org + signature: my-signature + is_default: true diff --git a/modules/nux/functions.php b/modules/nux/functions.php index ed9d747e8c..5020a31d3f 100644 --- a/modules/nux/functions.php +++ b/modules/nux/functions.php @@ -1,5 +1,4 @@ $value) { + $line_data[$key] = convert_to_boolean($value); + } + $rows[] = $line_data; } } } return $rows; }} +if (!hm_exists('convert_to_boolean')) { +function convert_to_boolean($value) { + if (in_array($value, ['true', '1', 'yes'])) { + return true; + } elseif (in_array($value, ['false', '0', 'no'])) { + return false; + } + return $value; +}} + /** * @subpackage nux/functions */ diff --git a/modules/nux/modules.php b/modules/nux/modules.php index 24040c88aa..7685fd558a 100644 --- a/modules/nux/modules.php +++ b/modules/nux/modules.php @@ -11,8 +11,9 @@ if (!defined('DEBUG_MODE')) { die(); } require_once APP_PATH.'modules/nux/functions.php'; -require_once APP_PATH . 'modules/nux/services.php'; -require_once APP_PATH . 'modules/profiles/hm-profiles.php'; +require_once APP_PATH.'modules/nux/services.php'; +require_once APP_PATH.'modules/profiles/hm-profiles.php'; +require_once APP_PATH.'modules/profiles/functions.php'; /** * @subpackage nux/handler @@ -275,184 +276,142 @@ public function process() list($success, $form) = $this->process_form(array('accounts_source')); if ($success) { - if (!is_array($this->request->files) || !array_key_exists('accounts_sample', $this->request->files)) { + if (! check_file_upload($this->request, 'accounts_sample')) { + Hm_Msgs::add('ERRError while uploading accounts sample'); return; } - if (!is_array($this->request->files['accounts_sample']) || !array_key_exists('tmp_name', $this->request->files['accounts_sample'])) { - return; - } - - if ($this->request->files['accounts_sample']['type'] == 'application/x-yaml') { - try { + try { + $extension = pathinfo($this->request->files['accounts_sample']['name'], PATHINFO_EXTENSION); + if (in_array(strtolower($extension), ['yaml', 'yml'])) { $servers = Yaml::parseFile($this->request->files['accounts_sample']['tmp_name']); - foreach ($servers as $key => $value) { - if (empty($value['user']['username']) or empty($value['user']['password'])) { - Hm_Msgs::add('ERRUsername and password are required for: ' . $key . ' server'); - return; - } - if ($value['jmap'] && !empty($value['jmap']['server'])) { - if (!$this->module_is_supported('jmap')) { - Hm_Msgs::add("ERRJMAP module is not enabled"); - }else { - $jmap_server_id = connect_to_imap_server( - $value['jmap']['server'], - $key, - null, - $value['user']['username'], - $value['user']['password'], - false, - null, - false, - 'jmap', - $this, - $value['imap']['hide_from_combined_view'] - ); - if ($jmap_server_id !== null) { - Hm_Msgs::add("JMAP Server " . $key . " saved"); - } - } - }elseif ($value['imap'] && !empty($value['imap']['server'])) { - // Check if module is supported - if (!$this->module_is_supported('imap')) { - Hm_Msgs::add("ERRIMAP module is not enabled"); - }else { - //TO DO: check first if the imap_server server is already configured before connecting can use the in_server_list function or create a new one specifically for my case - $imap_server_id = connect_to_imap_server( - $value['imap']['server'], - $key, - $value['imap']['port'], - $value['user']['username'], - $value['user']['password'], - $value['imap']['tls'], - $value['sieve']['host'].':'.$value['sieve']['port'], - !empty($value['sieve']['sieve_port']) && !empty($value['sieve']['sieve_host']) ? true : false, - 'imap', - $this, - $value['imap']['hide_from_combined_view'] - ); - if ($imap_server_id !== null) { - Hm_Msgs::add("Server " . $key . " saved"); - } - } - } - if ($value['smtp'] && !empty($value['smtp']['server'])) { - // Check if module is supported - if (!$this->module_is_supported('smtp')) { - Hm_Msgs::add("ERRSMTP module is not enabled"); + } elseif ($this->request->files['accounts_sample']['type'] == 'text/csv'){ + $servers = []; + $server_data = parse_csv_with_headers($this->request->files['accounts_sample']['tmp_name']); + + // Process keys to have same structure as yaml for single processing below + foreach ($server_data as $server_row) { + $data = []; + $server_name = $server_row['server_name']; + unset($server_row['server_name']); + foreach ($server_row as $key => $value) { + if (strpos($key, '_') !== false) { + list($prefix, $suffix) = explode('_', $key, 2); + $data[$prefix][$suffix] = $value; } else { - //TO DO: check first if the smtp_server server is already configured before connecting. can use the in_server_list function or create a new one specifically for my case - $smtp_server_id = connect_to_smtp_server( - $value['smtp']['server'], - $key, - $value['smtp']['port'], - $value['user']['username'], - $value['user']['password'], - $value['smtp']['tls'], - false - ); - if ($smtp_server_id !== null) { - Hm_Msgs::add("SMTP Server " . $key . " saved"); - } - } - } - // Verify connection requirements - if (($jmap_server_id === null && $imap_server_id === null) || $smtp_server_id === null) { - if ($jmap_server_id !== null) { - Hm_IMAP_List::del($jmap_server_id); - } - if ($imap_server_id !== null) { - Hm_IMAP_List::del($imap_server_id); - } - if ($smtp_server_id !== null) { - Hm_SMTP_List::del($smtp_server_id); + $data[$key] = $value; } } + $servers[$server_name] = $data; } - } catch (\Throwable $th) { - Hm_Msgs::add('ERR' . $th->getMessage()); } - }elseif($this->request->files['accounts_sample']['type'] == 'text/csv'){ - try { - $server_data = parse_csv_with_headers($this->request->files['accounts_sample']['tmp_name']); - foreach ($server_data as $server) { - if ($server['jmap_server'] && !empty($server['jmap_server'])) { - if (!$this->module_is_supported('jmap')) { - Hm_Msgs::add("ERRJMAP module is not enabled"); - }else { - $jmap_server_id = connect_to_imap_server( - $server['jmap_server'], - $server['server_name'], - null, - $server['username'], - $server['password'], - false, - null, - false, - 'jmap', - $this, - $server['hide_from_combined_view'] === "TRUE" - ); - if ($jmap_server_id !== null) { - Hm_Msgs::add("JMAP Server " . $server['server_name'] . " saved"); - } - } - }elseif($server['imap_server'] && !empty($server['imap_server'])) { - if (!$this->module_is_supported('imap')) { - Hm_Msgs::add("ERRIMAP module is not enabled"); - }else { - $imap_server_id = connect_to_imap_server( - $server['imap_server'], - $server['server_name'], - $server['imap_port'], - $server['username'], - $server['password'], - $server['imap_tls'] === "TRUE", - $server['sieve_host'].':'.$server['sieve_port'], - !empty($server['sieve_port']) && !empty($server['sieve_host']) ? true : false, - 'imap', - $this, - $server['imap_hide_from_combined_view'] === "TRUE" - ); - if ($imap_server_id !== null) { - Hm_Msgs::add("Server " . $server['server_name'] . " saved"); - } - } + } catch (\Exception $e) { + Hm_Msgs::add('ERR' . $e->getMessage()); + return; + } + if(empty($servers)) { + Hm_Msgs::add('ERRImported file is empty'); + return; + } + $errors = []; + foreach ($servers as $server_name => $server) { + $jmap_server_id = $imap_server_id = $smtp_server_id = null; + if (! empty($server['jmap']['server'])) { + if (! $this->module_is_supported('jmap')) { + $errors[] = 'JMAP module is not enabled'; + } else { + $jmap_server_id = connect_to_imap_server( + $server['jmap']['server'], + $server_name, + null, + $server['username'], + $server['password'], + false, + null, + false, + 'jmap', + $this, + $server['jmap']['hide_from_combined_view'], + false, + false + ); + if (! $jmap_server_id) { + $errors[] = "Failed to save server $server_name: JMAP problem"; + continue; } - if ($server['smtp_server'] && !empty($server['smtp_server'])) { - if (!$this->module_is_supported('smtp')) { - Hm_Msgs::add("ERRSMTP module is not enabled"); - } else { - $smtp_server_id = connect_to_smtp_server( - $server['smtp_server'], - $server['server_name'], - $server['smtp_port'], - $server['username'], - $server['password'], - $server['smtp_tls'] === "TRUE", - false - ); - if ($smtp_server_id !== null) { - Hm_Msgs::add("SMTP Server " . $server['server_name'] . " saved"); - } - } + } + } elseif (! empty($server['imap']['server'])) { + if (! $this->module_is_supported('imap')) { + $errors[] = 'IMAP module is not enabled'; + } else { + $imap_server_id = connect_to_imap_server( + $server['imap']['server'], + $server_name, + $server['imap']['port'], + $server['username'], + $server['password'], + $server['imap']['tls'], + $server['sieve']['host'].':'.($server['sieve']['port'] ?? 4190), + ! empty($server['sieve']['host']), + 'imap', + $this, + $server['imap']['hide_from_combined_view'], + false, + false + ); + if (! $imap_server_id) { + $errors[] = "Failed to save server $server_name: IMAP problem"; + continue; } - // Verify connection requirements - if (($jmap_server_id === null && $imap_server_id === null) || $smtp_server_id === null) { - if ($jmap_server_id !== null) { + } + } + if (! empty($server['smtp']['server'])) { + if (!$this->module_is_supported('smtp')) { + $errors[] = 'SMTP module is not enabled'; + } else { + $smtp_server_id = connect_to_smtp_server( + $server['smtp']['server'], + $server_name, + $server['smtp']['port'], + $server['username'], + $server['password'], + $server['smtp']['tls'], + false + ); + if (! $smtp_server_id) { + $errors[] = "Failed to save server $server_name: SMTP problem"; + if ($jmap_server_id) { Hm_IMAP_List::del($jmap_server_id); - } - if ($imap_server_id !== null) { + } elseif ($imap_server_id) { Hm_IMAP_List::del($imap_server_id); } - if ($smtp_server_id !== null) { - Hm_SMTP_List::del($smtp_server_id); - } - } + continue; + } } - } catch (\Exception $ex) { - Hm_Msgs::add('ERR' . $ex->getMessage()); } + if(! empty($server['profile']['reply_to']) && ($imap_server_id || $jmap_server_id) && $smtp_server_id) { + if (!$this->module_is_supported('profiles')) { + $errors[] = 'Profiles module is not enabled'; + continue; + } + + add_profile( + $server_name, + $server['profile']['signature'], + $server['profile']['reply_to'], + $server['profile']['is_default'], + $server['username'], + ($server['jmap']['server'] ?? $server['imap']['server']), + $smtp_server_id, + ($jmap_server_id ?? $imap_server_id), + $this + ); + } + } + foreach (array_unique($errors) as $error) { + Hm_Msgs::add("ERR$error"); } + $this->save_hm_msgs(); + Hm_Dispatch::page_redirect('?page=servers'); } } } @@ -507,17 +466,17 @@ protected function output() { '