diff --git a/python/tests/test_account.py b/python/tests/test_account.py index d1d63b3c0..fc5e13aa3 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -19,6 +19,7 @@ class TestOfflineAccountBasic: d = ac1.get_info() assert d["arch"] assert d["number_of_chats"] == "0" + assert d["bcc_self"] == "1" def test_is_not_configured(self, acfactory): ac1 = acfactory.get_unconfigured_account() @@ -37,6 +38,11 @@ class TestOfflineAccountBasic: ac1 = acfactory.get_unconfigured_account() assert "save_mime_headers" in ac1.get_config("sys.config_keys").split() + def test_has_bccself(self, acfactory): + ac1 = acfactory.get_unconfigured_account() + assert "bcc_self" in ac1.get_config("sys.config_keys").split() + assert ac1.get_config("bcc_self") == "1" + def test_selfcontact_if_unconfigured(self, acfactory): ac1 = acfactory.get_unconfigured_account() with pytest.raises(ValueError): @@ -351,18 +357,32 @@ class TestOnlineAccount: ac1._evlogger.consume_events() ac1.import_self_keys(dir.strpath) - def test_one_account_send(self, acfactory): + def test_one_account_send_bcc_setting(self, acfactory, lp): ac1 = acfactory.get_online_configuring_account() - c2 = ac1.create_contact(email=ac1.get_config("addr")) + c2 = ac1.create_contact(email="notexists@testrun.org") chat = ac1.create_chat_by_contact(c2) assert chat.id > const.DC_CHAT_ID_LAST_SPECIAL wait_successful_IMAP_SMTP_connection(ac1) wait_configuration_progress(ac1, 1000) + lp.sec("send out message with bcc to ourselves") msg_out = chat.send_text("message2") - # wait for own account to receive - ev = ac1._evlogger.get_matching("DC_EVENT_INCOMING_MSG|DC_EVENT_MSGS_CHANGED") - assert ev[1] == msg_out.id + ev = ac1._evlogger.get_matching("DC_EVENT_MSGS_CHANGED") + assert ev[2] == msg_out.id + # wait for send out (BCC) + assert ac1.get_config("bcc_self") == "1" + self_addr = ac1.get_config("addr") + ev = ac1._evlogger.get_matching("DC_EVENT_SMTP_MESSAGE_SENT") + assert self_addr in ev[2] + + ac1._evlogger.consume_events() + lp.sec("send out message without bcc") + ac1.set_config("bcc_self", "0") + msg_out = chat.send_text("message3") + ev = ac1._evlogger.get_matching("DC_EVENT_MSGS_CHANGED") + assert ev[2] == msg_out.id + ev = ac1._evlogger.get_matching("DC_EVENT_SMTP_MESSAGE_SENT") + assert self_addr not in ev[2] def test_mvbox_sentbox_threads(self, acfactory): ac1 = acfactory.get_online_configuring_account(mvbox=True, sentbox=True) diff --git a/src/config.rs b/src/config.rs index e64ca11bb..f39ba8538 100644 --- a/src/config.rs +++ b/src/config.rs @@ -30,6 +30,8 @@ pub enum Config { Selfstatus, Selfavatar, #[strum(props(default = "1"))] + BccSelf, + #[strum(props(default = "1"))] E2eeEnabled, #[strum(props(default = "1"))] MdnsEnabled, @@ -92,6 +94,14 @@ impl Context { } } + pub fn get_config_int(&self, key: Config) -> i32 { + self.get_config(key).and_then(|s| s.parse().ok()).unwrap() + } + + pub fn get_config_bool(&self, key: Config) -> bool { + self.get_config_int(key) != 0 + } + /// Set the given config key. /// If `None` is passed as a value the value is cleared and set to the default if there is one. pub fn set_config(&self, key: Config, value: Option<&str>) -> Result<(), Error> { diff --git a/src/context.rs b/src/context.rs index e5d4cbf87..d4e8e559f 100644 --- a/src/context.rs +++ b/src/context.rs @@ -8,6 +8,7 @@ use std::sync::{Arc, Condvar, Mutex, RwLock}; use libc::uintptr_t; use crate::chat::*; +use crate::config::Config; use crate::constants::*; use crate::contact::*; use crate::dc_tools::{dc_copy_file, dc_derive_safe_stem_ext}; @@ -234,14 +235,10 @@ impl Context { .sql .get_config_int(self, "dbversion") .unwrap_or_default(); - let e2ee_enabled = self - .sql - .get_config_int(self, "e2ee_enabled") - .unwrap_or_else(|| 1); - let mdns_enabled = self - .sql - .get_config_int(self, "mdns_enabled") - .unwrap_or_else(|| 1); + + let e2ee_enabled = self.get_config_int(Config::E2eeEnabled); + let mdns_enabled = self.get_config_int(Config::MdnsEnabled); + let bcc_self = self.get_config_int(Config::BccSelf); let prv_key_cnt: Option = self.sql @@ -259,26 +256,15 @@ impl Context { "".into() }; - let inbox_watch = self - .sql - .get_config_int(self, "inbox_watch") - .unwrap_or_else(|| 1); - let sentbox_watch = self - .sql - .get_config_int(self, "sentbox_watch") - .unwrap_or_else(|| 1); - let mvbox_watch = self - .sql - .get_config_int(self, "mvbox_watch") - .unwrap_or_else(|| 1); - let mvbox_move = self - .sql - .get_config_int(self, "mvbox_move") - .unwrap_or_else(|| 1); + let inbox_watch = self.get_config_int(Config::InboxWatch); + let sentbox_watch = self.get_config_int(Config::SentboxWatch); + let mvbox_watch = self.get_config_int(Config::MvboxWatch); + let mvbox_move = self.get_config_int(Config::MvboxMove); let folders_configured = self .sql .get_config_int(self, "folders_configured") .unwrap_or_default(); + let configured_sentbox_folder = self .sql .get_config(self, "configured_sentbox_folder") @@ -309,6 +295,7 @@ impl Context { res.insert("configured_mvbox_folder", configured_mvbox_folder); res.insert("mdns_enabled", mdns_enabled.to_string()); res.insert("e2ee_enabled", e2ee_enabled.to_string()); + res.insert("bcc_self", bcc_self.to_string()); res.insert( "private_key_count", prv_key_cnt.unwrap_or_default().to_string(), diff --git a/src/job.rs b/src/job.rs index 25ef9e8fe..cbdc70d9f 100644 --- a/src/job.rs +++ b/src/job.rs @@ -4,6 +4,7 @@ use deltachat_derive::{FromSql, ToSql}; use rand::{thread_rng, Rng}; use crate::chat; +use crate::config::Config; use crate::configure::*; use crate::constants::*; use crate::context::Context; @@ -666,11 +667,13 @@ pub fn job_send_msg(context: &Context, msg_id: u32) -> Result<(), Error> { mimefactory.msg.param.get_int(Param::GuranteeE2ee), ); } - if !vec_contains_lowercase(&mimefactory.recipients_addr, &mimefactory.from_addr) { - mimefactory.recipients_names.push("".to_string()); - mimefactory - .recipients_addr - .push(mimefactory.from_addr.to_string()); + if context.get_config_bool(Config::BccSelf) { + if !vec_contains_lowercase(&mimefactory.recipients_addr, &mimefactory.from_addr) { + mimefactory.recipients_names.push("".to_string()); + mimefactory + .recipients_addr + .push(mimefactory.from_addr.to_string()); + } } if mimefactory.recipients_addr.is_empty() { diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 85735f088..6c5128c2e 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -143,16 +143,11 @@ impl<'a> MimeFactory<'a> { /******************************************************************************* * Render a basic email ******************************************************************************/ - // restrict unsafe to parts, introduce wrapmime helpers where appropriate + // XXX restrict unsafe to parts, introduce wrapmime helpers where appropriate pub unsafe fn render(&mut self) -> Result<(), Error> { if self.loaded == Loaded::Nothing || !self.out.is_null() { bail!("Invalid use of mimefactory-object."); } - ensure!( - !self.recipients_names.is_empty() && !self.recipients_addr.is_empty(), - "message has no recipients" - ); - let context = &self.context; let from = wrapmime::new_mailbox_list(&self.from_displayname, &self.from_addr);