Skip to content
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

When site banning a federated user, also remove their content from our local communities. #4464

Merged
merged 9 commits into from
Mar 1, 2024

Conversation

dessalines
Copy link
Member

@dessalines dessalines commented Feb 20, 2024

communities.

- This works by:
  - Before a site ban, find all posts and comments to local communities
  - Send a federated community ban action for each local comm.
  - This also removes their content in the apub receive code.
- Adding back in federated community ban api tests.
- Adding in two more api tests for site bans.
- Fixes #4118
@dessalines dessalines changed the title When banning a federated user, also remove their content from our local communities. When site banning a federated user, also remove their content from our local communities. Feb 20, 2024
@Nothing4You
Copy link
Collaborator

Not sure if I understand the logic entirely, please correct me if I don't.

Ban/unban are in the same function, just with a bool specifying whether to ban or unban, so the steps below are the same for both banning and unbanning.

  1. User gets site banned by updating their Person to be banned=true/false
  2. Invalidate tokens if the user is local (not relevant for this case)
  3. Removing their locally known content (removed=true) when remove_data is true
  4. Creating a mod log entry for the site ban/unban
  5. Iterating over content by the affected user in local communities and issuing a ban/unban through federation
  6. Find community ids the user has posted or commented in
  7. Federate out community ban/ban+removal/unban for each local community
  8. Federating out the site ban
    This has currently no effect on other Lemmy instances, as they will ignore this when it's not coming from the user's home instance.

As 6. is not currently accepted on receiving instances, 5. is intended as an intermediate/alternative solution until proper handling for receiving 6. exists, which would also be able to deal with future communities on the local instance, which were created after the ban was issued.

This does not currently ban those users from communities locally, nor write this to the community ban mod log locally.
Due to the community bans being sent over federation, this will create those entries on all remote instances.
When a user gets unbanned, this will also federate unbans for all local communities, regardless of whether the user is explicitly banned in them. The user will not be unbanned locally in those communities.

Is this intended as a workaround to allow a site unban to be processed without effectively unbanning the user from all local communities, just telling other instances the user would be unbanned in them?
If it is, then this should probably exclude federating out unbans for communities where the user is already explicitly banned locally. For bans, this should still be federated, at least when content should be removed; otherwise there is no need. This might get a bit trickier when taking expiring bans into account.

If this is not intended as a workaround for allowing community unbans to be undone from previous implicit community bans, shouldn't those bans also exist locally and also be in the local mod log for consistency?
Also, how would community unbans be avoided for communities the user was already banned in prior to receiving a site ban?

@dessalines
Copy link
Member Author

Close, but your step 6 only applies to our local communities.

Yes it bans them locally. This has nothing to do with workarounds for unbanning. I don't think modlog entries are necessary, you'll already see the site ban.

crates/api/src/lib.rs Outdated Show resolved Hide resolved
crates/api/src/lib.rs Outdated Show resolved Hide resolved
@dessalines dessalines marked this pull request as draft February 26, 2024 14:56
@dessalines dessalines marked this pull request as ready for review February 27, 2024 15:56
reason: &Option<String>,
remove_data: &Option<bool>,
expires: &Option<i64>,
Copy link
Member

@Nutomic Nutomic Feb 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If its a temporary site ban then the user would get banned from local communities and never unbanned, right? Also if ban = false, any existing community bans for the user would be removed. Seems safer to remove these two params and use it only in case of permanent site ban.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also instead of running this logic on the instance where the ban originates, we could move it to the code which receives remote site bans. Then it would only have to ban the user from all known communities of that instance. This would reduce the amount of activities that have to get federated. However it wont work if a community gets federated later. Though with this implementation, the ban also wont federate to instances where the local communities dont have any followers.

Either way the core problem wont be solved. We only federate bans via activities, so if that doesnt get delivered or an instance fetches the community later, it wont know about the ban. A proper solution would be similar to #4475, federating a collection of users who are banned from each instance/community so that it can also be synchronized later. And for site bans we need to store them in a separate table as table site_ban (instance_id, person_id), to properly track which instance banned the user. All rather complex, so we can use this PR as a temporary, imperfect solution.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If its a temporary site ban then the user would get banned from local communities and never unbanned, right?

If you look below, the community ban form also includes that expires. So the site ban, and the community bans, would all expire at the same time.

Also if ban = false, any existing community bans for the user would be removed. Seems safer to remove these two params and use it only in case of permanent site ban.

That's true, but I think its still a good idea to federate community unbans. If we didn't run this code for unbans, then if someone was permabanned, then unbanned, their community bans would still be there.

Its a limitation, since community mods might have wanted that user banned, but I think overall its still better than leaving all the bans in place.

Also instead of running this logic on the instance where the ban originates, we could move it to the code which receives remote site bans. Then it would only have to ban the user from all known communities of that instance. This would reduce the amount of activities that have to get federated. However it wont work if a community gets federated later. Though with this implementation, the ban also wont federate to instances where the local communities dont have any followers.

That's up to you, but this code currently does work, and the API tests are passing. I don't think it makes much sense to federate out local site bans.

// Ignore all errors for these
CommunityPersonBan::ban(&mut context.pool(), &community_user_ban_form)
.await
.with_lemmy_type(LemmyErrorType::CommunityUserAlreadyBanned)
Copy link
Member

@Nutomic Nutomic Mar 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No reason to add an error message if errors are ignored. Same below.

expect(banAlphaOnBeta.banned).toBe(true);

// The beta site ban should NOT be federated to alpha
let alphaPerson2 = (await getSite(alphaUserHttp)).my_user?.local_user_view
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe you can simply do .my_user!, no need to be so verbose with explicit throw.

Copy link
Member

@Nutomic Nutomic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its really a hack but we can do this for now. Ive opened #4485 for a proper solution.

@dessalines dessalines enabled auto-merge (squash) March 1, 2024 16:31
@dessalines dessalines disabled auto-merge March 1, 2024 18:44
@dessalines dessalines merged commit 7eec871 into main Mar 1, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Content removal for local communities does not federate out when banning remote users
3 participants