-
Notifications
You must be signed in to change notification settings - Fork 255
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
base: develop
Are you sure you want to change the base?
Conversation
a561f07
to
09ba9c3
Compare
There was a problem hiding this 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### only_last_per_room | |
### `only_last_per_room` |
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: |
There was a problem hiding this comment.
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
?
synapse/docs/usage/configuration/config_documentation.md
Lines 3128 to 3138 in 90a6bd0
### `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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment why we noqa
.
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:
synapse/synapse/metrics/__init__.py
Lines 53 to 54 in 9c5d08f
# 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""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"""Configuration for MSC4174""" | |
"""Configuration for MSC4174: webpush push kind""" |
# ask for a 22 byte hash, so the base64 of it is 32, | ||
# the limit webpush allows for the topic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 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" |
There was a problem hiding this comment.
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
topic = urlsafe_b64encode( | ||
blake2s(room_id.encode(), digest_size=22).digest() | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sanity check our implementation
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. |
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
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.
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
(run the linters)