diff --git a/crates/api_common/src/utils.rs b/crates/api_common/src/utils.rs index 8f8ab8c547..1f72a4fd47 100644 --- a/crates/api_common/src/utils.rs +++ b/crates/api_common/src/utils.rs @@ -835,16 +835,6 @@ fn limit_expire_time(expires: DateTime) -> LemmyResult } } -pub fn check_community_valid(community: &Community) -> LemmyResult<()> { - if community.deleted || community.removed { - Err(LemmyErrorType::Deleted)? - } - if community.local_only { - return Err(LemmyErrorType::CouldntFindCommunity.into()); - } - Ok(()) -} - #[cfg(test)] mod tests { #![allow(clippy::unwrap_used)] diff --git a/crates/api_crud/src/post/create.rs b/crates/api_crud/src/post/create.rs index e4af92916c..28950c3d8b 100644 --- a/crates/api_crud/src/post/create.rs +++ b/crates/api_crud/src/post/create.rs @@ -166,20 +166,22 @@ pub async fn create_post( mark_post_as_read(person_id, post_id, &mut context.pool()).await?; if let Some(url) = updated_post.url.clone() { - spawn_try_task(async move { - let mut webmention = - Webmention::new::(updated_post.ap_id.clone().into(), url.clone().into())?; - webmention.set_checked(true); - match webmention - .send() - .instrument(tracing::info_span!("Sending webmention")) - .await - { - Err(WebmentionError::NoEndpointDiscovered(_)) => Ok(()), - Ok(_) => Ok(()), - Err(e) => Err(e).with_lemmy_type(LemmyErrorType::CouldntSendWebmention), - } - }); + if community.local_only { + spawn_try_task(async move { + let mut webmention = + Webmention::new::(updated_post.ap_id.clone().into(), url.clone().into())?; + webmention.set_checked(true); + match webmention + .send() + .instrument(tracing::info_span!("Sending webmention")) + .await + { + Err(WebmentionError::NoEndpointDiscovered(_)) => Ok(()), + Ok(_) => Ok(()), + Err(e) => Err(e).with_lemmy_type(LemmyErrorType::CouldntSendWebmention), + } + }); + } }; build_post_response(&context, community_id, &local_user_view.person, post_id).await diff --git a/crates/api_crud/src/site/read.rs b/crates/api_crud/src/site/read.rs index c340ce44be..b64503666a 100644 --- a/crates/api_crud/src/site/read.rs +++ b/crates/api_crud/src/site/read.rs @@ -79,7 +79,7 @@ pub async fn get_site( |pool| CommunityBlockView::for_person(pool, person_id), |pool| InstanceBlockView::for_person(pool, person_id), |pool| PersonBlockView::for_person(pool, person_id), - |pool| CommunityModeratorView::for_person(pool, person_id), + |pool| CommunityModeratorView::for_person(pool, person_id, true), |pool| LocalUserLanguage::read(pool, local_user_id) )) .with_lemmy_type(LemmyErrorType::SystemErrLogin)?; diff --git a/crates/apub/src/activities/following/follow.rs b/crates/apub/src/activities/following/follow.rs index 2b439f1f58..af4474c37b 100644 --- a/crates/apub/src/activities/following/follow.rs +++ b/crates/apub/src/activities/following/follow.rs @@ -25,7 +25,7 @@ use lemmy_db_schema::{ }, traits::Followable, }; -use lemmy_utils::error::LemmyError; +use lemmy_utils::error::{LemmyError, LemmyErrorType}; use url::Url; impl Follow { @@ -103,6 +103,10 @@ impl ActivityHandler for Follow { PersonFollower::follow(&mut context.pool(), &form).await?; } UserOrCommunity::Community(c) => { + // Dont allow following local-only community via federation. + if c.local_only { + return Err(LemmyErrorType::CouldntFindCommunity.into()); + } let form = CommunityFollowerForm { community_id: c.id, person_id: actor.id, diff --git a/crates/apub/src/api/read_person.rs b/crates/apub/src/api/read_person.rs index b32fc5b5f1..fd93da57de 100644 --- a/crates/apub/src/api/read_person.rs +++ b/crates/apub/src/api/read_person.rs @@ -86,8 +86,12 @@ pub async fn read_person( .list(&mut context.pool()) .await?; - let moderates = - CommunityModeratorView::for_person(&mut context.pool(), person_details_id).await?; + let moderates = CommunityModeratorView::for_person( + &mut context.pool(), + person_details_id, + local_user_view.is_some(), + ) + .await?; // Return the jwt Ok(Json(GetPersonDetailsResponse { diff --git a/crates/apub/src/http/comment.rs b/crates/apub/src/http/comment.rs index 4df3a3b1b1..db18ca6dc1 100644 --- a/crates/apub/src/http/comment.rs +++ b/crates/apub/src/http/comment.rs @@ -1,10 +1,15 @@ use crate::{ - http::{create_apub_response, create_apub_tombstone_response, redirect_remote_object}, + http::{ + check_community_valid, + create_apub_response, + create_apub_tombstone_response, + redirect_remote_object, + }, objects::comment::ApubComment, }; use activitypub_federation::{config::Data, traits::Object}; use actix_web::{web::Path, HttpResponse}; -use lemmy_api_common::{context::LemmyContext, utils::check_community_valid}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ newtypes::CommentId, source::{comment::Comment, community::Community, post::Post}, diff --git a/crates/apub/src/http/community.rs b/crates/apub/src/http/community.rs index 54277e8e7c..eab3001001 100644 --- a/crates/apub/src/http/community.rs +++ b/crates/apub/src/http/community.rs @@ -6,7 +6,7 @@ use crate::{ community_moderators::ApubCommunityModerators, community_outbox::ApubCommunityOutbox, }, - http::{create_apub_response, create_apub_tombstone_response}, + http::{check_community_valid, create_apub_response, create_apub_tombstone_response}, objects::{community::ApubCommunity, person::ApubPerson}, }; use activitypub_federation::{ @@ -16,7 +16,7 @@ use activitypub_federation::{ traits::{Collection, Object}, }; use actix_web::{web, web::Bytes, HttpRequest, HttpResponse}; -use lemmy_api_common::{context::LemmyContext, utils::check_community_valid}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{source::community::Community, traits::ApubActor}; use lemmy_utils::error::LemmyError; use serde::Deserialize; @@ -132,7 +132,7 @@ pub(crate) mod tests { }, traits::Crud, }; - use lemmy_utils::error::{LemmyErrorType, LemmyResult}; + use lemmy_utils::error::LemmyResult; use serde::de::DeserializeOwned; use serial_test::serial; diff --git a/crates/apub/src/http/mod.rs b/crates/apub/src/http/mod.rs index d3e925de49..762b726d7b 100644 --- a/crates/apub/src/http/mod.rs +++ b/crates/apub/src/http/mod.rs @@ -13,8 +13,11 @@ use activitypub_federation::{ use actix_web::{web, web::Bytes, HttpRequest, HttpResponse}; use http::{header::LOCATION, StatusCode}; use lemmy_api_common::context::LemmyContext; -use lemmy_db_schema::{newtypes::DbUrl, source::activity::SentActivity}; -use lemmy_utils::error::{LemmyError, LemmyResult}; +use lemmy_db_schema::{ + newtypes::DbUrl, + source::{activity::SentActivity, community::Community}, +}; +use lemmy_utils::error::{LemmyError, LemmyErrorType, LemmyResult}; use serde::{Deserialize, Serialize}; use std::ops::Deref; use url::Url; @@ -106,3 +109,13 @@ pub(crate) async fn get_activity( ) } } + +pub fn check_community_valid(community: &Community) -> LemmyResult<()> { + if community.deleted || community.removed { + Err(LemmyErrorType::Deleted)? + } + if community.local_only { + return Err(LemmyErrorType::CouldntFindCommunity.into()); + } + Ok(()) +} diff --git a/crates/apub/src/http/post.rs b/crates/apub/src/http/post.rs index e459293169..eff63dbc57 100644 --- a/crates/apub/src/http/post.rs +++ b/crates/apub/src/http/post.rs @@ -1,10 +1,15 @@ use crate::{ - http::{create_apub_response, create_apub_tombstone_response, redirect_remote_object}, + http::{ + check_community_valid, + create_apub_response, + create_apub_tombstone_response, + redirect_remote_object, + }, objects::post::ApubPost, }; use activitypub_federation::{config::Data, traits::Object}; use actix_web::{web, HttpResponse}; -use lemmy_api_common::{context::LemmyContext, utils::check_community_valid}; +use lemmy_api_common::context::LemmyContext; use lemmy_db_schema::{ newtypes::PostId, source::{community::Community, post::Post}, diff --git a/crates/db_views_actor/src/community_moderator_view.rs b/crates/db_views_actor/src/community_moderator_view.rs index cab4e2a092..c0d11fab46 100644 --- a/crates/db_views_actor/src/community_moderator_view.rs +++ b/crates/db_views_actor/src/community_moderator_view.rs @@ -56,17 +56,24 @@ impl CommunityModeratorView { .await } - pub async fn for_person(pool: &mut DbPool<'_>, person_id: PersonId) -> Result, Error> { + pub async fn for_person( + pool: &mut DbPool<'_>, + person_id: PersonId, + is_authenticated: bool, + ) -> Result, Error> { let conn = &mut get_conn(pool).await?; - community_moderator::table + let mut query = community_moderator::table .inner_join(community::table) .inner_join(person::table) .filter(community_moderator::person_id.eq(person_id)) .filter(community::deleted.eq(false)) .filter(community::removed.eq(false)) .select((community::all_columns, person::all_columns)) - .load::(conn) - .await + .into_boxed(); + if !is_authenticated { + query = query.filter(community::local_only.eq(false)); + } + query.load::(conn).await } /// Finds all communities first mods / creators diff --git a/crates/routes/src/feeds.rs b/crates/routes/src/feeds.rs index 56c75a6254..610860f502 100644 --- a/crates/routes/src/feeds.rs +++ b/crates/routes/src/feeds.rs @@ -21,7 +21,7 @@ use lemmy_db_views_actor::{ }; use lemmy_utils::{ cache_header::cache_1hour, - error::LemmyError, + error::{LemmyError, LemmyErrorType}, utils::markdown::{markdown_to_html, sanitize_html}, }; use once_cell::sync::Lazy; @@ -268,6 +268,9 @@ async fn get_feed_community( ) -> Result { let site_view = SiteView::read_local(&mut context.pool()).await?; let community = Community::read_from_name(&mut context.pool(), community_name, false).await?; + if community.local_only { + return Err(LemmyErrorType::CouldntFindCommunity.into()); + } check_private_instance(&None, &site_view.local_site)?; diff --git a/crates/utils/translations b/crates/utils/translations index 15815aea74..06a610696a 160000 --- a/crates/utils/translations +++ b/crates/utils/translations @@ -1 +1 @@ -Subproject commit 15815aea74fe97360afc03496b3ad62588649af0 +Subproject commit 06a610696af829248954e411ebe2cf3906092244