From f93562c6bf6e84f0910cf4ae0f01b60f194f4b26 Mon Sep 17 00:00:00 2001 From: Hocuri Date: Fri, 10 Nov 2023 17:54:25 +0100 Subject: [PATCH] Refactorings --- src/chat.rs | 24 +++++++++++++++++++++++- src/receive_imf.rs | 42 +++++++++++++++--------------------------- src/securejoin.rs | 5 +++++ 3 files changed, 43 insertions(+), 28 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index a5f05df97..b6dfab702 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -42,7 +42,7 @@ use crate::sync::{self, ChatAction, Sync::*, SyncData}; use crate::tools::{ buf_compress, create_id, create_outgoing_rfc724_mid, create_smeared_timestamp, create_smeared_timestamps, get_abs_path, gm2local_offset, improve_single_line_input, - strip_rtlo_characters, time, IsNoneOrEmpty, + smeared_time, strip_rtlo_characters, time, IsNoneOrEmpty, }; use crate::webxdc::WEBXDC_SUFFIX; @@ -567,6 +567,28 @@ impl ChatId { } } + /// Sets the 1:1 chat with the given address to ProtectionStatus::Protected, + /// and posts a `SystemMessage::ChatProtectionEnabled` into it. + /// + /// If necessary, creates a hidden chat for this. + pub(crate) async fn set_protection_for_contact( + context: &Context, + contact_id: ContactId, + ) -> Result<()> { + let chat_id = ChatId::create_for_contact_with_blocked(context, contact_id, Blocked::Yes) + .await + .with_context(|| format!("can't create chat for {}", contact_id))?; + chat_id + .set_protection( + context, + ProtectionStatus::Protected, + smeared_time(context), + Some(contact_id), + ) + .await?; + Ok(()) + } + /// Archives or unarchives a chat. pub async fn set_visibility(self, context: &Context, visibility: ChatVisibility) -> Result<()> { self.set_visibility_ex(context, Sync, visibility).await diff --git a/src/receive_imf.rs b/src/receive_imf.rs index 26f96d67f..cca73384a 100644 --- a/src/receive_imf.rs +++ b/src/receive_imf.rs @@ -2405,6 +2405,16 @@ async fn has_verified_encryption( return Ok(Verified); } + mark_recipients_as_verified(context, from_id, to_ids, mimeparser).await?; + Ok(Verified) +} + +async fn mark_recipients_as_verified( + context: &Context, + from_id: ContactId, + to_ids: Vec, + mimeparser: &MimeMessage, +) -> Result<(), anyhow::Error> { let rows = context .sql .query_map( @@ -2448,38 +2458,15 @@ async fn has_verified_encryption( peerstate.set_verified(PeerstateKeyType::GossipKey, fp, verifier_addr)?; peerstate.save_to_db(&context.sql).await?; - // TODO check if in other places where set_verified() is used we should also - // also set the chat as verified (& create a hidden chat if necessary) - - // TODO There is may be some code duplication with other code added recently - // and also some function should be extracted here because has_verified_encryption() - // is becoming very long and nested if !is_verified { - let to_id = Contact::add_or_lookup( + let (to_contact_id, _) = Contact::add_or_lookup( context, "", ContactAddress::new(&to_addr)?, Origin::Hidden, ) - .await? - .0; - let chat_id = ChatId::create_for_contact_with_blocked( - context, - to_id, - Blocked::Yes, - ) - .await - .with_context(|| { - format!("can't create chat for contact {}", to_addr) - })?; - chat_id - .set_protection( - context, - ProtectionStatus::Protected, - smeared_time(context), - Some(to_id), - ) - .await?; + .await?; + ChatId::set_protection_for_contact(context, to_contact_id).await?; } } } else { @@ -2491,7 +2478,8 @@ async fn has_verified_encryption( } } } - Ok(Verified) + + Ok(()) } /// Returns the last message referenced from `References` header if it is in the database. diff --git a/src/securejoin.rs b/src/securejoin.rs index da957a28a..7f88ae39b 100644 --- a/src/securejoin.rs +++ b/src/securejoin.rs @@ -606,6 +606,11 @@ pub(crate) async fn observe_securejoin_on_other_device( return Ok(HandshakeMessage::Ignore); } }; + if !peerstate.is_using_verified_key() { + // The `if` is purely for performance: + // If the verified key was used already, then the 1:1 chat was already protected. + ChatId::set_protection_for_contact(context, contact_id).await?; + } peerstate.set_verified(PeerstateKeyType::GossipKey, fingerprint, addr)?; peerstate.prefer_encrypt = EncryptPreference::Mutual; peerstate.save_to_db(&context.sql).await.unwrap_or_default();