Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MSC4174: add support for WebPush pusher kind #17987

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

MatMaul
Copy link
Contributor

@MatMaul MatMaul commented Dec 2, 2024

matrix-org/matrix-spec-proposals#4174

It has been tested using the hydrogen implementation.

Most of the code and doc is inspired from the sygnal implementation.

Pull Request Checklist

@MatMaul MatMaul force-pushed the msc4174 branch 7 times, most recently from a561f07 to 09ba9c3 Compare December 7, 2024 14:38
@github-actions github-actions bot deployed to PR Documentation Preview December 7, 2024 14:39 Active
@MatMaul MatMaul changed the title Add support of MSC4174 MSC4174: add support for WebPush pusher kind Dec 7, 2024
@github-actions github-actions bot deployed to PR Documentation Preview December 7, 2024 14:42 Active
@github-actions github-actions bot deployed to PR Documentation Preview December 7, 2024 14:54 Active
@github-actions github-actions bot deployed to PR Documentation Preview December 7, 2024 14:57 Active
@github-actions github-actions bot deployed to PR Documentation Preview December 7, 2024 17:39 Active
@MatMaul MatMaul marked this pull request as ready for review December 7, 2024 20:37
@MatMaul MatMaul requested a review from a team as a code owner December 7, 2024 20:37
@github-actions github-actions bot deployed to PR Documentation Preview December 9, 2024 16:04 Active
@github-actions github-actions bot deployed to PR Documentation Preview December 9, 2024 16:06 Active
@github-actions github-actions bot deployed to PR Documentation Preview December 9, 2024 16:39 Active
@github-actions github-actions bot deployed to PR Documentation Preview December 10, 2024 15:53 Active
@github-actions github-actions bot deployed to PR Documentation Preview December 13, 2024 11:43 Active
Copy link
Contributor

@MadLittleMods MadLittleMods left a comment

Choose a reason for hiding this comment

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

Here is a review of the code itself. I haven't inspected if this is actually a valid and good enough implementation of the WebPush spec itself.

so it can be used to pass identifiers specific to your client
(like which account the notification is for).

### events_only
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
### events_only
### `events_only`

any push message without a event id. This prevents your service worker being
forced to show a notification to push messages that clear the unread count.

### only_last_per_room
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
### only_last_per_room
### `only_last_per_room`

Comment on lines +6 to +13
In the synapse virtualenv, generate the server key pair by running
`vapid --gen --applicationServerKey`. This will generate a `private_key.pem`
(which you'll refer to in the config file with `vapid_private_key`)
and `public_key.pem` file, and also a string labeled `Application Server Key`.

You'll copy the Application Server Key to `vapid_app_server_key` so that
web applications can fetch it through `/capabilities` and use it to subscribe
to the push manager:
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems like a hassle. Any way to improve this?

Is it possible to make it generate if the file does not exist like we do for signing_key_path?

### `signing_key_path`
Path to the signing key to sign events and federation requests with.
*New in Synapse 1.67*: If this file does not exist, Synapse will create a new signing
key on startup and store it in this file.
Example configuration:
```yaml
signing_key_path: "CONFDIR/SERVERNAME.signing.key"
```

Does it matter if this key changes from time to time?

Copy link

Choose a reason for hiding this comment

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

It matters if the client isn't aware of this change

@@ -38,6 +38,14 @@
except ImportError:
HAS_AUTHLIB = False

# Determine whether pywebpush is installed.
try:
import pywebpush # noqa: F401
Copy link
Contributor

Choose a reason for hiding this comment

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

Comment why we noqa.

Suggested change
import pywebpush # noqa: F401
# This module is imported simply to detect whether the `pywebpush` is installed and
# is not used here; flake8 needn't warn that it's unused.
import pywebpush # noqa: F401

For example:

# This module is imported for its side effects; flake8 needn't warn that it's unused.
import synapse.metrics._reactor_metrics # noqa: F401

It looks like this is copying the pattern just above which should also have a note.

@@ -256,6 +264,28 @@ class MSC3866Config:
require_approval_for_new_accounts: bool = False


@attr.s(auto_attribs=True, frozen=True, slots=True)
class MSC4174Config:
"""Configuration for MSC4174"""
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
"""Configuration for MSC4174"""
"""Configuration for MSC4174: webpush push kind"""

Comment on lines +114 to +115
# ask for a 22 byte hash, so the base64 of it is 32,
# the limit webpush allows for the topic
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# ask for a 22 byte hash, so the base64 of it is 32,
# the limit webpush allows for the topic
# Ask for a 22-byte hash, so that when base64 the value, it ends up as 32-characters,
# which is the limit that webpush allows for the `topic`


async def send_webpush(self, content: JsonDict) -> Union[bool, List[str]]:
# web push only supports normal and low priority, so assume normal if absent
low_priority = content.get("prio") == "low"
Copy link
Contributor

Choose a reason for hiding this comment

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

"low" should be a constant PushPriority.LOW

Comment on lines +116 to +118
topic = urlsafe_b64encode(
blake2s(room_id.encode(), digest_size=22).digest()
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Sanity check our implementation

Suggested change
topic = urlsafe_b64encode(
blake2s(room_id.encode(), digest_size=22).digest()
)
topic = urlsafe_b64encode(
blake2s(room_id.encode(), digest_size=22).digest()
)
assert len(topic) == 32, "The max topic length that webpush allows is 32 characters"

def execute(
self, http_client: SimpleHttpClient, low_priority: bool, topic: bytes
) -> defer.Deferred[IResponse]:
# Convert the headers to the camelcase version.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this necessary?

The Headers type already does the canonicalization for you

MAX_CIPHERTEXT_LENGTH = 2000


class WebPushPusher(HttpPusher):
Copy link
Contributor

Choose a reason for hiding this comment

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

Any good tests we could add in tests/push/?

Just something that sanity checks that a push can be sent out so this continues to work into the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants