MSC4076: Add disable_badge_count to pusher configuration (#17975)
Some checks are pending
Build docker images / build (push) Waiting to run
Deploy the documentation / Calculate variables for GitHub Pages deployment (push) Waiting to run
Deploy the documentation / GitHub Pages (push) Blocked by required conditions
Build release artifacts / Build sdist (push) Waiting to run
Build release artifacts / Calculate list of debian distros (push) Waiting to run
Build release artifacts / Build .deb packages (push) Blocked by required conditions
Build release artifacts / Build wheels on ubuntu-22.04 for aarch64 (push) Waiting to run
Build release artifacts / Build wheels on ubuntu-22.04 for x86_64 (push) Waiting to run
Build release artifacts / Attach assets to release (push) Blocked by required conditions
Tests / lint-pydantic (push) Blocked by required conditions
Tests / lint-clippy (push) Blocked by required conditions
Tests / lint-clippy-nightly (push) Blocked by required conditions
Tests / lint-rustfmt (push) Blocked by required conditions
Tests / lint-readme (push) Blocked by required conditions
Tests / calculate-test-jobs (push) Blocked by required conditions
Tests / linting-done (push) Blocked by required conditions
Tests / Typechecking (push) Blocked by required conditions
Tests / lint-crlf (push) Waiting to run
Tests / lint-newsfile (push) Waiting to run
Tests / changes (push) Waiting to run
Tests / check-sampleconfig (push) Blocked by required conditions
Tests / check-schema-delta (push) Blocked by required conditions
Tests / check-lockfile (push) Waiting to run
Tests / lint (push) Blocked by required conditions
Tests / trial (push) Blocked by required conditions
Tests / trial-olddeps (push) Blocked by required conditions
Tests / trial-pypy (all, pypy-3.9) (push) Blocked by required conditions
Tests / sytest (push) Blocked by required conditions
Tests / export-data (push) Blocked by required conditions
Tests / portdb (11, 3.9) (push) Blocked by required conditions
Tests / portdb (17, 3.13) (push) Blocked by required conditions
Tests / complement (monolith, Postgres) (push) Blocked by required conditions
Tests / complement (monolith, SQLite) (push) Blocked by required conditions
Tests / complement (workers, Postgres) (push) Blocked by required conditions
Tests / cargo-test (push) Blocked by required conditions
Tests / cargo-bench (push) Blocked by required conditions
Tests / tests-done (push) Blocked by required conditions

This PR implements [MSC4076: Let E2EE clients calculate app badge counts
themselves
(disable_badge_count)](https://github.com/matrix-org/matrix-spec-proposals/pull/4076).
This commit is contained in:
manuroe 2024-12-03 23:58:43 +01:00 committed by GitHub
parent 657dd5151e
commit abf44ad324
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 98 additions and 6 deletions

View file

@ -0,0 +1 @@
[MSC4076](https://github.com/matrix-org/matrix-spec-proposals/pull/4076): Add `disable_badge_count` to pusher configuration.

View file

@ -448,3 +448,6 @@ class ExperimentalConfig(Config):
# MSC4222: Adding `state_after` to sync v2 # MSC4222: Adding `state_after` to sync v2
self.msc4222_enabled: bool = experimental.get("msc4222_enabled", False) self.msc4222_enabled: bool = experimental.get("msc4222_enabled", False)
# MSC4076: Add `disable_badge_count`` to pusher configuration
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)

View file

@ -127,6 +127,11 @@ class HttpPusher(Pusher):
if self.data is None: if self.data is None:
raise PusherConfigException("'data' key can not be null for HTTP pusher") raise PusherConfigException("'data' key can not be null for HTTP pusher")
# Check if badge counts should be disabled for this push gateway
self.disable_badge_count = self.hs.config.experimental.msc4076_enabled and bool(
self.data.get("org.matrix.msc4076.disable_badge_count", False)
)
self.name = "%s/%s/%s" % ( self.name = "%s/%s/%s" % (
pusher_config.user_name, pusher_config.user_name,
pusher_config.app_id, pusher_config.app_id,
@ -461,9 +466,10 @@ class HttpPusher(Pusher):
content: JsonDict = { content: JsonDict = {
"event_id": event.event_id, "event_id": event.event_id,
"room_id": event.room_id, "room_id": event.room_id,
"counts": {"unread": badge},
"prio": priority, "prio": priority,
} }
if not self.disable_badge_count:
content["counts"] = {"unread": badge}
# event_id_only doesn't include the tweaks, so override them. # event_id_only doesn't include the tweaks, so override them.
tweaks = {} tweaks = {}
else: else:
@ -478,11 +484,11 @@ class HttpPusher(Pusher):
"type": event.type, "type": event.type,
"sender": event.user_id, "sender": event.user_id,
"prio": priority, "prio": priority,
"counts": {
"unread": badge,
# 'missed_calls': 2
},
} }
if not self.disable_badge_count:
content["counts"] = {
"unread": badge,
}
if event.type == "m.room.member" and event.is_state(): if event.type == "m.room.member" and event.is_state():
content["membership"] = event.content["membership"] content["membership"] = event.content["membership"]
content["user_is_target"] = event.state_key == self.user_id content["user_is_target"] = event.state_key == self.user_id

View file

@ -17,9 +17,11 @@
# [This file includes modifications made by New Vector Limited] # [This file includes modifications made by New Vector Limited]
# #
# #
from typing import Any, List, Tuple from typing import Any, Dict, List, Tuple
from unittest.mock import Mock from unittest.mock import Mock
from parameterized import parameterized
from twisted.internet.defer import Deferred from twisted.internet.defer import Deferred
from twisted.test.proto_helpers import MemoryReactor from twisted.test.proto_helpers import MemoryReactor
@ -1085,3 +1087,83 @@ class HTTPPusherTests(HomeserverTestCase):
self.pump() self.pump()
self.assertEqual(len(self.push_attempts), 11) self.assertEqual(len(self.push_attempts), 11)
@parameterized.expand(
[
# Badge count disabled
(True, True),
(True, False),
# Badge count enabled
(False, True),
(False, False),
]
)
@override_config({"experimental_features": {"msc4076_enabled": True}})
def test_msc4076_badge_count(
self, disable_badge_count: bool, event_id_only: bool
) -> None:
# Register the user who gets notified
user_id = self.register_user("user", "pass")
access_token = self.login("user", "pass")
# Register the user who sends the message
other_user_id = self.register_user("otheruser", "pass")
other_access_token = self.login("otheruser", "pass")
# Register the pusher with disable_badge_count set to True
user_tuple = self.get_success(
self.hs.get_datastores().main.get_user_by_access_token(access_token)
)
assert user_tuple is not None
device_id = user_tuple.device_id
# Set the push data dict based on test input parameters
push_data: Dict[str, Any] = {
"url": "http://example.com/_matrix/push/v1/notify",
}
if disable_badge_count:
push_data["org.matrix.msc4076.disable_badge_count"] = True
if event_id_only:
push_data["format"] = "event_id_only"
self.get_success(
self.hs.get_pusherpool().add_or_update_pusher(
user_id=user_id,
device_id=device_id,
kind="http",
app_id="m.http",
app_display_name="HTTP Push Notifications",
device_display_name="pushy push",
pushkey="a@example.com",
lang=None,
data=push_data,
)
)
# Create a room
room = self.helper.create_room_as(user_id, tok=access_token)
# The other user joins
self.helper.join(room=room, user=other_user_id, tok=other_access_token)
# The other user sends a message
self.helper.send(room, body="Hi!", tok=other_access_token)
# Advance time a bit, so the pusher will register something has happened
self.pump()
# One push was attempted to be sent
self.assertEqual(len(self.push_attempts), 1)
self.assertEqual(
self.push_attempts[0][1], "http://example.com/_matrix/push/v1/notify"
)
if disable_badge_count:
# Verify that the notification DOESN'T contain a counts field
self.assertNotIn("counts", self.push_attempts[0][2]["notification"])
else:
# Ensure that the notification DOES contain a counts field
self.assertIn("counts", self.push_attempts[0][2]["notification"])
self.assertEqual(
self.push_attempts[0][2]["notification"]["counts"]["unread"], 1
)