Skip to content

MSC4174: add support for WebPush pusher kind#17987

Open
MatMaul wants to merge 19 commits intoelement-hq:developfrom
MatMaul:msc4174
Open

MSC4174: add support for WebPush pusher kind#17987
MatMaul wants to merge 19 commits intoelement-hq:developfrom
MatMaul:msc4174

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.

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We would have to edit the config file since we need to also specify vapid_app_server_key.
However if we make vapid_app_server_key also (possibly) take a file as vapid_private_key does, it looks a lot more sane to do the generation on the fly.


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

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I should remove the camel case part. It's a straight copy paste from sygnal impl TBH.

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.

@@ -0,0 +1,2 @@
MSC4174: add support for WebPush pusher kind.
Copy link
Contributor

Choose a reason for hiding this comment

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

@MatMaul Any interest in continuing this implementation?

WebPush came up recently as an alternative to MSC3013: 'Encrypted Push' in terms of leaking room_id/event_id metadata.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am at it again 💪

"'vapid_contact_email' must be provided when enabling WebPush support",
("experimental", "msc4174", "vapid_contact_email"),
)
if not self.msc4174.vapid_private_key:
Copy link
Contributor Author

Choose a reason for hiding this comment

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

MAX_CIPHERTEXT_LENGTH = 2000


class WebPushPusher(HttpPusher):
Copy link
Contributor Author

Choose a reason for hiding this comment

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

A lot of the logic is reused, send_badge and dispatch_push are actually quite small compared to the rest of the logic in HttpPusher.
Also while email notif (it's not really push honestly :) ) content is quite different, having push content be mostly similar between them outside of medium specific properties makes sense I believe.

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

Choose a reason for hiding this comment

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

Yeah I should remove the camel case part. It's a straight copy paste from sygnal impl TBH.

) -> defer.Deferred[IResponse]:
# Convert the headers to the camelcase version.
headers = {
b"User-Agent": ["sygnal"],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oups 😇

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 Author

Choose a reason for hiding this comment

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

We would have to edit the config file since we need to also specify vapid_app_server_key.
However if we make vapid_app_server_key also (possibly) take a file as vapid_private_key does, it looks a lot more sane to do the generation on the fly.

@@ -0,0 +1,2 @@
MSC4174: add support for WebPush pusher kind.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am at it again 💪

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