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

Commit 6caa303

Browse files
authored
fix: Push notifications for invite over federation (#13719)
1 parent 5c429b8 commit 6caa303

File tree

8 files changed

+42
-23
lines changed

8 files changed

+42
-23
lines changed

changelog.d/13719.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Send invite push notifications for invite over federation.

synapse/events/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,10 @@ def is_historical(self) -> bool:
289289
"""
290290
return self._dict.get("historical", False)
291291

292+
def is_notifiable(self) -> bool:
293+
"""Whether this event can trigger a push notification"""
294+
return not self.is_outlier() or self.is_out_of_band_membership()
295+
292296

293297
class EventBase(metaclass=abc.ABCMeta):
294298
@property

synapse/handlers/federation.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ def __init__(self, hs: "HomeServer"):
149149
self.http_client = hs.get_proxied_blacklisted_http_client()
150150
self._replication = hs.get_replication_data_handler()
151151
self._federation_event_handler = hs.get_federation_event_handler()
152+
self._bulk_push_rule_evaluator = hs.get_bulk_push_rule_evaluator()
152153

153154
self._clean_room_for_join_client = ReplicationCleanRoomRestServlet.make_client(
154155
hs
@@ -956,9 +957,15 @@ async def on_invite_request(
956957
)
957958

958959
context = EventContext.for_outlier(self._storage_controllers)
959-
await self._federation_event_handler.persist_events_and_notify(
960-
event.room_id, [(event, context)]
961-
)
960+
961+
await self._bulk_push_rule_evaluator.action_for_event_by_user(event, context)
962+
try:
963+
await self._federation_event_handler.persist_events_and_notify(
964+
event.room_id, [(event, context)]
965+
)
966+
except Exception:
967+
await self.store.remove_push_actions_from_staging(event.event_id)
968+
raise
962969

963970
return event
964971

synapse/handlers/federation_event.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,7 @@ async def persist_events_and_notify(
21702170
if instance != self._instance_name:
21712171
# Limit the number of events sent over replication. We choose 200
21722172
# here as that is what we default to in `max_request_body_size(..)`
2173+
result = {}
21732174
try:
21742175
for batch in batch_iter(event_and_contexts, 200):
21752176
result = await self._send_events(

synapse/push/bulk_push_rule_evaluator.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,11 @@ async def _get_rules_for_event(
173173

174174
async def _get_power_levels_and_sender_level(
175175
self, event: EventBase, context: EventContext
176-
) -> Tuple[dict, int]:
176+
) -> Tuple[dict, Optional[int]]:
177+
# There are no power levels and sender levels possible to get from outlier
178+
if event.internal_metadata.is_outlier():
179+
return {}, None
180+
177181
event_types = auth_types_for_event(event.room_version, event)
178182
prev_state_ids = await context.get_prev_state_ids(
179183
StateFilter.from_types(event_types)
@@ -250,8 +254,8 @@ async def action_for_event_by_user(
250254
should increment the unread count, and insert the results into the
251255
event_push_actions_staging table.
252256
"""
253-
if event.internal_metadata.is_outlier():
254-
# This can happen due to out of band memberships
257+
if not event.internal_metadata.is_notifiable():
258+
# Push rules for events that aren't notifiable can't be processed by this
255259
return
256260

257261
# Disable counting as unread unless the experimental configuration is

synapse/push/push_rule_evaluator.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,18 @@
4242
INEQUALITY_EXPR = re.compile("^([=<>]*)([0-9]*)$")
4343

4444

45-
def _room_member_count(
46-
ev: EventBase, condition: Mapping[str, Any], room_member_count: int
47-
) -> bool:
45+
def _room_member_count(condition: Mapping[str, Any], room_member_count: int) -> bool:
4846
return _test_ineq_condition(condition, room_member_count)
4947

5048

5149
def _sender_notification_permission(
52-
ev: EventBase,
5350
condition: Mapping[str, Any],
54-
sender_power_level: int,
51+
sender_power_level: Optional[int],
5552
power_levels: Dict[str, Union[int, Dict[str, int]]],
5653
) -> bool:
54+
if sender_power_level is None:
55+
return False
56+
5757
notif_level_key = condition.get("key")
5858
if notif_level_key is None:
5959
return False
@@ -129,7 +129,7 @@ def __init__(
129129
self,
130130
event: EventBase,
131131
room_member_count: int,
132-
sender_power_level: int,
132+
sender_power_level: Optional[int],
133133
power_levels: Dict[str, Union[int, Dict[str, int]]],
134134
relations: Dict[str, Set[Tuple[str, str]]],
135135
relations_match_enabled: bool,
@@ -198,10 +198,10 @@ def matches(
198198
elif condition["kind"] == "contains_display_name":
199199
return self._contains_display_name(display_name)
200200
elif condition["kind"] == "room_member_count":
201-
return _room_member_count(self._event, condition, self._room_member_count)
201+
return _room_member_count(condition, self._room_member_count)
202202
elif condition["kind"] == "sender_notification_permission":
203203
return _sender_notification_permission(
204-
self._event, condition, self._sender_power_level, self._power_levels
204+
condition, self._sender_power_level, self._power_levels
205205
)
206206
elif (
207207
condition["kind"] == "org.matrix.msc3772.relation_match"

synapse/storage/controllers/persist_events.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,16 +423,18 @@ async def enqueue(
423423
for d in ret_vals:
424424
replaced_events.update(d)
425425

426-
events = []
426+
persisted_events = []
427427
for event, _ in events_and_contexts:
428428
existing_event_id = replaced_events.get(event.event_id)
429429
if existing_event_id:
430-
events.append(await self.main_store.get_event(existing_event_id))
430+
persisted_events.append(
431+
await self.main_store.get_event(existing_event_id)
432+
)
431433
else:
432-
events.append(event)
434+
persisted_events.append(event)
433435

434436
return (
435-
events,
437+
persisted_events,
436438
self.main_store.get_room_max_token(),
437439
)
438440

synapse/storage/databases/main/events.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2134,13 +2134,13 @@ def _set_push_actions_for_event_and_users_txn(
21342134
appear in events_and_context.
21352135
"""
21362136

2137-
# Only non outlier events will have push actions associated with them,
2137+
# Only notifiable events will have push actions associated with them,
21382138
# so let's filter them out. (This makes joining large rooms faster, as
21392139
# these queries took seconds to process all the state events).
2140-
non_outlier_events = [
2140+
notifiable_events = [
21412141
event
21422142
for event, _ in events_and_contexts
2143-
if not event.internal_metadata.is_outlier()
2143+
if event.internal_metadata.is_notifiable()
21442144
]
21452145

21462146
sql = """
@@ -2153,7 +2153,7 @@ def _set_push_actions_for_event_and_users_txn(
21532153
WHERE event_id = ?
21542154
"""
21552155

2156-
if non_outlier_events:
2156+
if notifiable_events:
21572157
txn.execute_batch(
21582158
sql,
21592159
(
@@ -2163,7 +2163,7 @@ def _set_push_actions_for_event_and_users_txn(
21632163
event.depth,
21642164
event.event_id,
21652165
)
2166-
for event in non_outlier_events
2166+
for event in notifiable_events
21672167
),
21682168
)
21692169

0 commit comments

Comments
 (0)