X-Git-Url: http://these/git/?a=blobdiff_plain;f=crates%2Fapi_crud%2Fsrc%2Fcommunity%2Fupdate.rs;h=128be036fd241529c64e4d76a7907b0c77ecea4e;hb=3471f3533cb724b2cf6953d563aadfcc9f66c1d2;hp=b7352a62408837a8f50e66198f7e20bbeed984e8;hpb=166ec196b02d82115ab178588604f4a780d0c135;p=lemmy.git diff --git a/crates/api_crud/src/community/update.rs b/crates/api_crud/src/community/update.rs index b7352a62..128be036 100644 --- a/crates/api_crud/src/community/update.rs +++ b/crates/api_crud/src/community/update.rs @@ -1,158 +1,86 @@ use crate::PerformCrud; use actix_web::web::Data; use lemmy_api_common::{ - blocking, - community::{CommunityResponse, EditCommunity, HideCommunity}, - get_local_user_view_from_jwt, - is_admin, + build_response::build_community_response, + community::{CommunityResponse, EditCommunity}, + context::LemmyContext, + utils::{local_site_to_slur_regex, local_user_view_from_jwt, sanitize_html_opt}, }; -use lemmy_apub::protocol::activities::community::update::UpdateCommunity; use lemmy_db_schema::{ - diesel_option_overwrite_to_url, - naive_now, newtypes::PersonId, source::{ - community::{Community, CommunityForm}, - moderator::{ModHideCommunity, ModHideCommunityForm}, + actor_language::{CommunityLanguage, SiteLanguage}, + community::{Community, CommunityUpdateForm}, + local_site::LocalSite, }, traits::Crud, + utils::{diesel_option_overwrite, diesel_option_overwrite_to_url, naive_now}, +}; +use lemmy_db_views_actor::structs::CommunityModeratorView; +use lemmy_utils::{ + error::{LemmyError, LemmyErrorExt, LemmyErrorType}, + utils::{slurs::check_slurs_opt, validation::is_valid_body_field}, }; -use lemmy_db_views_actor::community_moderator_view::CommunityModeratorView; -use lemmy_utils::{utils::check_slurs_opt, ConnectionId, LemmyError}; -use lemmy_websocket::{send::send_community_ws_message, LemmyContext, UserOperationCrud}; #[async_trait::async_trait(?Send)] impl PerformCrud for EditCommunity { type Response = CommunityResponse; - #[tracing::instrument(skip(context, websocket_id))] - async fn perform( - &self, - context: &Data, - websocket_id: Option, - ) -> Result { + #[tracing::instrument(skip(context))] + async fn perform(&self, context: &Data) -> Result { let data: &EditCommunity = self; - let local_user_view = - get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - - check_slurs_opt(&data.title, &context.settings().slur_regex())?; - check_slurs_opt(&data.description, &context.settings().slur_regex())?; + let local_user_view = local_user_view_from_jwt(&data.auth, context).await?; + let local_site = LocalSite::read(&mut context.pool()).await?; - // Verify its a mod (only mods can edit it) - let community_id = data.community_id; - let mods: Vec = blocking(context.pool(), move |conn| { - CommunityModeratorView::for_community(conn, community_id) - .map(|v| v.into_iter().map(|m| m.moderator.id).collect()) - }) - .await??; - if !mods.contains(&local_user_view.person.id) { - return Err(LemmyError::from_message("not_a_moderator")); - } + let slur_regex = local_site_to_slur_regex(&local_site); + check_slurs_opt(&data.title, &slur_regex)?; + check_slurs_opt(&data.description, &slur_regex)?; + is_valid_body_field(&data.description, false)?; - let community_id = data.community_id; - let read_community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; + let title = sanitize_html_opt(&data.title); + let description = sanitize_html_opt(&data.description); let icon = diesel_option_overwrite_to_url(&data.icon)?; let banner = diesel_option_overwrite_to_url(&data.banner)?; + let description = diesel_option_overwrite(description); - let community_form = CommunityForm { - name: read_community.name, - title: data.title.to_owned().unwrap_or(read_community.title), - description: data.description.to_owned(), - public_key: read_community.public_key, - icon, - banner, - nsfw: data.nsfw, - hidden: Some(read_community.hidden), - updated: Some(naive_now()), - ..CommunityForm::default() - }; - + // Verify its a mod (only mods can edit it) let community_id = data.community_id; - let updated_community = blocking(context.pool(), move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community"))?; - - UpdateCommunity::send( - updated_community.into(), - &local_user_view.person.into(), - context, - ) - .await?; - - let op = UserOperationCrud::EditCommunity; - send_community_ws_message(data.community_id, op, websocket_id, None, context).await - } -} - -#[async_trait::async_trait(?Send)] -impl PerformCrud for HideCommunity { - type Response = CommunityResponse; - - #[tracing::instrument(skip(context, websocket_id))] - async fn perform( - &self, - context: &Data, - websocket_id: Option, - ) -> Result { - let data: &HideCommunity = self; - - // Verify its a admin (only admin can hide or unhide it) - let local_user_view = - get_local_user_view_from_jwt(&data.auth, context.pool(), context.secret()).await?; - is_admin(&local_user_view)?; + let mods: Vec = + CommunityModeratorView::for_community(&mut context.pool(), community_id) + .await + .map(|v| v.into_iter().map(|m| m.moderator.id).collect())?; + if !mods.contains(&local_user_view.person.id) { + return Err(LemmyErrorType::NotAModerator)?; + } let community_id = data.community_id; - let read_community = blocking(context.pool(), move |conn| { - Community::read(conn, community_id) - }) - .await??; - - let community_form = CommunityForm { - name: read_community.name, - title: read_community.title, - description: read_community.description.to_owned(), - public_key: read_community.public_key, - icon: Some(read_community.icon), - banner: Some(read_community.banner), - nsfw: Some(read_community.nsfw), - updated: Some(naive_now()), - hidden: Some(data.hidden), - ..CommunityForm::default() - }; + if let Some(languages) = data.discussion_languages.clone() { + let site_languages = SiteLanguage::read_local_raw(&mut context.pool()).await?; + // check that community languages are a subset of site languages + // https://stackoverflow.com/a/64227550 + let is_subset = languages.iter().all(|item| site_languages.contains(item)); + if !is_subset { + return Err(LemmyErrorType::LanguageNotAllowed)?; + } + CommunityLanguage::update(&mut context.pool(), languages, community_id).await?; + } - let mod_hide_community_form = ModHideCommunityForm { - community_id: data.community_id, - mod_person_id: local_user_view.person.id, - reason: data.reason.clone(), - hidden: Some(data.hidden), - }; + let community_form = CommunityUpdateForm::builder() + .title(title) + .description(description) + .icon(icon) + .banner(banner) + .nsfw(data.nsfw) + .posting_restricted_to_mods(data.posting_restricted_to_mods) + .updated(Some(Some(naive_now()))) + .build(); let community_id = data.community_id; - let updated_community = blocking(context.pool(), move |conn| { - Community::update(conn, community_id, &community_form) - }) - .await? - .map_err(|e| LemmyError::from_error_message(e, "couldnt_update_community_hidden_status"))?; - - blocking(context.pool(), move |conn| { - ModHideCommunity::create(conn, &mod_hide_community_form) - }) - .await??; - - UpdateCommunity::send( - updated_community.into(), - &local_user_view.person.into(), - context, - ) - .await?; + Community::update(&mut context.pool(), community_id, &community_form) + .await + .with_lemmy_type(LemmyErrorType::CouldntUpdateCommunity)?; - let op = UserOperationCrud::EditCommunity; - send_community_ws_message(data.community_id, op, websocket_id, None, context).await + build_community_response(context, local_user_view, community_id).await } }