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

Fix push for invites received over federation #15820

Merged
merged 9 commits into from
Jul 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/15820.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix long-standing bug where remote invites weren't correctly pushed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this fix spurred on by anything? Context?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noticed the error in Sentry when I was looking at other stuff

37 changes: 36 additions & 1 deletion synapse/push/push_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.
from typing import Dict

from synapse.api.constants import EventTypes, Membership
from synapse.events import EventBase
from synapse.push.presentable_names import calculate_room_name, name_from_member_event
from synapse.storage.controllers import StorageControllers
Expand Down Expand Up @@ -49,7 +50,41 @@ async def get_badge_count(store: DataStore, user_id: str, group_by_room: bool) -
async def get_context_for_event(
storage: StorageControllers, ev: EventBase, user_id: str
) -> Dict[str, str]:
Comment on lines 50 to 52
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historical problem but this function name is confusing because EventContext is also a thing.

And it would be nice to return a dataclass here so it's obvious what keys are available.

ctx = {}
ctx: Dict[str, str] = {}

if ev.internal_metadata.outlier:
# We don't have state for outliers, so we can't compute the context
# except for invites and knocks. (Such events are known as 'out-of-band
# memberships' for the user).
if ev.type != EventTypes.Member:
return ctx

# We might be able to pull out the display name for the sender straight
# from the membership event
event_display_name = ev.content.get("displayname")
if event_display_name and ev.state_key == ev.sender:
ctx["sender_display_name"] = event_display_name

room_state = []
if ev.content.get("membership") == Membership.INVITE:
room_state = ev.unsigned.get("invite_room_state", [])
elif ev.content.get("membership") == Membership.KNOCK:
room_state = ev.unsigned.get("knock_room_state", [])

# Ideally we'd reuse the logic in `calculate_room_name`, but that gets
# complicated to handle partial events vs pulling events from the DB.
for state_dict in room_state:
type_tuple = (state_dict["type"], state_dict.get("state_key"))
if type_tuple == (EventTypes.Member, ev.sender):
display_name = state_dict["content"].get("displayname")
if display_name:
ctx["sender_display_name"] = display_name
elif type_tuple == (EventTypes.Name, ""):
room_name = state_dict["content"].get("name")
if room_name:
ctx["name"] = room_name

return ctx

room_state_ids = await storage.state.get_state_ids_for_event(ev.event_id)

MadLittleMods marked this conversation as resolved.
Show resolved Hide resolved
Expand Down