2 activities::receive::verify_activity_domains_valid,
3 check_is_apub_id_valid,
4 fetcher::get_or_fetch_and_upsert_user,
5 inbox::get_activity_to_and_cc,
9 activity::{ActorAndObjectRefExt, Create, Delete, Undo, Update},
10 base::{AnyBase, AsBase, ExtendsExt},
11 object::{AsObject, Note},
14 use anyhow::{anyhow, Context};
16 private_message::{PrivateMessage, PrivateMessageForm},
17 private_message_view::PrivateMessageView,
20 use lemmy_structs::{blocking, user::PrivateMessageResponse};
21 use lemmy_utils::{location_info, LemmyError};
22 use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
25 pub(crate) async fn receive_create_private_message(
26 context: &LemmyContext,
29 request_counter: &mut i32,
30 ) -> Result<(), LemmyError> {
31 let create = Create::from_any_base(activity)?.context(location_info!())?;
32 verify_activity_domains_valid(&create, &expected_domain, true)?;
33 check_private_message_activity_valid(&create, context, request_counter).await?;
35 let note = Note::from_any_base(
39 .context(location_info!())?
42 .context(location_info!())?;
45 PrivateMessageForm::from_apub(¬e, context, Some(expected_domain), request_counter).await?;
47 let inserted_private_message = blocking(&context.pool(), move |conn| {
48 PrivateMessage::create(conn, &private_message)
52 let message = blocking(&context.pool(), move |conn| {
53 PrivateMessageView::read(conn, inserted_private_message.id)
57 let res = PrivateMessageResponse { message };
59 let recipient_id = res.message.recipient_id;
61 context.chat_server().do_send(SendUserRoomMessage {
62 op: UserOperation::CreatePrivateMessage,
71 pub(crate) async fn receive_update_private_message(
72 context: &LemmyContext,
75 request_counter: &mut i32,
76 ) -> Result<(), LemmyError> {
77 let update = Update::from_any_base(activity)?.context(location_info!())?;
78 verify_activity_domains_valid(&update, &expected_domain, true)?;
79 check_private_message_activity_valid(&update, context, request_counter).await?;
84 .context(location_info!())?
86 let note = Note::from_any_base(object)?.context(location_info!())?;
88 let private_message_form =
89 PrivateMessageForm::from_apub(¬e, context, Some(expected_domain), request_counter).await?;
91 let private_message_ap_id = private_message_form
94 .context(location_info!())?
96 let private_message = blocking(&context.pool(), move |conn| {
97 PrivateMessage::read_from_apub_id(conn, &private_message_ap_id)
101 let private_message_id = private_message.id;
102 blocking(&context.pool(), move |conn| {
103 PrivateMessage::update(conn, private_message_id, &private_message_form)
107 let private_message_id = private_message.id;
108 let message = blocking(&context.pool(), move |conn| {
109 PrivateMessageView::read(conn, private_message_id)
113 let res = PrivateMessageResponse { message };
115 let recipient_id = res.message.recipient_id;
117 context.chat_server().do_send(SendUserRoomMessage {
118 op: UserOperation::EditPrivateMessage,
127 pub(crate) async fn receive_delete_private_message(
128 context: &LemmyContext,
130 private_message: PrivateMessage,
131 request_counter: &mut i32,
132 ) -> Result<(), LemmyError> {
133 check_private_message_activity_valid(&delete, context, request_counter).await?;
135 let deleted_private_message = blocking(context.pool(), move |conn| {
136 PrivateMessage::update_deleted(conn, private_message.id, true)
140 let message = blocking(&context.pool(), move |conn| {
141 PrivateMessageView::read(&conn, deleted_private_message.id)
145 let res = PrivateMessageResponse { message };
146 let recipient_id = res.message.recipient_id;
147 context.chat_server().do_send(SendUserRoomMessage {
148 op: UserOperation::EditPrivateMessage,
157 pub(crate) async fn receive_undo_delete_private_message(
158 context: &LemmyContext,
160 expected_domain: &Url,
161 private_message: PrivateMessage,
162 request_counter: &mut i32,
163 ) -> Result<(), LemmyError> {
164 check_private_message_activity_valid(&undo, context, request_counter).await?;
165 let object = undo.object().to_owned().one().context(location_info!())?;
166 let delete = Delete::from_any_base(object)?.context(location_info!())?;
167 verify_activity_domains_valid(&delete, expected_domain, true)?;
168 check_private_message_activity_valid(&delete, context, request_counter).await?;
170 let deleted_private_message = blocking(context.pool(), move |conn| {
171 PrivateMessage::update_deleted(conn, private_message.id, false)
175 let message = blocking(&context.pool(), move |conn| {
176 PrivateMessageView::read(&conn, deleted_private_message.id)
180 let res = PrivateMessageResponse { message };
181 let recipient_id = res.message.recipient_id;
182 context.chat_server().do_send(SendUserRoomMessage {
183 op: UserOperation::EditPrivateMessage,
192 async fn check_private_message_activity_valid<T, Kind>(
194 context: &LemmyContext,
195 request_counter: &mut i32,
196 ) -> Result<(), LemmyError>
198 T: AsBase<Kind> + AsObject<Kind> + ActorAndObjectRefExt,
200 let to_and_cc = get_activity_to_and_cc(activity)?;
201 if to_and_cc.len() != 1 {
202 return Err(anyhow!("Private message can only be addressed to one user").into());
204 if to_and_cc.contains(&public()) {
205 return Err(anyhow!("Private message cant be public").into());
207 let user_id = activity
210 .single_xsd_any_uri()
211 .context(location_info!())?;
212 check_is_apub_id_valid(&user_id)?;
213 // check that the sender is a user, not a community
214 get_or_fetch_and_upsert_user(&user_id, &context, request_counter).await?;