Skip to content

Receive and store remote site bans (fixes #3399) #5515

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 35 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
08a324c
Receive and store remote site bans (fixes #3399)
Nutomic Mar 17, 2025
a47e48d
db schema changes, handly expiration
Nutomic Mar 17, 2025
900eb1d
partial federation changes
Nutomic Mar 17, 2025
aa8767c
add column `mod_ban.instance_id`
Nutomic Mar 18, 2025
858621a
remove unused
Nutomic Mar 18, 2025
71e1e19
wip: remove person.banned
Nutomic Mar 18, 2025
f60f6fd
fix down migration
Nutomic Mar 18, 2025
2ad4caf
fmt, keep banned status
Nutomic Mar 18, 2025
11d69db
fixes
Nutomic Mar 18, 2025
0eac34e
simplify
Nutomic Mar 18, 2025
2302931
update post removed
Nutomic Mar 18, 2025
d19200f
Merge branch 'main' into site-person-ban
Nutomic Mar 18, 2025
49f7636
Merge branch 'main' into site-person-ban
Nutomic Mar 19, 2025
da732c0
fix api tests
Nutomic Mar 19, 2025
44ed5f2
ban from local instance
Nutomic Mar 20, 2025
cbde6c5
banned() helpers
Nutomic Mar 20, 2025
34ef0cb
cleanup undo_block_user
Nutomic Mar 20, 2025
e65ee24
remove order by
Nutomic Mar 20, 2025
e6690b0
cache SiteView::read_local, add instance
Nutomic Mar 25, 2025
5879013
use local instance id for PersonView
Nutomic Mar 25, 2025
ac07ba7
add helper function person_with_instance_actions
Nutomic Mar 25, 2025
00a6554
use exists
Nutomic Mar 25, 2025
81503dc
comments update removed
Nutomic Mar 25, 2025
02e79c2
remove method is_mod_or_admin
Nutomic Mar 25, 2025
a943060
fix tests
Nutomic Mar 25, 2025
d1473c2
no unwrap
Nutomic Mar 25, 2025
564c7da
change local_instance_person_join
Nutomic Mar 25, 2025
afcdb56
remove LocalSite::read
Nutomic Mar 26, 2025
b805891
wip: home_instance_actions
Nutomic Mar 26, 2025
d79a934
add home_instance_actions to all structs
Nutomic Mar 26, 2025
7acc461
fixes
Nutomic Mar 27, 2025
1e6e1b9
fix tests
Nutomic Mar 27, 2025
27f1eb9
fmt
Nutomic Mar 27, 2025
f538d83
Merge branch 'main' into site-person-ban
Nutomic Mar 28, 2025
22131e2
Merge branch 'main' into site-person-ban
dessalines Mar 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api_tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"eslint": "^9.20.0",
"eslint-plugin-prettier": "^5.2.3",
"jest": "^29.5.0",
"lemmy-js-client": "1.0.0-action-structs.1",
"lemmy-js-client": "1.0.0-site-person-ban.1",
"prettier": "^3.5.0",
"ts-jest": "^29.1.0",
"tsoa": "^6.6.0",
Expand Down
10 changes: 5 additions & 5 deletions api_tests/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 30 additions & 19 deletions api_tests/src/post.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
getMyUser,
listInbox,
getModlog,
getCommunity,
} from "./shared";
import { PostView } from "lemmy-js-client/dist/types/PostView";
import { AdminBlockInstanceParams } from "lemmy-js-client/dist/types/AdminBlockInstanceParams";
Expand Down Expand Up @@ -461,7 +462,7 @@ test("Search for a post", async () => {
expect(betaPost?.post.name).toBeDefined();
});

test("Enforce site ban federation for local user", async () => {
test.only("Enforce site ban federation for local user", async () => {
if (!betaCommunity) {
throw "Missing beta community";
}
Expand Down Expand Up @@ -499,9 +500,11 @@ test("Enforce site ban federation for local user", async () => {
// alpha ban should be federated to beta
let alphaUserOnBeta1 = await waitUntil(
() => resolvePerson(beta, alphaUserActorId!),
res => res.person?.person.banned ?? false,
res => res.person?.home_instance_actions?.received_ban != null,
);
expect(alphaUserOnBeta1.person?.person.banned).toBe(true);
expect(
alphaUserOnBeta1.person?.home_instance_actions?.received_ban,
).toBeDefined();

// existing alpha post should be removed on beta
let betaBanRes = await waitUntil(
Expand Down Expand Up @@ -557,7 +560,9 @@ test("Enforce site ban federation for federated user", async () => {
await followBeta(alphaUserHttp);

let alphaUserOnBeta2 = await resolvePerson(beta, alphaUserActorId!);
expect(alphaUserOnBeta2.person?.person.banned).toBe(false);
expect(
alphaUserOnBeta2.person?.instance_actions?.received_ban,
).toBeUndefined();

if (!alphaUserOnBeta2.person) {
throw "Missing alpha person";
Expand All @@ -577,29 +582,35 @@ test("Enforce site ban federation for federated user", async () => {
);
expect(banAlphaOnBeta.banned).toBe(true);

// The beta site ban should NOT be federated to alpha
let alphaPerson2 = (await getMyUser(alphaUserHttp)).local_user_view.person;
expect(alphaPerson2.banned).toBe(false);

// existing alpha post should be removed on beta
let betaBanRes = await waitUntil(
() => getPost(beta, searchBeta1.post.id),
s => s.post_view.post.removed,
);
expect(betaBanRes.post_view.post.removed).toBe(true);
let betaRemovedPost = await getPost(beta, searchBeta1.post.id);
expect(betaRemovedPost.post_view.post.removed).toBe(true);

// existing alpha's post to the beta community should be removed on alpha
let alphaPostAfterRemoveOnBeta = await waitUntil(
// post should also be removed on alpha
let alphaRemovedPost = await waitUntil(
() => getPost(alpha, postRes1.post_view.post.id),
s => s.post_view.post.removed,
);
expect(betaBanRes.post_view.post.removed).toBe(true);
expect(alphaPostAfterRemoveOnBeta.post_view.post.removed).toBe(true);
expect(alphaRemovedPost.post_view.post.removed).toBe(true);

// User should not be shown to be banned from alpha
let alphaPerson2 = (await getMyUser(alphaUserHttp)).local_user_view;
expect(alphaPerson2.instance_actions?.received_ban).toBeUndefined();

// but the ban should be indicated by beta community on alpha
let communityWithBan = await getCommunity(
alphaUserHttp,
betaCommunity.community.id,
);
expect(
alphaPostAfterRemoveOnBeta.post_view.creator_community_actions
?.received_ban,
communityWithBan.community_view.instance_actions?.received_ban,
).toBeDefined();

// post to beta community is rejected
await expect(
createPost(alphaUserHttp, betaCommunity.community.id),
).rejects.toStrictEqual(Error("site_ban"));

await unfollowRemotes(alpha);
});

Expand Down
4 changes: 2 additions & 2 deletions crates/api/src/comment/distinguish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub async fn distinguish_comment(
.await?;

check_community_user_action(
&local_user_view.person,
&local_user_view,
&orig_comment.community,
&mut context.pool(),
)
Expand All @@ -37,7 +37,7 @@ pub async fn distinguish_comment(

// Verify that only a mod or admin can distinguish a comment
check_community_mod_action(
&local_user_view.person,
&local_user_view,
&orig_comment.community,
false,
&mut context.pool(),
Expand Down
7 changes: 3 additions & 4 deletions crates/api/src/comment/like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@ use lemmy_db_schema::{
source::{
comment::{CommentActions, CommentLikeForm},
comment_reply::CommentReply,
local_site::LocalSite,
},
traits::Likeable,
};
use lemmy_db_views::structs::{CommentView, LocalUserView};
use lemmy_db_views::structs::{CommentView, LocalUserView, SiteView};
use lemmy_utils::error::LemmyResult;
use std::ops::Deref;

Expand All @@ -25,7 +24,7 @@ pub async fn like_comment(
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<CommentResponse>> {
let local_site = LocalSite::read(&mut context.pool()).await?;
let local_site = SiteView::read_local(&mut context.pool()).await?.local_site;
let comment_id = data.comment_id;

let mut recipient_ids = Vec::<LocalUserId>::new();
Expand All @@ -48,7 +47,7 @@ pub async fn like_comment(
.await?;

check_community_user_action(
&local_user_view.person,
&local_user_view,
&orig_comment.community,
&mut context.pool(),
)
Expand Down
2 changes: 1 addition & 1 deletion crates/api/src/comment/list_comment_likes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub async fn list_comment_likes(

is_mod_or_admin(
&mut context.pool(),
&local_user_view.person,
&local_user_view,
comment_view.community.id,
)
.await?;
Expand Down
8 changes: 1 addition & 7 deletions crates/api/src/community/add_mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ pub async fn add_mod_to_community(
) -> LemmyResult<Json<AddModToCommunityResponse>> {
let community = Community::read(&mut context.pool(), data.community_id).await?;
// Verify that only mods or admins can add mod
check_community_mod_action(
&local_user_view.person,
&community,
false,
&mut context.pool(),
)
.await?;
check_community_mod_action(&local_user_view, &community, false, &mut context.pool()).await?;

// If its a mod removal, also check that you're a higher mod.
if !data.added {
Expand Down
8 changes: 1 addition & 7 deletions crates/api/src/community/ban.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,7 @@ pub async fn ban_from_community(
let community = Community::read(&mut context.pool(), data.community_id).await?;

// Verify that only mods or admins can ban
check_community_mod_action(
&local_user_view.person,
&community,
false,
&mut context.pool(),
)
.await?;
check_community_mod_action(&local_user_view, &community, false, &mut context.pool()).await?;

LocalUser::is_higher_mod_or_admin_check(
&mut context.pool(),
Expand Down
4 changes: 2 additions & 2 deletions crates/api/src/community/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use lemmy_api_common::{
community::{CommunityResponse, FollowCommunity},
context::LemmyContext,
send_activity::{ActivityChannel, SendActivityData},
utils::{check_community_deleted_removed, check_user_valid},
utils::{check_community_deleted_removed, check_local_user_valid},
};
use lemmy_db_schema::{
source::{
Expand All @@ -22,7 +22,7 @@ pub async fn follow_community(
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<CommunityResponse>> {
check_user_valid(&local_user_view.person)?;
check_local_user_valid(&local_user_view)?;
let community = Community::read(&mut context.pool(), data.community_id).await?;
let person_id = local_user_view.person.id;

Expand Down
7 changes: 1 addition & 6 deletions crates/api/src/community/pending_follows/approve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ pub async fn post_pending_follows_approve(
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<SuccessResponse>> {
is_mod_or_admin(
&mut context.pool(),
&local_user_view.person,
data.community_id,
)
.await?;
is_mod_or_admin(&mut context.pool(), &local_user_view, data.community_id).await?;

let activity_data = if data.approve {
CommunityActions::approve_follower(
Expand Down
7 changes: 1 addition & 6 deletions crates/api/src/community/pending_follows/count.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@ pub async fn get_pending_follows_count(
context: Data<LemmyContext>,
local_user_view: LocalUserView,
) -> LemmyResult<Json<GetCommunityPendingFollowsCountResponse>> {
is_mod_or_admin(
&mut context.pool(),
&local_user_view.person,
data.community_id,
)
.await?;
is_mod_or_admin(&mut context.pool(), &local_user_view, data.community_id).await?;
let count =
CommunityFollowerView::count_approval_required(&mut context.pool(), data.community_id).await?;
Ok(Json(GetCommunityPendingFollowsCountResponse { count }))
Expand Down
10 changes: 3 additions & 7 deletions crates/api/src/community/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,16 @@ use lemmy_api_common::{
context::LemmyContext,
utils::{check_private_instance, is_mod_or_admin_opt},
};
use lemmy_db_schema::source::{
actor_language::CommunityLanguage,
community::Community,
local_site::LocalSite,
};
use lemmy_db_views::structs::{CommunityView, LocalUserView};
use lemmy_db_schema::source::{actor_language::CommunityLanguage, community::Community};
use lemmy_db_views::structs::{CommunityView, LocalUserView, SiteView};
use lemmy_utils::error::LemmyResult;

pub async fn get_random_community(
data: Query<GetRandomCommunity>,
context: Data<LemmyContext>,
local_user_view: Option<LocalUserView>,
) -> LemmyResult<Json<CommunityResponse>> {
let local_site = LocalSite::read(&mut context.pool()).await?;
let local_site = SiteView::read_local(&mut context.pool()).await?.local_site;

check_private_instance(&local_user_view, &local_site)?;

Expand Down
2 changes: 1 addition & 1 deletion crates/api/src/community/transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pub async fn transfer_community(
let mut community_mods =
CommunityModeratorView::for_community(&mut context.pool(), community.id).await?;

check_community_user_action(&local_user_view.person, &community, &mut context.pool()).await?;
check_community_user_action(&local_user_view, &community, &mut context.pool()).await?;

// Make sure transferrer is either the top community mod, or an admin
if !(is_top_mod(&local_user_view, &community_mods).is_ok() || is_admin(&local_user_view).is_ok())
Expand Down
Loading