Skip to content

Commit 5cb4889

Browse files
committed
Move auth-required message handling to bob module
This has an important behavioural change: error reporting to the user will now happen in the group chat rather than in the possibly still hidden 1:1 chat with alice.
1 parent f3dd427 commit 5cb4889

File tree

2 files changed

+55
-44
lines changed

2 files changed

+55
-44
lines changed

src/securejoin.rs

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,6 @@ use qrinvite::QrInvite;
3434

3535
pub const NON_ALPHANUMERIC_WITHOUT_DOT: &AsciiSet = &NON_ALPHANUMERIC.remove(b'.');
3636

37-
macro_rules! joiner_progress {
38-
($context:tt, $contact_id:expr, $progress:expr) => {
39-
assert!(
40-
$progress >= 0 && $progress <= 1000,
41-
"value in range 0..1000 expected with: 0=error, 1..999=progress, 1000=success"
42-
);
43-
$context.emit_event($crate::events::EventType::SecurejoinJoinerProgress {
44-
contact_id: $contact_id,
45-
progress: $progress,
46-
});
47-
};
48-
}
49-
5037
macro_rules! inviter_progress {
5138
($context:tt, $contact_id:expr, $progress:expr) => {
5239
assert!(
@@ -384,32 +371,7 @@ pub(crate) async fn handle_securejoin_handshake(
384371
==== Bob - the joiner's side =====
385372
==== Step 4 in "Setup verified contact" protocol =====
386373
========================================================*/
387-
match BobState::from_db(&context.sql).await? {
388-
Some(mut bobstate) => match bobstate.handle_message(context, mime_message).await? {
389-
Some(BobHandshakeStage::Terminated(why)) => {
390-
could_not_establish_secure_connection(
391-
context,
392-
contact_id,
393-
bobstate.alice_chat(),
394-
why,
395-
)
396-
.await?;
397-
Ok(HandshakeMessage::Done)
398-
}
399-
Some(_stage) => {
400-
if join_vg {
401-
// the message reads "Alice replied, waiting for being added to the group…";
402-
// show it only on secure-join and not on setup-contact therefore.
403-
let msg = stock_str::secure_join_replies(context, contact_id).await;
404-
chat::add_info_msg(context, bobstate.alice_chat(), msg, time()).await?;
405-
}
406-
joiner_progress!(context, bobstate.invite().contact_id(), 400);
407-
Ok(HandshakeMessage::Done)
408-
}
409-
None => Ok(HandshakeMessage::Ignore),
410-
},
411-
None => Ok(HandshakeMessage::Ignore),
412-
}
374+
bob::handle_auth_required(context, mime_message).await
413375
}
414376
"vg-request-with-auth" | "vc-request-with-auth" => {
415377
/*==========================================================

src/securejoin/bob.rs

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ use crate::contact::Contact;
1111
use crate::context::Context;
1212
use crate::dc_tools::time;
1313
use crate::events::EventType;
14+
use crate::mimeparser::MimeMessage;
1415
use crate::{chat, stock_str};
1516

1617
use super::bobstate::{BobHandshakeStage, BobState};
1718
use super::qrinvite::QrInvite;
18-
use super::JoinError;
19+
use super::{HandshakeMessage, JoinError};
1920

2021
/// Starts the securejoin protocol with the QR `invite`.
2122
///
@@ -29,7 +30,10 @@ use super::JoinError;
2930
///
3031
/// The [`ChatId`] of the created chat is returned, for a SetupContact QR this is the 1:1
3132
/// chat with Alice, for a SecureJoin QR this is the group chat.
32-
pub async fn start_protocol(context: &Context, invite: QrInvite) -> Result<ChatId, JoinError> {
33+
pub(super) async fn start_protocol(
34+
context: &Context,
35+
invite: QrInvite,
36+
) -> Result<ChatId, JoinError> {
3337
// A 1:1 chat is needed to send messages to Alice. When joining a group this chat is
3438
// hidden, if a user starts sending messages in it it will be unhidden in
3539
// dc_receive_imf.
@@ -46,7 +50,7 @@ pub async fn start_protocol(context: &Context, invite: QrInvite) -> Result<ChatI
4650
BobState::start_protocol(context, invite.clone(), chat_id).await?;
4751
for state in aborted_states {
4852
error!(context, "Aborting previously unfinished QR Join process.");
49-
state.notify_aborted(context).await?;
53+
state.notify_aborted(context, "new QR scanned").await?;
5054
state.emit_progress(context, JoinerProgress::Error);
5155
}
5256
if matches!(stage, BobHandshakeStage::RequestWithAuthSent) {
@@ -74,8 +78,47 @@ pub async fn start_protocol(context: &Context, invite: QrInvite) -> Result<ChatI
7478
}
7579
}
7680

81+
/// Handles `vc-auth-required` and `vg-auth-required` handshake messages.
82+
///
83+
/// # Bob - the joiner's side
84+
/// ## Step 4 in the "Setup Contact protocol"
85+
pub(super) async fn handle_auth_required(
86+
context: &Context,
87+
message: &MimeMessage,
88+
) -> Result<HandshakeMessage> {
89+
match BobState::from_db(&context.sql).await? {
90+
Some(mut bobstate) => match bobstate.handle_message(context, message).await? {
91+
Some(BobHandshakeStage::Terminated(why)) => {
92+
bobstate.notify_aborted(context, why).await?;
93+
Ok(HandshakeMessage::Done)
94+
}
95+
Some(_stage) => {
96+
if bobstate.is_join_group() {
97+
// The message reads "Alice replied, waiting to be added to the group…",
98+
// so only show it on secure-join and not on setup-contact.
99+
let contact_id = bobstate.invite().contact_id();
100+
let msg = stock_str::secure_join_replies(context, contact_id).await;
101+
let chat_id = bobstate.joining_chat_id(context).await?;
102+
chat::add_info_msg(context, chat_id, msg, time()).await?;
103+
}
104+
bobstate.emit_progress(context, JoinerProgress::RequestWithAuthSent);
105+
Ok(HandshakeMessage::Done)
106+
}
107+
None => Ok(HandshakeMessage::Ignore),
108+
},
109+
None => Ok(HandshakeMessage::Ignore),
110+
}
111+
}
112+
77113
/// Private implementations for user interactions about this [`BobState`].
78114
impl BobState {
115+
fn is_join_group(&self) -> bool {
116+
match self.invite() {
117+
QrInvite::Contact { .. } => false,
118+
QrInvite::Group { .. } => true,
119+
}
120+
}
121+
79122
fn emit_progress(&self, context: &Context, progress: JoinerProgress) {
80123
let contact_id = self.invite().contact_id();
81124
context.emit_event(EventType::SecurejoinJoinerProgress {
@@ -122,15 +165,21 @@ impl BobState {
122165
}
123166
}
124167

125-
async fn notify_aborted(&self, context: &Context) -> Result<()> {
168+
/// Notifies the user that the SecureJoin was aborted.
169+
///
170+
/// This creates and info message in the chat being joined.
171+
async fn notify_aborted(&self, context: &Context, why: &str) -> Result<()> {
126172
let contact_addr = match Contact::get_by_id(context, self.invite().contact_id()).await {
127173
Ok(ref contact) => contact.get_addr().to_string(),
128174
Err(_) => "?".to_string(),
129175
};
130-
// TODO: custom stock string?
131176
let msg = stock_str::contact_not_verified(context, contact_addr).await;
132177
let chat_id = self.joining_chat_id(context).await?;
133178
chat::add_info_msg(context, chat_id, &msg, time()).await?;
179+
warn!(
180+
context,
181+
"StockMessage::ContactNotVerified posted to joining chat ({})", why
182+
);
134183
Ok(())
135184
}
136185
}

0 commit comments

Comments
 (0)