Skip to content

Commit 8b4c718

Browse files
authored
feat(backwards-compat): For now, send Chat-Verified header (instead of _verified) again
1 parent 2ada3cd commit 8b4c718

File tree

9 files changed

+87
-13
lines changed

9 files changed

+87
-13
lines changed

deltachat-rpc-client/tests/test_securejoin.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,10 @@ def test_verified_group_member_added_recovery(acfactory) -> None:
279279
ac1_contact_ac2 = ac1.create_contact(ac2)
280280
ac1_contact_ac3 = ac1.create_contact(ac3)
281281
ac1_contact_ac2_snapshot = ac1_contact_ac2.get_snapshot()
282-
assert ac1_contact_ac2_snapshot.is_verified
283-
assert ac1_contact_ac2_snapshot.verifier_id == ac1_contact_ac3.id
282+
# Until we reset verifications and then send the _verified header,
283+
# verification is not gossiped here:
284+
assert not ac1_contact_ac2_snapshot.is_verified
285+
assert ac1_contact_ac2_snapshot.verifier_id != ac1_contact_ac3.id
284286

285287

286288
def test_qr_join_chat_with_pending_bobstate_issue4894(acfactory):
@@ -442,7 +444,9 @@ def test_gossip_verification(acfactory) -> None:
442444

443445
# Group propagates verification using Autocrypt-Gossip header.
444446
carol_contact_alice_snapshot = carol_contact_alice.get_snapshot()
445-
assert carol_contact_alice_snapshot.is_verified
447+
# Until we reset verifications and then send the _verified header,
448+
# verification is not gossiped here:
449+
assert not carol_contact_alice_snapshot.is_verified
446450

447451
logging.info("Bob creates a Securejoin group")
448452
bob_group_chat = bob.create_group("Securejoin Group")
@@ -456,7 +460,9 @@ def test_gossip_verification(acfactory) -> None:
456460

457461
# Securejoin propagates verification.
458462
carol_contact_alice_snapshot = carol_contact_alice.get_snapshot()
459-
assert carol_contact_alice_snapshot.is_verified
463+
# Until we reset verifications and then send the _verified header,
464+
# verification is not gossiped here:
465+
assert not carol_contact_alice_snapshot.is_verified
460466

461467

462468
def test_securejoin_after_contact_resetup(acfactory) -> None:

python/tests/test_0_complex_or_slow.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ def test_synchronize_member_list_on_group_rejoin(self, acfactory, lp):
116116

117117
def test_qr_verified_group_and_chatting(acfactory, lp):
118118
ac1, ac2, ac3 = acfactory.get_online_accounts(3)
119-
ac1_addr = ac1.get_self_contact().addr
120119
lp.sec("ac1: create verified-group QR, ac2 scans and joins")
121120
chat1 = ac1.create_group_chat("hello")
122121
qr = chat1.get_join_qr()
@@ -174,7 +173,9 @@ def test_qr_verified_group_and_chatting(acfactory, lp):
174173
for ac2_contact in chat2.get_contacts():
175174
if ac2_contact == ac2_ac1_contact or ac2_contact.id == dc.const.DC_CONTACT_ID_SELF:
176175
continue
177-
assert ac2.get_self_contact().get_verifier(ac2_contact).addr == ac1_addr
176+
# Until we reset verifications and then send the _verified header,
177+
# verification is not gossiped here:
178+
assert ac2.get_self_contact().get_verifier(ac2_contact) is None
178179

179180
lp.sec("ac2: send message and let ac3 read it")
180181
chat2.send_text("hi")
@@ -409,7 +410,9 @@ def test_verified_group_vs_delete_server_after(acfactory, tmp_path, lp):
409410
assert msg_in.text == "hi2"
410411
assert msg_in.chat == chat2_offl
411412
assert msg_in.get_sender_contact().addr == ac2.get_config("addr")
412-
assert ac2_offl_ac1_contact.is_verified()
413+
# Until we reset verifications and then send the _verified header,
414+
# verification is not gossiped here:
415+
assert not ac2_offl_ac1_contact.is_verified()
413416

414417

415418
def test_deleted_msgs_dont_reappear(acfactory):

python/tests/test_1_online.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1238,8 +1238,11 @@ def test_qr_email_capitalization(acfactory, lp):
12381238

12391239
# ac1 should see both ac3 and ac2 as verified.
12401240
assert len(ac1_chat.get_contacts()) == 3
1241+
# Until we reset verifications and then send the _verified header,
1242+
# the verification of ac2 is not gossiped here:
12411243
for contact in ac1_chat.get_contacts():
1242-
assert contact.is_verified()
1244+
is_ac2 = contact.addr == ac2.get_config("addr")
1245+
assert contact.is_verified() != is_ac2
12431246

12441247

12451248
def test_set_get_contact_avatar(acfactory, data, lp):

src/aheader.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ impl fmt::Display for Aheader {
6161
if self.prefer_encrypt == EncryptPreference::Mutual {
6262
write!(fmt, " prefer-encrypt=mutual;")?;
6363
}
64-
if self.verified {
65-
write!(fmt, " _verified=1;")?;
66-
}
64+
// TODO After we reset all existing verifications,
65+
// we want to start sending the _verified attribute
66+
// if self.verified {
67+
// write!(fmt, " _verified=1;")?;
68+
// }
6769

6870
// adds a whitespace every 78 characters, this allows
6971
// email crate to wrap the lines according to RFC 5322
@@ -282,8 +284,9 @@ mod tests {
282284
.contains("[email protected]")
283285
);
284286

287+
// We don't send the _verified header yet:
285288
assert!(
286-
format!(
289+
!format!(
287290
"{}",
288291
Aheader {
289292
addr: "[email protected]".to_string(),

src/mimefactory.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,43 @@ impl MimeFactory {
13521352
let command = msg.param.get_cmd();
13531353
let mut placeholdertext = None;
13541354

1355+
let send_verified_headers = match chat.typ {
1356+
Chattype::Single => true,
1357+
Chattype::Group => true,
1358+
// Mailinglists and broadcast channels can actually never be verified:
1359+
Chattype::Mailinglist => false,
1360+
Chattype::OutBroadcast | Chattype::InBroadcast => false,
1361+
};
1362+
1363+
if send_verified_headers {
1364+
let was_protected: bool = context
1365+
.sql
1366+
.query_get_value("SELECT protected FROM chats WHERE id=?", (chat.id,))
1367+
.await?
1368+
.unwrap_or_default();
1369+
1370+
if was_protected {
1371+
let unverified_member_exists = context
1372+
.sql
1373+
.exists(
1374+
"SELECT COUNT(*)
1375+
FROM contacts, chats_contacts
1376+
WHERE chats_contacts.contact_id=contacts.id AND chats_contacts.chat_id=?
1377+
AND contacts.id>9
1378+
AND contacts.verifier=0",
1379+
(chat.id,),
1380+
)
1381+
.await?;
1382+
1383+
if !unverified_member_exists {
1384+
headers.push((
1385+
"Chat-Verified",
1386+
mail_builder::headers::raw::Raw::new("1").into(),
1387+
));
1388+
}
1389+
}
1390+
}
1391+
13551392
if chat.typ == Chattype::Group {
13561393
// Send group ID unless it is an ad hoc group that has no ID.
13571394
if !chat.grpid.is_empty() {

src/receive_imf.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3554,10 +3554,16 @@ async fn mark_recipients_as_verified(
35543554
mimeparser: &MimeMessage,
35553555
) -> Result<()> {
35563556
let verifier_id = Some(from_id).filter(|&id| id != ContactId::SELF);
3557+
3558+
// We don't yet send the _verified property in autocrypt headers.
3559+
// Until we do, we instead accept the Chat-Verified header as indication all contacts are verified.
3560+
// TODO: Ignore ChatVerified header once we reset existing verifications.
3561+
let chat_verified = mimeparser.get_header(HeaderDef::ChatVerified).is_some();
3562+
35573563
for gossiped_key in mimeparser
35583564
.gossiped_keys
35593565
.values()
3560-
.filter(|gossiped_key| gossiped_key.verified)
3566+
.filter(|gossiped_key| gossiped_key.verified || chat_verified)
35613567
{
35623568
let fingerprint = gossiped_key.public_key.dc_fingerprint().hex();
35633569
let Some(to_id) = lookup_key_contact_by_fingerprint(context, &fingerprint).await? else {

src/receive_imf/receive_imf_tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5133,6 +5133,7 @@ async fn test_dont_reverify_by_self_on_outgoing_msg() -> Result<()> {
51335133
let fiona = &tcm.fiona().await;
51345134

51355135
let bob_chat_id = chat::create_group(bob, "Group").await?;
5136+
bob.set_chat_protected(bob_chat_id).await;
51365137
let qr = get_securejoin_qr(bob, Some(bob_chat_id)).await?;
51375138
tcm.exec_securejoin_qr(fiona, bob, &qr).await;
51385139
tcm.exec_securejoin_qr(a0, bob, &qr).await;

src/test_utils.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,18 @@ impl TestContext {
11211121

11221122
chat_id
11231123
}
1124+
1125+
/// Set the legacy `protected` column in the chats table to 1,
1126+
/// because for now, only these chats that were once protected can be used
1127+
/// to gossip verifications.
1128+
// TODO remove the next statement
1129+
// when we send the _verified header for all verified contacts
1130+
pub(crate) async fn set_chat_protected(self: &TestContext, chat_id: chat::ChatId) {
1131+
self.sql
1132+
.execute("UPDATE chats SET protected=1 WHERE id=?", (chat_id,))
1133+
.await
1134+
.unwrap();
1135+
}
11241136
}
11251137

11261138
impl Deref for TestContext {

src/tests/verified_chats.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ async fn test_create_verified_oneonone_chat() -> Result<()> {
9797
let group_id = bob
9898
.create_group_with_members("Group with everyone", &[&alice, &fiona])
9999
.await;
100+
bob.set_chat_protected(group_id).await;
100101
assert_eq!(
101102
get_chat_msg(&bob, group_id, 0, 1).await.get_info_type(),
102103
SystemMessage::ChatE2ee
@@ -735,6 +736,7 @@ async fn test_no_reverification() -> Result<()> {
735736
let alice_chat_id = alice
736737
.create_group_with_members("Group", &[bob, charlie, fiona])
737738
.await;
739+
alice.set_chat_protected(alice_chat_id).await;
738740
let alice_sent = alice.send_text(alice_chat_id, "Hi!").await;
739741
let bob_rcvd_msg = bob.recv_msg(&alice_sent).await;
740742
let bob_alice_id = bob_rcvd_msg.from_id;
@@ -802,6 +804,7 @@ async fn test_no_direct_verification_via_bcc() -> Result<()> {
802804
mark_as_verified(alice, bob).await;
803805

804806
let alice_chat_id = alice.create_chat_id(bob).await;
807+
alice.set_chat_protected(alice_chat_id).await;
805808
let alice_sent_msg = alice.send_text(alice_chat_id, "Hello!").await;
806809
alice2.recv_msg(&alice_sent_msg).await;
807810

0 commit comments

Comments
 (0)