From 72a27d71dbeb782d9194ce563ab4575ca277ddc0 Mon Sep 17 00:00:00 2001 From: Will Hunt <2072976+Half-Shot@users.noreply.github.com> Date: Thu, 5 Nov 2026 15:11:10 +0000 Subject: [PATCH] Allow MSC4155 to work if `m.invite_permission_config` was previously set (#20476) Allow MSC4155 to work if m.invite_permission_config was previously set Fixes #20474 --- changelog.d/20476.bugfix | 1 + .../storage/databases/main/account_data.py | 6 ++-- tests/handlers/test_room_member.py | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 changelog.d/20476.bugfix diff --git a/changelog.d/20476.bugfix b/changelog.d/20476.bugfix new file mode 100644 index 0000000000..3e85368e97 --- /dev/null +++ b/changelog.d/20476.bugfix @@ -0,0 +1 @@ +Fix a bug introduced in Synapse 1.149.0 where an empty `m.invite_permission_config` account data event would take precedence over [MSC4155](https://github.com/matrix-org/matrix-spec-proposals/pull/4155) invite filtering rules. diff --git a/synapse/storage/databases/main/account_data.py b/synapse/storage/databases/main/account_data.py index 538280137b..9172dd5eb4 100644 --- a/synapse/storage/databases/main/account_data.py +++ b/synapse/storage/databases/main/account_data.py @@ -575,9 +575,9 @@ class AccountDataWorkerStore(PushRulesWorkerStore, CacheInvalidationWorkerStore) data = await self.get_global_account_data_by_type_for_user( user_id, AccountDataTypes.INVITE_PERMISSION_CONFIG ) - # If the user has an MSC4380-style config setting, prioritise that - # above an MSC4155 one - if data is not None: + # If the user has an MSC4380-style config setting AND has indicated + # a preference within it (no empty dict), prioritise that above an MSC4155 one. + if data: return MSC4380InviteRulesConfig.from_account_data(data) if self._msc4155_enabled: diff --git a/tests/handlers/test_room_member.py b/tests/handlers/test_room_member.py index 1b62830571..331aa229e0 100644 --- a/tests/handlers/test_room_member.py +++ b/tests/handlers/test_room_member.py @@ -680,6 +680,39 @@ class TestMSC4380InviteBlocking(FederatingHomeserverTestCase): ) ) + @override_config({"experimental_features": {"msc4155_enabled": True}}) + def test_msc4380_empty_config_falls_back_to_msc4155(self) -> None: + """Test that an empty MSC4380 config does not take precedence over an + MSC4155 config.""" + room_id = self.helper.create_room_as(self.alice, tok=self.alice_token) + + self.get_success( + self.store.add_account_data_for_user( + self.bob, + AccountDataTypes.INVITE_PERMISSION_CONFIG, + {}, + ) + ) + self.get_success( + self.store.add_account_data_for_user( + self.bob, + AccountDataTypes.MSC4155_INVITE_PERMISSION_CONFIG, + {"blocked_users": [self.alice]}, + ) + ) + + f = self.get_failure( + self.handler.update_membership( + requester=create_requester(self.alice), + target=UserID.from_string(self.bob), + room_id=room_id, + action=Membership.INVITE, + ), + SynapseError, + ).value + self.assertEqual(f.code, 403) + self.assertEqual(f.errcode, "M_INVITE_BLOCKED") + def test_msc4380_block_invite_remote(self) -> None: """Test that MSC4380 will block a user from being invited to a room by a remote user.""" # A remote user who sends the invite