Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Abstract code for stripping room state into a separate method (#8671)
Browse files Browse the repository at this point in the history
This is a requirement for [knocking](#6739), and is abstracting some code that was originally used by the invite flow. I'm separating it out into this PR as it's a fairly contained change.

For a bit of context: when you invite a user to a room, you send them [stripped state events](https://matrix.org/docs/spec/server_server/unstable#put-matrix-federation-v2-invite-roomid-eventid) as part of `invite_room_state`. This is so that their client can display useful information such as the room name and avatar. The same requirement applies to knocking, as it would be nice for clients to be able to display a list of rooms you've knocked on - room name and avatar included.

The reason we're sending membership events down as well is in the case that you are invited to a room that does not have an avatar or name set. In that case, the client should use the displayname/avatar of the inviter. That information is located in the inviter's membership event.

This is optional as knocks don't really have any user in the room to link up to. When you knock on a room, your knock is sent by you and inserted into the room. It wouldn't *really* make sense to show the avatar of a random user - plus it'd be a data leak. So I've opted not to send membership events to the client here. The UX on the client for when you knock on a room without a name/avatar is a separate problem.

In essence this is just moving some inline code to a reusable store method.
  • Loading branch information
anoadragon453 authored Oct 27, 2020
1 parent 4215a3a commit a699c04
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 29 deletions.
1 change: 1 addition & 0 deletions changelog.d/8671.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Abstract some invite-related code in preparation for landing knocking.
35 changes: 7 additions & 28 deletions synapse/handlers/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -1100,34 +1100,13 @@ async def persist_and_notify_client_event(

if event.type == EventTypes.Member:
if event.content["membership"] == Membership.INVITE:

def is_inviter_member_event(e):
return e.type == EventTypes.Member and e.sender == event.sender

current_state_ids = await context.get_current_state_ids()

# We know this event is not an outlier, so this must be
# non-None.
assert current_state_ids is not None

state_to_include_ids = [
e_id
for k, e_id in current_state_ids.items()
if k[0] in self.room_invite_state_types
or k == (EventTypes.Member, event.sender)
]

state_to_include = await self.store.get_events(state_to_include_ids)

event.unsigned["invite_room_state"] = [
{
"type": e.type,
"state_key": e.state_key,
"content": e.content,
"sender": e.sender,
}
for e in state_to_include.values()
]
event.unsigned[
"invite_room_state"
] = await self.store.get_stripped_room_state_from_event_context(
context,
self.room_invite_state_types,
membership_user_id=event.sender,
)

invitee = UserID.from_string(event.state_key)
if not self.hs.is_mine(invitee):
Expand Down
54 changes: 53 additions & 1 deletion synapse/storage/databases/main/events_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
RoomVersions,
)
from synapse.events import EventBase, make_event_from_dict
from synapse.events.snapshot import EventContext
from synapse.events.utils import prune_event
from synapse.logging.context import PreserveLoggingContext, current_context
from synapse.metrics.background_process_metrics import (
Expand All @@ -44,7 +45,7 @@
from synapse.storage.database import DatabasePool
from synapse.storage.engines import PostgresEngine
from synapse.storage.util.id_generators import MultiWriterIdGenerator, StreamIdGenerator
from synapse.types import Collection, get_domain_from_id
from synapse.types import Collection, JsonDict, get_domain_from_id
from synapse.util.caches.descriptors import cached
from synapse.util.caches.lrucache import LruCache
from synapse.util.iterutils import batch_iter
Expand Down Expand Up @@ -525,6 +526,57 @@ def _get_events_from_cache(self, events, allow_rejected, update_metrics=True):

return event_map

async def get_stripped_room_state_from_event_context(
self,
context: EventContext,
state_types_to_include: List[EventTypes],
membership_user_id: Optional[str],
) -> List[JsonDict]:
"""
Retrieve the stripped state from a room, given an event context to retrieve state
from as well as the state types to include. Optionally, include the membership
events from a specific user.
"Stripped" state means that only the `type`, `state_key`, `content` and `sender` keys
are included from each state event.
Args:
context: The event context to retrieve state of the room from.
state_types_to_include: The type of state events to include.
membership_user_id: An optional user ID to include the stripped membership state
events of. This is useful when generating the stripped state of a room for
invites. We want to send membership events of the inviter, so that the
invitee can display the inviter's profile information if the room lacks any.
Returns:
A list of dictionaries, each representing a stripped state event from the room.
"""
current_state_ids = await context.get_current_state_ids()

# We know this event is not an outlier, so this must be
# non-None.
assert current_state_ids is not None

# The state to include
state_to_include_ids = [
e_id
for k, e_id in current_state_ids.items()
if k[0] in state_types_to_include
or (membership_user_id and k == (EventTypes.Member, membership_user_id))
]

state_to_include = await self.get_events(state_to_include_ids)

return [
{
"type": e.type,
"state_key": e.state_key,
"content": e.content,
"sender": e.sender,
}
for e in state_to_include.values()
]

def _do_fetch(self, conn):
"""Takes a database connection and waits for requests for events from
the _event_fetch_list queue.
Expand Down

0 comments on commit a699c04

Please sign in to comment.