]> Untitled Git - lemmy.git/blob - crates/api_crud/src/community/update.rs
Fix API and clippy warnings
[lemmy.git] / crates / api_crud / src / community / update.rs
1 use crate::{community::send_community_websocket, PerformCrud};
2 use actix_web::web::Data;
3 use lemmy_api_common::{
4   blocking,
5   community::{CommunityResponse, EditCommunity},
6   get_local_user_view_from_jwt,
7 };
8 use lemmy_db_queries::{diesel_option_overwrite_to_url, Crud};
9 use lemmy_db_schema::{
10   naive_now,
11   source::community::{Community, CommunityForm},
12   PersonId,
13 };
14 use lemmy_db_views_actor::{
15   community_moderator_view::CommunityModeratorView,
16   community_view::CommunityView,
17 };
18 use lemmy_utils::{
19   utils::{check_slurs, check_slurs_opt},
20   ApiError,
21   ConnectionId,
22   LemmyError,
23 };
24 use lemmy_websocket::{LemmyContext, UserOperationCrud};
25
26 #[async_trait::async_trait(?Send)]
27 impl PerformCrud for EditCommunity {
28   type Response = CommunityResponse;
29
30   async fn perform(
31     &self,
32     context: &Data<LemmyContext>,
33     websocket_id: Option<ConnectionId>,
34   ) -> Result<CommunityResponse, LemmyError> {
35     let data: &EditCommunity = &self;
36     let local_user_view = get_local_user_view_from_jwt(&data.auth, context.pool()).await?;
37
38     check_slurs(&data.title)?;
39     check_slurs_opt(&data.description)?;
40
41     // Verify its a mod (only mods can edit it)
42     let community_id = data.community_id;
43     let mods: Vec<PersonId> = blocking(context.pool(), move |conn| {
44       CommunityModeratorView::for_community(conn, community_id)
45         .map(|v| v.into_iter().map(|m| m.moderator.id).collect())
46     })
47     .await??;
48     if !mods.contains(&local_user_view.person.id) {
49       return Err(ApiError::err("not_a_moderator").into());
50     }
51
52     let community_id = data.community_id;
53     let read_community = blocking(context.pool(), move |conn| {
54       Community::read(conn, community_id)
55     })
56     .await??;
57
58     let icon = diesel_option_overwrite_to_url(&data.icon)?;
59     let banner = diesel_option_overwrite_to_url(&data.banner)?;
60
61     let community_form = CommunityForm {
62       name: read_community.name,
63       title: data.title.to_owned(),
64       description: data.description.to_owned(),
65       icon,
66       banner,
67       creator_id: read_community.creator_id,
68       removed: Some(read_community.removed),
69       deleted: Some(read_community.deleted),
70       nsfw: data.nsfw,
71       updated: Some(naive_now()),
72       actor_id: Some(read_community.actor_id),
73       local: read_community.local,
74       private_key: read_community.private_key,
75       public_key: read_community.public_key,
76       last_refreshed_at: None,
77       published: None,
78       followers_url: None,
79       inbox_url: None,
80       shared_inbox_url: None,
81     };
82
83     let community_id = data.community_id;
84     match blocking(context.pool(), move |conn| {
85       Community::update(conn, community_id, &community_form)
86     })
87     .await?
88     {
89       Ok(community) => community,
90       Err(_e) => return Err(ApiError::err("couldnt_update_community").into()),
91     };
92
93     // TODO there needs to be some kind of an apub update
94     // process for communities and users
95
96     let community_id = data.community_id;
97     let person_id = local_user_view.person.id;
98     let community_view = blocking(context.pool(), move |conn| {
99       CommunityView::read(conn, community_id, Some(person_id))
100     })
101     .await??;
102
103     let res = CommunityResponse { community_view };
104
105     send_community_websocket(
106       &res,
107       context,
108       websocket_id,
109       UserOperationCrud::EditCommunity,
110     );
111
112     Ok(res)
113   }
114 }