mirror of
https://github.com/chatmail/core.git
synced 2026-04-19 14:36:29 +03:00
non-blocking group QR joins (#2508)
* refactor: cleanup send_handshake_msg() - rename to send_alice_handshake_msg() as used by Alice only - remove dead code from Bob (Bob's code is at BobState::send_handshake_message() since some time) - take a contact_id and not a chat_id; this makes things less confusing when info-messages are put to the final group chat * always directly return chat-id from dc_join_securejoin() * take care not to create a group twice * adapt documentation * add info-msg on group invites; add inviter directly after creation * document existing 'joinqr' command in repl tool * do not create empty one-to-one chats for group-joins * refactor: cleanup fingerprint_equals_sender() - the function takes a contact_id directly now. before it consumes the first contact of a one-to-one chat - which may be easily confused with the group-chat in creation. moreover, the conversion contact_id -> chat_id -> contact_id is unneeded overhead. * show info-messages in destination chat for alice * fingerprint_equals_sender() returns Err on database failure * tweak documentation * clarify what an 'unfinished tasks' task is. * add regression test for create_for_contact_with_blocked() * rename Blocked::Manually to better fitting Blocked::Yes * tweak test_secure_join() and make sure, Alice and Bob have only on chat after a group-join
This commit is contained in:
@@ -8,11 +8,11 @@
|
||||
//! protocol. Afterwards it must be stored in a mutex and the [`BobStateHandle`] should be
|
||||
//! used to work with the state.
|
||||
|
||||
use anyhow::{Error, Result};
|
||||
use anyhow::{bail, Error, Result};
|
||||
use async_std::sync::MutexGuard;
|
||||
|
||||
use crate::chat::{self, ChatId};
|
||||
use crate::constants::Viewtype;
|
||||
use crate::constants::{Blocked, Viewtype};
|
||||
use crate::contact::{Contact, Origin};
|
||||
use crate::context::Context;
|
||||
use crate::events::EventType;
|
||||
@@ -67,9 +67,18 @@ impl<'a> BobStateHandle<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the [`ChatId`] of the 1:1 chat with the inviter (Alice).
|
||||
pub fn chat_id(&self) -> ChatId {
|
||||
self.bobstate.chat_id
|
||||
/// Returns the [`ChatId`] of the group chat to join or the 1:1 chat with Alice.
|
||||
pub async fn chat_id(&self, context: &Context) -> Result<ChatId> {
|
||||
match self.bobstate.invite {
|
||||
QrInvite::Group { ref grpid, .. } => {
|
||||
if let Some((chat_id, _, _)) = chat::get_chat_id_by_grpid(context, &grpid).await? {
|
||||
Ok(chat_id)
|
||||
} else {
|
||||
bail!("chat not found")
|
||||
}
|
||||
}
|
||||
QrInvite::Contact { .. } => Ok(self.bobstate.chat_id),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference to the [`QrInvite`] of the joiner process.
|
||||
@@ -185,10 +194,11 @@ impl BobState {
|
||||
context: &Context,
|
||||
invite: QrInvite,
|
||||
) -> Result<(Self, BobHandshakeStage), JoinError> {
|
||||
let chat_id = ChatId::create_for_contact(context, invite.contact_id())
|
||||
.await
|
||||
.map_err(JoinError::UnknownContact)?;
|
||||
if fingerprint_equals_sender(context, invite.fingerprint(), chat_id).await? {
|
||||
let chat_id =
|
||||
ChatId::create_for_contact_with_blocked(context, invite.contact_id(), Blocked::Yes)
|
||||
.await
|
||||
.map_err(JoinError::UnknownContact)?;
|
||||
if fingerprint_equals_sender(context, invite.fingerprint(), invite.contact_id()).await? {
|
||||
// The scanned fingerprint matches Alice's key, we can proceed to step 4b.
|
||||
info!(context, "Taking securejoin protocol shortcut");
|
||||
let state = Self {
|
||||
@@ -297,7 +307,9 @@ impl BobState {
|
||||
self.next = SecureJoinStep::Terminated;
|
||||
return Ok(Some(BobHandshakeStage::Terminated(reason)));
|
||||
}
|
||||
if !fingerprint_equals_sender(context, self.invite.fingerprint(), self.chat_id).await? {
|
||||
if !fingerprint_equals_sender(context, self.invite.fingerprint(), self.invite.contact_id())
|
||||
.await?
|
||||
{
|
||||
self.next = SecureJoinStep::Terminated;
|
||||
return Ok(Some(BobHandshakeStage::Terminated("Fingerprint mismatch")));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user