mirror of
https://git.anonymousland.org/anonymousland/synapse-product.git
synced 2024-09-08 04:42:00 +00:00
Fix that user cannot /forget
rooms after the last member has left (#13546)
This commit is contained in:
parent
51d732db3b
commit
682dfcfc0d
1
changelog.d/13546.bugfix
Normal file
1
changelog.d/13546.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Fix bug that user cannot `/forget` rooms after the last member has left the room.
|
@ -1925,8 +1925,11 @@ class RoomMemberMasterHandler(RoomMemberHandler):
|
|||||||
]:
|
]:
|
||||||
raise SynapseError(400, "User %s in room %s" % (user_id, room_id))
|
raise SynapseError(400, "User %s in room %s" % (user_id, room_id))
|
||||||
|
|
||||||
if membership:
|
# In normal case this call is only required if `membership` is not `None`.
|
||||||
await self.store.forget(user_id, room_id)
|
# But: After the last member had left the room, the background update
|
||||||
|
# `_background_remove_left_rooms` is deleting rows related to this room from
|
||||||
|
# the table `current_state_events` and `get_current_state_events` is `None`.
|
||||||
|
await self.store.forget(user_id, room_id)
|
||||||
|
|
||||||
|
|
||||||
def get_users_which_can_issue_invite(auth_events: StateMap[EventBase]) -> List[str]:
|
def get_users_which_can_issue_invite(auth_events: StateMap[EventBase]) -> List[str]:
|
||||||
|
@ -6,7 +6,7 @@ import synapse.rest.admin
|
|||||||
import synapse.rest.client.login
|
import synapse.rest.client.login
|
||||||
import synapse.rest.client.room
|
import synapse.rest.client.room
|
||||||
from synapse.api.constants import EventTypes, Membership
|
from synapse.api.constants import EventTypes, Membership
|
||||||
from synapse.api.errors import LimitExceededError
|
from synapse.api.errors import LimitExceededError, SynapseError
|
||||||
from synapse.crypto.event_signing import add_hashes_and_signatures
|
from synapse.crypto.event_signing import add_hashes_and_signatures
|
||||||
from synapse.events import FrozenEventV3
|
from synapse.events import FrozenEventV3
|
||||||
from synapse.federation.federation_client import SendJoinResult
|
from synapse.federation.federation_client import SendJoinResult
|
||||||
@ -17,7 +17,11 @@ from synapse.util import Clock
|
|||||||
from tests.replication._base import BaseMultiWorkerStreamTestCase
|
from tests.replication._base import BaseMultiWorkerStreamTestCase
|
||||||
from tests.server import make_request
|
from tests.server import make_request
|
||||||
from tests.test_utils import make_awaitable
|
from tests.test_utils import make_awaitable
|
||||||
from tests.unittest import FederatingHomeserverTestCase, override_config
|
from tests.unittest import (
|
||||||
|
FederatingHomeserverTestCase,
|
||||||
|
HomeserverTestCase,
|
||||||
|
override_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestJoinsLimitedByPerRoomRateLimiter(FederatingHomeserverTestCase):
|
class TestJoinsLimitedByPerRoomRateLimiter(FederatingHomeserverTestCase):
|
||||||
@ -287,3 +291,88 @@ class TestReplicatedJoinsLimitedByPerRoomRateLimiter(BaseMultiWorkerStreamTestCa
|
|||||||
),
|
),
|
||||||
LimitExceededError,
|
LimitExceededError,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class RoomMemberMasterHandlerTestCase(HomeserverTestCase):
|
||||||
|
servlets = [
|
||||||
|
synapse.rest.admin.register_servlets,
|
||||||
|
synapse.rest.client.login.register_servlets,
|
||||||
|
synapse.rest.client.room.register_servlets,
|
||||||
|
]
|
||||||
|
|
||||||
|
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||||
|
self.handler = hs.get_room_member_handler()
|
||||||
|
self.store = hs.get_datastores().main
|
||||||
|
|
||||||
|
# Create two users.
|
||||||
|
self.alice = self.register_user("alice", "pass")
|
||||||
|
self.alice_ID = UserID.from_string(self.alice)
|
||||||
|
self.alice_token = self.login("alice", "pass")
|
||||||
|
self.bob = self.register_user("bob", "pass")
|
||||||
|
self.bob_ID = UserID.from_string(self.bob)
|
||||||
|
self.bob_token = self.login("bob", "pass")
|
||||||
|
|
||||||
|
# Create a room on this homeserver.
|
||||||
|
self.room_id = self.helper.create_room_as(self.alice, tok=self.alice_token)
|
||||||
|
|
||||||
|
def test_leave_and_forget(self) -> None:
|
||||||
|
"""Tests that forget a room is successfully. The test is performed with two users,
|
||||||
|
as forgetting by the last user respectively after all users had left the
|
||||||
|
is a special edge case."""
|
||||||
|
self.helper.join(self.room_id, user=self.bob, tok=self.bob_token)
|
||||||
|
|
||||||
|
# alice is not the last room member that leaves and forgets the room
|
||||||
|
self.helper.leave(self.room_id, user=self.alice, tok=self.alice_token)
|
||||||
|
self.get_success(self.handler.forget(self.alice_ID, self.room_id))
|
||||||
|
self.assertTrue(
|
||||||
|
self.get_success(self.store.did_forget(self.alice, self.room_id))
|
||||||
|
)
|
||||||
|
|
||||||
|
# the server has not forgotten the room
|
||||||
|
self.assertFalse(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room_id))
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_leave_and_forget_last_user(self) -> None:
|
||||||
|
"""Tests that forget a room is successfully when the last user has left the room."""
|
||||||
|
|
||||||
|
# alice is the last room member that leaves and forgets the room
|
||||||
|
self.helper.leave(self.room_id, user=self.alice, tok=self.alice_token)
|
||||||
|
self.get_success(self.handler.forget(self.alice_ID, self.room_id))
|
||||||
|
self.assertTrue(
|
||||||
|
self.get_success(self.store.did_forget(self.alice, self.room_id))
|
||||||
|
)
|
||||||
|
|
||||||
|
# the server has forgotten the room
|
||||||
|
self.assertTrue(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room_id))
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_forget_when_not_left(self) -> None:
|
||||||
|
"""Tests that a user cannot not forgets a room that has not left."""
|
||||||
|
self.get_failure(self.handler.forget(self.alice_ID, self.room_id), SynapseError)
|
||||||
|
|
||||||
|
def test_rejoin_forgotten_by_user(self) -> None:
|
||||||
|
"""Test that a user that has forgotten a room can do a re-join.
|
||||||
|
The room was not forgotten from the local server.
|
||||||
|
One local user is still member of the room."""
|
||||||
|
self.helper.join(self.room_id, user=self.bob, tok=self.bob_token)
|
||||||
|
|
||||||
|
self.helper.leave(self.room_id, user=self.alice, tok=self.alice_token)
|
||||||
|
self.get_success(self.handler.forget(self.alice_ID, self.room_id))
|
||||||
|
self.assertTrue(
|
||||||
|
self.get_success(self.store.did_forget(self.alice, self.room_id))
|
||||||
|
)
|
||||||
|
|
||||||
|
# the server has not forgotten the room
|
||||||
|
self.assertFalse(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room_id))
|
||||||
|
)
|
||||||
|
|
||||||
|
self.helper.join(self.room_id, user=self.alice, tok=self.alice_token)
|
||||||
|
# TODO: A join to a room does not invalidate the forgotten cache
|
||||||
|
# see https://github.com/matrix-org/synapse/issues/13262
|
||||||
|
self.store.did_forget.invalidate_all()
|
||||||
|
self.assertFalse(
|
||||||
|
self.get_success(self.store.did_forget(self.alice, self.room_id))
|
||||||
|
)
|
||||||
|
@ -158,7 +158,7 @@ class RoomMemberStoreTestCase(unittest.HomeserverTestCase):
|
|||||||
# Check that alice's display name is now None
|
# Check that alice's display name is now None
|
||||||
self.assertEqual(row[0]["display_name"], None)
|
self.assertEqual(row[0]["display_name"], None)
|
||||||
|
|
||||||
def test_room_is_locally_forgotten(self):
|
def test_room_is_locally_forgotten(self) -> None:
|
||||||
"""Test that when the last local user has forgotten a room it is known as forgotten."""
|
"""Test that when the last local user has forgotten a room it is known as forgotten."""
|
||||||
# join two local and one remote user
|
# join two local and one remote user
|
||||||
self.room = self.helper.create_room_as(self.u_alice, tok=self.t_alice)
|
self.room = self.helper.create_room_as(self.u_alice, tok=self.t_alice)
|
||||||
@ -199,7 +199,7 @@ class RoomMemberStoreTestCase(unittest.HomeserverTestCase):
|
|||||||
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_join_locally_forgotten_room(self):
|
def test_join_locally_forgotten_room(self) -> None:
|
||||||
"""Tests if a user joins a forgotten room the room is not forgotten anymore."""
|
"""Tests if a user joins a forgotten room the room is not forgotten anymore."""
|
||||||
self.room = self.helper.create_room_as(self.u_alice, tok=self.t_alice)
|
self.room = self.helper.create_room_as(self.u_alice, tok=self.t_alice)
|
||||||
self.assertFalse(
|
self.assertFalse(
|
||||||
|
Loading…
Reference in New Issue
Block a user