mirror of
https://github.com/chatmail/core.git
synced 2026-05-04 05:46:29 +03:00
Improve Chat.get_encryption_info() format
Group contacts by peerstate and make it easier to find contacts that prevent encryption by sorting them to the top of the list.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
- send normal messages with higher priority than MDNs #3243
|
||||
- make Scheduler stateless #3302
|
||||
- support `source_code_url` from Webxdc manifests #3314
|
||||
- improve chat encryption info, make it easier to find contacts without keys #3318
|
||||
|
||||
### API-Changes
|
||||
- deprecate unused `marker1before` argument of `dc_get_chat_msgs`
|
||||
|
||||
@@ -689,7 +689,7 @@ def test_gossip_encryption_preference(acfactory, lp):
|
||||
msg = ac1._evtracker.wait_next_incoming_message()
|
||||
assert msg.text == "first message"
|
||||
assert not msg.is_encrypted()
|
||||
res = "{} End-to-end encryption preferred.".format(ac2.get_config('addr'))
|
||||
res = "End-to-end encryption preferred:\n{}\n".format(ac2.get_config('addr'))
|
||||
assert msg.chat.get_encryption_info() == res
|
||||
lp.sec("ac2 learns that ac3 prefers encryption")
|
||||
ac2.create_chat(ac3)
|
||||
@@ -701,7 +701,7 @@ def test_gossip_encryption_preference(acfactory, lp):
|
||||
lp.sec("ac3 does not know that ac1 prefers encryption")
|
||||
ac1.create_chat(ac3)
|
||||
chat = ac3.create_chat(ac1)
|
||||
res = "{} No encryption.".format(ac1.get_config('addr'))
|
||||
res = "No encryption:\n{}\n".format(ac1.get_config('addr'))
|
||||
assert chat.get_encryption_info() == res
|
||||
msg = chat.send_text("not encrypted")
|
||||
msg = ac1._evtracker.wait_next_incoming_message()
|
||||
@@ -712,7 +712,7 @@ def test_gossip_encryption_preference(acfactory, lp):
|
||||
group_chat = ac1.create_group_chat("hello")
|
||||
group_chat.add_contact(ac2)
|
||||
encryption_info = group_chat.get_encryption_info()
|
||||
res = "{} End-to-end encryption preferred.".format(ac2.get_config("addr"))
|
||||
res = "End-to-end encryption preferred:\n{}\n".format(ac2.get_config("addr"))
|
||||
assert encryption_info == res
|
||||
msg = group_chat.send_text("hi")
|
||||
|
||||
@@ -727,10 +727,9 @@ def test_gossip_encryption_preference(acfactory, lp):
|
||||
lp.sec("ac3 learns that ac1 prefers encryption")
|
||||
msg = ac3._evtracker.wait_next_incoming_message()
|
||||
encryption_info = msg.chat.get_encryption_info().splitlines()
|
||||
res = "{} End-to-end encryption preferred.".format(ac1.get_config("addr"))
|
||||
assert res in encryption_info
|
||||
res = "{} End-to-end encryption preferred.".format(ac2.get_config("addr"))
|
||||
assert res in encryption_info
|
||||
assert encryption_info[0] == "End-to-end encryption preferred:"
|
||||
assert ac1.get_config("addr") in encryption_info[1:]
|
||||
assert ac2.get_config("addr") in encryption_info[1:]
|
||||
msg = chat.send_text("encrypted")
|
||||
assert msg.is_encrypted()
|
||||
|
||||
|
||||
94
src/chat.rs
94
src/chat.rs
@@ -842,7 +842,9 @@ impl ChatId {
|
||||
///
|
||||
/// To get more verbose summary for a contact, including its key fingerprint, use [`Contact::get_encrinfo`].
|
||||
pub async fn get_encryption_info(self, context: &Context) -> Result<String> {
|
||||
let mut ret = String::new();
|
||||
let mut ret_mutual = String::new();
|
||||
let mut ret_nopreference = String::new();
|
||||
let mut ret_reset = String::new();
|
||||
|
||||
for contact_id in get_chat_contacts(context, self)
|
||||
.await?
|
||||
@@ -853,7 +855,7 @@ impl ChatId {
|
||||
let addr = contact.get_addr();
|
||||
let peerstate = Peerstate::from_addr(context, addr).await?;
|
||||
|
||||
let stock_message = match peerstate
|
||||
match peerstate
|
||||
.filter(|peerstate| {
|
||||
peerstate
|
||||
.peek_key(PeerstateVerifiedStatus::Unverified)
|
||||
@@ -861,15 +863,36 @@ impl ChatId {
|
||||
})
|
||||
.map(|peerstate| peerstate.prefer_encrypt)
|
||||
{
|
||||
Some(EncryptPreference::Mutual) => stock_str::e2e_preferred(context).await,
|
||||
Some(EncryptPreference::NoPreference) => stock_str::e2e_available(context).await,
|
||||
Some(EncryptPreference::Reset) => stock_str::encr_none(context).await,
|
||||
None => stock_str::encr_none(context).await,
|
||||
Some(EncryptPreference::Mutual) => ret_mutual += &format!("{}\n", addr),
|
||||
Some(EncryptPreference::NoPreference) => ret_nopreference += &format!("{}\n", addr),
|
||||
Some(EncryptPreference::Reset) | None => ret_reset += &format!("{}\n", addr),
|
||||
};
|
||||
}
|
||||
|
||||
let mut ret = String::new();
|
||||
if !ret_reset.is_empty() {
|
||||
ret += &stock_str::encr_none(context).await;
|
||||
ret.push(':');
|
||||
ret.push('\n');
|
||||
ret += &ret_reset;
|
||||
}
|
||||
if !ret_nopreference.is_empty() {
|
||||
if !ret.is_empty() {
|
||||
ret.push('\n')
|
||||
ret.push('\n');
|
||||
}
|
||||
ret += &format!("{} {}", addr, stock_message);
|
||||
ret += &stock_str::e2e_available(context).await;
|
||||
ret.push(':');
|
||||
ret.push('\n');
|
||||
ret += &ret_nopreference;
|
||||
}
|
||||
if !ret_mutual.is_empty() {
|
||||
if !ret.is_empty() {
|
||||
ret.push('\n');
|
||||
}
|
||||
ret += &stock_str::e2e_preferred(context).await;
|
||||
ret.push(':');
|
||||
ret.push('\n');
|
||||
ret += &ret_mutual;
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
@@ -5374,4 +5397,59 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
async fn test_chat_get_encryption_info() -> Result<()> {
|
||||
let alice = TestContext::new_alice().await;
|
||||
let bob = TestContext::new_bob().await;
|
||||
|
||||
let contact_bob = Contact::create(&alice, "Bob", "bob@example.net").await?;
|
||||
let contact_fiona = Contact::create(&alice, "", "fiona@example.net").await?;
|
||||
|
||||
let chat_id = create_group_chat(&alice, ProtectionStatus::Unprotected, "Group").await?;
|
||||
assert_eq!(chat_id.get_encryption_info(&alice).await?, "");
|
||||
|
||||
add_contact_to_chat(&alice, chat_id, contact_bob).await?;
|
||||
assert_eq!(
|
||||
chat_id.get_encryption_info(&alice).await?,
|
||||
"No encryption:\n\
|
||||
bob@example.net\n"
|
||||
);
|
||||
|
||||
add_contact_to_chat(&alice, chat_id, contact_fiona).await?;
|
||||
assert_eq!(
|
||||
chat_id.get_encryption_info(&alice).await?,
|
||||
"No encryption:\n\
|
||||
bob@example.net\n\
|
||||
fiona@example.net\n"
|
||||
);
|
||||
|
||||
let direct_chat = bob.create_chat(&alice).await;
|
||||
send_text_msg(&bob, direct_chat.id, "Hello!".to_string()).await?;
|
||||
alice.recv_msg(&bob.pop_sent_msg().await).await;
|
||||
|
||||
assert_eq!(
|
||||
chat_id.get_encryption_info(&alice).await?,
|
||||
"No encryption:\n\
|
||||
fiona@example.net\n\
|
||||
\n\
|
||||
End-to-end encryption preferred:\n\
|
||||
bob@example.net\n"
|
||||
);
|
||||
|
||||
bob.set_config(Config::E2eeEnabled, Some("0")).await?;
|
||||
send_text_msg(&bob, direct_chat.id, "Hello!".to_string()).await?;
|
||||
alice.recv_msg(&bob.pop_sent_msg().await).await;
|
||||
|
||||
assert_eq!(
|
||||
chat_id.get_encryption_info(&alice).await?,
|
||||
"No encryption:\n\
|
||||
fiona@example.net\n\
|
||||
\n\
|
||||
End-to-end encryption available:\n\
|
||||
bob@example.net\n"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,7 +889,7 @@ impl Contact {
|
||||
};
|
||||
|
||||
ret += &format!(
|
||||
"{}\n{}:",
|
||||
"{}.\n{}:",
|
||||
stock_message,
|
||||
stock_str::finger_prints(context).await
|
||||
);
|
||||
@@ -1961,7 +1961,7 @@ mod tests {
|
||||
.await?;
|
||||
|
||||
let encrinfo = Contact::get_encrinfo(&alice, contact_bob_id).await?;
|
||||
assert_eq!(encrinfo, "No encryption.");
|
||||
assert_eq!(encrinfo, "No encryption");
|
||||
|
||||
let bob = TestContext::new_bob().await;
|
||||
let chat_alice = bob
|
||||
|
||||
@@ -73,10 +73,10 @@ pub enum StockMessage {
|
||||
#[strum(props(fallback = "Encrypted message"))]
|
||||
EncryptedMsg = 24,
|
||||
|
||||
#[strum(props(fallback = "End-to-end encryption available."))]
|
||||
#[strum(props(fallback = "End-to-end encryption available"))]
|
||||
E2eAvailable = 25,
|
||||
|
||||
#[strum(props(fallback = "No encryption."))]
|
||||
#[strum(props(fallback = "No encryption"))]
|
||||
EncrNone = 28,
|
||||
|
||||
#[strum(props(fallback = "This message was encrypted for another setup."))]
|
||||
@@ -94,7 +94,7 @@ pub enum StockMessage {
|
||||
#[strum(props(fallback = "Group image deleted."))]
|
||||
MsgGrpImgDeleted = 33,
|
||||
|
||||
#[strum(props(fallback = "End-to-end encryption preferred."))]
|
||||
#[strum(props(fallback = "End-to-end encryption preferred"))]
|
||||
E2ePreferred = 34,
|
||||
|
||||
#[strum(props(fallback = "%1$s verified."))]
|
||||
|
||||
Reference in New Issue
Block a user