Skip to content

Commit 8fd7148

Browse files
authored
Prevent suspended users from sending encrypted messages (#18157)
Missed in the first round.
1 parent caa1f9d commit 8fd7148

File tree

3 files changed

+128
-7
lines changed

3 files changed

+128
-7
lines changed

changelog.d/18157.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Prevent suspended users from sending encrypted messages.

synapse/handlers/message.py

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -644,11 +644,33 @@ async def create_event(
644644
"""
645645
await self.auth_blocking.check_auth_blocking(requester=requester)
646646

647-
if event_dict["type"] == EventTypes.Message:
648-
requester_suspended = await self.store.get_user_suspended_status(
649-
requester.user.to_string()
650-
)
651-
if requester_suspended:
647+
requester_suspended = await self.store.get_user_suspended_status(
648+
requester.user.to_string()
649+
)
650+
if requester_suspended:
651+
# We want to allow suspended users to perform "corrective" actions
652+
# asked of them by server admins, such as redact their messages and
653+
# leave rooms.
654+
if event_dict["type"] in ["m.room.redaction", "m.room.member"]:
655+
if event_dict["type"] == "m.room.redaction":
656+
event = await self.store.get_event(
657+
event_dict["content"]["redacts"], allow_none=True
658+
)
659+
if event:
660+
if event.sender != requester.user.to_string():
661+
raise SynapseError(
662+
403,
663+
"You can only redact your own events while account is suspended.",
664+
Codes.USER_ACCOUNT_SUSPENDED,
665+
)
666+
if event_dict["type"] == "m.room.member":
667+
if event_dict["content"]["membership"] != "leave":
668+
raise SynapseError(
669+
403,
670+
"Changing membership while account is suspended is not allowed.",
671+
Codes.USER_ACCOUNT_SUSPENDED,
672+
)
673+
else:
652674
raise SynapseError(
653675
403,
654676
"Sending messages while account is suspended is not allowed.",

tests/rest/client/test_rooms.py

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,23 @@ def test_suspended_user_cannot_invite_to_room(self) -> None:
13711371
)
13721372
self.assertEqual(channel.json_body["errcode"], "M_USER_SUSPENDED")
13731373

1374+
def test_suspended_user_can_leave_room(self) -> None:
1375+
channel = self.make_request(
1376+
"POST", f"/join/{self.room1}", access_token=self.tok1
1377+
)
1378+
self.assertEqual(channel.code, 200)
1379+
1380+
# set the user as suspended
1381+
self.get_success(self.store.set_user_suspended_status(self.user1, True))
1382+
1383+
# leave room
1384+
channel = self.make_request(
1385+
"POST",
1386+
f"/rooms/{self.room1}/leave",
1387+
access_token=self.tok1,
1388+
)
1389+
self.assertEqual(channel.code, 200)
1390+
13741391

13751392
class RoomAppserviceTsParamTestCase(unittest.HomeserverTestCase):
13761393
servlets = [
@@ -3989,10 +4006,25 @@ def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
39894006
self.user2 = self.register_user("teresa", "hackme")
39904007
self.tok2 = self.login("teresa", "hackme")
39914008

3992-
self.room1 = self.helper.create_room_as(room_creator=self.user1, tok=self.tok1)
4009+
self.admin = self.register_user("admin", "pass", True)
4010+
self.admin_tok = self.login("admin", "pass")
4011+
4012+
self.room1 = self.helper.create_room_as(
4013+
room_creator=self.user1, tok=self.tok1, room_version="11"
4014+
)
39934015
self.store = hs.get_datastores().main
39944016

3995-
def test_suspended_user_cannot_send_message_to_room(self) -> None:
4017+
self.room2 = self.helper.create_room_as(
4018+
room_creator=self.user1, is_public=False, tok=self.tok1
4019+
)
4020+
self.helper.send_state(
4021+
self.room2,
4022+
EventTypes.RoomEncryption,
4023+
{EventContentFields.ENCRYPTION_ALGORITHM: "m.megolm.v1.aes-sha2"},
4024+
tok=self.tok1,
4025+
)
4026+
4027+
def test_suspended_user_cannot_send_message_to_public_room(self) -> None:
39964028
# set the user as suspended
39974029
self.get_success(self.store.set_user_suspended_status(self.user1, True))
39984030

@@ -4004,6 +4036,24 @@ def test_suspended_user_cannot_send_message_to_room(self) -> None:
40044036
)
40054037
self.assertEqual(channel.json_body["errcode"], "M_USER_SUSPENDED")
40064038

4039+
def test_suspended_user_cannot_send_message_to_encrypted_room(self) -> None:
4040+
channel = self.make_request(
4041+
"PUT",
4042+
f"/_synapse/admin/v1/suspend/{self.user1}",
4043+
{"suspend": True},
4044+
access_token=self.admin_tok,
4045+
)
4046+
self.assertEqual(channel.code, 200)
4047+
self.assertEqual(channel.json_body, {f"user_{self.user1}_suspended": True})
4048+
4049+
channel = self.make_request(
4050+
"PUT",
4051+
f"/rooms/{self.room2}/send/m.room.encrypted/1",
4052+
access_token=self.tok1,
4053+
content={},
4054+
)
4055+
self.assertEqual(channel.json_body["errcode"], "M_USER_SUSPENDED")
4056+
40074057
def test_suspended_user_cannot_change_profile_data(self) -> None:
40084058
# set the user as suspended
40094059
self.get_success(self.store.set_user_suspended_status(self.user1, True))
@@ -4069,3 +4119,51 @@ def test_suspended_user_cannot_redact_messages_other_than_their_own(self) -> Non
40694119
shorthand=False,
40704120
)
40714121
self.assertEqual(channel.code, 200)
4122+
4123+
channel = self.make_request(
4124+
"PUT",
4125+
f"/_matrix/client/v3/rooms/{self.room1}/send/m.room.redaction/3456346",
4126+
access_token=self.tok1,
4127+
content={"reason": "bogus", "redacts": event_id},
4128+
shorthand=False,
4129+
)
4130+
self.assertEqual(channel.json_body["errcode"], "M_USER_SUSPENDED")
4131+
4132+
channel = self.make_request(
4133+
"PUT",
4134+
f"/_matrix/client/v3/rooms/{self.room1}/send/m.room.redaction/3456346",
4135+
access_token=self.tok1,
4136+
content={"reason": "bogus", "redacts": event_id2},
4137+
shorthand=False,
4138+
)
4139+
self.assertEqual(channel.code, 200)
4140+
4141+
def test_suspended_user_cannot_ban_others(self) -> None:
4142+
# user to ban joins room user1 created
4143+
self.make_request("POST", f"/rooms/{self.room1}/join", access_token=self.tok2)
4144+
4145+
# suspend user1
4146+
self.get_success(self.store.set_user_suspended_status(self.user1, True))
4147+
4148+
# user1 tries to ban other user while suspended
4149+
channel = self.make_request(
4150+
"POST",
4151+
f"/_matrix/client/v3/rooms/{self.room1}/ban",
4152+
access_token=self.tok1,
4153+
content={"reason": "spite", "user_id": self.user2},
4154+
shorthand=False,
4155+
)
4156+
self.assertEqual(channel.json_body["errcode"], "M_USER_SUSPENDED")
4157+
4158+
# un-suspend user1
4159+
self.get_success(self.store.set_user_suspended_status(self.user1, False))
4160+
4161+
# ban now goes through
4162+
channel = self.make_request(
4163+
"POST",
4164+
f"/_matrix/client/v3/rooms/{self.room1}/ban",
4165+
access_token=self.tok1,
4166+
content={"reason": "spite", "user_id": self.user2},
4167+
shorthand=False,
4168+
)
4169+
self.assertEqual(channel.code, 200)

0 commit comments

Comments
 (0)