Compare commits

...

3 Commits

Author SHA1 Message Date
Sebastian Klähn
f29d98333f undo test fixes 2024-11-12 10:36:49 +01:00
Sebastian Klähn
2c802516cf remove comment 2024-11-12 10:29:55 +01:00
Septias
51276e9320 add alias handling
Revert "add alias handling"

This reverts commit 5f7ca4ff9a.

add alias handling

add test

improvements

only do it for single chats

comment out test

clippy

improve test

remove unused function

revert change to stockstr

don't take mut refs

fixes

simplify

move outwards
2024-11-07 14:13:31 +01:00
2 changed files with 111 additions and 44 deletions

View File

@@ -4711,6 +4711,7 @@ impl Context {
#[cfg(test)]
mod tests {
use super::*;
use crate::chat;
use crate::chatlist::get_archived_cnt;
use crate::constants::{DC_GCL_ARCHIVED_ONLY, DC_GCL_NO_SPECIALS};
use crate::headerdef::HeaderDef;
@@ -7696,4 +7697,61 @@ mod tests {
Ok(())
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_reply_with_alias() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let bob = tcm.bob().await;
// Alice sends a message to Bob
let alice_bob_chat = alice.create_chat(&bob).await;
let alice_msg = alice.send_text(alice_bob_chat.id, "Hello Bob!").await;
let msg = alice_msg.load_from_db().await;
bob.recv_msg(&alice_msg).await;
// Bob replies using an alias email address
let alias_email = "bob.alias@example.org";
let reply_imf = format!(
"From: Bob Alias <{}>\r\n\
To: {}\r\n\
In-Reply-To: <{}>\r\n\
Message-ID: <reply1@alias.example.org>\r\n\
\r\n\
Hi Alice, this is Bob's alias.",
alias_email,
alice.get_primary_self_addr().await?,
msg.rfc724_mid
);
// Alice receives the raw message
let received = receive_imf(&alice, reply_imf.as_bytes(), false)
.await?
.unwrap();
// The message should appear in the existing 1:1 chat between Alice and Bob
assert_eq!(received.chat_id, alice_bob_chat.id);
let msg = Message::load_from_db(&alice, received.msg_ids[0]).await?;
assert_eq!(msg.text, "Hi Alice, this is Bob's alias.");
// Alias is displayed in chat
assert_eq!(
msg.param.get(Param::OverrideSenderDisplayname).unwrap(),
"Bob Alias"
);
// Chat remains 1:1
let contacts = chat::get_chat_contacts(&alice, alice_bob_chat.id)
.await
.unwrap();
assert_eq!(contacts, vec![ContactId::new(10)]);
// Following messages still go to 1:1 chat
let sent = alice.send_text(alice_bob_chat.id, "Hello again!").await;
let msg = Message::load_from_db(&alice, sent.sender_msg_id).await?;
assert_eq!(msg.chat_id, alice_bob_chat.id);
Ok(())
}
}

View File

@@ -966,52 +966,55 @@ async fn add_parts(
);
}
}
}
}
// Check if the message was sent with verified encryption and set the protection of
// the 1:1 chat accordingly.
let chat = match is_partial_download.is_none()
&& mime_parser.get_header(HeaderDef::SecureJoin).is_none()
&& !is_mdn
{
true => Some(Chat::load_from_db(context, chat_id).await?)
.filter(|chat| chat.typ == Chattype::Single),
false => None,
if let Some(chat_id) = chat_id {
let contact = Contact::get_by_id(context, from_id).await?;
// Check if the message was sent with verified encryption and set the protection of
// the 1:1 chat accordingly.
let chat = match is_partial_download.is_none()
&& mime_parser.get_header(HeaderDef::SecureJoin).is_none()
&& !is_mdn
{
true => Some(Chat::load_from_db(context, chat_id).await?)
.filter(|chat| chat.typ == Chattype::Single),
false => None,
};
if let Some(chat) = chat {
debug_assert!(chat.typ == Chattype::Single);
let mut new_protection = match verified_encryption {
VerifiedEncryption::Verified => ProtectionStatus::Protected,
VerifiedEncryption::NotVerified(_) => ProtectionStatus::Unprotected,
};
if let Some(chat) = chat {
debug_assert!(chat.typ == Chattype::Single);
let mut new_protection = match verified_encryption {
VerifiedEncryption::Verified => ProtectionStatus::Protected,
VerifiedEncryption::NotVerified(_) => ProtectionStatus::Unprotected,
};
if chat.protected != ProtectionStatus::Unprotected
&& new_protection == ProtectionStatus::Unprotected
// `chat.protected` must be maintained regardless of the `Config::VerifiedOneOnOneChats`.
// That's why the config is checked here, and not above.
&& context.get_config_bool(Config::VerifiedOneOnOneChats).await?
{
new_protection = ProtectionStatus::ProtectionBroken;
}
if chat.protected != new_protection {
// The message itself will be sorted under the device message since the device
// message is `MessageState::InNoticed`, which means that all following
// messages are sorted under it.
chat_id
.set_protection(
context,
new_protection,
mime_parser.timestamp_sent,
Some(from_id),
)
.await?;
}
if let Some(peerstate) = &mime_parser.peerstate {
restore_protection = new_protection != ProtectionStatus::Protected
&& peerstate.prefer_encrypt == EncryptPreference::Mutual
// Check that the contact still has the Autocrypt key same as the
// verified key, see also `Peerstate::is_using_verified_key()`.
&& contact.is_verified(context).await?;
}
if chat.protected != ProtectionStatus::Unprotected
&& new_protection == ProtectionStatus::Unprotected
// `chat.protected` must be maintained regardless of the `Config::VerifiedOneOnOneChats`.
// That's why the config is checked here, and not above.
&& context.get_config_bool(Config::VerifiedOneOnOneChats).await?
{
new_protection = ProtectionStatus::ProtectionBroken;
}
if chat.protected != new_protection {
// The message itself will be sorted under the device message since the device
// message is `MessageState::InNoticed`, which means that all following
// messages are sorted under it.
chat_id
.set_protection(
context,
new_protection,
mime_parser.timestamp_sent,
Some(from_id),
)
.await?;
}
if let Some(peerstate) = &mime_parser.peerstate {
restore_protection = new_protection != ProtectionStatus::Protected
&& peerstate.prefer_encrypt == EncryptPreference::Mutual
// Check that the contact still has the Autocrypt key same as the
// verified key, see also `Peerstate::is_using_verified_key()`.
&& contact.is_verified(context).await?;
}
}
}
@@ -1805,7 +1808,13 @@ async fn lookup_chat_by_reply(
// If this was a private message just to self, it was probably a private reply.
// It should not go into the group then, but into the private chat.
if is_probably_private_reply(context, to_ids, from_id, mime_parser, parent_chat.id).await? {
if parent_chat.get_type() != Chattype::Single
&& is_probably_private_reply(context, to_ids, from_id, mime_parser, parent_chat.id).await?
{
return Ok(None);
}
if parent_chat.is_protected() || mime_parser.decrypting_failed {
return Ok(None);
}