]> Untitled Git - lemmy.git/blob - lemmy_apub/src/activities/receive/private_message.rs
Some API cleanup, adding site_id to site aggregates.
[lemmy.git] / lemmy_apub / src / activities / receive / private_message.rs
1 use crate::{
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,
6   objects::FromApub,
7   NoteExt,
8 };
9 use activitystreams::{
10   activity::{ActorAndObjectRefExt, Create, Delete, Undo, Update},
11   base::{AsBase, ExtendsExt},
12   object::AsObject,
13   public,
14 };
15 use anyhow::{anyhow, Context};
16 use lemmy_db::{
17   source::private_message::PrivateMessage,
18   views::private_message_view::PrivateMessageView,
19 };
20 use lemmy_structs::{blocking, user::PrivateMessageResponse};
21 use lemmy_utils::{location_info, LemmyError};
22 use lemmy_websocket::{messages::SendUserRoomMessage, LemmyContext, UserOperation};
23 use url::Url;
24
25 pub(crate) async fn receive_create_private_message(
26   context: &LemmyContext,
27   create: Create,
28   expected_domain: Url,
29   request_counter: &mut i32,
30 ) -> Result<(), LemmyError> {
31   check_private_message_activity_valid(&create, context, request_counter).await?;
32
33   let note = NoteExt::from_any_base(
34     create
35       .object()
36       .as_one()
37       .context(location_info!())?
38       .to_owned(),
39   )?
40   .context(location_info!())?;
41
42   let private_message =
43     PrivateMessage::from_apub(&note, context, expected_domain, request_counter).await?;
44
45   let message = blocking(&context.pool(), move |conn| {
46     PrivateMessageView::read(conn, private_message.id)
47   })
48   .await??;
49
50   let res = PrivateMessageResponse {
51     private_message_view: message,
52   };
53
54   let recipient_id = res.private_message_view.recipient.id;
55
56   context.chat_server().do_send(SendUserRoomMessage {
57     op: UserOperation::CreatePrivateMessage,
58     response: res,
59     recipient_id,
60     websocket_id: None,
61   });
62
63   Ok(())
64 }
65
66 pub(crate) async fn receive_update_private_message(
67   context: &LemmyContext,
68   update: Update,
69   expected_domain: Url,
70   request_counter: &mut i32,
71 ) -> Result<(), LemmyError> {
72   check_private_message_activity_valid(&update, context, request_counter).await?;
73
74   let object = update
75     .object()
76     .as_one()
77     .context(location_info!())?
78     .to_owned();
79   let note = NoteExt::from_any_base(object)?.context(location_info!())?;
80
81   let private_message =
82     PrivateMessage::from_apub(&note, context, expected_domain, request_counter).await?;
83
84   let private_message_id = private_message.id;
85   let message = blocking(&context.pool(), move |conn| {
86     PrivateMessageView::read(conn, private_message_id)
87   })
88   .await??;
89
90   let res = PrivateMessageResponse {
91     private_message_view: message,
92   };
93
94   let recipient_id = res.private_message_view.recipient.id;
95
96   context.chat_server().do_send(SendUserRoomMessage {
97     op: UserOperation::EditPrivateMessage,
98     response: res,
99     recipient_id,
100     websocket_id: None,
101   });
102
103   Ok(())
104 }
105
106 pub(crate) async fn receive_delete_private_message(
107   context: &LemmyContext,
108   delete: Delete,
109   private_message: PrivateMessage,
110   request_counter: &mut i32,
111 ) -> Result<(), LemmyError> {
112   check_private_message_activity_valid(&delete, context, request_counter).await?;
113
114   let deleted_private_message = blocking(context.pool(), move |conn| {
115     PrivateMessage::update_deleted(conn, private_message.id, true)
116   })
117   .await??;
118
119   let message = blocking(&context.pool(), move |conn| {
120     PrivateMessageView::read(&conn, deleted_private_message.id)
121   })
122   .await??;
123
124   let res = PrivateMessageResponse {
125     private_message_view: message,
126   };
127   let recipient_id = res.private_message_view.recipient.id;
128   context.chat_server().do_send(SendUserRoomMessage {
129     op: UserOperation::EditPrivateMessage,
130     response: res,
131     recipient_id,
132     websocket_id: None,
133   });
134
135   Ok(())
136 }
137
138 pub(crate) async fn receive_undo_delete_private_message(
139   context: &LemmyContext,
140   undo: Undo,
141   expected_domain: &Url,
142   private_message: PrivateMessage,
143   request_counter: &mut i32,
144 ) -> Result<(), LemmyError> {
145   check_private_message_activity_valid(&undo, context, request_counter).await?;
146   let object = undo.object().to_owned().one().context(location_info!())?;
147   let delete = Delete::from_any_base(object)?.context(location_info!())?;
148   verify_activity_domains_valid(&delete, expected_domain, true)?;
149   check_private_message_activity_valid(&delete, context, request_counter).await?;
150
151   let deleted_private_message = blocking(context.pool(), move |conn| {
152     PrivateMessage::update_deleted(conn, private_message.id, false)
153   })
154   .await??;
155
156   let message = blocking(&context.pool(), move |conn| {
157     PrivateMessageView::read(&conn, deleted_private_message.id)
158   })
159   .await??;
160
161   let res = PrivateMessageResponse {
162     private_message_view: message,
163   };
164   let recipient_id = res.private_message_view.recipient.id;
165   context.chat_server().do_send(SendUserRoomMessage {
166     op: UserOperation::EditPrivateMessage,
167     response: res,
168     recipient_id,
169     websocket_id: None,
170   });
171
172   Ok(())
173 }
174
175 async fn check_private_message_activity_valid<T, Kind>(
176   activity: &T,
177   context: &LemmyContext,
178   request_counter: &mut i32,
179 ) -> Result<(), LemmyError>
180 where
181   T: AsBase<Kind> + AsObject<Kind> + ActorAndObjectRefExt,
182 {
183   let to_and_cc = get_activity_to_and_cc(activity);
184   if to_and_cc.len() != 1 {
185     return Err(anyhow!("Private message can only be addressed to one user").into());
186   }
187   if to_and_cc.contains(&public()) {
188     return Err(anyhow!("Private message cant be public").into());
189   }
190   let user_id = activity
191     .actor()?
192     .to_owned()
193     .single_xsd_any_uri()
194     .context(location_info!())?;
195   check_is_apub_id_valid(&user_id)?;
196   // check that the sender is a user, not a community
197   get_or_fetch_and_upsert_user(&user_id, &context, request_counter).await?;
198
199   Ok(())
200 }