de_mls/app/session/
messaging.rs1use std::sync::{Arc, RwLock};
5
6use crate::{
7 app::{
8 ConversationState, CreatorVote, LockExt, SessionRunner, UserError,
9 session::runner::send_packet,
10 },
11 core::{ConsensusPlugin, ConversationPluginsFactory, build_key_package_message},
12 mls_crypto::{KeyPackageBytes, MlsService},
13 protos::de_mls::messages::v1::{
14 AppMessage, BanRequest, ConversationMessage, ConversationUpdateRequest, RemoveMember,
15 conversation_update_request,
16 },
17};
18
19impl<P: ConsensusPlugin, CP: ConversationPluginsFactory> SessionRunner<P, CP> {
20 pub async fn send_kp_message(
29 arc: &Arc<RwLock<Self>>,
30 key_package: KeyPackageBytes,
31 ) -> Result<(), UserError> {
32 let (transport, packet) = {
33 let s = arc.read_or_err("session")?;
34 let packet = build_key_package_message(&s.conversation_name, key_package, &s.app_id);
35 (Arc::clone(s.transport()), packet)
36 };
37 send_packet(&transport, packet)?;
38 Ok(())
39 }
40
41 pub async fn send_app_message(
49 arc: &Arc<RwLock<Self>>,
50 message: Vec<u8>,
51 ) -> Result<(), UserError> {
52 let (transport, packet) = {
53 let mut s = arc.write_or_err("session")?;
54 let state = s.handle.current_state();
55 if matches!(
56 state,
57 ConversationState::PendingJoin
58 | ConversationState::Freezing
59 | ConversationState::Selection
60 ) {
61 return Err(UserError::ConversationBlocked(state.to_string()));
62 }
63
64 let app_msg: AppMessage = ConversationMessage {
65 message,
66 sender: s.identity_display.to_string(),
67 conversation_name: s.conversation_name.clone(),
68 }
69 .into();
70 let app_id = Arc::clone(&s.app_id);
71 let transport = Arc::clone(s.transport());
72 let packet = s
73 .handle
74 .expect_mls_mut()?
75 .build_message(&app_msg, &app_id)?;
76 (transport, packet)
77 };
78 send_packet(&transport, packet)?;
79 Ok(())
80 }
81
82 pub async fn process_ban_request(
87 arc: &Arc<RwLock<Self>>,
88 ban_request: BanRequest,
89 ) -> Result<(), UserError> {
90 {
91 let s = arc.read_or_err("session")?;
92 let state = s.handle.current_state();
93 if state != ConversationState::Working {
94 return Err(UserError::ConversationBlocked(state.to_string()));
95 }
96 }
97
98 Self::initiate_proposal(
99 arc,
100 ConversationUpdateRequest {
101 payload: Some(conversation_update_request::Payload::RemoveMember(
102 RemoveMember {
103 identity: ban_request.user_to_ban,
104 },
105 )),
106 },
107 CreatorVote::Yes,
108 )
109 .await?;
110
111 Ok(())
112 }
113}