From 38e01ef43f154e9555d1d0a345f323f0f494479c Mon Sep 17 00:00:00 2001 From: link2xt Date: Sun, 12 Mar 2023 16:11:18 +0000 Subject: [PATCH] api: do not allow to set `configured_*` configs via public API --- src/config.rs | 24 +++++++++++++++++++++--- src/configure.rs | 6 +++++- src/imap.rs | 26 ++++++++++++++------------ src/imap/scan_folders.rs | 3 ++- src/key.rs | 15 ++++++--------- src/message.rs | 26 ++++++++++---------------- src/test_utils.rs | 16 ++++++++-------- 7 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/config.rs b/src/config.rs index da21f91d9..ea3677056 100644 --- a/src/config.rs +++ b/src/config.rs @@ -4,7 +4,7 @@ use std::env; use std::path::Path; use std::str::FromStr; -use anyhow::{ensure, Context as _, Result}; +use anyhow::{bail, ensure, Context as _, Result}; use strum::{EnumProperty, IntoEnumIterator}; use strum_macros::{AsRefStr, Display, EnumIter, EnumProperty, EnumString}; @@ -487,7 +487,12 @@ impl Context { self.sql.set_raw_config(key.as_ref(), value).await?; } _ => { - self.sql.set_raw_config(key.as_ref(), value).await?; + let key = key.as_ref(); + if key.starts_with("configured_") { + bail!("not allowed to set {key} parameter directly"); + } else { + self.sql.set_raw_config(key, value).await?; + } } } Ok(()) @@ -556,7 +561,8 @@ impl Context { ) .await?; - self.set_config(Config::ConfiguredAddr, Some(primary_new)) + self.sql + .set_raw_config(Config::ConfiguredAddr.as_ref(), Some(primary_new)) .await?; if let Some(old_addr) = old_addr { @@ -698,6 +704,18 @@ mod tests { Ok(()) } + /// Test that it is not allowed to set configured parameters directly via public interface. + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] + async fn test_set_configured() -> Result<()> { + let t = TestContext::new().await; + + assert!(t + .set_config(Config::ConfiguredAddr, Some("alice@example.org")) + .await + .is_err()); + Ok(()) + } + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_self_addrs() -> Result<()> { let alice = TestContext::new_alice().await; diff --git a/src/configure.rs b/src/configure.rs index 378268800..021391a94 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -472,7 +472,11 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> { // the trailing underscore is correct param.save_as_configured_params(ctx).await?; - ctx.set_config(Config::ConfiguredTimestamp, Some(&time().to_string())) + ctx.sql + .set_raw_config( + Config::ConfiguredTimestamp.as_ref(), + Some(&time().to_string()), + ) .await?; progress!(ctx, 920); diff --git a/src/imap.rs b/src/imap.rs index 96740a070..54f9e8e97 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -1754,16 +1754,21 @@ impl Imap { .context("failed to configure mvbox")?; context - .set_config(Config::ConfiguredInboxFolder, Some("INBOX")) + .sql + .set_raw_config(Config::ConfiguredInboxFolder.as_ref(), Some("INBOX")) .await?; if let Some(mvbox_folder) = mvbox_folder { info!(context, "Setting MVBOX FOLDER TO {}", &mvbox_folder); context - .set_config(Config::ConfiguredMvboxFolder, Some(mvbox_folder)) + .sql + .set_raw_config(Config::ConfiguredMvboxFolder.as_ref(), Some(mvbox_folder)) .await?; } for (config, name) in folder_configs { - context.set_config(config, Some(&name)).await?; + context + .sql + .set_raw_config(config.as_ref(), Some(&name)) + .await?; } context .sql @@ -2652,15 +2657,12 @@ mod tests { println!("Testing: For folder {folder}, mvbox_move {mvbox_move}, chat_msg {chat_msg}, accepted {accepted_chat}, outgoing {outgoing}, setupmessage {setupmessage}"); let t = TestContext::new_alice().await; - t.ctx - .set_config(Config::ConfiguredMvboxFolder, Some("DeltaChat")) - .await?; - t.ctx - .set_config(Config::ConfiguredSentboxFolder, Some("Sent")) - .await?; - t.ctx - .set_config(Config::MvboxMove, Some(if mvbox_move { "1" } else { "0" })) - .await?; + t.set_raw_config(Config::ConfiguredMvboxFolder, Some("DeltaChat")) + .await; + t.set_raw_config(Config::ConfiguredSentboxFolder, Some("Sent")) + .await; + t.set_raw_config(Config::MvboxMove, Some(if mvbox_move { "1" } else { "0" })) + .await; if accepted_chat { let contact_id = Contact::create(&t.ctx, "", "bob@example.net").await?; diff --git a/src/imap/scan_folders.rs b/src/imap/scan_folders.rs index 8b63098b8..c1d1833e9 100644 --- a/src/imap/scan_folders.rs +++ b/src/imap/scan_folders.rs @@ -89,7 +89,8 @@ impl Imap { Config::ConfiguredTrashFolder, ] { context - .set_config(conf, folder_configs.get(&conf).map(|s| s.as_str())) + .sql + .set_raw_config(conf.as_ref(), folder_configs.get(&conf).map(|s| s.as_str())) .await?; } diff --git a/src/key.rs b/src/key.rs index 32deec2e3..f7e857d27 100644 --- a/src/key.rs +++ b/src/key.rs @@ -531,9 +531,8 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_load_self_generate_public() { let t = TestContext::new().await; - t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) - .await - .unwrap(); + t.set_raw_config(Config::ConfiguredAddr, Some("alice@example.org")) + .await; let key = SignedPublicKey::load_self(&t).await; assert!(key.is_ok()); } @@ -541,9 +540,8 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_load_self_generate_secret() { let t = TestContext::new().await; - t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) - .await - .unwrap(); + t.set_raw_config(Config::ConfiguredAddr, Some("alice@example.org")) + .await; let key = SignedSecretKey::load_self(&t).await; assert!(key.is_ok()); } @@ -553,9 +551,8 @@ i8pcjGO+IZffvyZJVRWfVooBJmWWbPB1pueo3tx8w3+fcuzpxz+RLFKaPyqXO+dD use std::thread; let t = TestContext::new().await; - t.set_config(Config::ConfiguredAddr, Some("alice@example.org")) - .await - .unwrap(); + t.set_raw_config(Config::ConfiguredAddr, Some("alice@example.org")) + .await; let thr0 = { let ctx = t.clone(); thread::spawn(move || { diff --git a/src/message.rs b/src/message.rs index 0a299c3e9..cdcb0732e 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1948,19 +1948,16 @@ mod tests { use crate::config::Config; let d = test::TestContext::new().await; - let ctx = &d.ctx; - - ctx.set_config(Config::ConfiguredAddr, Some("self@example.com")) - .await - .unwrap(); + d.set_raw_config(Config::ConfiguredAddr, Some("self@example.com")) + .await; let chat = d.create_chat_with_contact("", "dest@example.com").await; let mut msg = Message::new(Viewtype::Text); - let msg_id = chat::prepare_msg(ctx, chat.id, &mut msg).await.unwrap(); + let msg_id = chat::prepare_msg(&d, chat.id, &mut msg).await.unwrap(); - let _msg2 = Message::load_from_db(ctx, msg_id).await.unwrap(); + let _msg2 = Message::load_from_db(&d, msg_id).await.unwrap(); assert_eq!(_msg2.get_filemime(), None); } @@ -2088,11 +2085,8 @@ mod tests { use crate::config::Config; let d = test::TestContext::new().await; - let ctx = &d.ctx; - - ctx.set_config(Config::ConfiguredAddr, Some("self@example.com")) - .await - .unwrap(); + d.set_raw_config(Config::ConfiguredAddr, Some("self@example.com")) + .await; let chat = d.create_chat_with_contact("", "dest@example.com").await; @@ -2101,18 +2095,18 @@ mod tests { // Prepare message for sending, so it gets a Message-Id. assert!(msg.rfc724_mid.is_empty()); - let msg_id = chat::prepare_msg(ctx, chat.id, &mut msg).await.unwrap(); - let msg = Message::load_from_db(ctx, msg_id).await.unwrap(); + let msg_id = chat::prepare_msg(&d, chat.id, &mut msg).await.unwrap(); + let msg = Message::load_from_db(&d, msg_id).await.unwrap(); assert!(!msg.rfc724_mid.is_empty()); let mut msg2 = Message::new(Viewtype::Text); - msg2.set_quote(ctx, Some(&msg)) + msg2.set_quote(&d, Some(&msg)) .await .expect("can't set quote"); assert_eq!(msg2.quoted_text().unwrap(), msg.get_text()); let quoted_msg = msg2 - .quoted_message(ctx) + .quoted_message(&d) .await .expect("error while retrieving quoted message") .expect("quoted message not found"); diff --git a/src/test_utils.rs b/src/test_utils.rs index 596c0cba9..0425a35eb 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -381,20 +381,20 @@ impl TestContext { self.event_senders.write().await.push(sink) } + /// Set private configuration value for testing purposes. + pub async fn set_raw_config(&self, key: Config, value: Option<&str>) { + self.sql.set_raw_config(key.as_ref(), value).await.unwrap() + } + /// Configure as a given email address. /// /// The context will be configured but the key will not be pre-generated so if a key is /// used the fingerprint will be different every time. pub async fn configure_addr(&self, addr: &str) { self.ctx.set_config(Config::Addr, Some(addr)).await.unwrap(); - self.ctx - .set_config(Config::ConfiguredAddr, Some(addr)) - .await - .unwrap(); - self.ctx - .set_config(Config::Configured, Some("1")) - .await - .unwrap(); + self.set_raw_config(Config::ConfiguredAddr, Some(addr)) + .await; + self.set_raw_config(Config::Configured, Some("1")).await; if let Some(name) = addr.split('@').next() { self.set_name(name); }