Prevent 0-member/null room_version rooms from appearing in group room queries (#7465)

This commit is contained in:
Andrew Morgan 2020-05-15 17:17:42 +01:00 committed by GitHub
parent 1f36ff69e8
commit 16090a077f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 14 deletions

1
changelog.d/7465.bugfix Normal file
View File

@ -0,0 +1 @@
Prevent rooms with 0 members or with invalid version strings from breaking group queries.

View File

@ -68,24 +68,78 @@ class GroupServerWorkerStore(SQLBaseStore):
desc="get_invited_users_in_group", desc="get_invited_users_in_group",
) )
def get_rooms_in_group(self, group_id, include_private=False): def get_rooms_in_group(self, group_id: str, include_private: bool = False):
"""Retrieve the rooms that belong to a given group. Does not return rooms that
lack members.
Args:
group_id: The ID of the group to query for rooms
include_private: Whether to return private rooms in results
Returns:
Deferred[List[Dict[str, str|bool]]]: A list of dictionaries, each in the
form of:
{
"room_id": "!a_room_id:example.com", # The ID of the room
"is_public": False # Whether this is a public room or not
}
"""
# TODO: Pagination # TODO: Pagination
keyvalues = {"group_id": group_id} def _get_rooms_in_group_txn(txn):
if not include_private: sql = """
keyvalues["is_public"] = True SELECT room_id, is_public FROM group_rooms
WHERE group_id = ?
AND room_id IN (
SELECT group_rooms.room_id FROM group_rooms
LEFT JOIN room_stats_current ON
group_rooms.room_id = room_stats_current.room_id
AND joined_members > 0
AND local_users_in_room > 0
LEFT JOIN rooms ON
group_rooms.room_id = rooms.room_id
AND (room_version <> '') = ?
)
"""
args = [group_id, False]
return self.db.simple_select_list( if not include_private:
table="group_rooms", sql += " AND is_public = ?"
keyvalues=keyvalues, args += [True]
retcols=("room_id", "is_public"),
desc="get_rooms_in_group",
)
def get_rooms_for_summary_by_category(self, group_id, include_private=False): txn.execute(sql, args)
return [
{"room_id": room_id, "is_public": is_public}
for room_id, is_public in txn
]
return self.db.runInteraction("get_rooms_in_group", _get_rooms_in_group_txn)
def get_rooms_for_summary_by_category(
self, group_id: str, include_private: bool = False,
):
"""Get the rooms and categories that should be included in a summary request """Get the rooms and categories that should be included in a summary request
Returns ([rooms], [categories]) Args:
group_id: The ID of the group to query the summary for
include_private: Whether to return private rooms in results
Returns:
Deferred[Tuple[List, Dict]]: A tuple containing:
* A list of dictionaries with the keys:
* "room_id": str, the room ID
* "is_public": bool, whether the room is public
* "category_id": str|None, the category ID if set, else None
* "order": int, the sort order of rooms
* A dictionary with the key:
* category_id (str): a dictionary with the keys:
* "is_public": bool, whether the category is public
* "profile": str, the category profile
* "order": int, the sort order of rooms in this category
""" """
def _get_rooms_for_summary_txn(txn): def _get_rooms_for_summary_txn(txn):
@ -97,13 +151,23 @@ class GroupServerWorkerStore(SQLBaseStore):
SELECT room_id, is_public, category_id, room_order SELECT room_id, is_public, category_id, room_order
FROM group_summary_rooms FROM group_summary_rooms
WHERE group_id = ? WHERE group_id = ?
AND room_id IN (
SELECT group_rooms.room_id FROM group_rooms
LEFT JOIN room_stats_current ON
group_rooms.room_id = room_stats_current.room_id
AND joined_members > 0
AND local_users_in_room > 0
LEFT JOIN rooms ON
group_rooms.room_id = rooms.room_id
AND (room_version <> '') = ?
)
""" """
if not include_private: if not include_private:
sql += " AND is_public = ?" sql += " AND is_public = ?"
txn.execute(sql, (group_id, True)) txn.execute(sql, (group_id, False, True))
else: else:
txn.execute(sql, (group_id,)) txn.execute(sql, (group_id, False))
rooms = [ rooms = [
{ {