mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-22 01:25:44 +03:00
Add forgotten status to Room Details API (#13503)
This commit is contained in:
parent
c6ee9c0ee4
commit
d75512d19e
6 changed files with 101 additions and 1 deletions
1
changelog.d/13503.feature
Normal file
1
changelog.d/13503.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add forgotten status to Room Details API.
|
|
@ -302,6 +302,8 @@ The following fields are possible in the JSON response body:
|
||||||
* `state_events` - Total number of state_events of a room. Complexity of the room.
|
* `state_events` - Total number of state_events of a room. Complexity of the room.
|
||||||
* `room_type` - The type of the room taken from the room's creation event; for example "m.space" if the room is a space.
|
* `room_type` - The type of the room taken from the room's creation event; for example "m.space" if the room is a space.
|
||||||
If the room does not define a type, the value will be `null`.
|
If the room does not define a type, the value will be `null`.
|
||||||
|
* `forgotten` - Whether all local users have
|
||||||
|
[forgotten](https://spec.matrix.org/latest/client-server-api/#leaving-rooms) the room.
|
||||||
|
|
||||||
The API is:
|
The API is:
|
||||||
|
|
||||||
|
@ -330,7 +332,8 @@ A response body like the following is returned:
|
||||||
"guest_access": null,
|
"guest_access": null,
|
||||||
"history_visibility": "shared",
|
"history_visibility": "shared",
|
||||||
"state_events": 93534,
|
"state_events": 93534,
|
||||||
"room_type": "m.space"
|
"room_type": "m.space",
|
||||||
|
"forgotten": false
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -303,6 +303,7 @@ class RoomRestServlet(RestServlet):
|
||||||
|
|
||||||
members = await self.store.get_users_in_room(room_id)
|
members = await self.store.get_users_in_room(room_id)
|
||||||
ret["joined_local_devices"] = await self.store.count_devices_by_users(members)
|
ret["joined_local_devices"] = await self.store.count_devices_by_users(members)
|
||||||
|
ret["forgotten"] = await self.store.is_locally_forgotten_room(room_id)
|
||||||
|
|
||||||
return HTTPStatus.OK, ret
|
return HTTPStatus.OK, ret
|
||||||
|
|
||||||
|
|
|
@ -1215,6 +1215,30 @@ class RoomMemberWorkerStore(EventsWorkerStore):
|
||||||
"get_forgotten_rooms_for_user", _get_forgotten_rooms_for_user_txn
|
"get_forgotten_rooms_for_user", _get_forgotten_rooms_for_user_txn
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def is_locally_forgotten_room(self, room_id: str) -> bool:
|
||||||
|
"""Returns whether all local users have forgotten this room_id.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
room_id: The room ID to query.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Whether the room is forgotten.
|
||||||
|
"""
|
||||||
|
|
||||||
|
sql = """
|
||||||
|
SELECT count(*) > 0 FROM local_current_membership
|
||||||
|
INNER JOIN room_memberships USING (room_id, event_id)
|
||||||
|
WHERE
|
||||||
|
room_id = ?
|
||||||
|
AND forgotten = 0;
|
||||||
|
"""
|
||||||
|
|
||||||
|
rows = await self.db_pool.execute("is_forgotten_room", None, sql, room_id)
|
||||||
|
|
||||||
|
# `count(*)` returns always an integer
|
||||||
|
# If any rows still exist it means someone has not forgotten this room yet
|
||||||
|
return not rows[0][0]
|
||||||
|
|
||||||
async def get_rooms_user_has_been_in(self, user_id: str) -> Set[str]:
|
async def get_rooms_user_has_been_in(self, user_id: str) -> Set[str]:
|
||||||
"""Get all rooms that the user has ever been in.
|
"""Get all rooms that the user has ever been in.
|
||||||
|
|
||||||
|
|
|
@ -1633,6 +1633,7 @@ class RoomTestCase(unittest.HomeserverTestCase):
|
||||||
self.assertIn("history_visibility", channel.json_body)
|
self.assertIn("history_visibility", channel.json_body)
|
||||||
self.assertIn("state_events", channel.json_body)
|
self.assertIn("state_events", channel.json_body)
|
||||||
self.assertIn("room_type", channel.json_body)
|
self.assertIn("room_type", channel.json_body)
|
||||||
|
self.assertIn("forgotten", channel.json_body)
|
||||||
self.assertEqual(room_id_1, channel.json_body["room_id"])
|
self.assertEqual(room_id_1, channel.json_body["room_id"])
|
||||||
|
|
||||||
def test_single_room_devices(self) -> None:
|
def test_single_room_devices(self) -> None:
|
||||||
|
|
|
@ -23,6 +23,7 @@ from synapse.util import Clock
|
||||||
|
|
||||||
from tests import unittest
|
from tests import unittest
|
||||||
from tests.server import TestHomeServer
|
from tests.server import TestHomeServer
|
||||||
|
from tests.test_utils import event_injection
|
||||||
|
|
||||||
|
|
||||||
class RoomMemberStoreTestCase(unittest.HomeserverTestCase):
|
class RoomMemberStoreTestCase(unittest.HomeserverTestCase):
|
||||||
|
@ -157,6 +158,75 @@ 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):
|
||||||
|
"""Test that when the last local user has forgotten a room it is known as forgotten."""
|
||||||
|
# join two local and one remote user
|
||||||
|
self.room = self.helper.create_room_as(self.u_alice, tok=self.t_alice)
|
||||||
|
self.get_success(
|
||||||
|
event_injection.inject_member_event(self.hs, self.room, self.u_bob, "join")
|
||||||
|
)
|
||||||
|
self.get_success(
|
||||||
|
event_injection.inject_member_event(
|
||||||
|
self.hs, self.room, self.u_charlie.to_string(), "join"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
|
)
|
||||||
|
|
||||||
|
# local users leave the room and the room is not forgotten
|
||||||
|
self.get_success(
|
||||||
|
event_injection.inject_member_event(
|
||||||
|
self.hs, self.room, self.u_alice, "leave"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.get_success(
|
||||||
|
event_injection.inject_member_event(self.hs, self.room, self.u_bob, "leave")
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
|
)
|
||||||
|
|
||||||
|
# first user forgets the room, room is not forgotten
|
||||||
|
self.get_success(self.store.forget(self.u_alice, self.room))
|
||||||
|
self.assertFalse(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
|
)
|
||||||
|
|
||||||
|
# second (last local) user forgets the room and the room is forgotten
|
||||||
|
self.get_success(self.store.forget(self.u_bob, self.room))
|
||||||
|
self.assertTrue(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_join_locally_forgotten_room(self):
|
||||||
|
"""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.assertFalse(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
|
)
|
||||||
|
|
||||||
|
# after leaving and forget the room, it is forgotten
|
||||||
|
self.get_success(
|
||||||
|
event_injection.inject_member_event(
|
||||||
|
self.hs, self.room, self.u_alice, "leave"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.get_success(self.store.forget(self.u_alice, self.room))
|
||||||
|
self.assertTrue(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
|
)
|
||||||
|
|
||||||
|
# after rejoin the room is not forgotten anymore
|
||||||
|
self.get_success(
|
||||||
|
event_injection.inject_member_event(
|
||||||
|
self.hs, self.room, self.u_alice, "join"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertFalse(
|
||||||
|
self.get_success(self.store.is_locally_forgotten_room(self.room))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CurrentStateMembershipUpdateTestCase(unittest.HomeserverTestCase):
|
class CurrentStateMembershipUpdateTestCase(unittest.HomeserverTestCase):
|
||||||
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
def prepare(self, reactor: MemoryReactor, clock: Clock, hs: HomeServer) -> None:
|
||||||
|
|
Loading…
Reference in a new issue