]> Untitled Git - lemmy.git/blob - crates/api/src/local_user/ban_person.rs
Split apart api files (#2216)
[lemmy.git] / crates / api / src / local_user / ban_person.rs
1 use crate::Perform;
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   blocking,
5   get_local_user_view_from_jwt,
6   is_admin,
7   person::{BanPerson, BanPersonResponse},
8   remove_user_data,
9 };
10 use lemmy_apub::{
11   activities::block::SiteOrCommunity,
12   protocol::activities::block::{block_user::BlockUser, undo_block_user::UndoBlockUser},
13 };
14 use lemmy_db_schema::{
15   source::{
16     moderator::{ModBan, ModBanForm},
17     person::Person,
18     site::Site,
19   },
20   traits::Crud,
21 };
22 use lemmy_db_views_actor::person_view::PersonViewSafe;
23 use lemmy_utils::{utils::naive_from_unix, ConnectionId, LemmyError};
24 use lemmy_websocket::{messages::SendAllMessage, LemmyContext, UserOperation};
25
26 #[async_trait::async_trait(?Send)]
27 impl Perform for BanPerson {
28   type Response = BanPersonResponse;
29
30   #[tracing::instrument(skip(context, websocket_id))]
31   async fn perform(
32     &self,
33     context: &Data<LemmyContext>,
34     websocket_id: Option<ConnectionId>,
35   ) -> Result<BanPersonResponse, LemmyError> {
36     let data: &BanPerson = self;
37     let local_user_view =
38       get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?;
39
40     // Make sure user is an admin
41     is_admin(&local_user_view)?;
42
43     let ban = data.ban;
44     let banned_person_id = data.person_id;
45     let expires = data.expires.map(naive_from_unix);
46
47     let ban_person = move |conn: &'_ _| Person::ban_person(conn, banned_person_id, ban, expires);
48     let person = blocking(context.pool(), ban_person)
49       .await?
50       .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_user"))?;
51
52     // Remove their data if that's desired
53     let remove_data = data.remove_data.unwrap_or(false);
54     if remove_data {
55       remove_user_data(person.id, context.pool()).await?;
56     }
57
58     // Mod tables
59     let form = ModBanForm {
60       mod_person_id: local_user_view.person.id,
61       other_person_id: data.person_id,
62       reason: data.reason.to_owned(),
63       banned: Some(data.ban),
64       expires,
65     };
66
67     blocking(context.pool(), move |conn| ModBan::create(conn, &form)).await??;
68
69     let person_id = data.person_id;
70     let person_view = blocking(context.pool(), move |conn| {
71       PersonViewSafe::read(conn, person_id)
72     })
73     .await??;
74
75     let site = SiteOrCommunity::Site(
76       blocking(context.pool(), Site::read_local_site)
77         .await??
78         .into(),
79     );
80     // if the action affects a local user, federate to other instances
81     if person.local {
82       if ban {
83         BlockUser::send(
84           &site,
85           &person.into(),
86           &local_user_view.person.into(),
87           remove_data,
88           data.reason.clone(),
89           expires,
90           context,
91         )
92         .await?;
93       } else {
94         UndoBlockUser::send(
95           &site,
96           &person.into(),
97           &local_user_view.person.into(),
98           data.reason.clone(),
99           context,
100         )
101         .await?;
102       }
103     }
104
105     let res = BanPersonResponse {
106       person_view,
107       banned: data.ban,
108     };
109
110     context.chat_server().do_send(SendAllMessage {
111       op: UserOperation::BanPerson,
112       response: res.clone(),
113       websocket_id,
114     });
115
116     Ok(res)
117   }
118 }