Repository: LemmyNet/lemmy (language: rust)

Issue:
[Bug]: big instance mod unbanned user from individual instance is still banned. Is this a federation issue?
### Requirements

- [x] Is this a bug report? For questions or discussions use https://lemmy.ml/c/lemmy_support
- [x] Did you check to see if this issue already exists?
- [x] Is this only a single bug? Do not put multiple bugs in one issue.
- [x] Do you agree to follow the rules in our [Code of Conduct](https://join-lemmy.org/docs/code_of_conduct.html)?
- [x] Is this a backend issue? Use the [lemmy-ui](https://github.com/LemmyNet/lemmy-ui) repo for UI / frontend issues.

### Summary

A user was banned from a big instance com from their individual user instance. The ban was repealed but not federated. Nothing from that com has federated since the original ban.

### Steps to Reproduce

1. get banned
2. get unbanned
3. still be banned


### Technical Details

n/a

### Version

19.8

### Lemmy Instance URL

lemmy.world


Discussion / hints:
There is not enough information. Which instance are the user and community on? Who made the ban, and was it a community or site ban? 
ocean@lemmy.selfhostcat.com from asklemmy@lemmy.world.

Fix patch:
diff --git a/crates/apub/src/activities/block/block_user.rs b/crates/apub/src/activities/block/block_user.rs
index 737d14003a..32f0efb348 100644
--- a/crates/apub/src/activities/block/block_user.rs
+++ b/crates/apub/src/activities/block/block_user.rs
@@ -30,16 +30,11 @@ use lemmy_api_common::{
 use lemmy_db_schema::{
   source::{
     activity::ActivitySendTargets,
-    community::{
-      CommunityFollower,
-      CommunityFollowerForm,
-      CommunityPersonBan,
-      CommunityPersonBanForm,
-    },
+    community::{CommunityPersonBan, CommunityPersonBanForm},
     mod_log::moderator::{ModBan, ModBanForm, ModBanFromCommunity, ModBanFromCommunityForm},
     person::{Person, PersonUpdateForm},
   },
-  traits::{Bannable, Crud, Followable},
+  traits::{Bannable, Crud},
 };
 use lemmy_utils::error::{FederationError, LemmyError, LemmyResult};
 use url::Url;
@@ -188,11 +183,9 @@ impl ActivityHandler for BlockUser {
         };
         CommunityPersonBan::ban(&mut context.pool(), &community_user_ban_form).await?;
 
-        // Also unsubscribe them from the community, if they are subscribed
-        let community_follower_form = CommunityFollowerForm::new(community.id, blocked_person.id);
-        CommunityFollower::unfollow(&mut context.pool(), &community_follower_form)
-          .await
-          .ok();
+        // Dont unsubscribe the user so that we can receive a potential unban activity.
+        // If we unfollowed the community here, activities from the community would be rejected
+        // in [[can_accept_activity_in_community]] in case are no other local followers.
 
         if self.remove_data.unwrap_or(false) {
           remove_or_restore_user_data_in_community(


Test patch:
diff --git a/api_tests/src/post.spec.ts b/api_tests/src/post.spec.ts
index 80496a46cc..72b0b32e03 100644
--- a/api_tests/src/post.spec.ts
+++ b/api_tests/src/post.spec.ts
@@ -39,6 +39,7 @@ import {
   listReports,
   getMyUser,
   listInbox,
+  getModlog,
 } from "./shared";
 import { PostView } from "lemmy-js-client/dist/types/PostView";
 import { AdminBlockInstanceParams } from "lemmy-js-client/dist/types/AdminBlockInstanceParams";
@@ -651,8 +652,13 @@ test("Enforce community ban for federated user", async () => {
   );
   expect(unBanAlpha.banned).toBe(false);
 
-  // Need to re-follow the community
-  await followBeta(alpha);
+  // Check that unban was federated to alpha
+  await waitUntil(
+    () => getModlog(alpha),
+    m =>
+      m.modlog[0].type_ == "ModBanFromCommunity" &&
+      m.modlog[0].mod_ban_from_community.banned == false,
+  );
 
   let postRes3 = await createPost(alpha, betaCommunity.community.id);
   expect(postRes3.post_view.post).toBeDefined();
diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts
index 8e653f5e6b..e7d86c289d 100644
--- a/api_tests/src/shared.ts
+++ b/api_tests/src/shared.ts
@@ -27,6 +27,8 @@ import {
   ListInboxResponse,
   ListInbox,
   InboxDataType,
+  GetModlogResponse,
+  GetModlog,
 } from "lemmy-js-client";
 import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
 import { DeletePost } from "lemmy-js-client/dist/types/DeletePost";
@@ -901,6 +903,10 @@ export function approveCommunityPendingFollow(
   };
   return api.approveCommunityPendingFollow(form);
 }
+export function getModlog(api: LemmyHttp): Promise<GetModlogResponse> {
+  let form: GetModlog = {};
+  return api.getModlog(form);
+}
 
 export function delay(millis = 500) {
   return new Promise(resolve => setTimeout(resolve, millis));