From 8803e7834fc145418fed62e592258f18303c2e2e Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Mon, 9 Nov 2020 15:29:36 +0100 Subject: [PATCH] Enforce site and community bans for federated users --- lemmy_api/src/user.rs | 4 +- lemmy_apub/src/inbox/community_inbox.rs | 39 +++++++++++++++---- lemmy_apub/src/inbox/receive_for_community.rs | 2 - lemmy_apub/src/objects/user.rs | 2 +- lemmy_db/src/user.rs | 2 +- src/code_migrations.rs | 2 +- 6 files changed, 36 insertions(+), 15 deletions(-) diff --git a/lemmy_api/src/user.rs b/lemmy_api/src/user.rs index 6dffc1a7..41f77271 100644 --- a/lemmy_api/src/user.rs +++ b/lemmy_api/src/user.rs @@ -175,7 +175,7 @@ impl Perform for Register { published: None, updated: None, admin: data.admin, - banned: false, + banned: Some(false), show_nsfw: data.show_nsfw, theme: "browser".into(), default_sort_type: SortType::Active as i16, @@ -407,7 +407,7 @@ impl Perform for SaveUserSettings { published: Some(read_user.published), updated: Some(naive_now()), admin: read_user.admin, - banned: read_user.banned, + banned: Some(read_user.banned), show_nsfw: data.show_nsfw, theme: data.theme.to_owned(), default_sort_type: data.default_sort_type, diff --git a/lemmy_apub/src/inbox/community_inbox.rs b/lemmy_apub/src/inbox/community_inbox.rs index 630a2db9..6cd4a017 100644 --- a/lemmy_apub/src/inbox/community_inbox.rs +++ b/lemmy_apub/src/inbox/community_inbox.rs @@ -27,7 +27,9 @@ use actix_web::{web, HttpRequest, HttpResponse}; use anyhow::{anyhow, Context}; use lemmy_db::{ community::{Community, CommunityFollower, CommunityFollowerForm}, + community_view::CommunityUserBanView, user::User_, + DbPool, Followable, }; use lemmy_structs::blocking; @@ -110,14 +112,21 @@ pub(crate) async fn community_receive_message( context: &LemmyContext, request_counter: &mut i32, ) -> Result { - // TODO: check if the sending user is banned by the community + // Only users can send activities to the community, so we can get the actor as user + // unconditionally. + let actor_id = actor.actor_id_str(); + let user = blocking(&context.pool(), move |conn| { + User_::read_from_actor_id(&conn, &actor_id) + }) + .await??; + check_community_or_site_ban(&user, &to_community, context.pool()).await?; let any_base = activity.clone().into_any_base()?; let actor_url = actor.actor_id()?; let activity_kind = activity.kind().context(location_info!())?; let do_announce = match activity_kind { CommunityValidTypes::Follow => { - handle_follow(any_base.clone(), actor_url, &to_community, &context).await?; + handle_follow(any_base.clone(), user, &to_community, &context).await?; false } CommunityValidTypes::Undo => { @@ -172,17 +181,13 @@ pub(crate) async fn community_receive_message( /// Accept activity. async fn handle_follow( activity: AnyBase, - user_url: Url, + user: User_, community: &Community, context: &LemmyContext, ) -> Result { let follow = Follow::from_any_base(activity)?.context(location_info!())?; - verify_activity_domains_valid(&follow, &user_url, false)?; + verify_activity_domains_valid(&follow, &user.actor_id()?, false)?; - let user = blocking(&context.pool(), move |conn| { - User_::read_from_actor_id(&conn, user_url.as_str()) - }) - .await??; let community_follower_form = CommunityFollowerForm { community_id: community.id, user_id: user.id, @@ -250,3 +255,21 @@ async fn handle_undo_follow( Ok(()) } + +async fn check_community_or_site_ban( + user: &User_, + community: &Community, + pool: &DbPool, +) -> Result<(), LemmyError> { + if user.banned { + return Err(anyhow!("User is banned from site").into()); + } + let user_id = user.id; + let community_id = community.id; + let is_banned = move |conn: &'_ _| CommunityUserBanView::get(conn, user_id, community_id).is_ok(); + if blocking(pool, is_banned).await? { + return Err(anyhow!("User is banned from community").into()); + } + + Ok(()) +} diff --git a/lemmy_apub/src/inbox/receive_for_community.rs b/lemmy_apub/src/inbox/receive_for_community.rs index d4cd43d7..b6dfa1e4 100644 --- a/lemmy_apub/src/inbox/receive_for_community.rs +++ b/lemmy_apub/src/inbox/receive_for_community.rs @@ -135,7 +135,6 @@ pub(in crate::inbox) async fn receive_delete_for_community( activity: AnyBase, expected_domain: &Url, ) -> Result<(), LemmyError> { - dbg!("receive_delete_for_community"); let delete = Delete::from_any_base(activity)?.context(location_info!())?; verify_activity_domains_valid(&delete, &expected_domain, true)?; is_addressed_to_public(&delete)?; @@ -160,7 +159,6 @@ pub(in crate::inbox) async fn receive_remove_for_community( activity: AnyBase, expected_domain: &Url, ) -> Result<(), LemmyError> { - dbg!("receive_remove_for_community"); let remove = Remove::from_any_base(activity)?.context(location_info!())?; verify_activity_domains_valid(&remove, &expected_domain, false)?; is_addressed_to_public(&remove)?; diff --git a/lemmy_apub/src/objects/user.rs b/lemmy_apub/src/objects/user.rs index 5ef1ec8e..3c41b558 100644 --- a/lemmy_apub/src/objects/user.rs +++ b/lemmy_apub/src/objects/user.rs @@ -132,7 +132,7 @@ impl FromApub for UserForm { preferred_username: Some(preferred_username), password_encrypted: "".to_string(), admin: false, - banned: false, + banned: None, email: None, avatar, banner, diff --git a/lemmy_db/src/user.rs b/lemmy_db/src/user.rs index db8a999e..8dc613bb 100644 --- a/lemmy_db/src/user.rs +++ b/lemmy_db/src/user.rs @@ -46,7 +46,7 @@ pub struct UserForm { pub preferred_username: Option>, pub password_encrypted: String, pub admin: bool, - pub banned: bool, + pub banned: Option, pub email: Option>, pub avatar: Option>, pub published: Option, diff --git a/src/code_migrations.rs b/src/code_migrations.rs index adc4ae49..c41f5bd9 100644 --- a/src/code_migrations.rs +++ b/src/code_migrations.rs @@ -57,7 +57,7 @@ fn user_updates_2020_04_02(conn: &PgConnection) -> Result<(), LemmyError> { published: Some(cuser.published), updated: None, admin: cuser.admin, - banned: cuser.banned, + banned: Some(cuser.banned), show_nsfw: cuser.show_nsfw, theme: cuser.theme.to_owned(), default_sort_type: cuser.default_sort_type,