From ea7e2bcf5a1713cb69add91696da5113cf7a2d5f Mon Sep 17 00:00:00 2001 From: link2xt Date: Thu, 17 Sep 2026 15:13:42 +0000 Subject: [PATCH] refactor: remove configured_addr config configured_addr was already not used by real SMTP code. Rust tests which emulate sending with TestContext.pop_sent_msg() now have a way to set the "sending" address manually in memory. --- benches/decrypting.rs | 6 +- benches/receive_emails.rs | 11 --- deltachat-rpc-client/tests/test_cross_core.py | 4 +- .../tests/test_multitransport.py | 29 ------ deltachat-rpc-client/tests/test_securejoin.py | 3 +- deltachat-rpc-client/tests/test_something.py | 5 +- python/src/deltachat/testplugin.py | 7 +- python/tests/test_0_complex_or_slow.py | 1 - python/tests/test_3_offline.py | 10 -- src/chat.rs | 12 +-- src/config.rs | 67 +------------- src/configure.rs | 15 +-- src/contact.rs | 44 ++------- src/contact/contact_tests.rs | 12 +-- src/imex.rs | 5 - src/key.rs | 10 -- src/keyupdate/keyupdate_tests.rs | 4 - src/mimefactory.rs | 18 ++-- src/mimefactory/mimefactory_tests.rs | 21 ++--- .../shared_secret_decryption_tests.rs | 6 +- src/pgp/pgp_tests.rs | 4 - src/quota.rs | 8 -- src/receive_imf/receive_imf_tests.rs | 11 +-- src/securejoin/securejoin_tests.rs | 8 +- src/smtp.rs | 15 +-- src/sql/migrations/migrations_tests.rs | 10 ++ src/test_utils.rs | 67 +++++++------- src/tests/aeap.rs | 14 ++- src/transport.rs | 52 ++--------- src/transport/transport_tests.rs | 91 ------------------- 30 files changed, 121 insertions(+), 449 deletions(-) diff --git a/benches/decrypting.rs b/benches/decrypting.rs index c823f0fae..122ac9c95 100644 --- a/benches/decrypting.rs +++ b/benches/decrypting.rs @@ -31,7 +31,7 @@ use deltachat::internals_for_benches::create_broadcast_secret; use deltachat::internals_for_benches::save_broadcast_secret; use deltachat::securejoin::get_securejoin_qr; use deltachat::{ - Events, chat::ChatId, config::Config, context::Context, internals_for_benches::key_from_asc, + Events, chat::ChatId, context::Context, internals_for_benches::key_from_asc, internals_for_benches::parse_and_get_text, internals_for_benches::store_self_keypair, stock_str::StockStrings, }; @@ -57,10 +57,6 @@ async fn create_context() -> Context { .await .unwrap(); - context - .set_config(Config::ConfiguredAddr, Some("bob@example.net")) - .await - .unwrap(); let secret = key_from_asc(include_str!("../test-data/key/bob-secret.asc")).unwrap(); store_self_keypair(&context, &secret) .await diff --git a/benches/receive_emails.rs b/benches/receive_emails.rs index 89a3cffee..bb63384b1 100644 --- a/benches/receive_emails.rs +++ b/benches/receive_emails.rs @@ -5,7 +5,6 @@ use std::path::PathBuf; use criterion::{Criterion, criterion_group, criterion_main}; use deltachat::{ Events, - config::Config, context::Context, imex::{ImexMode, imex}, receive_imf::receive_imf, @@ -109,16 +108,6 @@ async fn create_context() -> Context { .unwrap(); } - let addr = "alice@example.com"; - context.set_config(Config::Addr, Some(addr)).await.unwrap(); - context - .set_config(Config::ConfiguredAddr, Some(addr)) - .await - .unwrap(); - context - .set_config(Config::Configured, Some("1")) - .await - .unwrap(); context } diff --git a/deltachat-rpc-client/tests/test_cross_core.py b/deltachat-rpc-client/tests/test_cross_core.py index 1c2e1c618..11a5609b8 100644 --- a/deltachat-rpc-client/tests/test_cross_core.py +++ b/deltachat-rpc-client/tests/test_cross_core.py @@ -104,7 +104,6 @@ def test_keyupdate_against_core_2_48_march_2026(acf, alice_and_remote_bob, repla # an accepted chat alone is not enough, a message must have flowed. alice_chat = alice_contact_bob.create_chat() alice.set_config("keyupdate_debounce", "1") - old_addr = alice.get_config("configured_addr") alice_chat.send_text("hi") assert remote_eval("bob.wait_for_incoming_msg().get_snapshot().text") == "hi" before = bob_sees() @@ -113,8 +112,9 @@ def test_keyupdate_against_core_2_48_march_2026(acf, alice_and_remote_bob, repla # and signature timestamps have one-second resolution: # without waiting, the re-signed key can tie with the copy Bob holds, keeping his. time.sleep(2) + old_addr = alice.list_transports()[0]["addr"] alice.add_transport_from_qr(acf.get_account_qr()) - (new_addr,) = [t["addr"] for t in alice.list_transports() if t["addr"] != old_addr] + new_addr = alice.list_transports()[1]["addr"] if replace_relay: alice.delete_transport(old_addr) alice.bring_online() diff --git a/deltachat-rpc-client/tests/test_multitransport.py b/deltachat-rpc-client/tests/test_multitransport.py index 4a804cfb0..f62df29f0 100644 --- a/deltachat-rpc-client/tests/test_multitransport.py +++ b/deltachat-rpc-client/tests/test_multitransport.py @@ -45,10 +45,8 @@ def test_add_second_address(acf) -> None: second_addr = account.list_transports()[1]["addr"] third_addr = account.list_transports()[2]["addr"] - assert account.get_config("configured_addr") == first_addr account.delete_transport(first_addr) assert len(account.list_transports()) == 2 - assert account.get_config("configured_addr") != first_addr account.delete_transport(second_addr) assert len(account.list_transports()) == 1 @@ -187,9 +185,6 @@ def test_transport_synchronization(acf, log) -> None: wait_for_io_started(ac1) [transport1, transport3] = ac1.list_transports() - log.section("ac1 changes the sending transport") - ac1.set_config("configured_addr", transport3["addr"]) - log.section("ac1 removes the first transport") ac1.delete_transport(transport1["addr"]) @@ -197,7 +192,6 @@ def test_transport_synchronization(acf, log) -> None: wait_for_io_started(ac1_clone) [transport3] = ac1_clone.list_transports() assert transport3["addr"] == addr3 - assert ac1_clone.get_config("configured_addr") == addr3 ac2_chat = ac2.create_chat(ac1) ac2_chat.send_text("Hello!") @@ -221,10 +215,6 @@ def test_transport_sync_new_as_primary(acf, log) -> None: [transport1, transport2] = ac1_transports ac1_clone.wait_for_event(EventType.TRANSPORTS_MODIFIED) assert len(ac1_clone.list_transports()) == 2 - assert ac1_clone.get_config("configured_addr") == transport1["addr"] - - log.section("ac1 changes the primary transport") - ac1.set_config("configured_addr", transport2["addr"]) log.section("ac1_clone receives a message via the new transport") ac1_chat = ac1.create_chat(bob) @@ -236,22 +226,6 @@ def test_transport_sync_new_as_primary(acf, log) -> None: assert ac1_clone.wait_for_incoming_msg().get_snapshot().text == "hello back" -def test_recognize_self_address(acf) -> None: - alice, bob = acf.get_online_accounts(2) - - bob_chat = bob.create_chat(alice) - - qr = acf.get_account_qr() - alice.add_transport_from_qr(qr) - - new_alice_addr = alice.list_transports()[1]["addr"] - alice.set_config("configured_addr", new_alice_addr) - - bob_chat.send_text("Hello!") - msg = alice.wait_for_incoming_msg().get_snapshot() - assert msg.chat == alice.create_chat(bob) - - def test_transport_limit(acf) -> None: """Test transports limit.""" account = acf.get_online_account() @@ -294,7 +268,6 @@ def test_message_info_imap_urls(acf) -> None: # Alice switches to another transport and removes the rest of the transports. new_alice_addr = alice.list_transports()[1]["addr"] - alice.set_config("configured_addr", new_alice_addr) removed_addrs = [] for transport in alice.list_transports(): if transport["addr"] != new_alice_addr: @@ -326,7 +299,6 @@ def test_remove_primary_transport(acf, log) -> None: log.section("Alice removes the primary relay") alice.delete_transport(transport1["addr"]) - assert alice.get_config("configured_addr") == transport2["addr"] alice.stop_io() alice.start_io() @@ -369,7 +341,6 @@ def test_qr_works_after_removing_primary_transport(acf, log) -> None: def test_background_fetch_from_second_transport(acf, direct_imap, dc): alice, alice_chat, bob_chat = alice_with_two_transports_and_bob(acf) [transport1, transport2] = alice.list_transports() - assert alice.get_config("configured_addr") == transport1["addr"] alice.stop_io() bob_chat.send_text("hello") diff --git a/deltachat-rpc-client/tests/test_securejoin.py b/deltachat-rpc-client/tests/test_securejoin.py index ed5dc8af9..c0a402ac4 100644 --- a/deltachat-rpc-client/tests/test_securejoin.py +++ b/deltachat-rpc-client/tests/test_securejoin.py @@ -647,9 +647,8 @@ def test_qr_scan_updates_new_relay_address(acf): bob.wait_for_securejoin_joiner_success() for ac in [alice, bob]: - old_addr = ac.get_config("configured_addr") + old_addr = ac.list_transports()[0]["addr"] ac.add_transport_from_qr(acf.get_account_qr()) - ac.set_config("configured_addr", ac.list_transports()[1]["addr"]) ac.delete_transport(old_addr) bob.secure_join(alice.get_qr_code()) diff --git a/deltachat-rpc-client/tests/test_something.py b/deltachat-rpc-client/tests/test_something.py index 148d8cb99..6f846847d 100644 --- a/deltachat-rpc-client/tests/test_something.py +++ b/deltachat-rpc-client/tests/test_something.py @@ -100,7 +100,6 @@ def test_lowercase_address(acf) -> None: ) assert account.is_configured() assert addr_upper != addr - assert account.get_config("configured_addr") == addr assert account.list_transports()[0]["addr"] == addr param = account.get_info()["used_transport_settings"] @@ -168,7 +167,7 @@ def test_list_transports(acf) -> None: def test_account(acf) -> None: alice, bob = acf.get_online_accounts(2) - bob_addr = bob.get_config("configured_addr") + bob_addr = bob.list_transports()[0]["addr"] alice_contact_bob = alice.create_contact(bob, "Bob") alice_chat_bob = alice_contact_bob.create_chat() alice_chat_bob.send_text("Hello!") @@ -331,7 +330,7 @@ def test_chat(acf) -> None: def test_contact(acf) -> None: alice, bob = acf.get_online_accounts(2) - bob_addr = bob.get_config("configured_addr") + bob_addr = bob.list_transports()[0]["addr"] alice_contact_bob = alice.create_contact(bob, "Bob") assert alice_contact_bob == alice.get_contact_by_id(alice_contact_bob.id) diff --git a/python/src/deltachat/testplugin.py b/python/src/deltachat/testplugin.py index 7dab54298..c74e1f9b4 100644 --- a/python/src/deltachat/testplugin.py +++ b/python/src/deltachat/testplugin.py @@ -370,12 +370,7 @@ class ACFactory: acname = ac._logid addr = f"{acname}@offline.org" lib.dc_add_pseudo_transport(ac._dc_context, as_dc_charpointer(addr)) - ac.update_config( - { - "configured_addr": addr, - "displayname": acname, - }, - ) + ac.set_config("displayname", acname) self._preconfigure_key(ac) self._acsetup.init_logging(ac) assert ac.is_configured(), "Pseudo configured account should look like if it is configured" diff --git a/python/tests/test_0_complex_or_slow.py b/python/tests/test_0_complex_or_slow.py index 3873ae33a..ee0c20c57 100644 --- a/python/tests/test_0_complex_or_slow.py +++ b/python/tests/test_0_complex_or_slow.py @@ -51,7 +51,6 @@ class TestGroupStressTests: lp.sec("ac2: receiving system message about contact addition") sysmsg = ac2._evtracker.wait_next_incoming_message() - assert ac5.get_config("configured_addr") in sysmsg.text assert sysmsg.chat.num_contacts() == 4 lp.sec("ac5: waiting for message about addition to the chat") diff --git a/python/tests/test_3_offline.py b/python/tests/test_3_offline.py index 71946db21..9dc1274e0 100644 --- a/python/tests/test_3_offline.py +++ b/python/tests/test_3_offline.py @@ -130,11 +130,6 @@ class TestOfflineContact: contact2.unblock() assert ac1.get_blocked_contacts() == [contact1] - def test_create_self_contact(self, acfactory): - ac1 = acfactory.get_pseudo_configured_account() - contact1 = ac1.create_contact(ac1.get_config("configured_addr")) - assert contact1.id == 1 - def test_get_contacts_and_delete(self, acfactory): ac1 = acfactory.get_pseudo_configured_account() ac2 = acfactory.get_pseudo_configured_account() @@ -223,7 +218,6 @@ class TestOfflineChat: ac2 = acfactory.get_pseudo_configured_account() chat = ac1.create_group_chat(name="title1") contact = chat.add_contact(ac2) - assert contact.addr == ac2.get_config("configured_addr") assert contact.name == ac2.get_config("displayname") assert contact.account == ac1 chat.remove_contact(ac2) @@ -456,7 +450,6 @@ class TestOfflineChat: contacts = ac2.get_contacts() assert len(contacts) == 1 contact2 = contacts[0] - assert contact2.addr == ac_contact.get_config("configured_addr") chat2 = contact2.create_chat() messages = chat2.get_messages() assert len(messages) == 2 + E2EE_INFO_MSGS @@ -552,7 +545,6 @@ class TestOfflineChat: contacts = ac2.get_contacts() assert len(contacts) == 1 contact2 = contacts[0] - assert contact2.addr == ac_contact.get_config("configured_addr") chat2 = contact2.create_chat() messages = chat2.get_messages() assert len(messages) == 2 + E2EE_INFO_MSGS @@ -604,7 +596,6 @@ class TestOfflineChat: contacts = ac2.get_contacts() assert len(contacts) == 1 contact2 = contacts[0] - assert contact2.addr == ac_contact.get_config("configured_addr") chat2 = contact2.create_chat() messages = chat2.get_messages() assert len(messages) == 2 + E2EE_INFO_MSGS @@ -621,7 +612,6 @@ class TestOfflineChat: contacts = ac2.get_contacts() assert len(contacts) == 1 contact2 = contacts[0] - assert contact2.addr == ac_contact.get_config("configured_addr") chat2 = contact2.create_chat() messages = chat2.get_messages() assert len(messages) == 2 + E2EE_INFO_MSGS diff --git a/src/chat.rs b/src/chat.rs index eb8526a53..f786b1ce5 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -2893,15 +2893,9 @@ async fn create_send_msg_jobs(context: &Context, msg: &mut Message) -> Result { - let Some(addr) = value else { - bail!("Cannot unset configured_addr"); - }; - - self.sql - .transaction(|transaction| { - if transaction.query_row( - "SELECT COUNT(*) FROM transports WHERE addr=?", - (addr,), - |row| { - let res: i64 = row.get(0)?; - Ok(res) - }, - )? == 0 - { - bail!("Address does not belong to any transport."); - } - transaction.execute( - "INSERT OR REPLACE INTO config (keyname, value) VALUES ('configured_addr', ?)", - (addr,), - )?; - - Ok(()) - }) - .await?; - self.sql.uncache_raw_config("configured_addr").await; - } _ => { self.sql.set_raw_config(key.as_ref(), value).await?; } @@ -854,18 +821,6 @@ impl Context { /// Determine whether the specified addr maps to the/a self addr. /// Returns `false` if no addresses are configured. pub(crate) async fn is_self_addr(&self, addr: &str) -> Result { - // Employ the config cache to optimize for `ConfiguredAddr` passed. - if !addr.is_empty() - && addr_cmp( - addr, - &self - .get_config(Config::ConfiguredAddr) - .await? - .unwrap_or_default(), - ) - { - return Ok(true); - } Ok(self .get_self_addrs() .await? @@ -873,20 +828,6 @@ impl Context { .any(|a| addr_cmp(addr, a))) } - /// Sets `primary_new` as the address used for sending. - /// - /// This should only be used by test code and during configure. - #[cfg(test)] // AEAP is disabled, but there are still tests for it - pub(crate) async fn set_primary_self_addr(&self, primary_new: &str) -> Result<()> { - self.quota.write().await.clear(); - - self.sql - .set_raw_config(Config::ConfiguredAddr.as_ref(), Some(primary_new)) - .await?; - self.emit_event(EventType::ConnectivityChanged); - Ok(()) - } - /// Returns all self addresses, newest first. pub(crate) async fn get_self_addrs(&self) -> Result> { let query_only = true; @@ -895,10 +836,10 @@ impl Context { .await } - /// Returns the address of the transport used for sending. - /// Returns an error if no self addr is configured. + /// Returns address of the first transport. pub async fn get_primary_self_addr(&self) -> Result { - self.get_config(Config::ConfiguredAddr) + self.sql + .query_get_value("SELECT addr FROM transports ORDER BY id", ()) .await? .context("No self addr configured") } diff --git a/src/configure.rs b/src/configure.rs index 98309e6b2..498e3aea9 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -37,8 +37,8 @@ use crate::sync::Sync::Nosync; use crate::tools::time; use crate::transport::{ ConfiguredCertificateChecks, ConfiguredLoginParam, ConfiguredServerLoginParam, - ConnectionCandidate, delete_transport_row, maybe_update_sending_transport, - purge_transport_caches, send_sync_transports, transport_addrs, + ConnectionCandidate, delete_transport_row, purge_transport_caches, send_sync_transports, + transport_addrs, }; use crate::{EventType, autorelay, stock_str}; @@ -275,7 +275,7 @@ impl Context { /// another one is chosen automatically. pub async fn delete_transport(&self, addr: &str) -> Result<()> { let now = time(); - let (removed_transport_id, reelected) = self + let removed_transport_id = self .sql .transaction(|transaction| { if transport_addrs(transaction)?.len() <= 1 { @@ -294,14 +294,9 @@ impl Context { let remove_timestamp = std::cmp::max(now, add_timestamp); let transport_id = delete_transport_row(transaction, addr, remove_timestamp)? .context("Transport disappeared")?; - let reelected = maybe_update_sending_transport(transaction)?; - Ok((transport_id, reelected)) + Ok(transport_id) }) .await?; - if let Some(new_addr) = reelected { - info!(self, "Using transport {new_addr:?} for sending now."); - self.sql.uncache_raw_config("configured_addr").await; - } send_sync_transports(self).await?; purge_transport_caches(self, removed_transport_id).await; // Restarting all IO also stops the removed transport's IMAP loop. @@ -801,8 +796,6 @@ mod tests { let t = &tcm.unconfigured().await; add_pseudo_transport(t, "primary@example.org").await?; - t.set_config(Config::ConfiguredAddr, Some("primary@example.org")) - .await?; assert_eq!(t.count_transports().await?, 1); t.check_relay_limit().await?; diff --git a/src/contact.rs b/src/contact.rs index fb6716baa..86eb1365e 100644 --- a/src/contact.rs +++ b/src/contact.rs @@ -718,9 +718,9 @@ impl Contact { .await? .unwrap_or_default(); contact.addr = context - .get_config(Config::ConfiguredAddr) - .await? - .unwrap_or_default(); + .get_primary_self_addr() + .await + .context("Cannot get address for self-contact")?; if let Some(self_fp) = self_fingerprint_opt(context).await? { contact.fingerprint = Some(self_fp.to_string()); } @@ -1421,10 +1421,6 @@ WHERE addr=? ); let contact = Contact::get_by_id(context, contact_id).await?; - let addr = context - .get_config(Config::ConfiguredAddr) - .await? - .unwrap_or_default(); let Some(fingerprint_other) = contact.fingerprint() else { return Ok(stock_str::encr_none(context)); @@ -1444,32 +1440,12 @@ WHERE addr=? .await? .dc_fingerprint() .human_readable(); - if addr < contact.addr { - cat_fingerprint( - &mut ret, - &stock_str::self_msg(context), - &addr, - &fingerprint_self, - ); - cat_fingerprint( - &mut ret, - contact.get_display_name(), - &contact.addr, - &fingerprint_other, - ); + if fingerprint_self < fingerprint_other { + cat_fingerprint(&mut ret, &stock_str::self_msg(context), &fingerprint_self); + cat_fingerprint(&mut ret, contact.get_display_name(), &fingerprint_other); } else { - cat_fingerprint( - &mut ret, - contact.get_display_name(), - &contact.addr, - &fingerprint_other, - ); - cat_fingerprint( - &mut ret, - &stock_str::self_msg(context), - &addr, - &fingerprint_self, - ); + cat_fingerprint(&mut ret, contact.get_display_name(), &fingerprint_other); + cat_fingerprint(&mut ret, &stock_str::self_msg(context), &fingerprint_self); } if let Some(public_key) = contact.public_key(context).await? @@ -1968,8 +1944,8 @@ pub(crate) async fn update_last_seen( Ok(()) } -fn cat_fingerprint(ret: &mut String, name: &str, addr: &str, fingerprint: &str) { - *ret += &format!("\n\n{name} ({addr}):\n{fingerprint}"); +fn cat_fingerprint(ret: &mut String, name: &str, fingerprint: &str) { + *ret += &format!("\n\n{name}:\n{fingerprint}"); } fn split_address_book(book: &str) -> Vec<(&str, &str)> { diff --git a/src/contact/contact_tests.rs b/src/contact/contact_tests.rs index 5a7e748d4..ca2d19000 100644 --- a/src/contact/contact_tests.rs +++ b/src/contact/contact_tests.rs @@ -887,11 +887,11 @@ async fn test_contact_get_encrinfo() -> Result<()> { "Messages are end-to-end encrypted. Fingerprints: -Me (alice@example.org): +Me: 2E6F A2CB 23B5 32D7 2863 4B58 64B0 8F61 A9ED 9443 -bob@example.net (bob@example.net): +bob@example.net: CCCB 5AA9 F6E1 141C 9431 65F1 DB18 B18C BCF7 0487 @@ -908,11 +908,11 @@ bob@example.net" "No encryption. Fingerprints: -Me (alice@example.org): +Me: 2E6F A2CB 23B5 32D7 2863 4B58 64B0 8F61 A9ED 9443 -bob@example.net (bob@example.net): +bob@example.net: CCCB 5AA9 F6E1 141C 9431 65F1 DB18 B18C BCF7 0487" ); @@ -1252,7 +1252,7 @@ async fn test_make_n_import_vcard() -> Result<()> { tokio::fs::write(&avatar_path, avatar_bytes).await?; bob.set_config(Config::Selfavatar, Some(avatar_path.to_str().unwrap())) .await?; - let bob_addr = bob.get_config(Config::ConfiguredAddr).await?.unwrap(); + let bob_addr = bob.get_primary_self_addr().await?; let bob_biography = bob.get_config(Config::Selfstatus).await?.unwrap(); let chat = bob.create_chat(alice).await; let sent_msg = bob.send_text(chat.id, "moin").await; @@ -1348,7 +1348,7 @@ async fn test_make_n_import_vcard() -> Result<()> { async fn test_import_vcard_key_change() -> Result<()> { let alice = &TestContext::new_alice().await; let bob = &TestContext::new_bob().await; - let bob_addr = &bob.get_config(Config::ConfiguredAddr).await?.unwrap(); + let bob_addr = &bob.get_primary_self_addr().await?; bob.set_config(Config::Displayname, Some("Bob")).await?; let vcard = make_vcard(bob, &[ContactId::SELF]).await?; alice.evtracker.clear_events(); diff --git a/src/imex.rs b/src/imex.rs index 00afc432c..c94726aef 100644 --- a/src/imex.rs +++ b/src/imex.rs @@ -961,10 +961,6 @@ mod tests { .await; assert!(context2.is_configured().await?); - assert_eq!( - context2.get_config(Config::ConfiguredAddr).await?, - Some("alice@example.org".to_string()) - ); Ok(()) } @@ -1074,7 +1070,6 @@ mod tests { .await; assert!(!context2.is_configured().await?); - assert_eq!(context2.get_config(Config::ConfiguredAddr).await?, None); Ok(()) } diff --git a/src/key.rs b/src/key.rs index 0c7d23b50..bca1341fe 100644 --- a/src/key.rs +++ b/src/key.rs @@ -657,7 +657,6 @@ mod tests { use std::time::Duration; use super::*; - use crate::config::Config; use crate::test_utils::{TestContext, TestContextManager, alice_keypair}; use crate::tools::SystemTime; use crate::transport::add_pseudo_transport; @@ -811,9 +810,6 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD async fn test_load_self_generate_public() { let t = TestContext::new().await; add_pseudo_transport(&t, "alice@example.org").await.unwrap(); - t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) - .await - .unwrap(); let key = load_self_public_key(&t).await; assert!(key.is_ok()); } @@ -822,9 +818,6 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD async fn test_load_self_generate_secret() { let t = TestContext::new().await; add_pseudo_transport(&t, "alice@example.org").await.unwrap(); - t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) - .await - .unwrap(); let key = load_self_secret_key(&t).await; assert!(key.is_ok()); } @@ -835,9 +828,6 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD let t = TestContext::new().await; add_pseudo_transport(&t, "alice@example.org").await.unwrap(); - t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) - .await - .unwrap(); let thr0 = { let ctx = t.clone(); thread::spawn(move || { diff --git a/src/keyupdate/keyupdate_tests.rs b/src/keyupdate/keyupdate_tests.rs index b08cbd29d..4567ee74b 100644 --- a/src/keyupdate/keyupdate_tests.rs +++ b/src/keyupdate/keyupdate_tests.rs @@ -260,10 +260,6 @@ async fn test_keyupdate_on_replacement() -> Result<()> { alice.add_transport("alice@relay.example.net").await; SystemTime::shift(Duration::from_secs(2)); alice.delete_transport("alice@example.org").await?; - assert_eq!( - alice.get_config(Config::ConfiguredAddr).await?.as_deref(), - Some("alice@relay.example.net") - ); maybe_send_keyupdate_message(alice).await?; let keyupdate = alice.pop_sent_msg().await; diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 5f2ac8754..7b595a4bd 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -433,9 +433,9 @@ pub(crate) fn render_queued_mail( #[cfg(test)] pub(crate) async fn render_queued_mail_with_context( queued_mail: QueuedMail, - context: &Context, + context: &crate::test_utils::TestContext, ) -> Result { - let from_addr = context.get_primary_self_addr().await?; + let from_addr = context.sending_addr().await; let public_key = crate::key::load_self_public_key(context).await?; let secret_key = crate::key::load_self_secret_key(context).await?; @@ -999,14 +999,10 @@ impl MimeFactory { true => context.get_config(Config::Displayname).await?, false => None, }; - let self_name = &match self_name { - Some(name) => name, - None => context - .get_config(Config::ConfiguredAddr) - .await? - .unwrap_or_default(), - }; - Ok(stock_str::subject_for_new_contact(context, self_name)) + Ok(stock_str::subject_for_new_contact( + context, + self_name.as_deref().unwrap_or("..."), + )) } pub fn recipients(&self) -> Vec { @@ -1228,7 +1224,7 @@ impl MimeFactory { /// /// Used only for tests. #[cfg(test)] - pub async fn render(self, context: &Context) -> Result { + pub async fn render(self, context: &crate::test_utils::TestContext) -> Result { // Does not matter, we are not going to return the QueuedMail. let bcc_self = false; let (queued_mail, _side_effects) = diff --git a/src/mimefactory/mimefactory_tests.rs b/src/mimefactory/mimefactory_tests.rs index fec298ed1..1b28b2a44 100644 --- a/src/mimefactory/mimefactory_tests.rs +++ b/src/mimefactory/mimefactory_tests.rs @@ -185,7 +185,7 @@ async fn test_subject_outgoing() { let t = TestContext::new_alice().await; t.allow_unencrypted().await.unwrap(); - assert_eq!(first_subject_str(t).await, "Message from alice@example.org"); + assert_eq!(first_subject_str(t).await, "Message from ..."); let t = TestContext::new_alice().await; t.allow_unencrypted().await.unwrap(); @@ -731,9 +731,9 @@ async fn test_remove_member_bcc() -> Result<()> { let charlie = &tcm.charlie().await; alice.allow_unencrypted().await?; - let alice_addr = alice.get_config(Config::ConfiguredAddr).await?.unwrap(); - let bob_addr = bob.get_config(Config::ConfiguredAddr).await?.unwrap(); - let charlie_addr = charlie.get_config(Config::ConfiguredAddr).await?.unwrap(); + let alice_addr = alice.get_primary_self_addr().await?; + let bob_addr = bob.get_primary_self_addr().await?; + let charlie_addr = charlie.get_primary_self_addr().await?; let bob_id = alice.add_or_lookup_address_contact_id(bob).await; let charlie_id = alice.add_or_lookup_address_contact_id(charlie).await; @@ -896,7 +896,7 @@ async fn test_new_member_is_first_recipient() -> Result<()> { assert!( sent_msg .recipients - .starts_with(&charlie.get_config(Config::ConfiguredAddr).await?.unwrap()) + .starts_with(&charlie.get_primary_self_addr().await?) ); remove_contact_from_chat(alice, group, bob_id).await?; @@ -904,11 +904,8 @@ async fn test_new_member_is_first_recipient() -> Result<()> { SystemTime::shift(Duration::from_secs(60)); add_contact_to_chat(alice, group, bob_id).await?; let sent_msg = alice.pop_sent_msg().await; - assert!( - sent_msg - .recipients - .starts_with(&bob.get_config(Config::ConfiguredAddr).await?.unwrap()) - ); + let bob_addr = bob.get_primary_self_addr().await?; + assert!(sent_msg.recipients.starts_with(&bob_addr)); Ok(()) } @@ -1116,7 +1113,7 @@ Autocrypt: addr=alice@example.org; prefer-encrypt=mutual; Content-Type: text/plain; charset="utf-8" Date: DATE To: -Subject: Message from alice@example.org +Subject: Message from ... References: Chat-Version: 1.0 Content-Transfer-Encoding: 7bit @@ -1168,7 +1165,7 @@ Content-Type: multipart/mixed; boundary="BOUNDARY" Date: DATE To: -Subject: Message from alice@example.org +Subject: Message from ... References: Chat-Version: 1.0 diff --git a/src/mimeparser/shared_secret_decryption_tests.rs b/src/mimeparser/shared_secret_decryption_tests.rs index 68db48b16..4f5546e00 100644 --- a/src/mimeparser/shared_secret_decryption_tests.rs +++ b/src/mimeparser/shared_secret_decryption_tests.rs @@ -131,7 +131,7 @@ async fn test_broadcast_security_attacker_signature() -> Result<()> { let secret = load_broadcast_secret(alice, alice_chat_id).await?.unwrap(); - let charlie_addr = charlie.get_config(Config::ConfiguredAddr).await?.unwrap(); + let charlie_addr = charlie.get_primary_self_addr().await?; test_shared_secret_decryption_ext( bob, @@ -183,7 +183,7 @@ async fn test_broadcast_security_happy_path() -> Result<()> { let secret = load_broadcast_secret(alice, alice_chat_id).await?.unwrap(); - let alice_addr = alice.get_config(Config::ConfiguredAddr).await?.unwrap(); + let alice_addr = alice.get_primary_self_addr().await?; test_shared_secret_decryption_ext(bob, &alice_addr, &secret, Some(alice), None).await } @@ -202,7 +202,7 @@ async fn test_qr_code_security() -> Result<()> { // Start a securejoin process, but don't finish it: join_securejoin(bob, &qr).await?; - let charlie_addr = charlie.get_config(Config::ConfiguredAddr).await?.unwrap(); + let charlie_addr = charlie.get_primary_self_addr().await?; let alice_fp = self_fingerprint(alice).await?; let secret_for_encryption = format!("securejoin/{alice_fp}/{authcode}"); diff --git a/src/pgp/pgp_tests.rs b/src/pgp/pgp_tests.rs index 65d85ab22..e4047c3e2 100644 --- a/src/pgp/pgp_tests.rs +++ b/src/pgp/pgp_tests.rs @@ -4,7 +4,6 @@ use tokio::sync::OnceCell; use super::*; use crate::transport::add_pseudo_transport; use crate::{ - config::Config, decrypt, key::{load_self_public_key, self_fingerprint, store_self_keypair}, mimefactory::{part_to_bytes, wrap_encrypted_part}, @@ -24,9 +23,6 @@ async fn decrypt_bytes( add_pseudo_transport(t, "alice@example.org") .await .expect("Failed to add pseudo transport"); - t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) - .await - .expect("Failed to configure address"); for secret in auth_tokens_for_decryption { token::save(t, token::Namespace::Auth, None, secret, 0).await?; diff --git a/src/quota.rs b/src/quota.rs index 64fb97110..069b62930 100644 --- a/src/quota.rs +++ b/src/quota.rs @@ -156,14 +156,6 @@ mod tests { }; assert!(!t.quota_needs_update(0, TIMEOUT).await); - t.evtracker.clear_events(); - t.set_primary_self_addr("new@addr").await?; - assert!(t.quota.read().await.is_empty()); - t.evtracker - .get_matching(|evt| matches!(evt, EventType::ConnectivityChanged)) - .await; - assert!(t.quota_needs_update(0, TIMEOUT).await); - Ok(()) } } diff --git a/src/receive_imf/receive_imf_tests.rs b/src/receive_imf/receive_imf_tests.rs index 2206b74ab..f247ec9ac 100644 --- a/src/receive_imf/receive_imf_tests.rs +++ b/src/receive_imf/receive_imf_tests.rs @@ -3853,7 +3853,7 @@ async fn test_unsigned_chat_group_hdr() -> Result<()> { let mut tcm = TestContextManager::new(); let alice = &tcm.alice().await; let bob = &tcm.bob().await; - let bob_addr = bob.get_config(Config::ConfiguredAddr).await?.unwrap(); + let bob_addr = bob.get_primary_self_addr().await?; let bob_id = alice.add_or_lookup_contact_id(bob).await; let alice_chat_id = create_group(alice, "foos").await?; add_contact_to_chat(alice, alice_chat_id, bob_id).await?; @@ -4541,7 +4541,7 @@ async fn test_outgoing_msg_forgery() -> Result<()> { let mut tcm = TestContextManager::new(); let export_dir = tempfile::tempdir().unwrap(); let alice = &tcm.alice().await; - let alice_addr = &alice.get_config(Config::ConfiguredAddr).await?.unwrap(); + let alice_addr = &alice.get_primary_self_addr().await?; imex(alice, ImexMode::ExportSelfKeys, export_dir.path(), None).await?; // We need Bob only to encrypt the forged message to Alice's key, actually Bob doesn't // participate in the scenario. @@ -5638,7 +5638,7 @@ async fn test_bcc_not_a_group() -> Result<()> { async fn test_lookup_key_contact_by_address_self() -> Result<()> { let mut tcm = TestContextManager::new(); let t = &tcm.alice().await; - let addr = &t.get_config(Config::ConfiguredAddr).await?.unwrap(); + let addr = &t.get_primary_self_addr().await?; assert_eq!( lookup_key_contact_by_address(t, addr, None).await?, Some(ContactId::SELF) @@ -5690,10 +5690,7 @@ async fn test_outgoing_determined_by_signature() -> Result<()> { let alice_dev2 = &tcm.unconfigured().await; alice_dev2.configure_addr(different_from).await; key::store_self_keypair(alice_dev2, &alice_keypair()).await?; - assert_ne!( - alice.get_config(Config::ConfiguredAddr).await?.unwrap(), - different_from - ); + assert_ne!(alice.get_primary_self_addr().await?, different_from); // Send message from alice_dev2 and check alice sees it as outgoing let chat_id = alice_dev2.create_chat_id(bob).await; diff --git a/src/securejoin/securejoin_tests.rs b/src/securejoin/securejoin_tests.rs index d3ec129f6..56be83ad7 100644 --- a/src/securejoin/securejoin_tests.rs +++ b/src/securejoin/securejoin_tests.rs @@ -50,11 +50,7 @@ async fn test_setup_contact_ext(case: SetupContactCase) -> (TestContext, TestCon let mut tcm = TestContextManager::new(); let alice = tcm.alice().await; - let alice_addr = &alice - .get_config(Config::ConfiguredAddr) - .await - .unwrap() - .unwrap(); + let alice_addr = alice.get_primary_self_addr().await.unwrap(); if case == SetupContactCase::AliceHasName { alice .set_config(Config::Displayname, Some("Alice")) @@ -118,7 +114,7 @@ async fn test_setup_contact_ext(case: SetupContactCase) -> (TestContext, TestCon let contact_alice_id = bob.add_or_lookup_contact_no_key(&alice).await.id; let sent = bob.pop_sent_msg().await; assert!(!sent.payload.contains("Bob Examplenet")); - assert_eq!(sent.recipient(), EmailAddress::new(alice_addr).unwrap()); + assert_eq!(sent.recipients, *alice_addr); let msg = alice.parse_msg(&sent).await; assert!(msg.signature.is_none()); assert_eq!( diff --git a/src/smtp.rs b/src/smtp.rs index 03093e80d..704d8fbda 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -13,7 +13,6 @@ use rusqlite::OptionalExtension as _; use tokio::task; use crate::chat::{ChatId, add_info_msg_with_cmd}; -use crate::config::Config; use crate::contact::{Contact, ContactId}; use crate::context::Context; use crate::events::EventType; @@ -558,7 +557,7 @@ pub(crate) async fn send_msg_to_smtp(context: &Context, smtp: &mut Smtp, rowid: .max(1); let rendered_mail = - mimefactory::render_queued_mail(queued_mail, &public_key, &secret_key, from_addr)?; + mimefactory::render_queued_mail(queued_mail, &public_key, &secret_key, from_addr.clone())?; let body = rendered_mail.message; info!( @@ -629,15 +628,9 @@ pub(crate) async fn send_msg_to_smtp(context: &Context, smtp: &mut Smtp, rowid: .await?; if let Some((chat_id, timestamp_sort)) = res { - let addr = context.get_config(Config::ConfiguredAddr).await?; - let text = unencrypted_email( - context, - addr.unwrap_or_default() - .split('@') - .nth(1) - .unwrap_or_default(), - ) - .await; + let text = + unencrypted_email(context, from_addr.split('@').nth(1).unwrap_or_default()) + .await; add_info_msg_with_cmd( context, chat_id, diff --git a/src/sql/migrations/migrations_tests.rs b/src/sql/migrations/migrations_tests.rs index 98d48c80f..d3b616efe 100644 --- a/src/sql/migrations/migrations_tests.rs +++ b/src/sql/migrations/migrations_tests.rs @@ -51,6 +51,12 @@ async fn test_unpublished_transport_migration_165() -> Result<()> { .scope(163, async move { TestContext::new_alice().await }) .await; let skewed = tools::time() + 3600; + t.sql + .execute( + "INSERT INTO config (keyname, value) VALUES ('configured_addr', 'alice@example.org')", + (), + ) + .await?; t.sql .execute( "INSERT INTO transports (addr, entered_param, configured_param, is_published, add_timestamp) @@ -91,6 +97,7 @@ async fn test_key_contacts_migration_autocrypt() -> Result<()> { .await; t.sql.call_write(|conn| Ok(conn.execute_batch(r#" + INSERT INTO config (keyname, value) VALUES ('configured_addr', 'alice@example.org'); INSERT INTO acpeerstates VALUES(1,'bob@example.net',0,0,NULL,1,1745589039,X'c6c04d045e30c757010800cec0b4bfc4277c88a0d652cc937d5cd66f2f9918a3e96a63d3bdd8f41858277f4075101680e7ffcf8c0cdb2b988a8a8e903449996a0cc93e45cf07225c0084549b44f5eada83b42bf19be1fddd8117a478bf5d639e270f64a210134aa52db113b4a4525e0ef3e2313990ac498762858349005f0aba3065dbe730095b27d26360e9e070c793c5cd23c663ece6cd7bc850bed4e5aee1fc160b250cdf0cb527374a4dc0d6af2ad292f9a015d52a27ba490e4d47153b7ec7db6f4252b7ba7f415e2470bf4bb4cc34ae23c7831ff7512c0e142fd3eaeaf9899816a67b504fb04d4f03b573793489476a28257313ea8d80987f0f3d47d192fdce896ba1ecb339152a470011010001cd113c626f62406578616d706c652e6e65743ec2c08b0410010800350219010502680b932f021b03040b090807061508090a0b02031602010127162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf70487069707ff53fae1e7d40cf1b2b0ea22c1cadd735b16fbdc4c0571fc88b9c489bb2023fce8e197880c4d579d67fa75124ae696fecc17cd5815362e00601e9240d10e0a46bfc0567b88312a41e56bedb045482de61279eb7d10cf15b23e56dc254084401eeaac0780f7ca912f6f9e3d4e4b3f82b1a0fc3ee6600e5367549dbc83242743dee435287c1ba1db604f4d7416780a5d43fe8047338866715a9081285797b96cb9340822d04331121646188e3c9e9bf209611fe9f72bf5df3f0cfdf46d698566ae5ef75e8fa05f5d760e22e592c61e2a48dffeff8cec2f425a5c04951df78f68362f475ba9a8f15e4f588d85f8738815d92d8ccd876833c1683927dd28f5ede9da8ecec04d045e30c757010800a207812db22369e2482375b6a71b2ef9212eb1090957291b1980edab25d5f970598ac638184d244dac0ae66a9287eac3aaab82c438185814539c667010aa219e3d8d1bbe698dfc953e160c51d26defe61ad68885bd9960aeb3a3d5bb637afab9df216d42894c37e5f6a12f2695ff634b32323c2783c499353758316800138370720320754ddd300dd14fa78f278bcab37f219979889cbc9971ef862739a8dada59c8ff2f88f4bb269aa88e808f0771b987d68779a929d58e17290684c4035e582c8124484dc2d344395129434b711583f20ebb71579cb97bbf4850fe35f2bfcf1ec9c7e949f15c6cc1e8b7d56d2784c83c8a125fb0d0fae53649724a899364550011010001c2c0760418010800200502680b932f021b0c162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf704873c3807fd1e3e54a16fc879fc006af060de9216a761188b73fcaa617383feb632b80bcbbf362ea4381bd15e58cffa5ec03da0cd50e4adf37be5c81a66d6a22b9835cbb9c219ecd7426547e6a8ec35839d76795aa448a544bc4a5ecfea0284c1ee576a3dc9fdd41beb54f3f60283451b1d292bddda076e1c02b82d957708dcea5f6fb4faf72f69bdff01ed89468e9870e1a081dac09ccc0b9590ac12e7b85008838e8f9aafcfb2bdcc63085a70819c4f6b8b77cff5716af43c834d114a22745eea504b90c431abadb06ba979021726de29fa09523254ff88d3a9a94ba22c46ba5eb4919ca3c8d1f58b1349c5dd1747afb88067dd2ee258b07b8eb0e09235da2469fcc08c79',NULL,'CCCB5AA9F6E1141C943165F1DB18B18CBCF70487',NULL,NULL,'',NULL,NULL,'',NULL); INSERT INTO contacts VALUES(10,'','bob@example.net',16384,0,0,'','',1745589041,'',0); INSERT INTO chats VALUES(10,100,'bob@example.net',0,'',0,'','',0,0,0,0,0,1745589039,0,NULL,0); @@ -131,6 +138,7 @@ async fn test_key_contacts_migration_email1() -> Result<()> { .await; t.sql.call_write(|conn| Ok(conn.execute_batch(r#" + INSERT INTO config (keyname, value) VALUES ('configured_addr', 'alice@example.org'); INSERT INTO acpeerstates VALUES(1,'bob@example.net',0,0,NULL,1,1745589039,X'c6c04d045e30c757010800cec0b4bfc4277c88a0d652cc937d5cd66f2f9918a3e96a63d3bdd8f41858277f4075101680e7ffcf8c0cdb2b988a8a8e903449996a0cc93e45cf07225c0084549b44f5eada83b42bf19be1fddd8117a478bf5d639e270f64a210134aa52db113b4a4525e0ef3e2313990ac498762858349005f0aba3065dbe730095b27d26360e9e070c793c5cd23c663ece6cd7bc850bed4e5aee1fc160b250cdf0cb527374a4dc0d6af2ad292f9a015d52a27ba490e4d47153b7ec7db6f4252b7ba7f415e2470bf4bb4cc34ae23c7831ff7512c0e142fd3eaeaf9899816a67b504fb04d4f03b573793489476a28257313ea8d80987f0f3d47d192fdce896ba1ecb339152a470011010001cd113c626f62406578616d706c652e6e65743ec2c08b0410010800350219010502680b932f021b03040b090807061508090a0b02031602010127162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf70487069707ff53fae1e7d40cf1b2b0ea22c1cadd735b16fbdc4c0571fc88b9c489bb2023fce8e197880c4d579d67fa75124ae696fecc17cd5815362e00601e9240d10e0a46bfc0567b88312a41e56bedb045482de61279eb7d10cf15b23e56dc254084401eeaac0780f7ca912f6f9e3d4e4b3f82b1a0fc3ee6600e5367549dbc83242743dee435287c1ba1db604f4d7416780a5d43fe8047338866715a9081285797b96cb9340822d04331121646188e3c9e9bf209611fe9f72bf5df3f0cfdf46d698566ae5ef75e8fa05f5d760e22e592c61e2a48dffeff8cec2f425a5c04951df78f68362f475ba9a8f15e4f588d85f8738815d92d8ccd876833c1683927dd28f5ede9da8ecec04d045e30c757010800a207812db22369e2482375b6a71b2ef9212eb1090957291b1980edab25d5f970598ac638184d244dac0ae66a9287eac3aaab82c438185814539c667010aa219e3d8d1bbe698dfc953e160c51d26defe61ad68885bd9960aeb3a3d5bb637afab9df216d42894c37e5f6a12f2695ff634b32323c2783c499353758316800138370720320754ddd300dd14fa78f278bcab37f219979889cbc9971ef862739a8dada59c8ff2f88f4bb269aa88e808f0771b987d68779a929d58e17290684c4035e582c8124484dc2d344395129434b711583f20ebb71579cb97bbf4850fe35f2bfcf1ec9c7e949f15c6cc1e8b7d56d2784c83c8a125fb0d0fae53649724a899364550011010001c2c0760418010800200502680b932f021b0c162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf704873c3807fd1e3e54a16fc879fc006af060de9216a761188b73fcaa617383feb632b80bcbbf362ea4381bd15e58cffa5ec03da0cd50e4adf37be5c81a66d6a22b9835cbb9c219ecd7426547e6a8ec35839d76795aa448a544bc4a5ecfea0284c1ee576a3dc9fdd41beb54f3f60283451b1d292bddda076e1c02b82d957708dcea5f6fb4faf72f69bdff01ed89468e9870e1a081dac09ccc0b9590ac12e7b85008838e8f9aafcfb2bdcc63085a70819c4f6b8b77cff5716af43c834d114a22745eea504b90c431abadb06ba979021726de29fa09523254ff88d3a9a94ba22c46ba5eb4919ca3c8d1f58b1349c5dd1747afb88067dd2ee258b07b8eb0e09235da2469fcc08c79',NULL,'CCCB5AA9F6E1141C943165F1DB18B18CBCF70487',NULL,NULL,'',NULL,NULL,'',NULL); INSERT INTO contacts VALUES(10,'','bob@example.net',16384,0,0,'','',1745589041,'',0); INSERT INTO chats VALUES(10,120,'Group',0,'',0,'','g=1745609548',0,0,0,0,0,1745609547,0,NULL,1); @@ -159,6 +167,7 @@ async fn test_key_contacts_migration_email2() -> Result<()> { .await; t.sql.call_write(|conn| Ok(conn.execute_batch(r#" + INSERT INTO config (keyname, value) VALUES ('configured_addr', 'alice@example.org'); INSERT INTO acpeerstates VALUES(1,'bob@example.net',0,0,NULL,20,1745589039,X'c6c04d045e30c757010800cec0b4bfc4277c88a0d652cc937d5cd66f2f9918a3e96a63d3bdd8f41858277f4075101680e7ffcf8c0cdb2b988a8a8e903449996a0cc93e45cf07225c0084549b44f5eada83b42bf19be1fddd8117a478bf5d639e270f64a210134aa52db113b4a4525e0ef3e2313990ac498762858349005f0aba3065dbe730095b27d26360e9e070c793c5cd23c663ece6cd7bc850bed4e5aee1fc160b250cdf0cb527374a4dc0d6af2ad292f9a015d52a27ba490e4d47153b7ec7db6f4252b7ba7f415e2470bf4bb4cc34ae23c7831ff7512c0e142fd3eaeaf9899816a67b504fb04d4f03b573793489476a28257313ea8d80987f0f3d47d192fdce896ba1ecb339152a470011010001cd113c626f62406578616d706c652e6e65743ec2c08b0410010800350219010502680b932f021b03040b090807061508090a0b02031602010127162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf70487069707ff53fae1e7d40cf1b2b0ea22c1cadd735b16fbdc4c0571fc88b9c489bb2023fce8e197880c4d579d67fa75124ae696fecc17cd5815362e00601e9240d10e0a46bfc0567b88312a41e56bedb045482de61279eb7d10cf15b23e56dc254084401eeaac0780f7ca912f6f9e3d4e4b3f82b1a0fc3ee6600e5367549dbc83242743dee435287c1ba1db604f4d7416780a5d43fe8047338866715a9081285797b96cb9340822d04331121646188e3c9e9bf209611fe9f72bf5df3f0cfdf46d698566ae5ef75e8fa05f5d760e22e592c61e2a48dffeff8cec2f425a5c04951df78f68362f475ba9a8f15e4f588d85f8738815d92d8ccd876833c1683927dd28f5ede9da8ecec04d045e30c757010800a207812db22369e2482375b6a71b2ef9212eb1090957291b1980edab25d5f970598ac638184d244dac0ae66a9287eac3aaab82c438185814539c667010aa219e3d8d1bbe698dfc953e160c51d26defe61ad68885bd9960aeb3a3d5bb637afab9df216d42894c37e5f6a12f2695ff634b32323c2783c499353758316800138370720320754ddd300dd14fa78f278bcab37f219979889cbc9971ef862739a8dada59c8ff2f88f4bb269aa88e808f0771b987d68779a929d58e17290684c4035e582c8124484dc2d344395129434b711583f20ebb71579cb97bbf4850fe35f2bfcf1ec9c7e949f15c6cc1e8b7d56d2784c83c8a125fb0d0fae53649724a899364550011010001c2c0760418010800200502680b932f021b0c162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf704873c3807fd1e3e54a16fc879fc006af060de9216a761188b73fcaa617383feb632b80bcbbf362ea4381bd15e58cffa5ec03da0cd50e4adf37be5c81a66d6a22b9835cbb9c219ecd7426547e6a8ec35839d76795aa448a544bc4a5ecfea0284c1ee576a3dc9fdd41beb54f3f60283451b1d292bddda076e1c02b82d957708dcea5f6fb4faf72f69bdff01ed89468e9870e1a081dac09ccc0b9590ac12e7b85008838e8f9aafcfb2bdcc63085a70819c4f6b8b77cff5716af43c834d114a22745eea504b90c431abadb06ba979021726de29fa09523254ff88d3a9a94ba22c46ba5eb4919ca3c8d1f58b1349c5dd1747afb88067dd2ee258b07b8eb0e09235da2469fcc08c79',NULL,'CCCB5AA9F6E1141C943165F1DB18B18CBCF70487',NULL,NULL,'',NULL,NULL,'',NULL); INSERT INTO contacts VALUES(10,'','bob@example.net',16384,0,0,'','',1745589041,'',0); INSERT INTO chats VALUES(10,100,'bob@example.net',0,'',0,'','',0,0,0,0,0,1745589039,0,NULL,0); @@ -192,6 +201,7 @@ async fn test_key_contacts_migration_verified() -> Result<()> { .await; t.sql.call_write(|conn| Ok(conn.execute_batch(r#" + INSERT INTO config (keyname, value) VALUES ('configured_addr', 'alice@example.org'); INSERT INTO acpeerstates VALUES(1,'bob@example.net',0,0,X'c6c04d045e30c757010800cec0b4bfc4277c88a0d652cc937d5cd66f2f9918a3e96a63d3bdd8f41858277f4075101680e7ffcf8c0cdb2b988a8a8e903449996a0cc93e45cf07225c0084549b44f5eada83b42bf19be1fddd8117a478bf5d639e270f64a210134aa52db113b4a4525e0ef3e2313990ac498762858349005f0aba3065dbe730095b27d26360e9e070c793c5cd23c663ece6cd7bc850bed4e5aee1fc160b250cdf0cb527374a4dc0d6af2ad292f9a015d52a27ba490e4d47153b7ec7db6f4252b7ba7f415e2470bf4bb4cc34ae23c7831ff7512c0e142fd3eaeaf9899816a67b504fb04d4f03b573793489476a28257313ea8d80987f0f3d47d192fdce896ba1ecb339152a470011010001cd113c626f62406578616d706c652e6e65743ec2c08b0410010800350219010502680be34b021b03040b090807061508090a0b02031602010127162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf70487921c07ff4f16327797bc5836071b5fcf2ae269c609b697c38b579f2449d0ff07f3e04db07822bfa83a6ca85308d99328c765f9b37b883a3526d38c3c005810ee6d9064acae1c68784781b9688be535a03ed5902d9ab5c9e5d28fb04aa621cb294445b9eab122d86afc0e2a4fd9a6a9af82f50b49295a9852f35c9ed8d816218ba98bc047cfe5fb9432e45ea63140bd16263728b1d1dd18d143b677e1ddd9cb5e939dd51cd7f2c2037cc89b5cee26917ea949e31c808996a5b7efc73636511173f59e2ab025902d86085110ac22988e86e663f19514c559a3b5a52838d1d1fa263f065fddf5fc8c8a1b4dac51aece76d536a3426f133be204dcb03c4a84242137373e39e7cec04d045e30c757010800a207812db22369e2482375b6a71b2ef9212eb1090957291b1980edab25d5f970598ac638184d244dac0ae66a9287eac3aaab82c438185814539c667010aa219e3d8d1bbe698dfc953e160c51d26defe61ad68885bd9960aeb3a3d5bb637afab9df216d42894c37e5f6a12f2695ff634b32323c2783c499353758316800138370720320754ddd300dd14fa78f278bcab37f219979889cbc9971ef862739a8dada59c8ff2f88f4bb269aa88e808f0771b987d68779a929d58e17290684c4035e582c8124484dc2d344395129434b711583f20ebb71579cb97bbf4850fe35f2bfcf1ec9c7e949f15c6cc1e8b7d56d2784c83c8a125fb0d0fae53649724a899364550011010001c2c0760418010800200502680be34b021b0c162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf7048798cf07fc09e848aa6595d435805efbbbd0b05bec2fffa88b3b1d6e0a3ba80e300bdd83aa5f03bfcc9361b2a90e9cf8980c775d707467c638a13d65a01eda4b57d3560fada0c675399c263e668a02b84733b2c8e71d7fb9f15cb076f933571d32fc3377bb59ff64da6808eeb96210776126504ae9d6916124d3c679ba810a6c92dfe7d58eba7df22e9f07241d343d3e1792fe48d36fd6ec7d1ed291eae5d5d688872f5c723d5a12c424ff32c25d1348d2b683c5cf9128efb957b0026e607d593528a01dea6458c4709779b8f99bd689ef1bfde7146461317ee2793a130663388977488a9fd1a652377445571b1c913ee14fe0b22d451943b4fe1d0578b71201f1ee106f4c',1,1745609547,X'c6c04d045e30c757010800cec0b4bfc4277c88a0d652cc937d5cd66f2f9918a3e96a63d3bdd8f41858277f4075101680e7ffcf8c0cdb2b988a8a8e903449996a0cc93e45cf07225c0084549b44f5eada83b42bf19be1fddd8117a478bf5d639e270f64a210134aa52db113b4a4525e0ef3e2313990ac498762858349005f0aba3065dbe730095b27d26360e9e070c793c5cd23c663ece6cd7bc850bed4e5aee1fc160b250cdf0cb527374a4dc0d6af2ad292f9a015d52a27ba490e4d47153b7ec7db6f4252b7ba7f415e2470bf4bb4cc34ae23c7831ff7512c0e142fd3eaeaf9899816a67b504fb04d4f03b573793489476a28257313ea8d80987f0f3d47d192fdce896ba1ecb339152a470011010001cd113c626f62406578616d706c652e6e65743ec2c08b0410010800350219010502680be34b021b03040b090807061508090a0b02031602010127162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf70487921c07ff4f16327797bc5836071b5fcf2ae269c609b697c38b579f2449d0ff07f3e04db07822bfa83a6ca85308d99328c765f9b37b883a3526d38c3c005810ee6d9064acae1c68784781b9688be535a03ed5902d9ab5c9e5d28fb04aa621cb294445b9eab122d86afc0e2a4fd9a6a9af82f50b49295a9852f35c9ed8d816218ba98bc047cfe5fb9432e45ea63140bd16263728b1d1dd18d143b677e1ddd9cb5e939dd51cd7f2c2037cc89b5cee26917ea949e31c808996a5b7efc73636511173f59e2ab025902d86085110ac22988e86e663f19514c559a3b5a52838d1d1fa263f065fddf5fc8c8a1b4dac51aece76d536a3426f133be204dcb03c4a84242137373e39e7cec04d045e30c757010800a207812db22369e2482375b6a71b2ef9212eb1090957291b1980edab25d5f970598ac638184d244dac0ae66a9287eac3aaab82c438185814539c667010aa219e3d8d1bbe698dfc953e160c51d26defe61ad68885bd9960aeb3a3d5bb637afab9df216d42894c37e5f6a12f2695ff634b32323c2783c499353758316800138370720320754ddd300dd14fa78f278bcab37f219979889cbc9971ef862739a8dada59c8ff2f88f4bb269aa88e808f0771b987d68779a929d58e17290684c4035e582c8124484dc2d344395129434b711583f20ebb71579cb97bbf4850fe35f2bfcf1ec9c7e949f15c6cc1e8b7d56d2784c83c8a125fb0d0fae53649724a899364550011010001c2c0760418010800200502680be34b021b0c162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf7048798cf07fc09e848aa6595d435805efbbbd0b05bec2fffa88b3b1d6e0a3ba80e300bdd83aa5f03bfcc9361b2a90e9cf8980c775d707467c638a13d65a01eda4b57d3560fada0c675399c263e668a02b84733b2c8e71d7fb9f15cb076f933571d32fc3377bb59ff64da6808eeb96210776126504ae9d6916124d3c679ba810a6c92dfe7d58eba7df22e9f07241d343d3e1792fe48d36fd6ec7d1ed291eae5d5d688872f5c723d5a12c424ff32c25d1348d2b683c5cf9128efb957b0026e607d593528a01dea6458c4709779b8f99bd689ef1bfde7146461317ee2793a130663388977488a9fd1a652377445571b1c913ee14fe0b22d451943b4fe1d0578b71201f1ee106f4c','CCCB5AA9F6E1141C943165F1DB18B18CBCF70487','CCCB5AA9F6E1141C943165F1DB18B18CBCF70487',X'c6c04d045e30c757010800cec0b4bfc4277c88a0d652cc937d5cd66f2f9918a3e96a63d3bdd8f41858277f4075101680e7ffcf8c0cdb2b988a8a8e903449996a0cc93e45cf07225c0084549b44f5eada83b42bf19be1fddd8117a478bf5d639e270f64a210134aa52db113b4a4525e0ef3e2313990ac498762858349005f0aba3065dbe730095b27d26360e9e070c793c5cd23c663ece6cd7bc850bed4e5aee1fc160b250cdf0cb527374a4dc0d6af2ad292f9a015d52a27ba490e4d47153b7ec7db6f4252b7ba7f415e2470bf4bb4cc34ae23c7831ff7512c0e142fd3eaeaf9899816a67b504fb04d4f03b573793489476a28257313ea8d80987f0f3d47d192fdce896ba1ecb339152a470011010001cd113c626f62406578616d706c652e6e65743ec2c08b0410010800350219010502680be34b021b03040b090807061508090a0b02031602010127162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf70487921c07ff4f16327797bc5836071b5fcf2ae269c609b697c38b579f2449d0ff07f3e04db07822bfa83a6ca85308d99328c765f9b37b883a3526d38c3c005810ee6d9064acae1c68784781b9688be535a03ed5902d9ab5c9e5d28fb04aa621cb294445b9eab122d86afc0e2a4fd9a6a9af82f50b49295a9852f35c9ed8d816218ba98bc047cfe5fb9432e45ea63140bd16263728b1d1dd18d143b677e1ddd9cb5e939dd51cd7f2c2037cc89b5cee26917ea949e31c808996a5b7efc73636511173f59e2ab025902d86085110ac22988e86e663f19514c559a3b5a52838d1d1fa263f065fddf5fc8c8a1b4dac51aece76d536a3426f133be204dcb03c4a84242137373e39e7cec04d045e30c757010800a207812db22369e2482375b6a71b2ef9212eb1090957291b1980edab25d5f970598ac638184d244dac0ae66a9287eac3aaab82c438185814539c667010aa219e3d8d1bbe698dfc953e160c51d26defe61ad68885bd9960aeb3a3d5bb637afab9df216d42894c37e5f6a12f2695ff634b32323c2783c499353758316800138370720320754ddd300dd14fa78f278bcab37f219979889cbc9971ef862739a8dada59c8ff2f88f4bb269aa88e808f0771b987d68779a929d58e17290684c4035e582c8124484dc2d344395129434b711583f20ebb71579cb97bbf4850fe35f2bfcf1ec9c7e949f15c6cc1e8b7d56d2784c83c8a125fb0d0fae53649724a899364550011010001c2c0760418010800200502680be34b021b0c162104cccb5aa9f6e1141c943165f1db18b18cbcf70487000a0910db18b18cbcf7048798cf07fc09e848aa6595d435805efbbbd0b05bec2fffa88b3b1d6e0a3ba80e300bdd83aa5f03bfcc9361b2a90e9cf8980c775d707467c638a13d65a01eda4b57d3560fada0c675399c263e668a02b84733b2c8e71d7fb9f15cb076f933571d32fc3377bb59ff64da6808eeb96210776126504ae9d6916124d3c679ba810a6c92dfe7d58eba7df22e9f07241d343d3e1792fe48d36fd6ec7d1ed291eae5d5d688872f5c723d5a12c424ff32c25d1348d2b683c5cf9128efb957b0026e607d593528a01dea6458c4709779b8f99bd689ef1bfde7146461317ee2793a130663388977488a9fd1a652377445571b1c913ee14fe0b22d451943b4fe1d0578b71201f1ee106f4c','CCCB5AA9F6E1141C943165F1DB18B18CBCF70487','',NULL,NULL,'',1); INSERT INTO contacts VALUES(10,'','bob@example.net',16384,0,0,'','',1745609549,'',0); INSERT INTO msgs VALUES(10,'29b4af31-1560-4bc8-9b2b-083f2a3d0432@localhost','',0,10,2,2,1745609547,10,13,1,0,'Messages are end-to-end encrypted.','','S=11',0,0,0,0,NULL,'',NULL,1,0,'',0,0,0,'',0,NULL,0,NULL,0); diff --git a/src/test_utils.rs b/src/test_utils.rs index 991b2cd78..f6425c79e 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -193,21 +193,11 @@ impl TestContextManager { to.recv_msg(&sent).await } - pub async fn change_addr(&self, test_context: &TestContext, new_addr: &str) { - self.section(&format!( - "{} changes her self address and reconfigures", - test_context.name() - )); - + pub async fn change_addr(&self, test_context: &mut TestContext, new_addr: &str) { test_context.add_transport(new_addr).await; - test_context.set_primary_self_addr(new_addr).await.unwrap(); + test_context.set_sending_addr(new_addr).await; // ensure_secret_key_exists() is called during configure key::ensure_secret_key_exists(test_context).await.unwrap(); - - assert_eq!( - test_context.get_primary_self_addr().await.unwrap(), - new_addr - ); } /// Executes SecureJoin protocol between `scanner` and `scanned`. @@ -252,10 +242,9 @@ impl TestContextManager { qr: &str, ) -> ChatId { assert!(joiner.pop_sent_msg_opt().await.is_none()); - let inviter_addr = inviters[0].get_primary_self_addr().await.unwrap(); + let inviter_addr = inviters[0].sending_addr().await; for inviter in inviters { assert!(inviter.pop_sent_msg_opt().await.is_none()); - assert_eq!(inviter.get_primary_self_addr().await.unwrap(), inviter_addr); } let chat_id = join_securejoin(&joiner.ctx, qr).await.unwrap(); @@ -435,6 +424,9 @@ pub struct TestContext { pub evtracker: EventTracker, log_sink: LogSink, + + /// From address to be used when emulating sending. + from: Option, } impl TestContext { @@ -530,6 +522,7 @@ impl TestContext { dir, evtracker: EventTracker::new(evtracker_receiver), log_sink, + from: None, } } @@ -560,10 +553,6 @@ impl TestContext { add_pseudo_transport(&self.ctx, addr) .await .expect("Failed to add pseudo transport"); - self.ctx - .set_config(Config::ConfiguredAddr, Some(addr)) - .await - .expect("Failed to configure address"); if let Some(name) = addr.split('@').next() { self.set_name(name); @@ -586,6 +575,28 @@ impl TestContext { self.self_public_key.lock().await.take(); } + pub async fn set_sending_addr(&mut self, addr: &str) { + if !self + .sql + .exists("SELECT COUNT(*) FROM transports WHERE addr=?", (addr,)) + .await + .unwrap() + { + panic!("Address {addr} is not configured"); + } + self.from = Some(addr.to_string()); + } + + pub async fn sending_addr(&self) -> String { + if let Some(ref from) = self.from { + from.clone() + } else { + self.get_primary_self_addr() + .await + .expect("Cannot get From address") + } + } + /// Retrieves a sent message from the jobs table. /// /// This retrieves and removes a message which has been scheduled to send from the jobs @@ -632,10 +643,7 @@ ORDER BY id" .await .expect("Failed to load queued mail"); if queued_mail.bcc_self { - let from = self - .get_primary_self_addr() - .await - .expect("Cannot get From address"); + let from = self.sending_addr().await; smtp::add_self_recipients( &self.ctx, &mut queued_mail.recipients, @@ -734,10 +742,7 @@ ORDER BY id" .await .expect("Failed to load queued mail"); if queued_mail.bcc_self { - let from = self - .get_primary_self_addr() - .await - .expect("Cannot get self address"); + let from = self.sending_addr().await; smtp::add_self_recipients( &self.ctx, &mut queued_mail.recipients, @@ -897,7 +902,7 @@ ORDER BY id" /// Returns the [`ContactId`] for the other [`TestContext`], creating a contact if necessary. pub async fn add_or_lookup_address_contact_id(&self, other: &TestContext) -> ContactId { - let primary_self_addr = other.ctx.get_primary_self_addr().await.unwrap(); + let primary_self_addr = other.sending_addr().await; let addr = ContactAddress::new(&primary_self_addr).unwrap(); // MailinglistAddress is the lowest allowed origin, we'd prefer to not modify the // origin when creating this contact. @@ -952,7 +957,7 @@ ORDER BY id" /// If the contact does not exist yet, a new contact will be created /// with the correct fingerprint, but without the public key. pub async fn add_or_lookup_contact_id_no_key(&self, other: &TestContext) -> ContactId { - let primary_self_addr = other.ctx.get_primary_self_addr().await.unwrap(); + let primary_self_addr = other.sending_addr().await; let addr = ContactAddress::new(&primary_self_addr).unwrap(); let fingerprint = self_fingerprint(other).await.unwrap(); @@ -1242,13 +1247,14 @@ ORDER BY id" } pub async fn encrypt_raw_message( - context: &Context, + context: &TestContext, receivers: &[&TestContext], payload: &[u8], ) -> Result { let public_key = key::load_self_public_key(context).await?; + let from = context.sending_addr().await; let aheader = Aheader { - addr: context.get_primary_self_addr().await?, + addr: from.clone(), public_key: public_key.clone(), prefer_encrypt: EncryptPreference::Mutual, }; @@ -1259,7 +1265,6 @@ pub async fn encrypt_raw_message( encryption_keyring.push(key::load_self_public_key(receiver).await?); } - let from = context.get_primary_self_addr().await?; let compress = false; let mut cleartext = format!("Autocrypt: {aheader}").into_bytes(); diff --git a/src/tests/aeap.rs b/src/tests/aeap.rs index 9e862571a..8c65bea0d 100644 --- a/src/tests/aeap.rs +++ b/src/tests/aeap.rs @@ -20,13 +20,14 @@ use crate::test_utils::TestContextManager; #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_change_primary_self_addr() -> Result<()> { let mut tcm = TestContextManager::new(); - let alice = tcm.alice().await; + let mut alice = tcm.alice().await; let bob = tcm.bob().await; tcm.send_recv_accept(&alice, &bob, "Hi").await; let bob_alice_chat = bob.create_chat(&alice).await; - tcm.change_addr(&alice, "alice@someotherdomain.xyz").await; + tcm.change_addr(&mut alice, "alice@someotherdomain.xyz") + .await; tcm.section("Bob sends a message to Alice, encrypting to her previous key"); let sent = bob.send_text(bob_alice_chat.id, "hi back").await; @@ -63,7 +64,7 @@ async fn check_aeap_transition(chat_for_transition: ChatForTransition) { const ALICE_NEW_ADDR: &str = "alice2@example.net"; let mut tcm = TestContextManager::new(); - let alice = &tcm.alice().await; + let alice = &mut tcm.alice().await; let bob = &tcm.bob().await; tcm.send_recv_accept(alice, bob, "Hi").await; @@ -105,10 +106,7 @@ async fn check_aeap_transition(chat_for_transition: ChatForTransition) { check_that_transition_worked(bob, &groups, alice_contact, ALICE_NEW_ADDR).await; tcm.section("Test switching back"); - alice - .set_primary_self_addr("alice@example.org") - .await - .unwrap(); + alice.set_sending_addr("alice@example.org").await; let sent = alice .send_text(chat_to_send, "Hello from my old addr!") .await; @@ -205,7 +203,7 @@ async fn test_aeap_replay_attack() -> Result<()> { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_write_to_alice_after_aeap() -> Result<()> { let mut tcm = TestContextManager::new(); - let alice = &tcm.alice().await; + let alice = &mut tcm.alice().await; let bob = &tcm.bob().await; let alice_grp_id = chat::create_group(alice, "Group").await?; diff --git a/src/transport.rs b/src/transport.rs index 70ca9abba..d62fb1815 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -276,14 +276,15 @@ impl ConfiguredLoginParam { .await } - /// Loads legacy configured param. Only used for tests and the migration. + /// Loads legacy configured param. Only used for tests and migration 131. pub(crate) async fn load_legacy(context: &Context) -> Result> { if !context.get_config_bool(Config::Configured).await? { return Ok(None); } let addr = context - .get_config(Config::ConfiguredAddr) + .sql + .get_raw_config("configured_addr") .await? .unwrap_or_default() .trim() @@ -480,8 +481,7 @@ pub(crate) async fn save_transport( ); let addr = addr_normalize(&configured.addr); - let configured_addr = context.get_config(Config::ConfiguredAddr).await?; - let mut modified = context + let modified = context .sql .execute( "INSERT INTO transports (addr, entered_param, configured_param, add_timestamp) @@ -503,14 +503,6 @@ pub(crate) async fn save_transport( .await? > 0; - if configured_addr.is_none() { - // If there is no transport yet, use the new transport for sending - context - .sql - .set_raw_config(Config::ConfiguredAddr.as_ref(), Some(&addr)) - .await?; - modified = true; - } Ok(modified) } @@ -625,7 +617,7 @@ pub(crate) async fn sync_transports( ) .collect(); - let (deleted_ids, reelected) = context + let deleted_ids = context .sql .transaction(|transaction| { let mut deleted_ids = Vec::new(); @@ -638,8 +630,7 @@ pub(crate) async fn sync_transports( } modified |= !deleted_ids.is_empty(); - let reelected = maybe_update_sending_transport(transaction)?; - Ok((deleted_ids, reelected)) + Ok(deleted_ids) }) .await?; @@ -647,12 +638,6 @@ pub(crate) async fn sync_transports( purge_transport_caches(context, *transport_id).await; } - if let Some(new_addr) = reelected { - info!(context, "Re-elected sending transport {new_addr:?}."); - context.sql.uncache_raw_config("configured_addr").await; - modified = true; - } - if modified { context.self_public_key.lock().await.take(); context @@ -711,31 +696,6 @@ pub(crate) async fn purge_transport_caches(context: &Context, transport_id: u32) context.metadata.write().await.remove(&transport_id); } -/// Elects another transport for sending if the current one vanished. -/// Any remaining transport works and selection is anyway moving -/// to the authority of the SMTP loop, see -pub(crate) fn maybe_update_sending_transport( - transaction: &mut rusqlite::Transaction, -) -> Result> { - let configured_addr: String = transaction.query_row( - "SELECT value FROM config WHERE keyname='configured_addr'", - (), - |row| row.get(0), - )?; - let addrs = transport_addrs(transaction)?; - if addrs.contains(&configured_addr) { - return Ok(None); - } - let Some(new_addr) = addrs.into_iter().next() else { - return Ok(None); - }; - transaction.execute( - "UPDATE config SET value=? WHERE keyname='configured_addr'", - (&new_addr,), - )?; - Ok(Some(new_addr)) -} - /// Adds transport entry to the `transports` table with empty configuration. pub async fn add_pseudo_transport(context: &Context, addr: &str) -> Result<()> { context.sql diff --git a/src/transport/transport_tests.rs b/src/transport/transport_tests.rs index a981c40b6..4ca90968b 100644 --- a/src/transport/transport_tests.rs +++ b/src/transport/transport_tests.rs @@ -197,10 +197,6 @@ async fn test_delete_transport() -> Result<()> { .evtracker .get_matching(|e| matches!(e, EventType::TransportsModified)) .await; - assert_eq!( - alice.get_config(Config::ConfiguredAddr).await?.as_deref(), - Some("alice@otherprovider.com") - ); sync_and_check_recipients(alice, alice2, "alice@otherprovider.com").await; check_addrs( @@ -226,50 +222,6 @@ async fn test_delete_transport() -> Result<()> { Ok(()) } -/// Tests that selecting sending transport by setting "configured_addr" does not -/// send the sync message, is not synchronized between devices even if sync message is forced, -/// and does not bump sending transport `add_timestamp`. -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_no_configured_addr_synchronization() -> Result<()> { - let mut tcm = TestContextManager::new(); - let alice = &tcm.alice().await; - let alice2 = &tcm.alice().await; - for a in [alice, alice2] { - a.set_config_bool(Config::SyncMsgs, true).await?; - a.set_config_bool(Config::BccSelf, true).await?; - } - - let addr = "alice@otherprovider.com"; - add_dummy_transport(alice, addr).await?; - send_sync_transports(alice).await?; - sync_and_check_recipients(alice, alice2, &format!("{addr} alice@example.org")).await; - - // Selects `addr` on `alice` as the sending transport - // and syncs the transport update to `alice2`, - // whose own sending transport must stay unchanged. - let old_timestamp = add_timestamp(alice2, addr).await; - let alice2_primary = alice2.get_config(Config::ConfiguredAddr).await?; - alice.set_config(Config::ConfiguredAddr, Some(addr)).await?; - assert_eq!(add_timestamp(alice, addr).await, old_timestamp); - - send_sync_transports(alice).await?; - alice.send_sync_msg().await?.unwrap(); - let sync_msg = alice.pop_sent_msg().await; - assert_eq!(sync_msg.recipients, format!("alice@example.org {addr}")); - // The sync message comes from the new sending address, - // which must not make `alice2` adopt it as its own sending address. - assert!(sync_msg.payload.contains(&format!("From: <{addr}>"))); - alice2.recv_msg_trash(&sync_msg).await; - - // add_timestamp must not change. - assert_eq!(add_timestamp(alice2, addr).await, old_timestamp); - assert_eq!( - alice2.get_config(Config::ConfiguredAddr).await?, - alice2_primary - ); - Ok(()) -} - /// Tests that `sync_transports()` requests an IO restart /// if and only if it modified anything. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -288,14 +240,6 @@ async fn test_sync_transports_requests_io_restart() -> Result<()> { Ok(()) } -async fn add_timestamp(t: &TestContext, addr: &str) -> i64 { - t.sql - .query_get_value("SELECT add_timestamp FROM transports WHERE addr=?", (addr,)) - .await - .unwrap() - .unwrap() -} - /// Tests that removing the last transport keeps it. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_removing_last_transport() -> Result<()> { @@ -308,10 +252,6 @@ async fn test_removing_last_transport() -> Result<()> { }; sync_transports(alice, &[], std::slice::from_ref(&removed)).await?; assert_eq!(alice.count_transports().await?, 1); - assert_eq!( - alice.get_config(Config::ConfiguredAddr).await?.as_deref(), - Some("alice@otherprovider.com") - ); let removed = RemovedTransportData { addr: "alice@otherprovider.com".to_string(), @@ -319,37 +259,6 @@ async fn test_removing_last_transport() -> Result<()> { }; sync_transports(alice, &[], std::slice::from_ref(&removed)).await?; assert_eq!(alice.count_transports().await?, 1); - assert_eq!( - alice.get_config(Config::ConfiguredAddr).await?.as_deref(), - Some("alice@otherprovider.com") - ); - Ok(()) -} - -/// Tests which transport is elected for sending. -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_maybe_update_sending_transport() -> Result<()> { - let t = &TestContext::new_alice().await; - - add_dummy_transport(t, "alice@one.com").await?; - assert_eq!( - t.sql.transaction(maybe_update_sending_transport).await?, - None - ); - - t.sql - .execute( - "DELETE FROM transports WHERE addr=?", - ("alice@example.org",), - ) - .await?; - assert_eq!( - t.sql - .transaction(maybe_update_sending_transport) - .await? - .as_deref(), - Some("alice@one.com") - ); Ok(()) }