api!: remove APIs to create protected chats

Create unprotected group in test_create_protected_grp_multidev
The test is renamed accordingly.

SystemMessage::ChatE2ee is added in encrypted groups
regardless of whether they are protected or not.
Previously new encrypted unprotected groups
had no message saying that messages are end-to-end encrypted
at all.
This commit is contained in:
link2xt
2025-08-18 10:59:14 +00:00
parent 3f165c1759
commit c2e4767585
37 changed files with 330 additions and 943 deletions

View File

@@ -1763,9 +1763,7 @@ dc_chat_t* dc_get_chat (dc_context_t* context, uint32_t ch
*
* @memberof dc_context_t
* @param context The context object.
* @param protect If set to 1 the function creates group with protection initially enabled.
* Only verified members are allowed in these groups
* and end-to-end-encryption is always enabled.
* @param protect Deprecated 2025-08-31, ignored.
* @param name The name of the group chat to create.
* The name may be changed later using dc_set_chat_name().
* To find out the name of a group later, see dc_chat_get_name()

View File

@@ -22,7 +22,7 @@ use std::sync::{Arc, LazyLock};
use std::time::{Duration, SystemTime};
use anyhow::Context as _;
use deltachat::chat::{ChatId, ChatVisibility, MessageListOptions, MuteDuration, ProtectionStatus};
use deltachat::chat::{ChatId, ChatVisibility, MessageListOptions, MuteDuration};
use deltachat::constants::DC_MSG_ID_LAST_SPECIAL;
use deltachat::contact::{Contact, ContactId, Origin};
use deltachat::context::{Context, ContextBuilder};
@@ -1721,7 +1721,7 @@ pub unsafe extern "C" fn dc_get_chat(context: *mut dc_context_t, chat_id: u32) -
#[no_mangle]
pub unsafe extern "C" fn dc_create_group_chat(
context: *mut dc_context_t,
protect: libc::c_int,
_protect: libc::c_int,
name: *const libc::c_char,
) -> u32 {
if context.is_null() || name.is_null() {
@@ -1729,22 +1729,12 @@ pub unsafe extern "C" fn dc_create_group_chat(
return 0;
}
let ctx = &*context;
let Some(protect) = ProtectionStatus::from_i32(protect)
.context("Bad protect-value for dc_create_group_chat()")
.log_err(ctx)
.ok()
else {
return 0;
};
block_on(async move {
chat::create_group_chat(ctx, protect, &to_string_lossy(name))
.await
block_on(chat::create_group_chat(ctx, &to_string_lossy(name)))
.context("Failed to create group chat")
.log_err(ctx)
.map(|id| id.to_u32())
.unwrap_or(0)
})
}
#[no_mangle]

View File

@@ -12,7 +12,6 @@ use deltachat::calls::ice_servers;
use deltachat::chat::{
self, add_contact_to_chat, forward_msgs, get_chat_media, get_chat_msgs, get_chat_msgs_ex,
marknoticed_chat, remove_contact_from_chat, Chat, ChatId, ChatItem, MessageListOptions,
ProtectionStatus,
};
use deltachat::chatlist::Chatlist;
use deltachat::config::Config;
@@ -978,16 +977,9 @@ impl CommandApi {
///
/// To check, if a chat is still unpromoted, you can look at the `is_unpromoted` property of `BasicChat` or `FullChat`.
/// This may be useful if you want to show some help for just created groups.
///
/// @param protect If set to 1 the function creates group with protection initially enabled.
/// Only verified members are allowed in these groups
async fn create_group_chat(&self, account_id: u32, name: String, protect: bool) -> Result<u32> {
async fn create_group_chat(&self, account_id: u32, name: String) -> Result<u32> {
let ctx = self.get_context(account_id).await?;
let protect = match protect {
true => ProtectionStatus::Protected,
false => ProtectionStatus::Unprotected,
};
chat::create_group_ex(&ctx, Some(protect), &name)
chat::create_group_chat(&ctx, &name)
.await
.map(|id| id.to_u32())
}
@@ -998,7 +990,7 @@ impl CommandApi {
/// address-contacts.
async fn create_group_chat_unencrypted(&self, account_id: u32, name: String) -> Result<u32> {
let ctx = self.get_context(account_id).await?;
chat::create_group_ex(&ctx, None, &name)
chat::create_group_chat_unencrypted(&ctx, &name)
.await
.map(|id| id.to_u32())
}

View File

@@ -6,9 +6,7 @@ use std::str::FromStr;
use std::time::Duration;
use anyhow::{bail, ensure, Result};
use deltachat::chat::{
self, Chat, ChatId, ChatItem, ChatVisibility, MuteDuration, ProtectionStatus,
};
use deltachat::chat::{self, Chat, ChatId, ChatItem, ChatVisibility, MuteDuration};
use deltachat::chatlist::*;
use deltachat::constants::*;
use deltachat::contact::*;
@@ -347,7 +345,6 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
createchat <contact-id>\n\
creategroup <name>\n\
createbroadcast <name>\n\
createprotected <name>\n\
addmember <contact-id>\n\
removemember <contact-id>\n\
groupname <name>\n\
@@ -740,8 +737,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
}
"creategroup" => {
ensure!(!arg1.is_empty(), "Argument <name> missing.");
let chat_id =
chat::create_group_chat(&context, ProtectionStatus::Unprotected, arg1).await?;
let chat_id = chat::create_group_chat(&context, arg1).await?;
println!("Group#{chat_id} created successfully.");
}
@@ -751,13 +747,6 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
println!("Broadcast#{chat_id} created successfully.");
}
"createprotected" => {
ensure!(!arg1.is_empty(), "Argument <name> missing.");
let chat_id =
chat::create_group_chat(&context, ProtectionStatus::Protected, arg1).await?;
println!("Group#{chat_id} created and protected successfully.");
}
"addmember" => {
ensure!(sel_chat.is_some(), "No chat selected");
ensure!(!arg1.is_empty(), "Argument <contact-id> missing.");

View File

@@ -300,7 +300,7 @@ class Account:
chats.append(AttrDict(item))
return chats
def create_group(self, name: str, protect: bool = False) -> Chat:
def create_group(self, name: str) -> Chat:
"""Create a new group chat.
After creation,
@@ -317,12 +317,8 @@ class Account:
To check, if a chat is still unpromoted, you can look at the `is_unpromoted` property of a chat
(see `get_full_snapshot()` / `get_basic_snapshot()`).
This may be useful if you want to show some help for just created groups.
:param protect: If set to 1 the function creates group with protection initially enabled.
Only verified members are allowed in these groups
and end-to-end-encryption is always enabled.
"""
return Chat(self, self._rpc.create_group_chat(self.id, name, protect))
return Chat(self, self._rpc.create_group_chat(self.id, name))
def create_broadcast(self, name: str) -> Chat:
"""Create a new **broadcast channel**

View File

@@ -58,8 +58,7 @@ def test_qr_setup_contact_svg(acfactory) -> None:
assert "Alice" in svg
@pytest.mark.parametrize("protect", [True, False])
def test_qr_securejoin(acfactory, protect):
def test_qr_securejoin(acfactory):
alice, bob, fiona = acfactory.get_online_accounts(3)
# Setup second device for Alice
@@ -67,7 +66,7 @@ def test_qr_securejoin(acfactory, protect):
alice2 = alice.clone()
logging.info("Alice creates a group")
alice_chat = alice.create_group("Group", protect=protect)
alice_chat = alice.create_group("Group")
logging.info("Bob joins the group")
qr_code = alice_chat.get_qr_code()
@@ -123,8 +122,8 @@ def test_qr_securejoin_contact_request(acfactory) -> None:
bob_chat_alice = snapshot.chat
assert bob_chat_alice.get_basic_snapshot().is_contact_request
alice_chat = alice.create_group("Verified group", protect=True)
logging.info("Bob joins verified group")
alice_chat = alice.create_group("Group")
logging.info("Bob joins the group")
qr_code = alice_chat.get_qr_code()
bob.secure_join(qr_code)
while True:
@@ -148,8 +147,8 @@ def test_qr_readreceipt(acfactory) -> None:
for joiner in [bob, charlie]:
joiner.wait_for_securejoin_joiner_success()
logging.info("Alice creates a verified group")
group = alice.create_group("Group", protect=True)
logging.info("Alice creates a group")
group = alice.create_group("Group")
alice_contact_bob = alice.create_contact(bob, "Bob")
alice_contact_charlie = alice.create_contact(charlie, "Charlie")
@@ -214,10 +213,10 @@ def test_verified_group_member_added_recovery(acfactory) -> None:
"""Tests verified group recovery by reverifying then removing and adding a member back."""
ac1, ac2, ac3 = acfactory.get_online_accounts(3)
logging.info("ac1 creates verified group")
chat = ac1.create_group("Verified group", protect=True)
logging.info("ac1 creates a group")
chat = ac1.create_group("Group")
logging.info("ac2 joins verified group")
logging.info("ac2 joins the group")
qr_code = chat.get_qr_code()
ac2.secure_join(qr_code)
ac2.wait_for_securejoin_joiner_success()
@@ -299,8 +298,8 @@ def test_qr_join_chat_with_pending_bobstate_issue4894(acfactory):
# we first create a fully joined verified group, and then start
# joining a second time but interrupt it, to create pending bob state
logging.info("ac1: create verified group that ac2 fully joins")
ch1 = ac1.create_group("Group", protect=True)
logging.info("ac1: create a group that ac2 fully joins")
ch1 = ac1.create_group("Group")
qr_code = ch1.get_qr_code()
ac2.secure_join(qr_code)
ac1.wait_for_securejoin_inviter_success()
@@ -323,7 +322,7 @@ def test_qr_join_chat_with_pending_bobstate_issue4894(acfactory):
assert ac2.create_contact(ac3).get_snapshot().is_verified
logging.info("ac3: create a verified group VG with ac2")
vg = ac3.create_group("ac3-created", protect=True)
vg = ac3.create_group("ac3-created")
vg.add_contact(ac3.create_contact(ac2))
# ensure ac2 receives message in VG
@@ -354,7 +353,7 @@ def test_qr_new_group_unblocked(acfactory):
"""
ac1, ac2 = acfactory.get_online_accounts(2)
ac1_chat = ac1.create_group("Group for joining", protect=True)
ac1_chat = ac1.create_group("Group for joining")
qr_code = ac1_chat.get_qr_code()
ac2.secure_join(qr_code)
@@ -379,7 +378,7 @@ def test_aeap_flow_verified(acfactory):
addr, password = acfactory.get_credentials()
logging.info("ac1: create verified-group QR, ac2 scans and joins")
chat = ac1.create_group("hello", protect=True)
chat = ac1.create_group("hello")
qr_code = chat.get_qr_code()
logging.info("ac2: start QR-code based join-group protocol")
ac2.secure_join(qr_code)
@@ -446,7 +445,7 @@ def test_gossip_verification(acfactory) -> None:
assert carol_contact_alice_snapshot.is_verified
logging.info("Bob creates a Securejoin group")
bob_group_chat = bob.create_group("Securejoin Group", protect=True)
bob_group_chat = bob.create_group("Securejoin Group")
bob_group_chat.add_contact(bob_contact_alice)
bob_group_chat.add_contact(bob_contact_carol)
bob_group_chat.send_message(text="Hello Securejoin group")
@@ -469,7 +468,7 @@ def test_securejoin_after_contact_resetup(acfactory) -> None:
ac1, ac2, ac3 = acfactory.get_online_accounts(3)
# ac3 creates protected group with ac1.
ac3_chat = ac3.create_group("Verified group", protect=True)
ac3_chat = ac3.create_group("Group")
# ac1 joins ac3 group.
ac3_qr_code = ac3_chat.get_qr_code()
@@ -526,8 +525,8 @@ def test_securejoin_after_contact_resetup(acfactory) -> None:
def test_withdraw_securejoin_qr(acfactory):
alice, bob = acfactory.get_online_accounts(2)
logging.info("Alice creates a verified group")
alice_chat = alice.create_group("Verified group", protect=True)
logging.info("Alice creates a group")
alice_chat = alice.create_group("Group")
logging.info("Bob joins verified group")
qr_code = alice_chat.get_qr_code()

View File

@@ -404,18 +404,16 @@ class Account:
self,
name: str,
contacts: Optional[List[Contact]] = None,
verified: bool = False,
) -> Chat:
"""create a new group chat object.
Chats are unpromoted until the first message is sent.
:param contacts: list of contacts to add
:param verified: if true only verified contacts can be added.
:returns: a :class:`deltachat.chat.Chat` object.
"""
bytes_name = name.encode("utf8")
chat_id = lib.dc_create_group_chat(self._dc_context, int(verified), bytes_name)
chat_id = lib.dc_create_group_chat(self._dc_context, 0, bytes_name)
chat = Chat(self, chat_id)
if contacts is not None:
for contact in contacts:

View File

@@ -604,20 +604,6 @@ class ACFactory:
ac2.create_chat(ac1)
return ac1.create_chat(ac2)
def get_protected_chat(self, ac1: Account, ac2: Account):
chat = ac1.create_group_chat("Protected Group", verified=True)
qr = chat.get_join_qr()
ac2.qr_join_chat(qr)
ac2._evtracker.wait_securejoin_joiner_progress(1000)
ev = ac2._evtracker.get_matching("DC_EVENT_MSGS_CHANGED")
msg = ac2.get_message_by_id(ev.data2)
assert msg is not None
assert msg.text == "Messages are end-to-end encrypted."
msg = ac2._evtracker.wait_next_incoming_message()
assert msg is not None
assert "Member Me " in msg.text and " added by " in msg.text
return chat
def introduce_each_other(self, accounts, sending=True):
to_wait = []
for i, acc in enumerate(accounts):

View File

@@ -118,7 +118,7 @@ def test_qr_verified_group_and_chatting(acfactory, lp):
ac1, ac2, ac3 = acfactory.get_online_accounts(3)
ac1_addr = ac1.get_self_contact().addr
lp.sec("ac1: create verified-group QR, ac2 scans and joins")
chat1 = ac1.create_group_chat("hello", verified=True)
chat1 = ac1.create_group_chat("hello")
qr = chat1.get_join_qr()
lp.sec("ac2: start QR-code based join-group protocol")
chat2 = ac2.qr_join_chat(qr)
@@ -171,8 +171,10 @@ def test_qr_verified_group_and_chatting(acfactory, lp):
lp.sec("ac2: Check that ac1 verified ac3 for ac2")
ac2_ac1_contact = ac2.get_contacts()[0]
assert ac2.get_self_contact().get_verifier(ac2_ac1_contact).id == dc.const.DC_CONTACT_ID_SELF
ac2_ac3_contact = ac2.get_contacts()[1]
assert ac2.get_self_contact().get_verifier(ac2_ac3_contact).addr == ac1_addr
for ac2_contact in chat2.get_contacts():
if ac2_contact == ac2_ac1_contact or ac2_contact.id == dc.const.DC_CONTACT_ID_SELF:
continue
assert ac2.get_self_contact().get_verifier(ac2_contact).addr == ac1_addr
lp.sec("ac2: send message and let ac3 read it")
chat2.send_text("hi")
@@ -264,7 +266,7 @@ def test_see_new_verified_member_after_going_online(acfactory, tmp_path, lp):
ac1_offl.stop_io()
lp.sec("ac1: create verified-group QR, ac2 scans and joins")
chat = ac1.create_group_chat("hello", verified=True)
chat = ac1.create_group_chat("hello")
qr = chat.get_join_qr()
lp.sec("ac2: start QR-code based join-group protocol")
chat2 = ac2.qr_join_chat(qr)
@@ -318,7 +320,7 @@ def test_use_new_verified_group_after_going_online(acfactory, data, tmp_path, lp
ac1.set_avatar(avatar_path)
lp.sec("ac1: create verified-group QR, ac2 scans and joins")
chat = ac1.create_group_chat("hello", verified=True)
chat = ac1.create_group_chat("hello")
qr = chat.get_join_qr()
lp.sec("ac2: start QR-code based join-group protocol")
ac2.qr_join_chat(qr)
@@ -371,7 +373,7 @@ def test_verified_group_vs_delete_server_after(acfactory, tmp_path, lp):
ac2_offl.stop_io()
lp.sec("ac1: create verified-group QR, ac2 scans and joins")
chat1 = ac1.create_group_chat("hello", verified=True)
chat1 = ac1.create_group_chat("hello")
qr = chat1.get_join_qr()
lp.sec("ac2: start QR-code based join-group protocol")
chat2 = ac2.qr_join_chat(qr)
@@ -401,15 +403,6 @@ def test_verified_group_vs_delete_server_after(acfactory, tmp_path, lp):
chat2.send_text("hi2")
lp.sec("ac2_offl: receiving message")
ev = ac2_offl._evtracker.get_matching("DC_EVENT_INCOMING_MSG|DC_EVENT_MSGS_CHANGED")
msg_in = ac2_offl.get_message_by_id(ev.data2)
assert msg_in.is_system_message()
assert msg_in.text == "Messages are end-to-end encrypted."
# We need to consume one event that has data2=0
ev = ac2_offl._evtracker.get_matching("DC_EVENT_INCOMING_MSG|DC_EVENT_MSGS_CHANGED")
assert ev.data2 == 0
ev = ac2_offl._evtracker.get_matching("DC_EVENT_INCOMING_MSG|DC_EVENT_MSGS_CHANGED")
msg_in = ac2_offl.get_message_by_id(ev.data2)
assert not msg_in.is_system_message()

View File

@@ -1204,7 +1204,7 @@ def test_import_export_online_all(acfactory, tmp_path, data, lp):
def test_qr_email_capitalization(acfactory, lp):
"""Regression test for a bug
that resulted in failure to propagate verification via gossip in a verified group
that resulted in failure to propagate verification
when the database already contained the contact with a different email address capitalization.
"""
@@ -1215,17 +1215,17 @@ def test_qr_email_capitalization(acfactory, lp):
lp.sec(f"ac1 creates a contact for ac2 ({ac2_addr_uppercase})")
ac1.create_contact(ac2_addr_uppercase)
lp.sec("ac3 creates a verified group with a QR code")
chat = ac3.create_group_chat("hello", verified=True)
lp.sec("ac3 creates a group with a QR code")
chat = ac3.create_group_chat("hello")
qr = chat.get_join_qr()
lp.sec("ac1 joins a verified group via a QR code")
lp.sec("ac1 joins a group via a QR code")
ac1_chat = ac1.qr_join_chat(qr)
msg = ac1._evtracker.wait_next_incoming_message()
assert msg.text == "Member Me added by {}.".format(ac3.get_config("addr"))
assert len(ac1_chat.get_contacts()) == 2
lp.sec("ac2 joins a verified group via a QR code")
lp.sec("ac2 joins a group via a QR code")
ac2.qr_join_chat(qr)
ac1._evtracker.wait_next_incoming_message()

View File

@@ -271,10 +271,9 @@ class TestOfflineChat:
chat.set_name("Homework")
assert chat.get_messages()[-1].text == "abc homework xyz Homework"
@pytest.mark.parametrize("verified", [True, False])
def test_group_chat_qr(self, acfactory, ac1, verified):
def test_group_chat_qr(self, acfactory, ac1):
ac2 = acfactory.get_pseudo_configured_account()
chat = ac1.create_group_chat(name="title1", verified=verified)
chat = ac1.create_group_chat(name="title1")
assert chat.is_group()
qr = chat.get_join_qr()
assert ac2.check_qr(qr).is_ask_verifygroup

View File

@@ -306,14 +306,12 @@ impl ChatId {
/// Create a group or mailinglist raw database record with the given parameters.
/// The function does not add SELF nor checks if the record already exists.
#[expect(clippy::too_many_arguments)]
pub(crate) async fn create_multiuser_record(
context: &Context,
chattype: Chattype,
grpid: &str,
grpname: &str,
create_blocked: Blocked,
create_protected: ProtectionStatus,
param: Option<String>,
timestamp: i64,
) -> Result<Self> {
@@ -321,31 +319,27 @@ impl ChatId {
let timestamp = cmp::min(timestamp, smeared_time(context));
let row_id =
context.sql.insert(
"INSERT INTO chats (type, name, grpid, blocked, created_timestamp, protected, param) VALUES(?, ?, ?, ?, ?, ?, ?);",
"INSERT INTO chats (type, name, grpid, blocked, created_timestamp, protected, param) VALUES(?, ?, ?, ?, ?, 0, ?);",
(
chattype,
&grpname,
grpid,
create_blocked,
timestamp,
create_protected,
param.unwrap_or_default(),
),
).await?;
let chat_id = ChatId::new(u32::try_from(row_id)?);
let chat = Chat::load_from_db(context, chat_id).await?;
if create_protected == ProtectionStatus::Protected {
chat_id
.add_protection_msg(context, ProtectionStatus::Protected, None, timestamp)
.await?;
} else {
chat_id.maybe_add_encrypted_msg(context, timestamp).await?;
if chat.is_encrypted(context).await? {
chat_id.add_encrypted_msg(context, timestamp).await?;
}
info!(
context,
"Created group/mailinglist '{}' grpid={} as {}, blocked={}, protected={create_protected}.",
"Created group/mailinglist '{}' grpid={} as {}, blocked={}.",
&grpname,
grpid,
chat_id,
@@ -500,111 +494,8 @@ impl ChatId {
Ok(())
}
/// Sets protection without sending a message.
///
/// Returns whether the protection status was actually modified.
pub(crate) async fn inner_set_protection(
self,
context: &Context,
protect: ProtectionStatus,
) -> Result<bool> {
ensure!(!self.is_special(), "Invalid chat-id {self}.");
let chat = Chat::load_from_db(context, self).await?;
if protect == chat.protected {
info!(context, "Protection status unchanged for {}.", self);
return Ok(false);
}
match protect {
ProtectionStatus::Protected => match chat.typ {
Chattype::Single
| Chattype::Group
| Chattype::OutBroadcast
| Chattype::InBroadcast => {}
Chattype::Mailinglist => bail!("Cannot protect mailing lists"),
},
ProtectionStatus::Unprotected => {}
};
context
.sql
.execute("UPDATE chats SET protected=? WHERE id=?;", (protect, self))
.await?;
context.emit_event(EventType::ChatModified(self));
chatlist_events::emit_chatlist_item_changed(context, self);
// make sure, the receivers will get all keys
self.reset_gossiped_timestamp(context).await?;
Ok(true)
}
/// Adds an info message to the chat, telling the user that the protection status changed.
///
/// Params:
///
/// * `contact_id`: In a 1:1 chat, pass the chat partner's contact id.
/// * `timestamp_sort` is used as the timestamp of the added message
/// and should be the timestamp of the change happening.
pub(crate) async fn add_protection_msg(
self,
context: &Context,
protect: ProtectionStatus,
contact_id: Option<ContactId>,
timestamp_sort: i64,
) -> Result<()> {
if contact_id == Some(ContactId::SELF) {
// Do not add protection messages to Saved Messages chat.
// This chat never gets protected and unprotected,
// we do not want the first message
// to be a protection message with an arbitrary timestamp.
return Ok(());
}
let text = context.stock_protection_msg(protect, contact_id).await;
let cmd = match protect {
ProtectionStatus::Protected => SystemMessage::ChatProtectionEnabled,
ProtectionStatus::Unprotected => SystemMessage::ChatProtectionDisabled,
};
add_info_msg_with_cmd(
context,
self,
&text,
cmd,
timestamp_sort,
None,
None,
None,
None,
)
.await?;
Ok(())
}
/// Adds message "Messages are end-to-end encrypted" if appropriate.
///
/// This function is rather slow because it does a lot of database queries,
/// but this is fine because it is only called on chat creation.
async fn maybe_add_encrypted_msg(self, context: &Context, timestamp_sort: i64) -> Result<()> {
let chat = Chat::load_from_db(context, self).await?;
// as secure-join adds its own message on success (after some other messasges),
// we do not want to add "Messages are end-to-end encrypted" on chat creation.
// we detect secure join by `can_send` (for Bob, scanner side) and by `blocked` (for Alice, inviter side) below.
if !chat.is_encrypted(context).await?
|| self <= DC_CHAT_ID_LAST_SPECIAL
|| chat.is_device_talk()
|| chat.is_self_talk()
|| (!chat.can_send(context).await? && !chat.is_contact_request())
|| chat.blocked == Blocked::Yes
{
return Ok(());
}
/// Adds message "Messages are end-to-end encrypted".
async fn add_encrypted_msg(self, context: &Context, timestamp_sort: i64) -> Result<()> {
let text = stock_str::messages_e2e_encrypted(context).await;
add_info_msg_with_cmd(
context,
@@ -621,74 +512,6 @@ impl ChatId {
Ok(())
}
/// Sets protection and adds a message.
///
/// `timestamp_sort` is used as the timestamp of the added message
/// and should be the timestamp of the change happening.
async fn set_protection_for_timestamp_sort(
self,
context: &Context,
protect: ProtectionStatus,
timestamp_sort: i64,
contact_id: Option<ContactId>,
) -> Result<()> {
let protection_status_modified = self
.inner_set_protection(context, protect)
.await
.with_context(|| format!("Cannot set protection for {self}"))?;
if protection_status_modified {
self.add_protection_msg(context, protect, contact_id, timestamp_sort)
.await?;
chatlist_events::emit_chatlist_item_changed(context, self);
}
Ok(())
}
/// Sets protection and sends or adds a message.
///
/// `timestamp_sent` is the "sent" timestamp of a message caused the protection state change.
pub(crate) async fn set_protection(
self,
context: &Context,
protect: ProtectionStatus,
timestamp_sent: i64,
contact_id: Option<ContactId>,
) -> Result<()> {
let sort_to_bottom = true;
let (received, incoming) = (false, false);
let ts = self
.calc_sort_timestamp(context, timestamp_sent, sort_to_bottom, received, incoming)
.await?
// Always sort protection messages below `SystemMessage::SecurejoinWait{,Timeout}` ones
// in case of race conditions.
.saturating_add(1);
self.set_protection_for_timestamp_sort(context, protect, ts, contact_id)
.await
}
/// 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,
timestamp: i64,
) -> 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,
timestamp,
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
@@ -2666,19 +2489,12 @@ impl ChatIdBlocked {
})
.await?;
if protected {
chat_id
.add_protection_msg(
context,
ProtectionStatus::Protected,
Some(contact_id),
smeared_time,
)
.await?;
} else {
chat_id
.maybe_add_encrypted_msg(context, smeared_time)
.await?;
let chat = Chat::load_from_db(context, chat_id).await?;
if chat.is_encrypted(context).await?
&& !chat.param.exists(Param::Devicetalk)
&& !chat.param.exists(Param::Selftalk)
{
chat_id.add_encrypted_msg(context, smeared_time).await?;
}
Ok(Self {
@@ -3651,22 +3467,24 @@ pub async fn get_past_chat_contacts(context: &Context, chat_id: ChatId) -> Resul
}
/// Creates a group chat with a given `name`.
/// Deprecated on 2025-06-21, use `create_group_ex()`.
pub async fn create_group_chat(
context: &Context,
protect: ProtectionStatus,
name: &str,
) -> Result<ChatId> {
create_group_ex(context, Some(protect), name).await
pub async fn create_group_chat(context: &Context, name: &str) -> Result<ChatId> {
let is_encrypted = true;
create_group_ex(context, is_encrypted, name).await
}
/// Creates a new unencrypted group chat.
pub async fn create_group_chat_unencrypted(context: &Context, name: &str) -> Result<ChatId> {
let is_encrypted = false;
create_group_ex(context, is_encrypted, name).await
}
/// Creates a group chat.
///
/// * `encryption` - If `Some`, the chat is encrypted (with key-contacts) and can be protected.
/// * `is_encrypted` - If true, the chat is encrypted (with key-contacts).
/// * `name` - Chat name.
pub async fn create_group_ex(
pub(crate) async fn create_group_ex(
context: &Context,
encryption: Option<ProtectionStatus>,
is_encrypted: bool,
name: &str,
) -> Result<ChatId> {
let mut chat_name = sanitize_single_line(name);
@@ -3677,9 +3495,10 @@ pub async fn create_group_ex(
chat_name = "".to_string();
}
let grpid = match encryption {
Some(_) => create_id(),
None => String::new(),
let grpid = if is_encrypted {
create_id()
} else {
String::new()
};
let timestamp = create_smeared_timestamp(context);
@@ -3700,19 +3519,9 @@ pub async fn create_group_ex(
chatlist_events::emit_chatlist_changed(context);
chatlist_events::emit_chatlist_item_changed(context, chat_id);
match encryption {
Some(ProtectionStatus::Protected) => {
let protect = ProtectionStatus::Protected;
chat_id
.set_protection_for_timestamp_sort(context, protect, timestamp, None)
.await?;
}
Some(ProtectionStatus::Unprotected) => {
// Add "Messages are end-to-end encrypted." message
// even to unprotected chats.
chat_id.maybe_add_encrypted_msg(context, timestamp).await?;
}
None => {}
if is_encrypted {
// Add "Messages are end-to-end encrypted." message.
chat_id.add_encrypted_msg(context, timestamp).await?;
}
if !context.get_config_bool(Config::Bot).await?

View File

@@ -96,7 +96,7 @@ async fn test_get_draft() {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_delete_draft() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "abc").await?;
let chat_id = create_group_chat(&t, "abc").await?;
let mut msg = Message::new_text("hi!".to_string());
chat_id.set_draft(&t, Some(&mut msg)).await?;
@@ -120,7 +120,7 @@ async fn test_forwarding_draft_failing() -> Result<()> {
chat_id.set_draft(&t, Some(&mut msg)).await?;
assert_eq!(msg.id, chat_id.get_draft(&t).await?.unwrap().id);
let chat_id2 = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id2 = create_group_chat(&t, "foo").await?;
assert!(forward_msgs(&t, &[msg.id], chat_id2).await.is_err());
Ok(())
}
@@ -169,7 +169,7 @@ async fn test_draft_stable_ids() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_only_one_draft_per_chat() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "abc").await?;
let chat_id = create_group_chat(&t, "abc").await?;
let msgs: Vec<message::Message> = (1..=1000)
.map(|i| Message::new_text(i.to_string()))
@@ -196,7 +196,7 @@ async fn test_only_one_draft_per_chat() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_change_quotes_on_reused_message_object() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "chat").await?;
let chat_id = create_group_chat(&t, "chat").await?;
let quote1 =
Message::load_from_db(&t, send_text_msg(&t, chat_id, "quote1".to_string()).await?).await?;
let quote2 =
@@ -247,7 +247,7 @@ async fn test_quote_replies() -> Result<()> {
let alice = TestContext::new_alice().await;
let bob = TestContext::new_bob().await;
let grp_chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "grp").await?;
let grp_chat_id = create_group_chat(&alice, "grp").await?;
let grp_msg_id = send_text_msg(&alice, grp_chat_id, "bar".to_string()).await?;
let grp_msg = Message::load_from_db(&alice, grp_msg_id).await?;
@@ -295,9 +295,7 @@ async fn test_quote_replies() -> Result<()> {
async fn test_add_contact_to_chat_ex_add_self() {
// Adding self to a contact should succeed, even though it's pointless.
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo")
.await
.unwrap();
let chat_id = create_group_chat(&t, "foo").await.unwrap();
let added = add_contact_to_chat_ex(&t, Nosync, chat_id, ContactId::SELF, false)
.await
.unwrap();
@@ -336,8 +334,7 @@ async fn test_member_add_remove() -> Result<()> {
}
tcm.section("Create and promote a group.");
let alice_chat_id =
create_group_chat(&alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(&alice, "Group chat").await?;
let alice_fiona_contact_id = alice.add_or_lookup_contact_id(&fiona).await;
add_contact_to_chat(&alice, alice_chat_id, alice_fiona_contact_id).await?;
let sent = alice
@@ -399,8 +396,7 @@ async fn test_parallel_member_remove() -> Result<()> {
let alice_charlie_contact_id = alice.add_or_lookup_contact_id(&charlie).await;
tcm.section("Alice creates and promotes a group");
let alice_chat_id =
create_group_chat(&alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(&alice, "Group chat").await?;
add_contact_to_chat(&alice, alice_chat_id, alice_bob_contact_id).await?;
add_contact_to_chat(&alice, alice_chat_id, alice_fiona_contact_id).await?;
let alice_sent_msg = alice
@@ -457,8 +453,7 @@ async fn test_msg_with_implicit_member_removed() -> Result<()> {
let alice_bob_contact_id = alice.add_or_lookup_contact_id(&bob).await;
let alice_fiona_contact_id = alice.add_or_lookup_contact_id(&fiona).await;
let bob_fiona_contact_id = bob.add_or_lookup_contact_id(&fiona).await;
let alice_chat_id =
create_group_chat(&alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(&alice, "Group chat").await?;
add_contact_to_chat(&alice, alice_chat_id, alice_bob_contact_id).await?;
let sent_msg = alice.send_text(alice_chat_id, "I created a group").await;
let bob_received_msg = bob.recv_msg(&sent_msg).await;
@@ -504,7 +499,7 @@ async fn test_modify_chat_multi_device() -> Result<()> {
a1.set_config_bool(Config::BccSelf, true).await?;
// create group and sync it to the second device
let a1_chat_id = create_group_chat(&a1, ProtectionStatus::Unprotected, "foo").await?;
let a1_chat_id = create_group_chat(&a1, "foo").await?;
let sent = a1.send_text(a1_chat_id, "ho!").await;
let a1_msg = a1.get_last_msg().await;
let a1_chat = Chat::load_from_db(&a1, a1_chat_id).await?;
@@ -602,7 +597,7 @@ async fn test_modify_chat_disordered() -> Result<()> {
let fiona = tcm.fiona().await;
let fiona_id = alice.add_or_lookup_contact_id(&fiona).await;
let alice_chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foo").await?;
let alice_chat_id = create_group_chat(&alice, "foo").await?;
send_text_msg(&alice, alice_chat_id, "populate".to_string()).await?;
add_contact_to_chat(&alice, alice_chat_id, bob_id).await?;
@@ -649,9 +644,7 @@ async fn test_lost_member_added() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let charlie = &tcm.charlie().await;
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "Group", &[bob])
.await;
let alice_chat_id = alice.create_group_with_members("Group", &[bob]).await;
let alice_sent = alice.send_text(alice_chat_id, "Hi!").await;
let bob_chat_id = bob.recv_msg(&alice_sent).await.chat_id;
assert_eq!(get_chat_contacts(bob, bob_chat_id).await?.len(), 2);
@@ -681,7 +674,7 @@ async fn test_modify_chat_lost() -> Result<()> {
let fiona = tcm.fiona().await;
let fiona_id = alice.add_or_lookup_contact_id(&fiona).await;
let alice_chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foo").await?;
let alice_chat_id = create_group_chat(&alice, "foo").await?;
add_contact_to_chat(&alice, alice_chat_id, bob_id).await?;
add_contact_to_chat(&alice, alice_chat_id, charlie_id).await?;
add_contact_to_chat(&alice, alice_chat_id, fiona_id).await?;
@@ -722,7 +715,7 @@ async fn test_leave_group() -> Result<()> {
let bob = tcm.bob().await;
tcm.section("Alice creates group chat with Bob.");
let alice_chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foo").await?;
let alice_chat_id = create_group_chat(&alice, "foo").await?;
let bob_contact = alice.add_or_lookup_contact(&bob).await.id;
add_contact_to_chat(&alice, alice_chat_id, bob_contact).await?;
@@ -1381,9 +1374,7 @@ async fn test_pinned() {
tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
let chat_id2 = t.get_self_chat().await.id;
tokio::time::sleep(std::time::Duration::from_millis(1000)).await;
let chat_id3 = create_group_chat(&t, ProtectionStatus::Unprotected, "foo")
.await
.unwrap();
let chat_id3 = create_group_chat(&t, "foo").await.unwrap();
let chatlist = get_chats_from_chat_list(&t, DC_GCL_NO_SPECIALS).await;
assert_eq!(chatlist, vec![chat_id3, chat_id2, chat_id1]);
@@ -1473,9 +1464,7 @@ async fn test_set_chat_name() {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "foo")
.await
.unwrap();
let chat_id = create_group_chat(alice, "foo").await.unwrap();
assert_eq!(
Chat::load_from_db(alice, chat_id).await.unwrap().get_name(),
"foo"
@@ -1547,7 +1536,7 @@ async fn test_shall_attach_selfavatar() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(alice, "foo").await?;
assert!(!shall_attach_selfavatar(alice, chat_id).await?);
let contact_id = alice.add_or_lookup_contact_id(bob).await;
@@ -1569,7 +1558,7 @@ async fn test_profile_data_on_group_leave() -> Result<()> {
let mut tcm = TestContextManager::new();
let t = &tcm.alice().await;
let bob = &tcm.bob().await;
let chat_id = create_group_chat(t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(t, "foo").await?;
let contact_id = t.add_or_lookup_contact_id(bob).await;
add_contact_to_chat(t, chat_id, contact_id).await?;
@@ -1594,9 +1583,7 @@ async fn test_profile_data_on_group_leave() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_set_mute_duration() {
let t = TestContext::new().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo")
.await
.unwrap();
let chat_id = create_group_chat(&t, "foo").await.unwrap();
// Initial
assert_eq!(
Chat::load_from_db(&t, chat_id).await.unwrap().is_muted(),
@@ -1645,7 +1632,7 @@ async fn test_set_mute_duration() {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_add_info_msg() -> Result<()> {
let t = TestContext::new().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
add_info_msg(&t, chat_id, "foo info", time()).await?;
let msg = t.get_last_msg_in(chat_id).await;
@@ -1662,7 +1649,7 @@ async fn test_add_info_msg() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_add_info_msg_with_cmd() -> Result<()> {
let t = TestContext::new().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let msg_id = add_info_msg_with_cmd(
&t,
chat_id,
@@ -1931,14 +1918,14 @@ async fn test_classic_email_chat() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_chat_get_color() -> Result<()> {
let t = TestContext::new().await;
let chat_id = create_group_ex(&t, None, "a chat").await?;
let chat_id = create_group_chat_unencrypted(&t, "a chat").await?;
let color1 = Chat::load_from_db(&t, chat_id).await?.get_color(&t).await?;
assert_eq!(color1, 0x6239dc);
// upper-/lowercase makes a difference for the colors, these are different groups
// (in contrast to email addresses, where upper-/lowercase is ignored in practise)
let t = TestContext::new().await;
let chat_id = create_group_ex(&t, None, "A CHAT").await?;
let chat_id = create_group_chat_unencrypted(&t, "A CHAT").await?;
let color2 = Chat::load_from_db(&t, chat_id).await?.get_color(&t).await?;
assert_ne!(color2, color1);
Ok(())
@@ -1948,7 +1935,7 @@ async fn test_chat_get_color() -> Result<()> {
async fn test_chat_get_color_encrypted() -> Result<()> {
let mut tcm = TestContextManager::new();
let t = &tcm.alice().await;
let chat_id = create_group_ex(t, Some(ProtectionStatus::Unprotected), "a chat").await?;
let chat_id = create_group_chat(t, "a chat").await?;
let color1 = Chat::load_from_db(t, chat_id).await?.get_color(t).await?;
set_chat_name(t, chat_id, "A CHAT").await?;
let color2 = Chat::load_from_db(t, chat_id).await?.get_color(t).await?;
@@ -2137,7 +2124,7 @@ async fn test_forward_info_msg() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let chat_id1 = create_group_chat(alice, ProtectionStatus::Unprotected, "a").await?;
let chat_id1 = create_group_chat(alice, "a").await?;
send_text_msg(alice, chat_id1, "msg one".to_string()).await?;
let bob_id = alice.add_or_lookup_contact_id(bob).await;
add_contact_to_chat(alice, chat_id1, bob_id).await?;
@@ -2204,8 +2191,7 @@ async fn test_forward_group() -> Result<()> {
let bob_chat = bob.create_chat(&alice).await;
// Alice creates a group with Bob.
let alice_group_chat_id =
create_group_chat(&alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_group_chat_id = create_group_chat(&alice, "Group").await?;
let bob_id = alice.add_or_lookup_contact_id(&bob).await;
let charlie_id = alice.add_or_lookup_contact_id(&charlie).await;
add_contact_to_chat(&alice, alice_group_chat_id, bob_id).await?;
@@ -2257,8 +2243,7 @@ async fn test_only_minimal_data_are_forwarded() -> Result<()> {
.set_config(Config::Displayname, Some("secretname"))
.await?;
let bob_id = alice.add_or_lookup_contact_id(&bob).await;
let group_id =
create_group_chat(&alice, ProtectionStatus::Unprotected, "secretgrpname").await?;
let group_id = create_group_chat(&alice, "secretgrpname").await?;
add_contact_to_chat(&alice, group_id, bob_id).await?;
let mut msg = Message::new_text("bla foo".to_owned());
let sent_msg = alice.send_msg(group_id, &mut msg).await;
@@ -2273,7 +2258,7 @@ async fn test_only_minimal_data_are_forwarded() -> Result<()> {
let orig_msg = bob.recv_msg(&sent_msg).await;
let charlie_id = bob.add_or_lookup_contact_id(&charlie).await;
let single_id = ChatId::create_for_contact(&bob, charlie_id).await?;
let group_id = create_group_chat(&bob, ProtectionStatus::Unprotected, "group2").await?;
let group_id = create_group_chat(&bob, "group2").await?;
add_contact_to_chat(&bob, group_id, charlie_id).await?;
let broadcast_id = create_broadcast(&bob, "Channel".to_string()).await?;
add_contact_to_chat(&bob, broadcast_id, charlie_id).await?;
@@ -2371,7 +2356,7 @@ async fn test_save_msgs_order() -> Result<()> {
for a in [alice, alice1] {
a.set_config_bool(Config::SyncMsgs, true).await?;
}
let chat_id = create_group_chat(alice, ProtectionStatus::Protected, "grp").await?;
let chat_id = create_group_chat(alice, "grp").await?;
let sent = [
alice.send_text(chat_id, "0").await,
alice.send_text(chat_id, "1").await,
@@ -2492,7 +2477,7 @@ async fn test_resend_own_message() -> Result<()> {
let alice = TestContext::new_alice().await;
let bob = TestContext::new_bob().await;
let fiona = TestContext::new_fiona().await;
let alice_grp = create_group_chat(&alice, ProtectionStatus::Unprotected, "grp").await?;
let alice_grp = create_group_chat(&alice, "grp").await?;
add_contact_to_chat(
&alice,
alice_grp,
@@ -2579,7 +2564,7 @@ async fn test_resend_foreign_message_fails() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_grp = create_group_chat(alice, ProtectionStatus::Unprotected, "grp").await?;
let alice_grp = create_group_chat(alice, "grp").await?;
add_contact_to_chat(alice, alice_grp, alice.add_or_lookup_contact_id(bob).await).await?;
let sent1 = alice.send_text(alice_grp, "alice->bob").await;
@@ -2596,7 +2581,7 @@ async fn test_resend_info_message_fails() -> Result<()> {
let bob = &tcm.bob().await;
let charlie = &tcm.charlie().await;
let alice_grp = create_group_chat(alice, ProtectionStatus::Unprotected, "grp").await?;
let alice_grp = create_group_chat(alice, "grp").await?;
add_contact_to_chat(alice, alice_grp, alice.add_or_lookup_contact_id(bob).await).await?;
alice.send_text(alice_grp, "alice->bob").await;
@@ -2619,7 +2604,7 @@ async fn test_can_send_group() -> Result<()> {
let chat_id = ChatId::create_for_contact(&alice, bob).await?;
let chat = Chat::load_from_db(&alice, chat_id).await?;
assert!(chat.can_send(&alice).await?);
let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&alice, "foo").await?;
assert_eq!(
Chat::load_from_db(&alice, chat_id)
.await?
@@ -3115,7 +3100,7 @@ async fn test_chat_get_encryption_info() -> Result<()> {
let contact_bob = alice.add_or_lookup_contact_id(bob).await;
let contact_fiona = alice.add_or_lookup_contact_id(fiona).await;
let chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let chat_id = create_group_chat(alice, "Group").await?;
assert_eq!(
chat_id.get_encryption_info(alice).await?,
"End-to-end encryption available"
@@ -3177,9 +3162,7 @@ async fn test_out_failed_on_all_keys_missing() -> Result<()> {
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
let bob_chat_id = bob
.create_group_with_members(ProtectionStatus::Unprotected, "", &[alice, fiona])
.await;
let bob_chat_id = bob.create_group_with_members("", &[alice, fiona]).await;
bob.send_text(bob_chat_id, "Gossiping Fiona's key").await;
alice
.recv_msg(&bob.send_text(bob_chat_id, "No key gossip").await)
@@ -3197,8 +3180,8 @@ async fn test_out_failed_on_all_keys_missing() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_chat_media() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id1 = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id2 = create_group_chat(&t, ProtectionStatus::Unprotected, "bar").await?;
let chat_id1 = create_group_chat(&t, "foo").await?;
let chat_id2 = create_group_chat(&t, "bar").await?;
assert_eq!(
get_chat_media(
@@ -3422,7 +3405,7 @@ async fn test_get_chat_media_webxdc_order() -> Result<()> {
async fn test_blob_renaming() -> Result<()> {
let alice = TestContext::new_alice().await;
let bob = TestContext::new_bob().await;
let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "Group").await?;
let chat_id = create_group_chat(&alice, "Group").await?;
add_contact_to_chat(&alice, chat_id, alice.add_or_lookup_contact_id(&bob).await).await?;
let file = alice.get_blobdir().join("harmless_file.\u{202e}txt.exe");
fs::write(&file, "aaa").await?;
@@ -3484,9 +3467,7 @@ async fn test_sync_blocked() -> Result<()> {
// - Group chats synchronisation.
// - That blocking a group deletes it on other devices.
let fiona = TestContext::new_fiona().await;
let fiona_grp_chat_id = fiona
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[alice0])
.await;
let fiona_grp_chat_id = fiona.create_group_with_members("grp", &[alice0]).await;
let sent_msg = fiona.send_text(fiona_grp_chat_id, "hi").await;
let a0_grp_chat_id = alice0.recv_msg(&sent_msg).await.chat_id;
let a1_grp_chat_id = alice1.recv_msg(&sent_msg).await.chat_id;
@@ -3619,9 +3600,7 @@ async fn test_sync_delete_chat() -> Result<()> {
.get_matching(|evt| matches!(evt, EventType::ChatDeleted { .. }))
.await;
let bob_grp_chat_id = bob
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[alice0])
.await;
let bob_grp_chat_id = bob.create_group_with_members("grp", &[alice0]).await;
let sent_msg = bob.send_text(bob_grp_chat_id, "hi").await;
let a0_grp_chat_id = alice0.recv_msg(&sent_msg).await.chat_id;
let a1_grp_chat_id = alice1.recv_msg(&sent_msg).await.chat_id;
@@ -3988,9 +3967,7 @@ async fn test_info_contact_id() -> Result<()> {
}
// Alice creates group, Bob receives group
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "play", &[bob])
.await;
let alice_chat_id = alice.create_group_with_members("play", &[bob]).await;
let sent_msg1 = alice.send_text(alice_chat_id, "moin").await;
let msg = bob.recv_msg(&sent_msg1).await;
@@ -4085,8 +4062,7 @@ async fn test_add_member_bug() -> Result<()> {
let alice_fiona_contact_id = alice.add_or_lookup_contact_id(fiona).await;
// Create a group.
let alice_chat_id =
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(alice, "Group chat").await?;
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
add_contact_to_chat(alice, alice_chat_id, alice_fiona_contact_id).await?;
@@ -4130,8 +4106,7 @@ async fn test_past_members() -> Result<()> {
let alice_fiona_contact_id = alice.add_or_lookup_contact_id(fiona).await;
tcm.section("Alice creates a chat.");
let alice_chat_id =
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(alice, "Group chat").await?;
add_contact_to_chat(alice, alice_chat_id, alice_fiona_contact_id).await?;
alice
.send_text(alice_chat_id, "Hi! I created a group.")
@@ -4165,8 +4140,7 @@ async fn test_non_member_cannot_modify_member_list() -> Result<()> {
let alice_bob_contact_id = alice.add_or_lookup_contact_id(bob).await;
let alice_chat_id =
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(alice, "Group chat").await?;
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
let alice_sent_msg = alice
.send_text(alice_chat_id, "Hi! I created a group.")
@@ -4209,8 +4183,7 @@ async fn unpromoted_group_no_tombstones() -> Result<()> {
let alice_bob_contact_id = alice.add_or_lookup_contact_id(bob).await;
let alice_fiona_contact_id = alice.add_or_lookup_contact_id(fiona).await;
let alice_chat_id =
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(alice, "Group chat").await?;
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
add_contact_to_chat(alice, alice_chat_id, alice_fiona_contact_id).await?;
assert_eq!(get_chat_contacts(alice, alice_chat_id).await?.len(), 3);
@@ -4241,8 +4214,7 @@ async fn test_expire_past_members_after_60_days() -> Result<()> {
let fiona = &tcm.fiona().await;
let alice_fiona_contact_id = alice.add_or_lookup_contact_id(fiona).await;
let alice_chat_id =
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(alice, "Group chat").await?;
add_contact_to_chat(alice, alice_chat_id, alice_fiona_contact_id).await?;
alice
.send_text(alice_chat_id, "Hi! I created a group.")
@@ -4279,7 +4251,7 @@ async fn test_past_members_order() -> Result<()> {
let fiona = tcm.fiona().await;
let fiona_contact_id = t.add_or_lookup_contact_id(&fiona).await;
let chat_id = create_group_chat(t, ProtectionStatus::Unprotected, "Group chat").await?;
let chat_id = create_group_chat(t, "Group chat").await?;
add_contact_to_chat(t, chat_id, bob_contact_id).await?;
add_contact_to_chat(t, chat_id, charlie_contact_id).await?;
add_contact_to_chat(t, chat_id, fiona_contact_id).await?;
@@ -4341,8 +4313,7 @@ async fn test_restore_backup_after_60_days() -> Result<()> {
let alice_bob_contact_id = alice.add_or_lookup_contact_id(bob).await;
let alice_charlie_contact_id = alice.add_or_lookup_contact_id(charlie).await;
let alice_chat_id =
create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
let alice_chat_id = create_group_chat(alice, "Group chat").await?;
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
add_contact_to_chat(alice, alice_chat_id, alice_charlie_contact_id).await?;
@@ -4530,9 +4501,7 @@ async fn test_cannot_send_edit_request() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let chat_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "My Group", &[bob])
.await;
let chat_id = alice.create_group_with_members("My Group", &[bob]).await;
// Alice can edit her message
let sent1 = alice.send_text(chat_id, "foo").await;
@@ -4703,7 +4672,7 @@ async fn test_no_address_contacts_in_group_chats() -> Result<()> {
let bob = &tcm.bob().await;
let charlie = &tcm.charlie().await;
let chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group chat").await?;
let chat_id = create_group_chat(alice, "Group chat").await?;
let bob_key_contact_id = alice.add_or_lookup_contact_id(bob).await;
let charlie_address_contact_id = alice.add_or_lookup_address_contact_id(charlie).await;
@@ -4762,7 +4731,7 @@ async fn test_create_unencrypted_group_chat() -> Result<()> {
let bob = &tcm.bob().await;
let charlie = &tcm.charlie().await;
let chat_id = create_group_ex(alice, None, "Group chat").await?;
let chat_id = create_group_chat_unencrypted(alice, "Group chat").await?;
let bob_key_contact_id = alice.add_or_lookup_contact_id(bob).await;
let charlie_address_contact_id = alice.add_or_lookup_address_contact_id(charlie).await;
@@ -4783,7 +4752,7 @@ async fn test_create_unencrypted_group_chat() -> Result<()> {
async fn test_create_group_invalid_name() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let chat_id = create_group_ex(alice, None, " ").await?;
let chat_id = create_group_chat(alice, " ").await?;
let chat = Chat::load_from_db(alice, chat_id).await?;
assert_eq!(chat.get_name(), "");
Ok(())
@@ -4829,7 +4798,7 @@ async fn test_long_group_name() -> Result<()> {
let bob = &tcm.bob().await;
let group_name = "δδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδδ";
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, group_name).await?;
let alice_chat_id = create_group_chat(alice, group_name).await?;
let alice_bob_contact_id = alice.add_or_lookup_contact_id(bob).await;
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
let sent = alice

View File

@@ -481,8 +481,8 @@ mod tests {
use super::*;
use crate::chat::save_msgs;
use crate::chat::{
ProtectionStatus, add_contact_to_chat, create_group_chat, get_chat_contacts,
remove_contact_from_chat, send_text_msg,
add_contact_to_chat, create_group_chat, get_chat_contacts, remove_contact_from_chat,
send_text_msg,
};
use crate::receive_imf::receive_imf;
use crate::stock_str::StockMessage;
@@ -495,15 +495,9 @@ mod tests {
async fn test_try_load() {
let mut tcm = TestContextManager::new();
let bob = &tcm.bob().await;
let chat_id1 = create_group_chat(bob, ProtectionStatus::Unprotected, "a chat")
.await
.unwrap();
let chat_id2 = create_group_chat(bob, ProtectionStatus::Unprotected, "b chat")
.await
.unwrap();
let chat_id3 = create_group_chat(bob, ProtectionStatus::Unprotected, "c chat")
.await
.unwrap();
let chat_id1 = create_group_chat(bob, "a chat").await.unwrap();
let chat_id2 = create_group_chat(bob, "b chat").await.unwrap();
let chat_id3 = create_group_chat(bob, "c chat").await.unwrap();
// check that the chatlist starts with the most recent message
let chats = Chatlist::try_load(bob, 0, None, None).await.unwrap();
@@ -536,9 +530,7 @@ mod tests {
// receive a message from alice
let alice = &tcm.alice().await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "alice chat")
.await
.unwrap();
let alice_chat_id = create_group_chat(alice, "alice chat").await.unwrap();
add_contact_to_chat(
alice,
alice_chat_id,
@@ -576,9 +568,7 @@ mod tests {
async fn test_sort_self_talk_up_on_forward() {
let t = TestContext::new_alice().await;
t.update_device_chats().await.unwrap();
create_group_chat(&t, ProtectionStatus::Unprotected, "a chat")
.await
.unwrap();
create_group_chat(&t, "a chat").await.unwrap();
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();
assert_eq!(chats.len(), 3);
@@ -765,9 +755,7 @@ mod tests {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_summary_unwrap() {
let t = TestContext::new().await;
let chat_id1 = create_group_chat(&t, ProtectionStatus::Unprotected, "a chat")
.await
.unwrap();
let chat_id1 = create_group_chat(&t, "a chat").await.unwrap();
let mut msg = Message::new_text("foo:\nbar \r\n test".to_string());
chat_id1.set_draft(&t, Some(&mut msg)).await.unwrap();
@@ -783,9 +771,7 @@ mod tests {
async fn test_get_summary_deleted_draft() {
let t = TestContext::new().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "a chat")
.await
.unwrap();
let chat_id = create_group_chat(&t, "a chat").await.unwrap();
let mut msg = Message::new_text("Foobar".to_string());
chat_id.set_draft(&t, Some(&mut msg)).await.unwrap();
@@ -824,15 +810,9 @@ mod tests {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_load_broken() {
let t = TestContext::new_bob().await;
let chat_id1 = create_group_chat(&t, ProtectionStatus::Unprotected, "a chat")
.await
.unwrap();
create_group_chat(&t, ProtectionStatus::Unprotected, "b chat")
.await
.unwrap();
create_group_chat(&t, ProtectionStatus::Unprotected, "c chat")
.await
.unwrap();
let chat_id1 = create_group_chat(&t, "a chat").await.unwrap();
create_group_chat(&t, "b chat").await.unwrap();
create_group_chat(&t, "c chat").await.unwrap();
// check that the chatlist starts with the most recent message
let chats = Chatlist::try_load(&t, 0, None, None).await.unwrap();

View File

@@ -1216,9 +1216,6 @@ impl Context {
mark_contact_id_as_verified(self, contact_id, Some(ContactId::SELF)).await?;
let chat_id = ChatId::create_for_contact(self, contact_id).await?;
chat_id
.set_protection(self, ProtectionStatus::Protected, time(), Some(contact_id))
.await?;
let mut msg = Message::new_text(self.get_self_report().await?);

View File

@@ -604,7 +604,7 @@ async fn test_draft_self_report() -> Result<()> {
let chat_id = alice.draft_self_report().await?;
let msg = get_chat_msg(&alice, chat_id, 0, 1).await;
assert_eq!(msg.get_info_type(), SystemMessage::ChatProtectionEnabled);
assert_eq!(msg.get_info_type(), SystemMessage::ChatE2ee);
let chat = Chat::load_from_db(&alice, chat_id).await?;
assert!(chat.is_protected());

View File

@@ -12,7 +12,7 @@ use crate::receive_imf::receive_imf;
use crate::test_utils::{TestContext, TestContextManager};
use crate::timesmearing::MAX_SECONDS_TO_LEND_FROM_FUTURE;
use crate::{
chat::{self, Chat, ChatItem, ProtectionStatus, create_group_chat, send_text_msg},
chat::{self, Chat, ChatItem, create_group_chat, send_text_msg},
tools::IsNoneOrEmpty,
};
@@ -164,7 +164,7 @@ async fn test_ephemeral_enable_disable() -> Result<()> {
async fn test_ephemeral_unpromoted() -> Result<()> {
let alice = TestContext::new_alice().await;
let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "Group name").await?;
let chat_id = create_group_chat(&alice, "Group name").await?;
// Group is unpromoted, the timer can be changed without sending a message.
assert!(chat_id.is_unpromoted(&alice).await?);
@@ -799,8 +799,7 @@ async fn test_ephemeral_timer_non_member() -> Result<()> {
let bob = &tcm.bob().await;
let alice_bob_contact_id = alice.add_or_lookup_contact_id(bob).await;
let alice_chat_id =
create_group_chat(alice, ProtectionStatus::Unprotected, "Group name").await?;
let alice_chat_id = create_group_chat(alice, "Group name").await?;
add_contact_to_chat(alice, alice_chat_id, alice_bob_contact_id).await?;
send_text_msg(alice, alice_chat_id, "Hi!".to_string()).await?;

View File

@@ -66,8 +66,8 @@ mod test_chatlist_events {
use crate::{
EventType,
chat::{
self, ChatId, ChatVisibility, MuteDuration, ProtectionStatus, create_broadcast,
create_group_chat, set_muted,
self, ChatId, ChatVisibility, MuteDuration, create_broadcast, create_group_chat,
set_muted,
},
config::Config,
constants::*,
@@ -138,12 +138,7 @@ mod test_chatlist_events {
async fn test_change_chat_visibility() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat_id = create_group_chat(
&alice,
crate::chat::ProtectionStatus::Unprotected,
"my_group",
)
.await?;
let chat_id = create_group_chat(&alice, "my_group").await?;
chat_id
.set_visibility(&alice, ChatVisibility::Pinned)
@@ -289,7 +284,7 @@ mod test_chatlist_events {
async fn test_delete_chat() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
alice.evtracker.clear_events();
chat.delete(&alice).await?;
@@ -303,7 +298,7 @@ mod test_chatlist_events {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
alice.evtracker.clear_events();
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
wait_for_chatlist_and_specific_item(&alice, chat).await;
Ok(())
}
@@ -324,7 +319,7 @@ mod test_chatlist_events {
async fn test_mute_chat() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
alice.evtracker.clear_events();
chat::set_muted(&alice, chat, MuteDuration::Forever).await?;
@@ -343,7 +338,7 @@ mod test_chatlist_events {
async fn test_mute_chat_expired() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
let mute_duration = MuteDuration::Until(
std::time::SystemTime::now()
@@ -363,7 +358,7 @@ mod test_chatlist_events {
async fn test_change_chat_name() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
alice.evtracker.clear_events();
chat::set_chat_name(&alice, chat, "New Name").await?;
@@ -377,7 +372,7 @@ mod test_chatlist_events {
async fn test_change_chat_profile_image() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
alice.evtracker.clear_events();
let file = alice.dir.path().join("avatar.png");
@@ -395,9 +390,7 @@ mod test_chatlist_events {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let chat = alice
.create_group_with_members(ProtectionStatus::Unprotected, "My Group", &[&bob])
.await;
let chat = alice.create_group_with_members("My Group", &[&bob]).await;
let sent_msg = alice.send_text(chat, "Hello").await;
let chat_id_for_bob = bob.recv_msg(&sent_msg).await.chat_id;
@@ -419,9 +412,7 @@ mod test_chatlist_events {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let chat = alice
.create_group_with_members(ProtectionStatus::Unprotected, "My Group", &[&bob])
.await;
let chat = alice.create_group_with_members("My Group", &[&bob]).await;
let sent_msg = alice.send_text(chat, "Hello").await;
let chat_id_for_bob = bob.recv_msg(&sent_msg).await.chat_id;
@@ -438,9 +429,7 @@ mod test_chatlist_events {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let chat = alice
.create_group_with_members(ProtectionStatus::Unprotected, "My Group", &[&bob])
.await;
let chat = alice.create_group_with_members("My Group", &[&bob]).await;
let sent_msg = alice.send_text(chat, "Hello").await;
let chat_id_for_bob = bob.recv_msg(&sent_msg).await.chat_id;
@@ -456,7 +445,7 @@ mod test_chatlist_events {
async fn test_delete_message() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
let message = chat::send_text_msg(&alice, chat, "Hello World".to_owned()).await?;
alice.evtracker.clear_events();
@@ -473,9 +462,7 @@ mod test_chatlist_events {
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let chat = alice
.create_group_with_members(ProtectionStatus::Unprotected, "My Group", &[&bob])
.await;
let chat = alice.create_group_with_members("My Group", &[&bob]).await;
let sent_msg = alice.send_text(chat, "Hello").await;
let chat_id_for_bob = bob.recv_msg(&sent_msg).await.chat_id;
chat_id_for_bob.accept(&bob).await?;
@@ -516,7 +503,7 @@ mod test_chatlist_events {
async fn test_update_after_ephemeral_messages() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
chat.set_ephemeral_timer(&alice, crate::ephemeral::Timer::Enabled { duration: 60 })
.await?;
alice
@@ -560,8 +547,7 @@ First thread."#;
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let alice_chatid =
chat::create_group_chat(&alice.ctx, ProtectionStatus::Protected, "the chat").await?;
let alice_chatid = chat::create_group_chat(&alice.ctx, "the chat").await?;
// Step 1: Generate QR-code, secure-join implied by chatid
let qr = get_securejoin_qr(&alice.ctx, Some(alice_chatid)).await?;
@@ -608,7 +594,7 @@ First thread."#;
async fn test_resend_message() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
let msg_id = chat::send_text_msg(&alice, chat, "Hello".to_owned()).await?;
let _ = alice.pop_sent_msg().await;
@@ -628,7 +614,7 @@ First thread."#;
async fn test_reaction() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = tcm.alice().await;
let chat = create_group_chat(&alice, ProtectionStatus::Protected, "My Group").await?;
let chat = create_group_chat(&alice, "My Group").await?;
let msg_id = chat::send_text_msg(&alice, chat, "Hello".to_owned()).await?;
let _ = alice.pop_sent_msg().await;

View File

@@ -6,8 +6,7 @@ use std::time::Duration;
use super::*;
use crate::chat::{
self, ChatId, ProtectionStatus, add_contact_to_chat, create_group_chat,
remove_contact_from_chat, send_text_msg,
self, ChatId, add_contact_to_chat, create_group_chat, remove_contact_from_chat, send_text_msg,
};
use crate::chatlist::Chatlist;
use crate::constants;
@@ -352,9 +351,7 @@ async fn test_subject_in_group() -> Result<()> {
let mut tcm = TestContextManager::new();
let t = tcm.alice().await;
let bob = tcm.bob().await;
let group_id = chat::create_group_chat(&t, chat::ProtectionStatus::Unprotected, "groupname")
.await
.unwrap();
let group_id = chat::create_group_chat(&t, "groupname").await.unwrap();
let bob_contact_id = t.add_or_lookup_contact_id(&bob).await;
chat::add_contact_to_chat(&t, group_id, bob_contact_id).await?;
@@ -756,7 +753,7 @@ async fn test_remove_member_bcc() -> Result<()> {
let charlie_contact = Contact::get_by_id(alice, charlie_id).await?;
let charlie_addr = charlie_contact.get_addr();
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "foo").await?;
let alice_chat_id = create_group_chat(alice, "foo").await?;
add_contact_to_chat(alice, alice_chat_id, bob_id).await?;
add_contact_to_chat(alice, alice_chat_id, charlie_id).await?;
send_text_msg(alice, alice_chat_id, "Creating a group".to_string()).await?;
@@ -846,16 +843,12 @@ async fn test_dont_remove_self() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let first_group = alice
.create_group_with_members(ProtectionStatus::Unprotected, "First group", &[bob])
.await;
let first_group = alice.create_group_with_members("First group", &[bob]).await;
alice.send_text(first_group, "Hi! I created a group.").await;
remove_contact_from_chat(alice, first_group, ContactId::SELF).await?;
alice.pop_sent_msg().await;
let second_group = alice
.create_group_with_members(ProtectionStatus::Unprotected, "First group", &[bob])
.await;
let second_group = alice.create_group_with_members("First group", &[bob]).await;
let sent = alice
.send_text(second_group, "Hi! I created another group.")
.await;
@@ -883,9 +876,7 @@ async fn test_new_member_is_first_recipient() -> Result<()> {
let bob_id = alice.add_or_lookup_contact_id(bob).await;
let charlie_id = alice.add_or_lookup_contact_id(charlie).await;
let group = alice
.create_group_with_members(ProtectionStatus::Unprotected, "Group", &[bob])
.await;
let group = alice.create_group_with_members("Group", &[bob]).await;
alice.send_text(group, "Hi! I created a group.").await;
SystemTime::shift(Duration::from_secs(60));

View File

@@ -574,7 +574,7 @@ mod tests {
use super::*;
use crate::{
EventType,
chat::{self, ChatId, ProtectionStatus, add_contact_to_chat, resend_msgs, send_msg},
chat::{self, ChatId, add_contact_to_chat, resend_msgs, send_msg},
message::{Message, Viewtype},
test_utils::{TestContext, TestContextManager},
};
@@ -962,9 +962,7 @@ mod tests {
let mut tcm = TestContextManager::new();
let alice = &mut tcm.alice().await;
let bob = &mut tcm.bob().await;
let group = chat::create_group_chat(alice, ProtectionStatus::Unprotected, "group chat")
.await
.unwrap();
let group = chat::create_group_chat(alice, "group chat").await.unwrap();
// Alice sends webxdc to bob
let mut instance = Message::new(Viewtype::File);

View File

@@ -1,5 +1,5 @@
use super::*;
use crate::chat::{ProtectionStatus, create_group_chat};
use crate::chat::create_group_chat;
use crate::config::Config;
use crate::securejoin::get_securejoin_qr;
use crate::test_utils::{TestContext, TestContextManager, sync};
@@ -479,7 +479,7 @@ async fn test_withdraw_verifycontact() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_withdraw_verifygroup() -> Result<()> {
let alice = TestContext::new_alice().await;
let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&alice, "foo").await?;
let qr = get_securejoin_qr(&alice, Some(chat_id)).await?;
// scanning own verify-group code offers withdrawing
@@ -520,8 +520,8 @@ async fn test_withdraw_multidevice() -> Result<()> {
// Alice creates two QR codes on the first device:
// group QR code and contact QR code.
let chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let chat2_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group 2").await?;
let chat_id = create_group_chat(alice, "Group").await?;
let chat2_id = create_group_chat(alice, "Group 2").await?;
let contact_qr = get_securejoin_qr(alice, None).await?;
let group_qr = get_securejoin_qr(alice, Some(chat_id)).await?;
let group2_qr = get_securejoin_qr(alice, Some(chat2_id)).await?;

View File

@@ -14,9 +14,7 @@ use mailparse::SingleInfo;
use num_traits::FromPrimitive;
use regex::Regex;
use crate::chat::{
self, Chat, ChatId, ChatIdBlocked, ProtectionStatus, remove_from_chat_contacts_table,
};
use crate::chat::{self, Chat, ChatId, ChatIdBlocked, remove_from_chat_contacts_table};
use crate::config::Config;
use crate::constants::{self, Blocked, Chattype, DC_CHAT_ID_TRASH, EDITED_PREFIX, ShowEmails};
use crate::contact::{Contact, ContactId, Origin, mark_contact_id_as_verified};
@@ -794,7 +792,6 @@ pub(crate) async fn receive_imf_inner(
allow_creation,
&mut mime_parser,
is_partial_download,
&verified_encryption,
parent_message,
)
.await?;
@@ -812,7 +809,6 @@ pub(crate) async fn receive_imf_inner(
is_partial_download,
replace_msg_id,
prevent_rename,
verified_encryption,
chat_id,
chat_id_blocked,
is_dc_message,
@@ -1319,7 +1315,6 @@ async fn do_chat_assignment(
allow_creation: bool,
mime_parser: &mut MimeMessage,
is_partial_download: Option<u32>,
verified_encryption: &VerifiedEncryption,
parent_message: Option<Message>,
) -> Result<(ChatId, Blocked)> {
let is_bot = context.get_config_bool(Config::Bot).await?;
@@ -1376,7 +1371,6 @@ async fn do_chat_assignment(
from_id,
to_ids,
past_ids,
verified_encryption,
grpid,
)
.await?
@@ -1478,45 +1472,6 @@ async fn do_chat_assignment(
);
}
}
// 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()
{
true => Some(Chat::load_from_db(context, chat_id).await?)
.filter(|chat| chat.typ == Chattype::Single),
false => None,
};
if let Some(chat) = chat {
ensure_and_debug_assert!(
chat.typ == Chattype::Single,
"Chat {chat_id} is not Single",
);
let new_protection = match verified_encryption {
VerifiedEncryption::Verified => ProtectionStatus::Protected,
VerifiedEncryption::NotVerified(_) => ProtectionStatus::Unprotected,
};
ensure_and_debug_assert!(
chat.protected == ProtectionStatus::Unprotected
|| new_protection == ProtectionStatus::Protected,
"Chat {chat_id} can't downgrade to Unprotected",
);
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?;
}
}
}
}
} else {
@@ -1547,7 +1502,6 @@ async fn do_chat_assignment(
from_id,
to_ids,
past_ids,
verified_encryption,
grpid,
)
.await?
@@ -1669,7 +1623,6 @@ async fn add_parts(
is_partial_download: Option<u32>,
mut replace_msg_id: Option<MsgId>,
prevent_rename: bool,
verified_encryption: VerifiedEncryption,
chat_id: ChatId,
chat_id_blocked: Blocked,
is_dc_message: MessengerMessage,
@@ -1718,16 +1671,7 @@ async fn add_parts(
apply_out_broadcast_changes(context, mime_parser, &mut chat, from_id).await?
}
Chattype::Group => {
apply_group_changes(
context,
mime_parser,
&mut chat,
from_id,
to_ids,
past_ids,
&verified_encryption,
)
.await?
apply_group_changes(context, mime_parser, &mut chat, from_id, to_ids, past_ids).await?
}
Chattype::InBroadcast => {
apply_in_broadcast_changes(context, mime_parser, &mut chat, from_id).await?
@@ -2632,27 +2576,12 @@ async fn create_group(
from_id: ContactId,
to_ids: &[Option<ContactId>],
past_ids: &[Option<ContactId>],
verified_encryption: &VerifiedEncryption,
grpid: &str,
) -> Result<Option<(ChatId, Blocked)>> {
let to_ids_flat: Vec<ContactId> = to_ids.iter().filter_map(|x| *x).collect();
let mut chat_id = None;
let mut chat_id_blocked = Default::default();
let create_protected = if mime_parser.get_header(HeaderDef::ChatVerified).is_some() {
if let VerifiedEncryption::NotVerified(err) = verified_encryption {
warn!(
context,
"Creating unprotected group because of the verification problem: {err:#}."
);
ProtectionStatus::Unprotected
} else {
ProtectionStatus::Protected
}
} else {
ProtectionStatus::Unprotected
};
async fn self_explicitly_added(
context: &Context,
mime_parser: &&mut MimeMessage,
@@ -2688,7 +2617,6 @@ async fn create_group(
grpid,
grpname,
create_blocked,
create_protected,
None,
mime_parser.timestamp_sent,
)
@@ -2860,7 +2788,6 @@ async fn apply_group_changes(
from_id: ContactId,
to_ids: &[Option<ContactId>],
past_ids: &[Option<ContactId>],
verified_encryption: &VerifiedEncryption,
) -> Result<GroupChangesInfo> {
let to_ids_flat: Vec<ContactId> = to_ids.iter().filter_map(|x| *x).collect();
ensure!(chat.typ == Chattype::Group);
@@ -2875,24 +2802,6 @@ async fn apply_group_changes(
let is_from_in_chat =
!chat_contacts.contains(&ContactId::SELF) || chat_contacts.contains(&from_id);
if mime_parser.get_header(HeaderDef::ChatVerified).is_some() && !chat.is_protected() {
if let VerifiedEncryption::NotVerified(err) = verified_encryption {
warn!(
context,
"Not marking chat {} as protected due to verification problem: {err:#}.", chat.id,
);
} else {
chat.id
.set_protection(
context,
ProtectionStatus::Protected,
mime_parser.timestamp_sent,
Some(from_id),
)
.await?;
}
}
if let Some(removed_addr) = mime_parser.get_header(HeaderDef::ChatGroupMemberRemoved) {
// TODO: if address "alice@example.org" is a member of the group twice,
// with old and new key,
@@ -3318,7 +3227,6 @@ async fn create_or_lookup_mailinglist_or_broadcast(
&listid,
name,
blocked,
ProtectionStatus::Unprotected,
param,
mime_parser.timestamp_sent,
)
@@ -3599,7 +3507,6 @@ async fn create_adhoc_group(
"", // Ad hoc groups have no ID.
grpname,
create_blocked,
ProtectionStatus::Unprotected,
None,
mime_parser.timestamp_sent,
)
@@ -3696,7 +3603,6 @@ async fn mark_recipients_as_verified(
}
mark_contact_id_as_verified(context, to_id, verifier_id).await?;
ChatId::set_protection_for_contact(context, to_id, mimeparser.timestamp_sent).await?;
}
Ok(())

View File

@@ -2944,7 +2944,7 @@ async fn test_outgoing_private_reply_multidevice() -> Result<()> {
let charlie = tcm.charlie().await;
// =============== Bob creates a group ===============
let group_id = chat::create_group_chat(&bob, ProtectionStatus::Unprotected, "Group").await?;
let group_id = chat::create_group_chat(&bob, "Group").await?;
chat::add_to_chat_contacts_table(
&bob,
time(),
@@ -3042,9 +3042,7 @@ async fn test_auto_accept_protected_group_for_bots() -> Result<()> {
bob.set_config(Config::Bot, Some("1")).await.unwrap();
mark_as_verified(alice, bob).await;
mark_as_verified(bob, alice).await;
let group_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob])
.await;
let group_id = alice.create_group_with_members("Group", &[bob]).await;
let sent = alice.send_text(group_id, "Hello!").await;
let msg = bob.recv_msg(&sent).await;
let chat = chat::Chat::load_from_db(bob, msg.chat_id).await?;
@@ -3092,13 +3090,11 @@ async fn test_bot_accepts_another_group_after_qr_scan() -> Result<()> {
let bob = &tcm.bob().await;
bob.set_config(Config::Bot, Some("1")).await?;
let group_id = chat::create_group_chat(alice, ProtectionStatus::Protected, "Group").await?;
let group_id = chat::create_group_chat(alice, "Group").await?;
let qr = get_securejoin_qr(alice, Some(group_id)).await?;
tcm.exec_securejoin_qr(bob, alice, &qr).await;
let group_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob])
.await;
let group_id = alice.create_group_with_members("Group", &[bob]).await;
let sent = alice.send_text(group_id, "Hello!").await;
let msg = bob.recv_msg(&sent).await;
let chat = chat::Chat::load_from_db(bob, msg.chat_id).await?;
@@ -3152,7 +3148,7 @@ async fn test_no_private_reply_to_blocked_account() -> Result<()> {
let bob = tcm.bob().await;
tcm.section("Bob creates a group");
let group_id = chat::create_group_chat(&bob, ProtectionStatus::Unprotected, "Group").await?;
let group_id = chat::create_group_chat(&bob, "Group").await?;
chat::add_to_chat_contacts_table(
&bob,
time(),
@@ -3228,11 +3224,7 @@ async fn test_blocked_contact_creates_group() -> Result<()> {
chat.id.block(&alice).await?;
let group_id = bob
.create_group_with_members(
ProtectionStatus::Unprotected,
"group name",
&[&alice, &fiona],
)
.create_group_with_members("group name", &[&alice, &fiona])
.await;
let sent = bob.send_text(group_id, "Heyho, I'm a spammer!").await;
@@ -3253,7 +3245,7 @@ async fn test_blocked_contact_creates_group() -> Result<()> {
assert_eq!(rcvd.chat_blocked, Blocked::Request);
// In order not to lose context, Bob's message should also be shown in the group
let msgs = chat::get_chat_msgs(&alice, rcvd.chat_id).await?;
assert_eq!(msgs.len(), 2);
assert_eq!(msgs.len(), 3);
Ok(())
}
@@ -3728,7 +3720,7 @@ async fn test_unsigned_chat_group_hdr() -> Result<()> {
let bob = &tcm.bob().await;
let bob_addr = bob.get_config(Config::Addr).await?.unwrap();
let bob_id = alice.add_or_lookup_contact_id(bob).await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "foos").await?;
let alice_chat_id = create_group_chat(alice, "foos").await?;
add_contact_to_chat(alice, alice_chat_id, bob_id).await?;
send_text_msg(alice, alice_chat_id, "populate".to_string()).await?;
let sent_msg = alice.pop_sent_msg().await;
@@ -3774,7 +3766,7 @@ async fn test_sync_member_list_on_rejoin() -> Result<()> {
let bob_id = alice.add_or_lookup_contact_id(bob).await;
let fiona_id = alice.add_or_lookup_contact_id(fiona).await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "foos").await?;
let alice_chat_id = create_group_chat(alice, "foos").await?;
add_contact_to_chat(alice, alice_chat_id, bob_id).await?;
add_contact_to_chat(alice, alice_chat_id, fiona_id).await?;
@@ -3812,7 +3804,7 @@ async fn test_ignore_outdated_membership_changes() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_bob_id = alice.add_or_lookup_contact_id(bob).await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "grp").await?;
let alice_chat_id = create_group_chat(alice, "grp").await?;
// Alice creates a group chat. Bob accepts it.
add_contact_to_chat(alice, alice_chat_id, alice_bob_id).await?;
@@ -3860,7 +3852,7 @@ async fn test_dont_recreate_contacts_on_add_remove() -> Result<()> {
let fiona = &tcm.fiona().await;
let charlie = &tcm.charlie().await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_chat_id = create_group_chat(alice, "Group").await?;
add_contact_to_chat(
alice,
@@ -3911,7 +3903,7 @@ async fn test_delayed_removal_is_ignored() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
let chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let chat_id = create_group_chat(alice, "Group").await?;
let alice_bob = alice.add_or_lookup_contact_id(bob).await;
let alice_fiona = alice.add_or_lookup_contact_id(fiona).await;
// create chat with three members
@@ -3964,7 +3956,7 @@ async fn test_dont_readd_with_normal_msg() -> Result<()> {
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_chat_id = create_group_chat(alice, "Group").await?;
add_contact_to_chat(
alice,
@@ -4202,7 +4194,7 @@ async fn test_member_left_does_not_create_chat() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_chat_id = create_group_chat(alice, "Group").await?;
add_contact_to_chat(
alice,
alice_chat_id,
@@ -4230,7 +4222,7 @@ async fn test_recreate_member_list_on_missing_add_of_self() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_chat_id = create_group_chat(alice, "Group").await?;
add_contact_to_chat(
alice,
alice_chat_id,
@@ -4274,7 +4266,7 @@ async fn test_recreate_member_list_on_missing_add_of_self() -> Result<()> {
async fn test_keep_member_list_if_possibly_nomember() -> Result<()> {
let alice = TestContext::new_alice().await;
let bob = TestContext::new_bob().await;
let alice_chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_chat_id = create_group_chat(&alice, "Group").await?;
add_contact_to_chat(
&alice,
alice_chat_id,
@@ -4414,7 +4406,7 @@ async fn test_create_group_with_big_msg() -> Result<()> {
let file_bytes = include_bytes!("../../test-data/image/screenshot.png");
let bob_grp_id = create_group_chat(&bob, ProtectionStatus::Unprotected, "Group").await?;
let bob_grp_id = create_group_chat(&bob, "Group").await?;
add_contact_to_chat(&bob, bob_grp_id, ba_contact).await?;
let mut msg = Message::new(Viewtype::Image);
msg.set_file_from_bytes(&bob, "a.jpg", file_bytes, None)?;
@@ -4445,7 +4437,7 @@ async fn test_create_group_with_big_msg() -> Result<()> {
// Now Bob can send encrypted messages to Alice.
let bob_grp_id = create_group_chat(&bob, ProtectionStatus::Unprotected, "Group1").await?;
let bob_grp_id = create_group_chat(&bob, "Group1").await?;
add_contact_to_chat(&bob, bob_grp_id, ba_contact).await?;
let mut msg = Message::new(Viewtype::Image);
msg.set_file_from_bytes(&bob, "a.jpg", file_bytes, None)?;
@@ -4486,7 +4478,7 @@ async fn test_partial_group_consistency() -> Result<()> {
let bob = tcm.bob().await;
let fiona = tcm.fiona().await;
let bob_id = alice.add_or_lookup_contact_id(&bob).await;
let alice_chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foos").await?;
let alice_chat_id = create_group_chat(&alice, "foos").await?;
add_contact_to_chat(&alice, alice_chat_id, bob_id).await?;
send_text_msg(&alice, alice_chat_id, "populate".to_string()).await?;
@@ -4566,7 +4558,7 @@ async fn test_protected_group_add_remove_member_missing_key() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
mark_as_verified(alice, bob).await;
let group_id = create_group_chat(alice, ProtectionStatus::Protected, "Group").await?;
let group_id = create_group_chat(alice, "Group").await?;
let alice_bob_id = alice.add_or_lookup_contact(bob).await.id;
add_contact_to_chat(alice, group_id, alice_bob_id).await?;
alice.send_text(group_id, "Hello!").await;
@@ -4663,7 +4655,7 @@ async fn test_unarchive_on_member_removal() -> Result<()> {
let fiona = &tcm.fiona().await;
let bob_id = alice.add_or_lookup_contact_id(bob).await;
let fiona_id = alice.add_or_lookup_contact_id(fiona).await;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "foos").await?;
let alice_chat_id = create_group_chat(alice, "foos").await?;
add_contact_to_chat(alice, alice_chat_id, bob_id).await?;
add_contact_to_chat(alice, alice_chat_id, fiona_id).await?;
@@ -4696,9 +4688,7 @@ async fn test_no_op_member_added_is_trash() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "foos", &[bob])
.await;
let alice_chat_id = alice.create_group_with_members("foos", &[bob]).await;
send_text_msg(alice, alice_chat_id, "populate".to_string()).await?;
let msg = alice.pop_sent_msg().await;
bob.recv_msg(&msg).await;
@@ -4765,7 +4755,7 @@ async fn test_references() -> Result<()> {
let bob = &tcm.bob().await;
alice.set_config_bool(Config::BccSelf, true).await?;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_chat_id = create_group_chat(alice, "Group").await?;
alice
.send_text(alice_chat_id, "Hi! I created a group.")
.await;
@@ -4809,7 +4799,7 @@ async fn test_prefer_references_to_downloaded_msgs() -> Result<()> {
let fiona = &tcm.fiona().await;
let alice_bob_id = tcm.send_recv(bob, alice, "hi").await.from_id;
let alice_fiona_id = tcm.send_recv(fiona, alice, "hi").await.from_id;
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let alice_chat_id = create_group_chat(alice, "Group").await?;
add_contact_to_chat(alice, alice_chat_id, alice_bob_id).await?;
// W/o fiona the test doesn't work -- the last message is assigned to the 1:1 chat due to
// `is_probably_private_reply()`.
@@ -5009,12 +4999,7 @@ async fn test_group_name_with_newline() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let chat_id = create_group_chat(
alice,
ProtectionStatus::Unprotected,
"Group\r\nwith\nnewlines",
)
.await?;
let chat_id = create_group_chat(alice, "Group\r\nwith\nnewlines").await?;
add_contact_to_chat(alice, chat_id, alice.add_or_lookup_contact_id(bob).await).await?;
send_text_msg(alice, chat_id, "populate".to_string()).await?;
let bob_chat_id = bob.recv_msg(&alice.pop_sent_msg().await).await.chat_id;
@@ -5032,7 +5017,7 @@ async fn test_rename_chat_on_missing_message() -> Result<()> {
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let charlie = tcm.charlie().await;
let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "Group").await?;
let chat_id = create_group_chat(&alice, "Group").await?;
add_to_chat_contacts_table(
&alice,
time(),
@@ -5068,7 +5053,7 @@ async fn test_rename_chat_after_creating_invite() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
for populate_before_securejoin in [false, true] {
let alice_chat_id = create_group_chat(alice, ProtectionStatus::Protected, "Group").await?;
let alice_chat_id = create_group_chat(alice, "Group").await?;
let qr = get_securejoin_qr(alice, Some(alice_chat_id)).await?;
SystemTime::shift(Duration::from_secs(60));
@@ -5098,7 +5083,7 @@ async fn test_two_group_securejoins() -> Result<()> {
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
let group_id = chat::create_group_chat(alice, ProtectionStatus::Protected, "Group").await?;
let group_id = chat::create_group_chat(alice, "Group").await?;
let qr = get_securejoin_qr(alice, Some(group_id)).await?;
@@ -5123,8 +5108,7 @@ async fn test_unverified_member_msg() -> Result<()> {
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
let alice_chat_id =
chat::create_group_chat(alice, ProtectionStatus::Protected, "Group").await?;
let alice_chat_id = chat::create_group_chat(alice, "Group").await?;
let qr = get_securejoin_qr(alice, Some(alice_chat_id)).await?;
tcm.exec_securejoin_qr(bob, alice, &qr).await;
@@ -5150,12 +5134,15 @@ async fn test_dont_reverify_by_self_on_outgoing_msg() -> Result<()> {
let bob = &tcm.bob().await;
let fiona = &tcm.fiona().await;
let bob_chat_id = chat::create_group_chat(bob, ProtectionStatus::Protected, "Group").await?;
let bob_chat_id = chat::create_group_chat(bob, "Group").await?;
let qr = get_securejoin_qr(bob, Some(bob_chat_id)).await?;
tcm.exec_securejoin_qr(fiona, bob, &qr).await;
tcm.exec_securejoin_qr(a0, bob, &qr).await;
tcm.exec_securejoin_qr(a1, bob, &qr).await;
// Shift time by one week to trigger gossip.
SystemTime::shift(Duration::from_secs(7 * 24 * 3600));
let a0_chat_id = a0.get_last_msg().await.chat_id;
let a0_sent_msg = a0.send_text(a0_chat_id, "Hi").await;
a1.recv_msg(&a0_sent_msg).await;
@@ -5211,9 +5198,7 @@ async fn test_no_address_contact_added_into_group() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "Group", &[bob])
.await;
let alice_chat_id = alice.create_group_with_members("Group", &[bob]).await;
let bob_received_msg = bob
.recv_msg(&alice.send_text(alice_chat_id, "Message").await)
.await;
@@ -5493,7 +5478,7 @@ async fn test_small_unencrypted_group() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_chat_id = chat::create_group_ex(alice, None, "Unencrypted group").await?;
let alice_chat_id = chat::create_group_chat_unencrypted(alice, "Unencrypted group").await?;
let alice_bob_id = alice.add_or_lookup_address_contact_id(bob).await;
add_contact_to_chat(alice, alice_chat_id, alice_bob_id).await?;
send_text_msg(alice, alice_chat_id, "Hello!".to_string()).await?;

View File

@@ -4,8 +4,7 @@ use anyhow::{Context as _, Error, Result, bail, ensure};
use deltachat_contact_tools::ContactAddress;
use percent_encoding::{NON_ALPHANUMERIC, utf8_percent_encode};
use crate::chat::{self, Chat, ChatId, ChatIdBlocked, ProtectionStatus, get_chat_id_by_grpid};
use crate::chatlist_events;
use crate::chat::{self, Chat, ChatId, ChatIdBlocked, get_chat_id_by_grpid};
use crate::config::Config;
use crate::constants::{Blocked, Chattype, NON_ALPHANUMERIC_WITHOUT_DOT};
use crate::contact::mark_contact_id_as_verified;
@@ -414,13 +413,6 @@ pub(crate) async fn handle_securejoin_handshake(
context.emit_event(EventType::ContactsChanged(Some(contact_id)));
if let Some(group_chat_id) = group_chat_id {
// Join group.
secure_connection_established(
context,
contact_id,
group_chat_id,
mime_message.timestamp_sent,
)
.await?;
chat::add_contact_to_chat_ex(context, Nosync, group_chat_id, contact_id, true)
.await?;
let is_group = true;
@@ -431,13 +423,6 @@ pub(crate) async fn handle_securejoin_handshake(
} else {
let chat_id = info_chat_id(context, contact_id).await?;
// Setup verified contact.
secure_connection_established(
context,
contact_id,
chat_id,
mime_message.timestamp_sent,
)
.await?;
send_alice_handshake_msg(context, contact_id, "vc-contact-confirm")
.await
.context("failed sending vc-contact-confirm message")?;
@@ -560,8 +545,6 @@ pub(crate) async fn observe_securejoin_on_other_device(
mark_contact_id_as_verified(context, contact_id, Some(ContactId::SELF)).await?;
ChatId::set_protection_for_contact(context, contact_id, mime_message.timestamp_sent).await?;
if step == "vg-member-added" || step == "vc-contact-confirm" {
let is_group = mime_message
.get_header(HeaderDef::ChatGroupMemberAdded)
@@ -592,28 +575,6 @@ pub(crate) async fn observe_securejoin_on_other_device(
}
}
async fn secure_connection_established(
context: &Context,
contact_id: ContactId,
chat_id: ChatId,
timestamp: i64,
) -> Result<()> {
let private_chat_id = ChatIdBlocked::get_for_contact(context, contact_id, Blocked::Yes)
.await?
.id;
private_chat_id
.set_protection(
context,
ProtectionStatus::Protected,
timestamp,
Some(contact_id),
)
.await?;
context.emit_event(EventType::ChatModified(chat_id));
chatlist_events::emit_chatlist_item_changed(context, chat_id);
Ok(())
}
/* ******************************************************************************
* Tools: Misc.
******************************************************************************/

View File

@@ -74,16 +74,6 @@ pub(super) async fn start_protocol(context: &Context, invite: QrInvite) -> Resul
send_handshake_message(context, &invite, chat_id, BobHandshakeMsg::RequestWithAuth)
.await?;
// Mark 1:1 chat as verified already.
chat_id
.set_protection(
context,
ProtectionStatus::Protected,
time(),
Some(invite.contact_id()),
)
.await?;
context.emit_event(EventType::SecurejoinJoinerProgress {
contact_id: invite.contact_id(),
progress: JoinerProgress::RequestWithAuthSent.to_usize(),
@@ -215,15 +205,6 @@ pub(super) async fn handle_auth_required(
}
}
chat_id
.set_protection(
context,
ProtectionStatus::Protected,
message.timestamp_sent,
Some(invite.contact_id()),
)
.await?;
context.emit_event(EventType::SecurejoinJoinerProgress {
contact_id: invite.contact_id(),
progress: JoinerProgress::RequestWithAuthSent.to_usize(),
@@ -359,7 +340,6 @@ async fn joining_chat_id(
grpid,
name,
Blocked::Not,
ProtectionStatus::Unprotected, // protection is added later as needed
None,
create_smeared_timestamp(context),
)

View File

@@ -11,13 +11,10 @@ use crate::stock_str::{self, messages_e2e_encrypted};
use crate::test_utils::{
TestContext, TestContextManager, TimeShiftFalsePositiveNote, get_chat_msg,
};
use crate::tools::SystemTime;
use std::time::Duration;
#[derive(PartialEq)]
enum SetupContactCase {
Normal,
CheckProtectionTimestamp,
WrongAliceGossip,
AliceIsBot,
AliceHasName,
@@ -28,11 +25,6 @@ async fn test_setup_contact() {
test_setup_contact_ex(SetupContactCase::Normal).await
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_setup_contact_protection_timestamp() {
test_setup_contact_ex(SetupContactCase::CheckProtectionTimestamp).await
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_setup_contact_wrong_alice_gossip() {
test_setup_contact_ex(SetupContactCase::WrongAliceGossip).await
@@ -164,10 +156,6 @@ async fn test_setup_contact_ex(case: SetupContactCase) {
assert!(sent.payload.contains("Auto-Submitted: auto-replied"));
assert!(!sent.payload.contains("Bob Examplenet"));
let mut msg = alice.parse_msg(&sent).await;
let vc_request_with_auth_ts_sent = msg
.get_header(HeaderDef::Date)
.and_then(|value| mailparse::dateparse(value).ok())
.unwrap();
assert!(msg.was_encrypted());
assert_eq!(
msg.get_header(HeaderDef::SecureJoin).unwrap(),
@@ -214,10 +202,6 @@ async fn test_setup_contact_ex(case: SetupContactCase) {
assert_eq!(contact_bob.is_verified(&alice).await.unwrap(), false);
assert_eq!(contact_bob.get_authname(), "");
if case == SetupContactCase::CheckProtectionTimestamp {
SystemTime::shift(Duration::from_secs(3600));
}
tcm.section("Step 5+6: Alice receives vc-request-with-auth, sends vc-contact-confirm");
alice.recv_msg_trash(&sent).await;
assert_eq!(contact_bob.is_verified(&alice).await.unwrap(), true);
@@ -247,9 +231,6 @@ async fn test_setup_contact_ex(case: SetupContactCase) {
assert!(msg.is_info());
let expected_text = messages_e2e_encrypted(&alice).await;
assert_eq!(msg.get_text(), expected_text);
if case == SetupContactCase::CheckProtectionTimestamp {
assert_eq!(msg.timestamp_sort, vc_request_with_auth_ts_sent + 1);
}
}
// Make sure Alice hasn't yet sent their name to Bob.
@@ -292,10 +273,10 @@ async fn test_setup_contact_ex(case: SetupContactCase) {
let mut i = 0..msg_cnt;
let msg = get_chat_msg(&bob, bob_chat.get_id(), i.next().unwrap(), msg_cnt).await;
assert!(msg.is_info());
assert_eq!(msg.get_text(), stock_str::securejoin_wait(&bob).await);
assert_eq!(msg.get_text(), messages_e2e_encrypted(&bob).await);
let msg = get_chat_msg(&bob, bob_chat.get_id(), i.next().unwrap(), msg_cnt).await;
assert!(msg.is_info());
assert_eq!(msg.get_text(), messages_e2e_encrypted(&bob).await);
assert_eq!(msg.get_text(), stock_str::securejoin_wait(&bob).await);
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
@@ -448,8 +429,7 @@ async fn test_secure_join() -> Result<()> {
assert_eq!(Chatlist::try_load(&alice, 0, None, None).await?.len(), 0);
assert_eq!(Chatlist::try_load(&bob, 0, None, None).await?.len(), 0);
let alice_chatid =
chat::create_group_chat(&alice, ProtectionStatus::Protected, "the chat").await?;
let alice_chatid = chat::create_group_chat(&alice, "the chat").await?;
tcm.section("Step 1: Generate QR-code, secure-join implied by chatid");
let qr = get_securejoin_qr(&alice, Some(alice_chatid)).await.unwrap();
@@ -583,7 +563,7 @@ async fn test_secure_join() -> Result<()> {
Blocked::Yes,
"Alice's 1:1 chat with Bob is not hidden"
);
// There should be 3 messages in the chat:
// There should be 2 messages in the chat:
// - The ChatProtectionEnabled message
// - You added member bob@example.net
let msg = get_chat_msg(&alice, alice_chatid, 0, 2).await;
@@ -619,7 +599,6 @@ async fn test_secure_join() -> Result<()> {
}
let bob_chat = Chat::load_from_db(&bob.ctx, bob_chatid).await?;
assert!(bob_chat.is_protected());
assert!(bob_chat.typ == Chattype::Group);
// On this "happy path", Alice and Bob get only a group-chat where all information are added to.
@@ -667,7 +646,7 @@ async fn test_unknown_sender() -> Result<()> {
tcm.execute_securejoin(&alice, &bob).await;
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group with Bob", &[&bob])
.create_group_with_members("Group with Bob", &[&bob])
.await;
let sent = alice.send_text(alice_chat_id, "Hi!").await;
@@ -733,10 +712,8 @@ async fn test_parallel_securejoin() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_chat1_id =
chat::create_group_chat(alice, ProtectionStatus::Protected, "First chat").await?;
let alice_chat2_id =
chat::create_group_chat(alice, ProtectionStatus::Protected, "Second chat").await?;
let alice_chat1_id = chat::create_group_chat(alice, "First chat").await?;
let alice_chat2_id = chat::create_group_chat(alice, "Second chat").await?;
let qr1 = get_securejoin_qr(alice, Some(alice_chat1_id)).await?;
let qr2 = get_securejoin_qr(alice, Some(alice_chat2_id)).await?;

View File

@@ -11,7 +11,7 @@ use tokio::sync::RwLock;
use crate::accounts::Accounts;
use crate::blob::BlobObject;
use crate::chat::{self, Chat, ChatId, ProtectionStatus};
use crate::chat::{self, Chat, ChatId};
use crate::config::Config;
use crate::contact::{Contact, ContactId, Origin};
use crate::context::Context;
@@ -1083,13 +1083,6 @@ pub(crate) async fn messages_e2e_encrypted(context: &Context) -> String {
translated(context, StockMessage::ChatProtectionEnabled).await
}
/// Stock string: `%1$s sent a message from another device.`
pub(crate) async fn chat_protection_disabled(context: &Context, contact_id: ContactId) -> String {
translated(context, StockMessage::ChatProtectionDisabled)
.await
.replace1(&contact_id.get_stock_name(context).await)
}
/// Stock string: `Reply`.
pub(crate) async fn reply_noun(context: &Context) -> String {
translated(context, StockMessage::ReplyNoun).await
@@ -1334,26 +1327,6 @@ impl Context {
Ok(())
}
/// Returns a stock message saying that protection status has changed.
pub(crate) async fn stock_protection_msg(
&self,
protect: ProtectionStatus,
contact_id: Option<ContactId>,
) -> String {
match protect {
ProtectionStatus::Unprotected => {
if let Some(contact_id) = contact_id {
chat_protection_disabled(self, contact_id).await
} else {
// In a group chat, it's not possible to downgrade verification.
// In a 1:1 chat, the `contact_id` always has to be provided.
"[Error] No contact_id given".to_string()
}
}
ProtectionStatus::Protected => messages_e2e_encrypted(self).await,
}
}
pub(crate) async fn update_device_chats(&self) -> Result<()> {
if self.get_config_bool(Config::Bot).await? {
return Ok(());

View File

@@ -346,7 +346,7 @@ mod tests {
use anyhow::bail;
use super::*;
use crate::chat::{Chat, ProtectionStatus, remove_contact_from_chat};
use crate::chat::{Chat, remove_contact_from_chat};
use crate::chatlist::Chatlist;
use crate::contact::{Contact, Origin};
use crate::securejoin::get_securejoin_qr;
@@ -721,8 +721,7 @@ mod tests {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
alice.set_config_bool(Config::SyncMsgs, true).await?;
let alice_chatid =
chat::create_group_chat(alice, ProtectionStatus::Protected, "the chat").await?;
let alice_chatid = chat::create_group_chat(alice, "the chat").await?;
let qr = get_securejoin_qr(alice, Some(alice_chatid)).await?;
// alice2 syncs the QR code token.

View File

@@ -21,8 +21,8 @@ use tokio::runtime::Handle;
use tokio::{fs, task};
use crate::chat::{
self, Chat, ChatId, ChatIdBlocked, MessageListOptions, ProtectionStatus,
add_to_chat_contacts_table, create_group_chat,
self, Chat, ChatId, ChatIdBlocked, MessageListOptions, add_to_chat_contacts_table,
create_group_chat,
};
use crate::chatlist::Chatlist;
use crate::config::Config;
@@ -1066,11 +1066,10 @@ impl TestContext {
pub async fn create_group_with_members(
&self,
protect: ProtectionStatus,
chat_name: &str,
members: &[&TestContext],
) -> ChatId {
let chat_id = create_group_chat(self, protect, chat_name).await.unwrap();
let chat_id = create_group_chat(self, chat_name).await.unwrap();
let mut to_add = vec![];
for member in members {
let contact_id = self.add_or_lookup_contact_id(member).await;

View File

@@ -9,7 +9,7 @@
use anyhow::Result;
use crate::chat::{self, Chat, ChatId, ProtectionStatus};
use crate::chat::{self, Chat, ChatId};
use crate::contact::{Contact, ContactId};
use crate::message::Message;
use crate::receive_imf::receive_imf;
@@ -90,24 +90,12 @@ async fn check_aeap_transition(chat_for_transition: ChatForTransition, verified:
}
let mut groups = vec![
chat::create_group_chat(bob, chat::ProtectionStatus::Unprotected, "Group 0")
.await
.unwrap(),
chat::create_group_chat(bob, chat::ProtectionStatus::Unprotected, "Group 1")
.await
.unwrap(),
chat::create_group_chat(bob, "Group 0").await.unwrap(),
chat::create_group_chat(bob, "Group 1").await.unwrap(),
];
if verified {
groups.push(
chat::create_group_chat(bob, chat::ProtectionStatus::Protected, "Group 2")
.await
.unwrap(),
);
groups.push(
chat::create_group_chat(bob, chat::ProtectionStatus::Protected, "Group 3")
.await
.unwrap(),
);
groups.push(chat::create_group_chat(bob, "Group 2").await.unwrap());
groups.push(chat::create_group_chat(bob, "Group 3").await.unwrap());
}
let alice_contact = bob.add_or_lookup_contact_id(alice).await;
@@ -201,8 +189,7 @@ async fn test_aeap_replay_attack() -> Result<()> {
tcm.send_recv_accept(&alice, &bob, "Hi").await;
tcm.send_recv(&bob, &alice, "Hi back").await;
let group =
chat::create_group_chat(&bob, chat::ProtectionStatus::Unprotected, "Group 0").await?;
let group = chat::create_group_chat(&bob, "Group 0").await?;
let bob_alice_contact = bob.add_or_lookup_contact_id(&alice).await;
let bob_fiona_contact = bob.add_or_lookup_contact_id(&fiona).await;
@@ -243,16 +230,13 @@ async fn test_write_to_alice_after_aeap() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let alice_grp_id = chat::create_group_chat(alice, ProtectionStatus::Protected, "Group").await?;
let alice_grp_id = chat::create_group_chat(alice, "Group").await?;
let qr = get_securejoin_qr(alice, Some(alice_grp_id)).await?;
tcm.exec_securejoin_qr(bob, alice, &qr).await;
let bob_alice_contact = bob.add_or_lookup_contact(alice).await;
assert!(bob_alice_contact.is_verified(bob).await?);
let bob_alice_chat = bob.create_chat(alice).await;
assert!(bob_alice_chat.is_protected());
let bob_unprotected_grp_id = bob
.create_group_with_members(ProtectionStatus::Unprotected, "Group", &[alice])
.await;
let bob_unprotected_grp_id = bob.create_group_with_members("Group", &[alice]).await;
tcm.change_addr(alice, "alice@someotherdomain.xyz").await;
let sent = alice.send_text(alice_grp_id, "Hello!").await;
@@ -260,7 +244,6 @@ async fn test_write_to_alice_after_aeap() -> Result<()> {
assert!(bob_alice_contact.is_verified(bob).await?);
let bob_alice_chat = Chat::load_from_db(bob, bob_alice_chat.id).await?;
assert!(bob_alice_chat.is_protected());
let mut msg = Message::new_text("hi".to_string());
chat::send_msg(bob, bob_alice_chat.id, &mut msg).await?;

View File

@@ -2,9 +2,7 @@ use anyhow::Result;
use pretty_assertions::assert_eq;
use crate::chat::resend_msgs;
use crate::chat::{
self, Chat, ProtectionStatus, add_contact_to_chat, remove_contact_from_chat, send_msg,
};
use crate::chat::{self, Chat, add_contact_to_chat, remove_contact_from_chat, send_msg};
use crate::config::Config;
use crate::constants::Chattype;
use crate::contact::{Contact, ContactId};
@@ -38,8 +36,8 @@ async fn check_verified_oneonone_chat_protection_not_broken(by_classical_email:
tcm.execute_securejoin(&alice, &bob).await;
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&bob, &alice, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
assert_verified(&bob, &alice).await;
if by_classical_email {
tcm.section("Bob uses a classical MUA to send a message to Alice");
@@ -59,7 +57,7 @@ async fn check_verified_oneonone_chat_protection_not_broken(by_classical_email:
.unwrap();
let contact = alice.add_or_lookup_contact(&bob).await;
assert_eq!(contact.is_verified(&alice).await.unwrap(), true);
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
} else {
tcm.section("Bob sets up another Delta Chat device");
let bob2 = tcm.unconfigured().await;
@@ -71,7 +69,7 @@ async fn check_verified_oneonone_chat_protection_not_broken(by_classical_email:
.await;
let contact = alice.add_or_lookup_contact(&bob2).await;
assert_eq!(contact.is_verified(&alice).await.unwrap(), false);
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
}
tcm.section("Bob sends another message from DC");
@@ -79,7 +77,7 @@ async fn check_verified_oneonone_chat_protection_not_broken(by_classical_email:
tcm.send_recv(&bob, &alice, "Using DC again").await;
// Bob's chat is marked as verified again
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
@@ -91,21 +89,17 @@ async fn test_create_verified_oneonone_chat() -> Result<()> {
tcm.execute_securejoin(&alice, &bob).await;
tcm.execute_securejoin(&bob, &fiona).await;
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&bob, &alice, ProtectionStatus::Protected).await;
assert_verified(&bob, &fiona, ProtectionStatus::Protected).await;
assert_verified(&fiona, &bob, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
assert_verified(&bob, &alice).await;
assert_verified(&bob, &fiona).await;
assert_verified(&fiona, &bob).await;
let group_id = bob
.create_group_with_members(
ProtectionStatus::Protected,
"Group with everyone",
&[&alice, &fiona],
)
.create_group_with_members("Group with everyone", &[&alice, &fiona])
.await;
assert_eq!(
get_chat_msg(&bob, group_id, 0, 1).await.get_info_type(),
SystemMessage::ChatProtectionEnabled
SystemMessage::ChatE2ee
);
{
@@ -117,7 +111,7 @@ async fn test_create_verified_oneonone_chat() -> Result<()> {
get_chat_msg(&fiona, msg.chat_id, 0, 2)
.await
.get_info_type(),
SystemMessage::ChatProtectionEnabled
SystemMessage::ChatE2ee
);
}
@@ -125,26 +119,6 @@ async fn test_create_verified_oneonone_chat() -> Result<()> {
let alice_fiona_contact = alice.add_or_lookup_contact(&fiona).await;
assert!(alice_fiona_contact.is_verified(&alice).await.unwrap(),);
// Alice should have a hidden protected chat with Fiona
{
let chat = alice.get_chat(&fiona).await;
assert!(chat.is_protected());
let msg = get_chat_msg(&alice, chat.id, 0, 1).await;
let expected_text = stock_str::messages_e2e_encrypted(&alice).await;
assert_eq!(msg.text, expected_text);
}
// Fiona should have a hidden protected chat with Alice
{
let chat = fiona.get_chat(&alice).await;
assert!(chat.is_protected());
let msg0 = get_chat_msg(&fiona, chat.id, 0, 1).await;
let expected_text = stock_str::messages_e2e_encrypted(&fiona).await;
assert_eq!(msg0.text, expected_text);
}
tcm.section("Fiona reinstalls DC");
drop(fiona);
@@ -180,7 +154,7 @@ async fn test_missing_key_reexecute_securejoin() -> Result<()> {
let bob = &tcm.bob().await;
let chat_id = tcm.execute_securejoin(bob, alice).await;
let chat = Chat::load_from_db(bob, chat_id).await?;
assert!(chat.is_protected());
assert!(chat.can_send(bob).await?);
bob.sql
.execute(
"DELETE FROM public_keys WHERE fingerprint=?",
@@ -191,9 +165,13 @@ async fn test_missing_key_reexecute_securejoin() -> Result<()> {
.hex(),),
)
.await?;
let chat = Chat::load_from_db(bob, chat_id).await?;
assert!(!chat.can_send(bob).await?);
let chat_id = tcm.execute_securejoin(bob, alice).await;
let chat = Chat::load_from_db(bob, chat_id).await?;
assert!(chat.is_protected());
assert!(chat.can_send(bob).await?);
Ok(())
}
@@ -261,7 +239,7 @@ async fn test_degrade_verified_oneonone_chat() -> Result<()> {
let msg0 = get_chat_msg(&alice, alice_chat.id, 0, 1).await;
let enabled = stock_str::messages_e2e_encrypted(&alice).await;
assert_eq!(msg0.text, enabled);
assert_eq!(msg0.param.get_cmd(), SystemMessage::ChatProtectionEnabled);
assert_eq!(msg0.param.get_cmd(), SystemMessage::ChatE2ee);
let email_chat = alice.get_email_chat(&bob).await;
assert!(!email_chat.is_encrypted(&alice).await?);
@@ -369,7 +347,7 @@ async fn test_mdn_doesnt_disable_verification() -> Result<()> {
let body = rendered_msg.message;
receive_imf(&alice, body.as_bytes(), false).await.unwrap();
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
Ok(())
}
@@ -384,7 +362,7 @@ async fn test_outgoing_mua_msg() -> Result<()> {
mark_as_verified(&bob, &alice).await;
tcm.send_recv_accept(&bob, &alice, "Heyho from DC").await;
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
let sent = receive_imf(
&alice,
@@ -497,7 +475,7 @@ async fn test_message_from_old_dc_setup() -> Result<()> {
mark_as_verified(bob, alice).await;
tcm.send_recv(bob, alice, "Now i have it!").await;
assert_verified(alice, bob, ProtectionStatus::Protected).await;
assert_verified(alice, bob).await;
let msg = alice.recv_msg(&sent_old).await;
assert!(msg.get_showpadlock());
@@ -528,7 +506,7 @@ async fn test_verify_then_verify_again() -> Result<()> {
mark_as_verified(&bob, &alice).await;
alice.create_chat(&bob).await;
assert_verified(&alice, &bob, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob).await;
tcm.section("Bob reinstalls DC");
drop(bob);
@@ -537,42 +515,39 @@ async fn test_verify_then_verify_again() -> Result<()> {
e2ee::ensure_secret_key_exists(&bob_new).await?;
tcm.execute_securejoin(&bob_new, &alice).await;
assert_verified(&alice, &bob_new, ProtectionStatus::Protected).await;
assert_verified(&alice, &bob_new).await;
Ok(())
}
/// Tests that on the second device of a protected group creator the first message is
/// `SystemMessage::ChatProtectionEnabled` and the second one is the message populating the group.
/// Tests that on the second device of a group creator the first message is
/// `SystemMessage::ChatE2ee` and the second one is the message populating the group.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_create_protected_grp_multidev() -> Result<()> {
async fn test_create_grp_multidev() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let alice1 = &tcm.alice().await;
let group_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group", &[])
.await;
let group_id = alice.create_group_with_members("Group", &[]).await;
assert_eq!(
get_chat_msg(alice, group_id, 0, 1).await.get_info_type(),
SystemMessage::ChatProtectionEnabled
SystemMessage::ChatE2ee
);
let sent = alice.send_text(group_id, "Hey").await;
// This time shift is necessary to reproduce the bug when the original message is sorted over
// the "protection enabled" message so that these messages have different timestamps.
// the "Messages are end-to-end encrypted" message so that these messages have different timestamps.
SystemTime::shift(std::time::Duration::from_secs(3600));
let msg = alice1.recv_msg(&sent).await;
let group1 = Chat::load_from_db(alice1, msg.chat_id).await?;
assert_eq!(group1.get_type(), Chattype::Group);
assert!(group1.is_protected());
assert_eq!(
chat::get_chat_contacts(alice1, group1.id).await?,
vec![ContactId::SELF]
);
assert_eq!(
get_chat_msg(alice1, group1.id, 0, 2).await.get_info_type(),
SystemMessage::ChatProtectionEnabled
SystemMessage::ChatE2ee
);
assert_eq!(get_chat_msg(alice1, group1.id, 1, 2).await.id, msg.id);
@@ -592,10 +567,8 @@ async fn test_verified_member_added_reordering() -> Result<()> {
tcm.execute_securejoin(bob, alice).await;
tcm.execute_securejoin(fiona, alice).await;
// Alice creates protected group with Bob.
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob])
.await;
// Alice creates a group with Bob.
let alice_chat_id = alice.create_group_with_members("Group", &[bob]).await;
let alice_sent_group_promotion = alice.send_text(alice_chat_id, "I created a group").await;
let msg = bob.recv_msg(&alice_sent_group_promotion).await;
let bob_chat_id = msg.chat_id;
@@ -621,8 +594,6 @@ async fn test_verified_member_added_reordering() -> Result<()> {
// Fiona receives late "Member added" message
// and the chat becomes protected.
fiona.recv_msg(&alice_sent_member_added).await;
let fiona_chat = Chat::load_from_db(fiona, fiona_received_message.chat_id).await?;
assert_eq!(fiona_chat.is_protected(), true);
Ok(())
}
@@ -665,9 +636,7 @@ async fn test_verified_lost_member_added() -> Result<()> {
tcm.execute_securejoin(bob, alice).await;
tcm.execute_securejoin(fiona, alice).await;
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob])
.await;
let alice_chat_id = alice.create_group_with_members("Group", &[bob]).await;
let alice_sent = alice.send_text(alice_chat_id, "Hi!").await;
let bob_chat_id = bob.recv_msg(&alice_sent).await.chat_id;
assert_eq!(chat::get_chat_contacts(bob, bob_chat_id).await?.len(), 2);
@@ -728,9 +697,7 @@ async fn test_verified_chat_editor_reordering() -> Result<()> {
tcm.execute_securejoin(alice, bob).await;
tcm.section("Alice creates a protected group with Bob");
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob])
.await;
let alice_chat_id = alice.create_group_with_members("Group", &[bob]).await;
let alice_sent = alice.send_text(alice_chat_id, "Hi!").await;
let bob_chat_id = bob.recv_msg(&alice_sent).await.chat_id;
@@ -811,7 +778,7 @@ async fn test_no_reverification() -> Result<()> {
tcm.section("Alice creates a protected group with Bob, Charlie and Fiona");
let alice_chat_id = alice
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob, charlie, fiona])
.create_group_with_members("Group", &[bob, charlie, fiona])
.await;
let alice_sent = alice.send_text(alice_chat_id, "Hi!").await;
let bob_rcvd_msg = bob.recv_msg(&alice_sent).await;
@@ -899,13 +866,7 @@ async fn test_no_direct_verification_via_bcc() -> Result<()> {
// ============== Helper Functions ==============
async fn assert_verified(this: &TestContext, other: &TestContext, protected: ProtectionStatus) {
async fn assert_verified(this: &TestContext, other: &TestContext) {
let contact = this.add_or_lookup_contact(other).await;
assert_eq!(contact.is_verified(this).await.unwrap(), true);
let chat = this.get_chat(other).await;
assert_eq!(
chat.is_protected(),
protected == ProtectionStatus::Protected
);
}

View File

@@ -169,7 +169,7 @@ pub(crate) async fn intercept_get_updates(
#[cfg(test)]
mod tests {
use crate::chat::{ChatId, ProtectionStatus, create_group_chat};
use crate::chat::{ChatId, create_group_chat};
use crate::chatlist::Chatlist;
use crate::contact::Contact;
use crate::message::Message;
@@ -231,7 +231,7 @@ mod tests {
assert_eq!(msg.chat_id, bob_chat_id);
// Integrate Webxdc into another group
let group_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let group_id = create_group_chat(&t, "foo").await?;
let integration_id = t.init_webxdc_integration(Some(group_id)).await?.unwrap();
let locations = location::get_range(&t, Some(group_id), None, 0, 0).await?;

View File

@@ -5,8 +5,8 @@ use serde_json::json;
use super::*;
use crate::chat::{
ChatId, ProtectionStatus, add_contact_to_chat, create_broadcast, create_group_chat,
forward_msgs, remove_contact_from_chat, resend_msgs, send_msg, send_text_msg,
ChatId, add_contact_to_chat, create_broadcast, create_group_chat, forward_msgs,
remove_contact_from_chat, resend_msgs, send_msg, send_text_msg,
};
use crate::chatlist::Chatlist;
use crate::config::Config;
@@ -78,7 +78,7 @@ async fn send_webxdc_instance(t: &TestContext, chat_id: ChatId) -> Result<Messag
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_send_webxdc_instance() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
// send as .xdc file
let instance = send_webxdc_instance(&t, chat_id).await?;
@@ -97,7 +97,7 @@ async fn test_send_webxdc_instance() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_send_invalid_webxdc() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
// sending invalid .xdc as file is possible, but must not result in Viewtype::Webxdc
let mut instance = create_webxdc_instance(
@@ -126,7 +126,7 @@ async fn test_send_invalid_webxdc() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_set_draft_invalid_webxdc() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let mut instance = create_webxdc_instance(
&t,
@@ -143,7 +143,7 @@ async fn test_set_draft_invalid_webxdc() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_send_special_webxdc_format() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
// chess.xdc is failing for some zip-versions, see #3476, if we know more details about why, we can have a nicer name for the test :)
let mut instance = create_webxdc_instance(
@@ -164,7 +164,7 @@ async fn test_send_special_webxdc_format() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_forward_webxdc_instance() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
t.send_webxdc_status_update(
instance.id,
@@ -213,7 +213,7 @@ async fn test_resend_webxdc_instance_and_info() -> Result<()> {
// Alice uses webxdc in a group
alice.set_config_bool(Config::BccSelf, false).await?;
let alice_grp = create_group_chat(&alice, ProtectionStatus::Unprotected, "grp").await?;
let alice_grp = create_group_chat(&alice, "grp").await?;
let alice_instance = send_webxdc_instance(&alice, alice_grp).await?;
assert_eq!(alice_grp.get_msg_cnt(&alice).await?, 2);
alice
@@ -395,7 +395,7 @@ async fn test_webxdc_update_for_not_downloaded_instance() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_delete_webxdc_instance() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let now = tools::time();
t.receive_status_update(
@@ -428,7 +428,7 @@ async fn test_delete_webxdc_instance() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_delete_chat_with_webxdc() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let now = tools::time();
t.receive_status_update(
@@ -461,7 +461,7 @@ async fn test_delete_chat_with_webxdc() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_delete_webxdc_draft() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let mut instance = create_webxdc_instance(
&t,
@@ -498,7 +498,7 @@ async fn test_delete_webxdc_draft() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_create_status_update_record() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
assert_eq!(
@@ -633,7 +633,7 @@ async fn test_create_status_update_record() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_receive_status_update() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let now = tools::time();
@@ -904,7 +904,7 @@ async fn test_send_big_webxdc_status_update() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_render_webxdc_status_update_object() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "a chat").await?;
let chat_id = create_group_chat(&t, "a chat").await?;
let mut instance = create_webxdc_instance(
&t,
"minimal.xdc",
@@ -932,7 +932,7 @@ async fn test_render_webxdc_status_update_object() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_render_webxdc_status_update_object_range() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "a chat").await?;
let chat_id = create_group_chat(&t, "a chat").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
t.send_webxdc_status_update(instance.id, r#"{"payload": 1}"#)
.await?;
@@ -979,7 +979,7 @@ async fn test_render_webxdc_status_update_object_range() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_pop_status_update() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "a chat").await?;
let chat_id = create_group_chat(&t, "a chat").await?;
let instance1 = send_webxdc_instance(&t, chat_id).await?;
let instance2 = send_webxdc_instance(&t, chat_id).await?;
let instance3 = send_webxdc_instance(&t, chat_id).await?;
@@ -1109,7 +1109,7 @@ async fn test_draft_and_send_webxdc_status_update() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_send_webxdc_status_update_to_non_webxdc() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let msg_id = send_text_msg(&t, chat_id, "ho!".to_string()).await?;
assert!(
t.send_webxdc_status_update(msg_id, r#"{"foo":"bar"}"#)
@@ -1122,7 +1122,7 @@ async fn test_send_webxdc_status_update_to_non_webxdc() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_webxdc_blob() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let buf = instance.get_webxdc_blob(&t, "index.html").await?;
@@ -1141,7 +1141,7 @@ async fn test_get_webxdc_blob() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_webxdc_blob_default_icon() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let buf = instance.get_webxdc_blob(&t, WEBXDC_DEFAULT_ICON).await?;
@@ -1153,7 +1153,7 @@ async fn test_get_webxdc_blob_default_icon() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_webxdc_blob_with_absolute_paths() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let buf = instance.get_webxdc_blob(&t, "/index.html").await?;
@@ -1166,7 +1166,7 @@ async fn test_get_webxdc_blob_with_absolute_paths() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_webxdc_blob_with_subdirs() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let mut instance = create_webxdc_instance(
&t,
"some-files.xdc",
@@ -1265,7 +1265,7 @@ async fn test_parse_webxdc_manifest_source_code_url() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_webxdc_min_api_too_large() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "chat").await?;
let chat_id = create_group_chat(&t, "chat").await?;
let mut instance = create_webxdc_instance(
&t,
"with-min-api-1001.xdc",
@@ -1283,7 +1283,7 @@ async fn test_webxdc_min_api_too_large() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_webxdc_info() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let info = instance.get_webxdc_info(&t).await?;
@@ -1363,7 +1363,7 @@ async fn test_get_webxdc_info() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_get_webxdc_self_addr() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&t, "foo").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
let info1 = instance.get_webxdc_info(&t).await?;
@@ -1601,7 +1601,7 @@ async fn test_webxdc_info_msg_cleanup_series() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_webxdc_info_msg_no_cleanup_on_interrupted_series() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "c").await?;
let chat_id = create_group_chat(&t, "c").await?;
let instance = send_webxdc_instance(&t, chat_id).await?;
t.send_webxdc_status_update(instance.id, r#"{"info":"i1", "payload":1}"#)
@@ -1623,7 +1623,7 @@ async fn test_webxdc_no_internet_access() -> Result<()> {
let t = TestContext::new_alice().await;
let self_id = t.get_self_chat().await.id;
let single_id = t.create_chat_with_contact("bob", "bob@e.com").await.id;
let group_id = create_group_chat(&t, ProtectionStatus::Unprotected, "chat").await?;
let group_id = create_group_chat(&t, "chat").await?;
let broadcast_id = create_broadcast(&t, "Channel".to_string()).await?;
for chat_id in [self_id, single_id, group_id, broadcast_id] {
@@ -1655,7 +1655,7 @@ async fn test_webxdc_no_internet_access() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_webxdc_chatlist_summary() -> Result<()> {
let t = TestContext::new_alice().await;
let chat_id = create_group_chat(&t, ProtectionStatus::Unprotected, "chat").await?;
let chat_id = create_group_chat(&t, "chat").await?;
let mut instance = create_webxdc_instance(
&t,
"with-minimal-manifest.xdc",
@@ -1727,7 +1727,7 @@ async fn test_webxdc_reject_updates_from_non_groupmembers() -> Result<()> {
let alice = &tcm.alice().await;
let bob = &tcm.bob().await;
let contact_bob = alice.add_or_lookup_contact_id(bob).await;
let chat_id = create_group_chat(alice, ProtectionStatus::Unprotected, "Group").await?;
let chat_id = create_group_chat(alice, "Group").await?;
add_contact_to_chat(alice, chat_id, contact_bob).await?;
let instance = send_webxdc_instance(alice, chat_id).await?;
bob.recv_msg(&alice.pop_sent_msg().await).await;
@@ -1758,7 +1758,7 @@ async fn test_webxdc_reject_updates_from_non_groupmembers() -> Result<()> {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_webxdc_delete_event() -> Result<()> {
let alice = TestContext::new_alice().await;
let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "foo").await?;
let chat_id = create_group_chat(&alice, "foo").await?;
let instance = send_webxdc_instance(&alice, chat_id).await?;
message::delete_msgs(&alice, &[instance.id]).await?;
alice
@@ -1912,7 +1912,7 @@ async fn test_webxdc_notify_one() -> Result<()> {
let fiona = tcm.fiona().await;
let grp_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[&bob, &fiona])
.create_group_with_members("grp", &[&bob, &fiona])
.await;
let alice_instance = send_webxdc_instance(&alice, grp_id).await?;
let sent1 = alice.pop_sent_msg().await;
@@ -1958,7 +1958,7 @@ async fn test_webxdc_notify_multiple() -> Result<()> {
let fiona = tcm.fiona().await;
let grp_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[&bob, &fiona])
.create_group_with_members("grp", &[&bob, &fiona])
.await;
let alice_instance = send_webxdc_instance(&alice, grp_id).await?;
let sent1 = alice.pop_sent_msg().await;
@@ -2001,9 +2001,7 @@ async fn test_webxdc_no_notify_self() -> Result<()> {
let alice = tcm.alice().await;
let alice2 = tcm.alice().await;
let grp_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[])
.await;
let grp_id = alice.create_group_with_members("grp", &[]).await;
let alice_instance = send_webxdc_instance(&alice, grp_id).await?;
let sent1 = alice.pop_sent_msg().await;
let alice2_instance = alice2.recv_msg(&sent1).await;
@@ -2043,7 +2041,7 @@ async fn test_webxdc_notify_all() -> Result<()> {
let fiona = tcm.fiona().await;
let grp_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[&bob, &fiona])
.create_group_with_members("grp", &[&bob, &fiona])
.await;
let alice_instance = send_webxdc_instance(&alice, grp_id).await?;
let sent1 = alice.pop_sent_msg().await;
@@ -2083,7 +2081,7 @@ async fn test_webxdc_notify_bob_and_all() -> Result<()> {
let fiona = tcm.fiona().await;
let grp_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[&bob, &fiona])
.create_group_with_members("grp", &[&bob, &fiona])
.await;
let alice_instance = send_webxdc_instance(&alice, grp_id).await?;
let sent1 = alice.pop_sent_msg().await;
@@ -2117,7 +2115,7 @@ async fn test_webxdc_notify_all_and_bob() -> Result<()> {
let fiona = tcm.fiona().await;
let grp_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[&bob, &fiona])
.create_group_with_members("grp", &[&bob, &fiona])
.await;
let alice_instance = send_webxdc_instance(&alice, grp_id).await?;
let sent1 = alice.pop_sent_msg().await;
@@ -2149,9 +2147,7 @@ async fn test_webxdc_href() -> Result<()> {
let alice = tcm.alice().await;
let bob = tcm.bob().await;
let grp_id = alice
.create_group_with_members(ProtectionStatus::Unprotected, "grp", &[&bob])
.await;
let grp_id = alice.create_group_with_members("grp", &[&bob]).await;
let instance = send_webxdc_instance(&alice, grp_id).await?;
let sent1 = alice.pop_sent_msg().await;
@@ -2181,9 +2177,7 @@ async fn test_webxdc_href() -> Result<()> {
async fn test_self_addr_consistency() -> Result<()> {
let mut tcm = TestContextManager::new();
let alice = &tcm.alice().await;
let alice_chat = alice
.create_group_with_members(ProtectionStatus::Unprotected, "No friends :(", &[])
.await;
let alice_chat = alice.create_group_with_members("No friends :(", &[]).await;
let mut instance = create_webxdc_instance(
alice,
"minimal.xdc",

View File

@@ -1,5 +1,5 @@
Single#Chat#10: bob@example.net [KEY bob@example.net] 🛡️
--------------------------------------------------------------------------------
Msg#10: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO 🛡️]
Msg#10: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO]
Msg#11🔒: Me (Contact#Contact#Self): Test This is encrypted, signed, and has an Autocrypt Header without prefer-encrypt=mutual. √
--------------------------------------------------------------------------------

View File

@@ -1,6 +1,6 @@
Single#Chat#10: bob@example.net [KEY bob@example.net] 🛡️
--------------------------------------------------------------------------------
Msg#10: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO 🛡️]
Msg#10: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO]
Msg#11🔒: (Contact#Contact#10): Heyho from DC [FRESH]
Msg#13🔒: Me (Contact#Contact#Self): Sending with DC again √
--------------------------------------------------------------------------------

View File

@@ -1,9 +1,9 @@
Group#Chat#11: Group [3 member(s)] 🛡️
Group#Chat#11: Group [3 member(s)]
--------------------------------------------------------------------------------
Msg#11: info (Contact#Contact#Info): alice@example.org invited you to join this group.
Msg#13: info (Contact#Contact#Info): alice@example.org invited you to join this group.
Waiting for the device of alice@example.org to reply… [NOTICED][INFO]
Msg#13: info (Contact#Contact#Info): alice@example.org replied, waiting for being added to the group… [NOTICED][INFO]
Msg#17: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO 🛡️]
Msg#18🔒: (Contact#Contact#10): Member Me added by alice@example.org. [FRESH][INFO]
Msg#15: info (Contact#Contact#Info): alice@example.org replied, waiting for being added to the group… [NOTICED][INFO]
Msg#12: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO]
Msg#17🔒: (Contact#Contact#10): Member Me added by alice@example.org. [FRESH][INFO]
--------------------------------------------------------------------------------

View File

@@ -1,11 +1,11 @@
Group#Chat#11: Group [3 member(s)] 🛡️
Group#Chat#11: Group [3 member(s)]
--------------------------------------------------------------------------------
Msg#11: info (Contact#Contact#Info): alice@example.org invited you to join this group.
Msg#13: info (Contact#Contact#Info): alice@example.org invited you to join this group.
Waiting for the device of alice@example.org to reply… [NOTICED][INFO]
Msg#13: info (Contact#Contact#Info): alice@example.org replied, waiting for being added to the group… [NOTICED][INFO]
Msg#16🔒: (Contact#Contact#11): [FRESH]
Msg#18: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO 🛡️]
Msg#19: info (Contact#Contact#Info): Member bob@example.net added. [NOTICED][INFO]
Msg#20🔒: (Contact#Contact#10): Member Me added by alice@example.org. [FRESH][INFO]
Msg#15: info (Contact#Contact#Info): alice@example.org replied, waiting for being added to the group… [NOTICED][INFO]
Msg#12: info (Contact#Contact#Info): Messages are end-to-end encrypted. [NOTICED][INFO]
Msg#17🔒: (Contact#Contact#11): [FRESH]
Msg#18: info (Contact#Contact#Info): Member bob@example.net added. [NOTICED][INFO]
Msg#19🔒: (Contact#Contact#10): Member Me added by alice@example.org. [FRESH][INFO]
--------------------------------------------------------------------------------