Compare commits
28 Commits
release-v1
...
dmr/stater
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c9388f19e | ||
|
|
df8c0c44cf | ||
|
|
c07b3e3878 | ||
|
|
83fd6533b7 | ||
|
|
49fa59e3bb | ||
|
|
0c5424a5b5 | ||
|
|
315a8cbbb1 | ||
|
|
2c4af4fca8 | ||
|
|
a0387e896d | ||
|
|
41228675b6 | ||
|
|
b78717e658 | ||
|
|
d249b292a2 | ||
|
|
fa5d7dd6f5 | ||
|
|
8a2c3e0b05 | ||
|
|
593720f6b1 | ||
|
|
92d79770d1 | ||
|
|
510d9724c9 | ||
|
|
03aecf1ef3 | ||
|
|
4321a327cf | ||
|
|
2b96cfd869 | ||
|
|
d132cbaf6d | ||
|
|
2baa1fcbe6 | ||
|
|
f09b0b9643 | ||
|
|
534495e440 | ||
|
|
c8953500bc | ||
|
|
a8f52a1973 | ||
|
|
9b2e97ba6e | ||
|
|
087aa366a6 |
113
CHANGES.md
113
CHANGES.md
@@ -1,114 +1,7 @@
|
||||
Synapse 1.64.0 (2022-08-02)
|
||||
===========================
|
||||
Synapse vNext
|
||||
=============
|
||||
|
||||
No significant changes since 1.64.0rc2.
|
||||
|
||||
|
||||
Deprecation Warning
|
||||
-------------------
|
||||
|
||||
Synapse v1.66.0 will remove the ability to delegate the tasks of verifying email address ownership, and password reset confirmation, to an identity server.
|
||||
|
||||
If you require your homeserver to verify e-mail addresses or to support password resets via e-mail, please configure your homeserver with SMTP access so that it can send e-mails on its own behalf.
|
||||
[Consult the configuration documentation for more information.](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email)
|
||||
|
||||
|
||||
Synapse 1.64.0rc2 (2022-07-29)
|
||||
==============================
|
||||
|
||||
This RC reintroduces support for `account_threepid_delegates.email`, which was removed in 1.64.0rc1. It remains deprecated and will be removed altogether in Synapse v1.66.0. ([\#13406](https://github.com/matrix-org/synapse/issues/13406))
|
||||
|
||||
|
||||
Synapse 1.64.0rc1 (2022-07-26)
|
||||
==============================
|
||||
|
||||
This RC removed the ability to delegate the tasks of verifying email address ownership, and password reset confirmation, to an identity server.
|
||||
|
||||
We have also stopped building `.deb` packages for Ubuntu 21.10 as it is no longer an active version of Ubuntu.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Improve error messages when media thumbnails cannot be served. ([\#13038](https://github.com/matrix-org/synapse/issues/13038))
|
||||
- Allow pagination from remote event after discovering it from [MSC3030](https://github.com/matrix-org/matrix-spec-proposals/pull/3030) `/timestamp_to_event`. ([\#13205](https://github.com/matrix-org/synapse/issues/13205))
|
||||
- Add a `room_type` field in the responses for the list room and room details admin APIs. Contributed by @andrewdoh. ([\#13208](https://github.com/matrix-org/synapse/issues/13208))
|
||||
- Add support for room version 10. ([\#13220](https://github.com/matrix-org/synapse/issues/13220))
|
||||
- Add per-room rate limiting for room joins. For each room, Synapse now monitors the rate of join events in that room, and throttles additional joins if that rate grows too large. ([\#13253](https://github.com/matrix-org/synapse/issues/13253), [\#13254](https://github.com/matrix-org/synapse/issues/13254), [\#13255](https://github.com/matrix-org/synapse/issues/13255), [\#13276](https://github.com/matrix-org/synapse/issues/13276))
|
||||
- Support Implicit TLS (TLS without using a STARTTLS upgrade, typically on port 465) for sending emails, enabled by the new option `force_tls`. Contributed by Jan Schär. ([\#13317](https://github.com/matrix-org/synapse/issues/13317))
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix a bug introduced in Synapse 1.15.0 where adding a user through the Synapse Admin API with a phone number would fail if the `enable_email_notifs` and `email_notifs_for_new_users` options were enabled. Contributed by @thomasweston12. ([\#13263](https://github.com/matrix-org/synapse/issues/13263))
|
||||
- Fix a bug introduced in Synapse 1.40.0 where a user invited to a restricted room would be briefly unable to join. ([\#13270](https://github.com/matrix-org/synapse/issues/13270))
|
||||
- Fix a long-standing bug where, in rare instances, Synapse could store the incorrect state for a room after a state resolution. ([\#13278](https://github.com/matrix-org/synapse/issues/13278))
|
||||
- Fix a bug introduced in v1.18.0 where the `synapse_pushers` metric would overcount pushers when they are replaced. ([\#13296](https://github.com/matrix-org/synapse/issues/13296))
|
||||
- Disable autocorrection and autocapitalisation on the username text field shown during registration when using SSO. ([\#13350](https://github.com/matrix-org/synapse/issues/13350))
|
||||
- Update locked version of `frozendict` to 2.3.3, which has fixes for memory leaks affecting `/sync`. ([\#13284](https://github.com/matrix-org/synapse/issues/13284), [\#13352](https://github.com/matrix-org/synapse/issues/13352))
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Provide an example of using the Admin API. Contributed by @jejo86. ([\#13231](https://github.com/matrix-org/synapse/issues/13231))
|
||||
- Move the documentation for how URL previews work to the URL preview module. ([\#13233](https://github.com/matrix-org/synapse/issues/13233), [\#13261](https://github.com/matrix-org/synapse/issues/13261))
|
||||
- Add another `contrib` script to help set up worker processes. Contributed by @villepeh. ([\#13271](https://github.com/matrix-org/synapse/issues/13271))
|
||||
- Document that certain config options were added or changed in Synapse 1.62. Contributed by @behrmann. ([\#13314](https://github.com/matrix-org/synapse/issues/13314))
|
||||
- Document the new `rc_invites.per_issuer` throttling option added in Synapse 1.63. ([\#13333](https://github.com/matrix-org/synapse/issues/13333))
|
||||
- Mention that BuildKit is needed when building Docker images for tests. ([\#13338](https://github.com/matrix-org/synapse/issues/13338))
|
||||
- Improve Caddy reverse proxy documentation. ([\#13344](https://github.com/matrix-org/synapse/issues/13344))
|
||||
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Drop tables that were formerly used for groups/communities. ([\#12967](https://github.com/matrix-org/synapse/issues/12967))
|
||||
- Drop support for delegating email verification to an external server. ([\#13192](https://github.com/matrix-org/synapse/issues/13192))
|
||||
- Drop support for calling `/_matrix/client/v3/account/3pid/bind` without an `id_access_token`, which was not permitted by the spec. Contributed by @Vetchu. ([\#13239](https://github.com/matrix-org/synapse/issues/13239))
|
||||
- Stop building `.deb` packages for Ubuntu 21.10 (Impish Indri), which has reached end of life. ([\#13326](https://github.com/matrix-org/synapse/issues/13326))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Use lower transaction isolation level when purging rooms to avoid serialization errors. Contributed by Nick @ Beeper. ([\#12942](https://github.com/matrix-org/synapse/issues/12942))
|
||||
- Remove code which incorrectly attempted to reconcile state with remote servers when processing incoming events. ([\#12943](https://github.com/matrix-org/synapse/issues/12943))
|
||||
- Make the AS login method call `Auth.get_user_by_req` for checking the AS token. ([\#13094](https://github.com/matrix-org/synapse/issues/13094))
|
||||
- Always use a version of canonicaljson that supports the C implementation of frozendict. ([\#13172](https://github.com/matrix-org/synapse/issues/13172))
|
||||
- Add prometheus counters for ephemeral events and to device messages pushed to app services. Contributed by Brad @ Beeper. ([\#13175](https://github.com/matrix-org/synapse/issues/13175))
|
||||
- Refactor receipts servlet logic to avoid duplicated code. ([\#13198](https://github.com/matrix-org/synapse/issues/13198))
|
||||
- Preparation for database schema simplifications: populate `state_key` and `rejection_reason` for existing rows in the `events` table. ([\#13215](https://github.com/matrix-org/synapse/issues/13215))
|
||||
- Remove unused database table `event_reference_hashes`. ([\#13218](https://github.com/matrix-org/synapse/issues/13218))
|
||||
- Further reduce queries used sending events when creating new rooms. Contributed by Nick @ Beeper (@fizzadar). ([\#13224](https://github.com/matrix-org/synapse/issues/13224))
|
||||
- Call the v2 identity service `/3pid/unbind` endpoint, rather than v1. Contributed by @Vetchu. ([\#13240](https://github.com/matrix-org/synapse/issues/13240))
|
||||
- Use an asynchronous cache wrapper for the get event cache. Contributed by Nick @ Beeper (@fizzadar). ([\#13242](https://github.com/matrix-org/synapse/issues/13242), [\#13308](https://github.com/matrix-org/synapse/issues/13308))
|
||||
- Optimise federation sender and appservice pusher event stream processing queries. Contributed by Nick @ Beeper (@fizzadar). ([\#13251](https://github.com/matrix-org/synapse/issues/13251))
|
||||
- Log the stack when waiting for an entire room to be un-partial stated. ([\#13257](https://github.com/matrix-org/synapse/issues/13257))
|
||||
- Fix spurious warning when fetching state after a missing prev event. ([\#13258](https://github.com/matrix-org/synapse/issues/13258))
|
||||
- Clean-up tests for notifications. ([\#13260](https://github.com/matrix-org/synapse/issues/13260))
|
||||
- Do not fail build if complement with workers fails. ([\#13266](https://github.com/matrix-org/synapse/issues/13266))
|
||||
- Don't pull out state in `compute_event_context` for unconflicted state. ([\#13267](https://github.com/matrix-org/synapse/issues/13267), [\#13274](https://github.com/matrix-org/synapse/issues/13274))
|
||||
- Reduce the rebuild time for the complement-synapse docker image. ([\#13279](https://github.com/matrix-org/synapse/issues/13279))
|
||||
- Don't pull out the full state when creating an event. ([\#13281](https://github.com/matrix-org/synapse/issues/13281), [\#13307](https://github.com/matrix-org/synapse/issues/13307))
|
||||
- Upgrade from Poetry 1.1.12 to 1.1.14, to fix bugs when locking packages. ([\#13285](https://github.com/matrix-org/synapse/issues/13285))
|
||||
- Make `DictionaryCache` expire full entries if they haven't been queried in a while, even if specific keys have been queried recently. ([\#13292](https://github.com/matrix-org/synapse/issues/13292))
|
||||
- Use `HTTPStatus` constants in place of literals in tests. ([\#13297](https://github.com/matrix-org/synapse/issues/13297))
|
||||
- Improve performance of query `_get_subset_users_in_room_with_profiles`. ([\#13299](https://github.com/matrix-org/synapse/issues/13299))
|
||||
- Up batch size of `bulk_get_push_rules` and `_get_joined_profiles_from_event_ids`. ([\#13300](https://github.com/matrix-org/synapse/issues/13300))
|
||||
- Remove unnecessary `json.dumps` from tests. ([\#13303](https://github.com/matrix-org/synapse/issues/13303))
|
||||
- Reduce memory usage of sending dummy events. ([\#13310](https://github.com/matrix-org/synapse/issues/13310))
|
||||
- Prevent formatting changes of [#3679](https://github.com/matrix-org/synapse/pull/3679) from appearing in `git blame`. ([\#13311](https://github.com/matrix-org/synapse/issues/13311))
|
||||
- Change `get_users_in_room` and `get_rooms_for_user` caches to enable pruning of old entries. ([\#13313](https://github.com/matrix-org/synapse/issues/13313))
|
||||
- Validate federation destinations and log an error if a destination is invalid. ([\#13318](https://github.com/matrix-org/synapse/issues/13318))
|
||||
- Fix `FederationClient.get_pdu()` returning events from the cache as `outliers` instead of original events we saw over federation. ([\#13320](https://github.com/matrix-org/synapse/issues/13320))
|
||||
- Reduce memory usage of state caches. ([\#13323](https://github.com/matrix-org/synapse/issues/13323))
|
||||
- Reduce the amount of state we store in the `state_cache`. ([\#13324](https://github.com/matrix-org/synapse/issues/13324))
|
||||
- Add missing type hints to open tracing module. ([\#13328](https://github.com/matrix-org/synapse/issues/13328), [\#13345](https://github.com/matrix-org/synapse/issues/13345), [\#13362](https://github.com/matrix-org/synapse/issues/13362))
|
||||
- Remove old base slaved store and de-duplicate cache ID generators. Contributed by Nick @ Beeper (@fizzadar). ([\#13329](https://github.com/matrix-org/synapse/issues/13329), [\#13349](https://github.com/matrix-org/synapse/issues/13349))
|
||||
- When reporting metrics is enabled, use ~8x less data to describe DB transaction metrics. ([\#13342](https://github.com/matrix-org/synapse/issues/13342))
|
||||
- Faster room joins: skip soft fail checks while Synapse only has partial room state, since the current membership of event senders may not be accurately known. ([\#13354](https://github.com/matrix-org/synapse/issues/13354))
|
||||
As of this release, Synapse no longer allows the tasks of verifying email address ownership, and password reset confirmation, to be delegated to an identity server. For more information, see the [upgrade notes](https://matrix-org.github.io/synapse/v1.64/upgrade.html#upgrading-to-v1640).
|
||||
|
||||
|
||||
Synapse 1.63.1 (2022-07-20)
|
||||
|
||||
12
book.toml
12
book.toml
@@ -34,14 +34,6 @@ additional-css = [
|
||||
"docs/website_files/table-of-contents.css",
|
||||
"docs/website_files/remove-nav-buttons.css",
|
||||
"docs/website_files/indent-section-headers.css",
|
||||
"docs/website_files/version-picker.css",
|
||||
]
|
||||
additional-js = [
|
||||
"docs/website_files/table-of-contents.js",
|
||||
"docs/website_files/version-picker.js",
|
||||
"docs/website_files/version.js",
|
||||
]
|
||||
theme = "docs/website_files/theme"
|
||||
|
||||
[preprocessor.schema_versions]
|
||||
command = "./scripts-dev/schema_versions.py"
|
||||
additional-js = ["docs/website_files/table-of-contents.js"]
|
||||
theme = "docs/website_files/theme"
|
||||
1
changelog.d/12942.misc
Normal file
1
changelog.d/12942.misc
Normal file
@@ -0,0 +1 @@
|
||||
Use lower isolation level when purging rooms to avoid serialization errors. Contributed by Nick @ Beeper.
|
||||
1
changelog.d/12943.misc
Normal file
1
changelog.d/12943.misc
Normal file
@@ -0,0 +1 @@
|
||||
Remove code which incorrectly attempted to reconcile state with remote servers when processing incoming events.
|
||||
1
changelog.d/12967.removal
Normal file
1
changelog.d/12967.removal
Normal file
@@ -0,0 +1 @@
|
||||
Drop tables used for groups/communities.
|
||||
1
changelog.d/13038.feature
Normal file
1
changelog.d/13038.feature
Normal file
@@ -0,0 +1 @@
|
||||
Provide more info why we don't have any thumbnails to serve.
|
||||
1
changelog.d/13094.misc
Normal file
1
changelog.d/13094.misc
Normal file
@@ -0,0 +1 @@
|
||||
Make the AS login method call `Auth.get_user_by_req` for checking the AS token.
|
||||
1
changelog.d/13172.misc
Normal file
1
changelog.d/13172.misc
Normal file
@@ -0,0 +1 @@
|
||||
Always use a version of canonicaljson that supports the C implementation of frozendict.
|
||||
1
changelog.d/13175.misc
Normal file
1
changelog.d/13175.misc
Normal file
@@ -0,0 +1 @@
|
||||
Add prometheus counters for ephemeral events and to device messages pushed to app services. Contributed by Brad @ Beeper.
|
||||
1
changelog.d/13192.removal
Normal file
1
changelog.d/13192.removal
Normal file
@@ -0,0 +1 @@
|
||||
Drop support for delegating email verification to an external server.
|
||||
1
changelog.d/13198.misc
Normal file
1
changelog.d/13198.misc
Normal file
@@ -0,0 +1 @@
|
||||
Refactor receipts servlet logic to avoid duplicated code.
|
||||
1
changelog.d/13205.feature
Normal file
1
changelog.d/13205.feature
Normal file
@@ -0,0 +1 @@
|
||||
Allow pagination from remote event after discovering it from MSC3030 `/timestamp_to_event`.
|
||||
1
changelog.d/13208.feature
Normal file
1
changelog.d/13208.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add a `room_type` field in the responses for the list room and room details admin API. Contributed by @andrewdoh.
|
||||
1
changelog.d/13215.misc
Normal file
1
changelog.d/13215.misc
Normal file
@@ -0,0 +1 @@
|
||||
Preparation for database schema simplifications: populate `state_key` and `rejection_reason` for existing rows in the `events` table.
|
||||
1
changelog.d/13218.misc
Normal file
1
changelog.d/13218.misc
Normal file
@@ -0,0 +1 @@
|
||||
Remove unused database table `event_reference_hashes`.
|
||||
1
changelog.d/13220.feature
Normal file
1
changelog.d/13220.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add support for room version 10.
|
||||
1
changelog.d/13224.misc
Normal file
1
changelog.d/13224.misc
Normal file
@@ -0,0 +1 @@
|
||||
Further reduce queries used sending events when creating new rooms. Contributed by Nick @ Beeper (@fizzadar).
|
||||
1
changelog.d/13231.doc
Normal file
1
changelog.d/13231.doc
Normal file
@@ -0,0 +1 @@
|
||||
Provide an example of using the Admin API. Contributed by @jejo86.
|
||||
1
changelog.d/13233.doc
Normal file
1
changelog.d/13233.doc
Normal file
@@ -0,0 +1 @@
|
||||
Move the documentation for how URL previews work to the URL preview module.
|
||||
1
changelog.d/13239.removal
Normal file
1
changelog.d/13239.removal
Normal file
@@ -0,0 +1 @@
|
||||
Drop support for calling `/_matrix/client/v3/account/3pid/bind` without an `id_access_token`, which was not permitted by the spec. Contributed by @Vetchu.
|
||||
1
changelog.d/13240.misc
Normal file
1
changelog.d/13240.misc
Normal file
@@ -0,0 +1 @@
|
||||
Call the v2 identity service `/3pid/unbind` endpoint, rather than v1.
|
||||
1
changelog.d/13242.misc
Normal file
1
changelog.d/13242.misc
Normal file
@@ -0,0 +1 @@
|
||||
Use an asynchronous cache wrapper for the get event cache. Contributed by Nick @ Beeper (@fizzadar).
|
||||
1
changelog.d/13251.misc
Normal file
1
changelog.d/13251.misc
Normal file
@@ -0,0 +1 @@
|
||||
Optimise federation sender and appservice pusher event stream processing queries. Contributed by Nick @ Beeper (@fizzadar).
|
||||
1
changelog.d/13253.misc
Normal file
1
changelog.d/13253.misc
Normal file
@@ -0,0 +1 @@
|
||||
Preparatory work for a per-room rate limiter on joins.
|
||||
1
changelog.d/13254.misc
Normal file
1
changelog.d/13254.misc
Normal file
@@ -0,0 +1 @@
|
||||
Preparatory work for a per-room rate limiter on joins.
|
||||
1
changelog.d/13255.misc
Normal file
1
changelog.d/13255.misc
Normal file
@@ -0,0 +1 @@
|
||||
Preparatory work for a per-room rate limiter on joins.
|
||||
1
changelog.d/13257.misc
Normal file
1
changelog.d/13257.misc
Normal file
@@ -0,0 +1 @@
|
||||
Log the stack when waiting for an entire room to be un-partial stated.
|
||||
1
changelog.d/13258.misc
Normal file
1
changelog.d/13258.misc
Normal file
@@ -0,0 +1 @@
|
||||
Fix spurious warning when fetching state after a missing prev event.
|
||||
1
changelog.d/13260.misc
Normal file
1
changelog.d/13260.misc
Normal file
@@ -0,0 +1 @@
|
||||
Clean-up tests for notifications.
|
||||
1
changelog.d/13261.doc
Normal file
1
changelog.d/13261.doc
Normal file
@@ -0,0 +1 @@
|
||||
Move the documentation for how URL previews work to the URL preview module.
|
||||
1
changelog.d/13263.bugfix
Normal file
1
changelog.d/13263.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in Synapse 1.15.0 where adding a user through the Synapse Admin API with a phone number would fail if the "enable_email_notifs" and "email_notifs_for_new_users" options were enabled. Contributed by @thomasweston12.
|
||||
1
changelog.d/13266.misc
Normal file
1
changelog.d/13266.misc
Normal file
@@ -0,0 +1 @@
|
||||
Do not fail build if complement with workers fails.
|
||||
1
changelog.d/13267.misc
Normal file
1
changelog.d/13267.misc
Normal file
@@ -0,0 +1 @@
|
||||
Don't pull out state in `compute_event_context` for unconflicted state.
|
||||
1
changelog.d/13270.bugfix
Normal file
1
changelog.d/13270.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in Synapse 1.40 where a user invited to a restricted room would be briefly unable to join.
|
||||
1
changelog.d/13271.doc
Normal file
1
changelog.d/13271.doc
Normal file
@@ -0,0 +1 @@
|
||||
Add another `contrib` script to help set up worker processes. Contributed by @villepeh.
|
||||
1
changelog.d/13274.misc
Normal file
1
changelog.d/13274.misc
Normal file
@@ -0,0 +1 @@
|
||||
Don't pull out state in `compute_event_context` for unconflicted state.
|
||||
1
changelog.d/13276.feature
Normal file
1
changelog.d/13276.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add per-room rate limiting for room joins. For each room, Synapse now monitors the rate of join events in that room, and throttle additional joins if that rate grows too large.
|
||||
1
changelog.d/13278.bugfix
Normal file
1
changelog.d/13278.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix long-standing bug where in rare instances Synapse could store the incorrect state for a room after a state resolution.
|
||||
1
changelog.d/13279.misc
Normal file
1
changelog.d/13279.misc
Normal file
@@ -0,0 +1 @@
|
||||
Reduce the rebuild time for the complement-synapse docker image.
|
||||
1
changelog.d/13281.misc
Normal file
1
changelog.d/13281.misc
Normal file
@@ -0,0 +1 @@
|
||||
Don't pull out the full state when creating an event.
|
||||
1
changelog.d/13284.misc
Normal file
1
changelog.d/13284.misc
Normal file
@@ -0,0 +1 @@
|
||||
Update locked version of `frozendict` to 2.3.2, which has a fix for a memory leak.
|
||||
1
changelog.d/13285.misc
Normal file
1
changelog.d/13285.misc
Normal file
@@ -0,0 +1 @@
|
||||
Upgrade from Poetry 1.1.14 to 1.1.12, to fix bugs when locking packages.
|
||||
1
changelog.d/13292.misc
Normal file
1
changelog.d/13292.misc
Normal file
@@ -0,0 +1 @@
|
||||
Make `DictionaryCache` expire full entries if they haven't been queried in a while, even if specific keys have been queried recently.
|
||||
1
changelog.d/13296.bugfix
Normal file
1
changelog.d/13296.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in v1.18.0 where the `synapse_pushers` metric would overcount pushers when they are replaced.
|
||||
1
changelog.d/13297.misc
Normal file
1
changelog.d/13297.misc
Normal file
@@ -0,0 +1 @@
|
||||
Use `HTTPStatus` constants in place of literals in tests.
|
||||
1
changelog.d/13299.misc
Normal file
1
changelog.d/13299.misc
Normal file
@@ -0,0 +1 @@
|
||||
Improve performance of query `_get_subset_users_in_room_with_profiles`.
|
||||
1
changelog.d/13300.misc
Normal file
1
changelog.d/13300.misc
Normal file
@@ -0,0 +1 @@
|
||||
Up batch size of `bulk_get_push_rules` and `_get_joined_profiles_from_event_ids`.
|
||||
1
changelog.d/13303.misc
Normal file
1
changelog.d/13303.misc
Normal file
@@ -0,0 +1 @@
|
||||
Remove unnecessary `json.dumps` from tests.
|
||||
1
changelog.d/13307.misc
Normal file
1
changelog.d/13307.misc
Normal file
@@ -0,0 +1 @@
|
||||
Don't pull out the full state when creating an event.
|
||||
1
changelog.d/13308.misc
Normal file
1
changelog.d/13308.misc
Normal file
@@ -0,0 +1 @@
|
||||
Use an asynchronous cache wrapper for the get event cache. Contributed by Nick @ Beeper (@fizzadar).
|
||||
1
changelog.d/13310.misc
Normal file
1
changelog.d/13310.misc
Normal file
@@ -0,0 +1 @@
|
||||
Reduce memory usage of sending dummy events.
|
||||
1
changelog.d/13311.misc
Normal file
1
changelog.d/13311.misc
Normal file
@@ -0,0 +1 @@
|
||||
Prevent formatting changes of [#3679](https://github.com/matrix-org/synapse/pull/3679) from appearing in `git blame`.
|
||||
1
changelog.d/13313.misc
Normal file
1
changelog.d/13313.misc
Normal file
@@ -0,0 +1 @@
|
||||
Change `get_users_in_room` and `get_rooms_for_user` caches to enable pruning of old entries.
|
||||
1
changelog.d/13314.doc
Normal file
1
changelog.d/13314.doc
Normal file
@@ -0,0 +1 @@
|
||||
Add notes when config options where changed. Contributed by @behrmann.
|
||||
1
changelog.d/13318.misc
Normal file
1
changelog.d/13318.misc
Normal file
@@ -0,0 +1 @@
|
||||
Validate federation destinations and log an error if a destination is invalid.
|
||||
1
changelog.d/13320.misc
Normal file
1
changelog.d/13320.misc
Normal file
@@ -0,0 +1 @@
|
||||
Fix `FederationClient.get_pdu()` returning events from the cache as `outliers` instead of original events we saw over federation.
|
||||
1
changelog.d/13323.misc
Normal file
1
changelog.d/13323.misc
Normal file
@@ -0,0 +1 @@
|
||||
Reduce memory usage of state caches.
|
||||
1
changelog.d/13324.misc
Normal file
1
changelog.d/13324.misc
Normal file
@@ -0,0 +1 @@
|
||||
Reduce the amount of state we store in the `state_cache`.
|
||||
1
changelog.d/13326.removal
Normal file
1
changelog.d/13326.removal
Normal file
@@ -0,0 +1 @@
|
||||
Stop builindg `.deb` packages for Ubuntu 21.10 (Impish Indri), which has reached end of life.
|
||||
1
changelog.d/13328.misc
Normal file
1
changelog.d/13328.misc
Normal file
@@ -0,0 +1 @@
|
||||
Add missing type hints to open tracing module.
|
||||
1
changelog.d/13329.misc
Normal file
1
changelog.d/13329.misc
Normal file
@@ -0,0 +1 @@
|
||||
Remove old base slaved store and de-duplicate cache ID generators. Contributed by Nick @ Beeper (@fizzadar).
|
||||
1
changelog.d/13333.doc
Normal file
1
changelog.d/13333.doc
Normal file
@@ -0,0 +1 @@
|
||||
Document the new `rc_invites.per_issuer` throttling option added in Synapse 1.63.
|
||||
1
changelog.d/13338.doc
Normal file
1
changelog.d/13338.doc
Normal file
@@ -0,0 +1 @@
|
||||
Mention that BuildKit is needed when building Docker images for tests.
|
||||
1
changelog.d/13342.misc
Normal file
1
changelog.d/13342.misc
Normal file
@@ -0,0 +1 @@
|
||||
When reporting metrics is enabled, use ~8x less data to describe DB transaction metrics.
|
||||
1
changelog.d/13345.misc
Normal file
1
changelog.d/13345.misc
Normal file
@@ -0,0 +1 @@
|
||||
Add missing type hints to open tracing module.
|
||||
1
changelog.d/13349.misc
Normal file
1
changelog.d/13349.misc
Normal file
@@ -0,0 +1 @@
|
||||
Remove old base slaved store and de-duplicate cache ID generators. Contributed by Nick @ Beeper (@fizzadar).
|
||||
1
changelog.d/13352.bugfix
Normal file
1
changelog.d/13352.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Update locked version of `frozendict` to 2.3.3, which has fixes for memory leaks affecting `/sync`.
|
||||
1
changelog.d/13354.misc
Normal file
1
changelog.d/13354.misc
Normal file
@@ -0,0 +1 @@
|
||||
Faster room joins: skip soft fail checks while Synapse only has partial room state, since the current membership of event senders may not be accurately known.
|
||||
1
changelog.d/13362.misc
Normal file
1
changelog.d/13362.misc
Normal file
@@ -0,0 +1 @@
|
||||
Add missing type hints to open tracing module.
|
||||
1
changelog.d/13395.misc
Normal file
1
changelog.d/13395.misc
Normal file
@@ -0,0 +1 @@
|
||||
WIP: stateres debug script.
|
||||
18
debian/changelog
vendored
18
debian/changelog
vendored
@@ -1,21 +1,3 @@
|
||||
matrix-synapse-py3 (1.64.0) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.64.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 02 Aug 2022 10:32:30 +0100
|
||||
|
||||
matrix-synapse-py3 (1.64.0~rc2) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.64.0rc2.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Fri, 29 Jul 2022 12:22:53 +0100
|
||||
|
||||
matrix-synapse-py3 (1.64.0~rc1) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.64.0rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 26 Jul 2022 12:11:49 +0100
|
||||
|
||||
matrix-synapse-py3 (1.63.1) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.63.1.
|
||||
|
||||
@@ -79,32 +79,63 @@ server {
|
||||
}
|
||||
```
|
||||
|
||||
### Caddy v1
|
||||
|
||||
```
|
||||
matrix.example.com {
|
||||
proxy /_matrix http://localhost:8008 {
|
||||
transparent
|
||||
}
|
||||
|
||||
proxy /_synapse/client http://localhost:8008 {
|
||||
transparent
|
||||
}
|
||||
}
|
||||
|
||||
example.com:8448 {
|
||||
proxy / http://localhost:8008 {
|
||||
transparent
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Caddy v2
|
||||
|
||||
```
|
||||
matrix.example.com {
|
||||
reverse_proxy /_matrix/* localhost:8008
|
||||
reverse_proxy /_synapse/client/* localhost:8008
|
||||
reverse_proxy /_matrix/* http://localhost:8008
|
||||
reverse_proxy /_synapse/client/* http://localhost:8008
|
||||
}
|
||||
|
||||
example.com:8448 {
|
||||
reverse_proxy localhost:8008
|
||||
reverse_proxy http://localhost:8008
|
||||
}
|
||||
```
|
||||
|
||||
[Delegation](delegate.md) example:
|
||||
|
||||
```
|
||||
(matrix-well-known-header) {
|
||||
# Headers
|
||||
header Access-Control-Allow-Origin "*"
|
||||
header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
|
||||
header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
|
||||
header Content-Type "application/json"
|
||||
}
|
||||
|
||||
example.com {
|
||||
header /.well-known/matrix/* Content-Type application/json
|
||||
header /.well-known/matrix/* Access-Control-Allow-Origin *
|
||||
respond /.well-known/matrix/server `{"m.server": "matrix.example.com:443"}`
|
||||
respond /.well-known/matrix/client `{"m.homeserver":{"base_url":"https://matrix.example.com"},"m.identity_server":{"base_url":"https://identity.example.com"}}`
|
||||
handle /.well-known/matrix/server {
|
||||
import matrix-well-known-header
|
||||
respond `{"m.server":"matrix.example.com:443"}`
|
||||
}
|
||||
|
||||
handle /.well-known/matrix/client {
|
||||
import matrix-well-known-header
|
||||
respond `{"m.homeserver":{"base_url":"https://matrix.example.com"},"m.identity_server":{"base_url":"https://identity.example.com"}}`
|
||||
}
|
||||
}
|
||||
|
||||
matrix.example.com {
|
||||
reverse_proxy /_matrix/* localhost:8008
|
||||
reverse_proxy /_synapse/client/* localhost:8008
|
||||
reverse_proxy /_matrix/* http://localhost:8008
|
||||
reverse_proxy /_synapse/client/* http://localhost:8008
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -91,15 +91,18 @@ process, for example:
|
||||
|
||||
# Upgrading to v1.64.0
|
||||
|
||||
## Deprecation of the ability to delegate e-mail verification to identity servers
|
||||
## Delegation of email validation no longer supported
|
||||
|
||||
Synapse v1.66.0 will remove the ability to delegate the tasks of verifying email address ownership, and password reset confirmation, to an identity server.
|
||||
As of this version, Synapse no longer allows the tasks of verifying email address
|
||||
ownership, and password reset confirmation, to be delegated to an identity server.
|
||||
|
||||
If you require your homeserver to verify e-mail addresses or to support password resets via e-mail, please configure your homeserver with SMTP access so that it can send e-mails on its own behalf.
|
||||
[Consult the configuration documentation for more information.](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#email)
|
||||
|
||||
The option that will be removed is `account_threepid_delegates.email`.
|
||||
To continue to allow users to add email addresses to their homeserver accounts,
|
||||
and perform password resets, make sure that Synapse is configured with a
|
||||
working email server in the `email` configuration section (including, at a
|
||||
minimum, a `notif_from` setting.)
|
||||
|
||||
Specifying an `email` setting under `account_threepid_delegates` will now cause
|
||||
an error at startup.
|
||||
|
||||
## Changes to the event replication streams
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,11 +24,6 @@ Finally, we also stylise the chapter titles in the left sidebar by indenting the
|
||||
slightly so that they are more visually distinguishable from the section headers
|
||||
(the bold titles). This is done through the `indent-section-headers.css` file.
|
||||
|
||||
In addition to these modifications, we have added a version picker to the documentation.
|
||||
Users can switch between documentations for different versions of Synapse.
|
||||
This functionality was implemented through the `version-picker.js` and
|
||||
`version-picker.css` files.
|
||||
|
||||
More information can be found in mdbook's official documentation for
|
||||
[injecting page JS/CSS](https://rust-lang.github.io/mdBook/format/config.html)
|
||||
and
|
||||
|
||||
@@ -131,18 +131,6 @@
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
{{/if}}
|
||||
<div class="version-picker">
|
||||
<div class="dropdown">
|
||||
<div class="select">
|
||||
<span></span>
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
</div>
|
||||
<input type="hidden" name="version">
|
||||
<ul class="dropdown-menu">
|
||||
<!-- Versions will be added dynamically in version-picker.js -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1 class="menu-title">{{ book_title }}</h1>
|
||||
@@ -321,4 +309,4 @@
|
||||
{{/if}}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,78 +0,0 @@
|
||||
.version-picker {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.version-picker .dropdown {
|
||||
width: 130px;
|
||||
max-height: 29px;
|
||||
margin-left: 10px;
|
||||
display: inline-block;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--theme-popup-border);
|
||||
position: relative;
|
||||
font-size: 13px;
|
||||
color: var(--fg);
|
||||
height: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
.version-picker .dropdown .select {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
padding: 5px 2px 5px 15px;
|
||||
}
|
||||
.version-picker .dropdown .select > i {
|
||||
font-size: 10px;
|
||||
color: var(--fg);
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
line-height: 20px !important;
|
||||
}
|
||||
.version-picker .dropdown:hover {
|
||||
border: 1px solid var(--theme-popup-border);
|
||||
}
|
||||
.version-picker .dropdown:active {
|
||||
background-color: var(--theme-popup-bg);
|
||||
}
|
||||
.version-picker .dropdown.active:hover,
|
||||
.version-picker .dropdown.active {
|
||||
border: 1px solid var(--theme-popup-border);
|
||||
border-radius: 2px 2px 0 0;
|
||||
background-color: var(--theme-popup-bg);
|
||||
}
|
||||
.version-picker .dropdown.active .select > i {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
.version-picker .dropdown .dropdown-menu {
|
||||
position: absolute;
|
||||
background-color: var(--theme-popup-bg);
|
||||
width: 100%;
|
||||
left: -1px;
|
||||
right: 1px;
|
||||
margin-top: 1px;
|
||||
border: 1px solid var(--theme-popup-border);
|
||||
border-radius: 0 0 4px 4px;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
z-index: 9;
|
||||
}
|
||||
.version-picker .dropdown .dropdown-menu li {
|
||||
font-size: 12px;
|
||||
padding: 6px 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.version-picker .dropdown .dropdown-menu {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
.version-picker .dropdown .dropdown-menu li:hover {
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
.version-picker .dropdown .dropdown-menu li.active::before {
|
||||
display: inline-block;
|
||||
content: "✓";
|
||||
margin-inline-start: -14px;
|
||||
width: 14px;
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
|
||||
const dropdown = document.querySelector('.version-picker .dropdown');
|
||||
const dropdownMenu = dropdown.querySelector('.dropdown-menu');
|
||||
|
||||
fetchVersions(dropdown, dropdownMenu).then(() => {
|
||||
initializeVersionDropdown(dropdown, dropdownMenu);
|
||||
});
|
||||
|
||||
/**
|
||||
* Initialize the dropdown functionality for version selection.
|
||||
*
|
||||
* @param {Element} dropdown - The dropdown element.
|
||||
* @param {Element} dropdownMenu - The dropdown menu element.
|
||||
*/
|
||||
function initializeVersionDropdown(dropdown, dropdownMenu) {
|
||||
// Toggle the dropdown menu on click
|
||||
dropdown.addEventListener('click', function () {
|
||||
this.setAttribute('tabindex', 1);
|
||||
this.classList.toggle('active');
|
||||
dropdownMenu.style.display = (dropdownMenu.style.display === 'block') ? 'none' : 'block';
|
||||
});
|
||||
|
||||
// Remove the 'active' class and hide the dropdown menu on focusout
|
||||
dropdown.addEventListener('focusout', function () {
|
||||
this.classList.remove('active');
|
||||
dropdownMenu.style.display = 'none';
|
||||
});
|
||||
|
||||
// Handle item selection within the dropdown menu
|
||||
const dropdownMenuItems = dropdownMenu.querySelectorAll('li');
|
||||
dropdownMenuItems.forEach(function (item) {
|
||||
item.addEventListener('click', function () {
|
||||
dropdownMenuItems.forEach(function (item) {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
this.classList.add('active');
|
||||
dropdown.querySelector('span').textContent = this.textContent;
|
||||
dropdown.querySelector('input').value = this.getAttribute('id');
|
||||
|
||||
window.location.href = changeVersion(window.location.href, this.textContent);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* This function fetches the available versions from a GitHub repository
|
||||
* and inserts them into the version picker.
|
||||
*
|
||||
* @param {Element} dropdown - The dropdown element.
|
||||
* @param {Element} dropdownMenu - The dropdown menu element.
|
||||
* @returns {Promise<Array<string>>} A promise that resolves with an array of available versions.
|
||||
*/
|
||||
function fetchVersions(dropdown, dropdownMenu) {
|
||||
return new Promise((resolve, reject) => {
|
||||
window.addEventListener("load", () => {
|
||||
|
||||
fetch("https://api.github.com/repos/matrix-org/synapse/git/trees/gh-pages", {
|
||||
cache: "force-cache",
|
||||
}).then(res =>
|
||||
res.json()
|
||||
).then(resObject => {
|
||||
const excluded = ['dev-docs', 'v1.91.0', 'v1.80.0', 'v1.69.0'];
|
||||
const tree = resObject.tree.filter(item => item.type === "tree" && !excluded.includes(item.path));
|
||||
const versions = tree.map(item => item.path).sort(sortVersions);
|
||||
|
||||
// Create a list of <li> items for versions
|
||||
versions.forEach((version) => {
|
||||
const li = document.createElement("li");
|
||||
li.textContent = version;
|
||||
li.id = version;
|
||||
|
||||
if (window.SYNAPSE_VERSION === version) {
|
||||
li.classList.add('active');
|
||||
dropdown.querySelector('span').textContent = version;
|
||||
dropdown.querySelector('input').value = version;
|
||||
}
|
||||
|
||||
dropdownMenu.appendChild(li);
|
||||
});
|
||||
|
||||
resolve(versions);
|
||||
|
||||
}).catch(ex => {
|
||||
console.error("Failed to fetch version data", ex);
|
||||
reject(ex);
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom sorting function to sort an array of version strings.
|
||||
*
|
||||
* @param {string} a - The first version string to compare.
|
||||
* @param {string} b - The second version string to compare.
|
||||
* @returns {number} - A negative number if a should come before b, a positive number if b should come before a, or 0 if they are equal.
|
||||
*/
|
||||
function sortVersions(a, b) {
|
||||
// Put 'develop' and 'latest' at the top
|
||||
if (a === 'develop' || a === 'latest') return -1;
|
||||
if (b === 'develop' || b === 'latest') return 1;
|
||||
|
||||
const versionA = (a.match(/v\d+(\.\d+)+/) || [])[0];
|
||||
const versionB = (b.match(/v\d+(\.\d+)+/) || [])[0];
|
||||
|
||||
return versionB.localeCompare(versionA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the version in a URL path.
|
||||
*
|
||||
* @param {string} url - The original URL to be modified.
|
||||
* @param {string} newVersion - The new version to replace the existing version in the URL.
|
||||
* @returns {string} The updated URL with the new version.
|
||||
*/
|
||||
function changeVersion(url, newVersion) {
|
||||
const parsedURL = new URL(url);
|
||||
const pathSegments = parsedURL.pathname.split('/');
|
||||
|
||||
// Modify the version
|
||||
pathSegments[2] = newVersion;
|
||||
|
||||
// Reconstruct the URL
|
||||
parsedURL.pathname = pathSegments.join('/');
|
||||
|
||||
return parsedURL.href;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
window.SYNAPSE_VERSION = 'v1.64';
|
||||
12
mypy.ini
12
mypy.ini
@@ -141,9 +141,15 @@ ignore_missing_imports = True
|
||||
[mypy-canonicaljson]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-dictdiffer.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-ijson.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-incremental.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-lxml]
|
||||
ignore_missing_imports = True
|
||||
|
||||
@@ -158,6 +164,9 @@ ignore_missing_imports = True
|
||||
[mypy-parameterized.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pydot.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-pymacaroons.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
@@ -178,6 +187,3 @@ ignore_missing_imports = True
|
||||
|
||||
[mypy-treq.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-incremental.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
212
poetry.lock
generated
212
poetry.lock
generated
@@ -228,6 +228,20 @@ wrapt = ">=1.10,<2"
|
||||
[package.extras]
|
||||
dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"]
|
||||
|
||||
[[package]]
|
||||
name = "dictdiffer"
|
||||
version = "0.9.0"
|
||||
description = "Dictdiffer is a library that helps you to diff and patch dictionaries."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.extras]
|
||||
tests = ["pytest-pydocstyle (>=2.2.0)", "pytest-pycodestyle (>=2.2.0)", "pytest (>=6)", "pytest-pydocstyle (>=2)", "pytest-pycodestyle (>=2)", "pytest (==5.4.3)", "tox (>=3.7.0)", "sphinx (>=3)", "pytest-isort (>=1.2.0)", "pytest-cov (>=2.10.1)", "mock (>=1.3.0)", "check-manifest (>=0.42)"]
|
||||
numpy = ["numpy (>=1.20.0)", "numpy (>=1.18.0)", "numpy (>=1.15.0)", "numpy (>=1.13.0)"]
|
||||
docs = ["sphinx-rtd-theme (>=0.2)", "Sphinx (>=3)"]
|
||||
all = ["numpy (>=1.20.0)", "pytest-pydocstyle (>=2.2.0)", "pytest-pycodestyle (>=2.2.0)", "pytest (>=6)", "pytest-pydocstyle (>=2)", "pytest-pycodestyle (>=2)", "pytest (==5.4.3)", "numpy (>=1.18.0)", "numpy (>=1.15.0)", "numpy (>=1.13.0)", "tox (>=3.7.0)", "sphinx (>=3)", "pytest-isort (>=1.2.0)", "pytest-cov (>=2.10.1)", "mock (>=1.3.0)", "check-manifest (>=0.42)", "sphinx-rtd-theme (>=0.2)", "Sphinx (>=3)"]
|
||||
|
||||
[[package]]
|
||||
name = "docutils"
|
||||
version = "0.18.1"
|
||||
@@ -290,7 +304,7 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
|
||||
|
||||
[[package]]
|
||||
name = "frozendict"
|
||||
version = "2.3.3"
|
||||
version = "2.3.0"
|
||||
description = "A simple immutable dictionary"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -502,7 +516,7 @@ pyasn1 = ">=0.4.6"
|
||||
|
||||
[[package]]
|
||||
name = "lxml"
|
||||
version = "4.9.1"
|
||||
version = "4.8.0"
|
||||
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
|
||||
category = "main"
|
||||
optional = true
|
||||
@@ -540,7 +554,7 @@ test = ["tox", "twisted", "aiounittest"]
|
||||
|
||||
[[package]]
|
||||
name = "matrix-synapse-ldap3"
|
||||
version = "0.2.1"
|
||||
version = "0.2.0"
|
||||
description = "An LDAP3 auth provider for Synapse"
|
||||
category = "main"
|
||||
optional = true
|
||||
@@ -552,7 +566,7 @@ service-identity = "*"
|
||||
Twisted = ">=15.1.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["matrix-synapse", "tox", "ldaptor", "mypy (==0.910)", "types-setuptools", "black (==22.3.0)", "flake8 (==4.0.1)", "isort (==5.9.3)"]
|
||||
dev = ["isort (==5.9.3)", "flake8 (==4.0.1)", "black (==21.9b0)", "types-setuptools", "mypy (==0.910)", "ldaptor", "tox", "matrix-synapse"]
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
@@ -778,6 +792,17 @@ category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pydot"
|
||||
version = "1.4.2"
|
||||
description = "Python interface to Graphviz's Dot"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = ">=2.1.4"
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "2.4.0"
|
||||
@@ -1563,7 +1588,7 @@ url_preview = ["lxml"]
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.7.1"
|
||||
content-hash = "c24bbcee7e86dbbe7cdbf49f91a25b310bf21095452641e7440129f59b077f78"
|
||||
content-hash = "726ecbbacd7199e4f42517cbcafedeebf560e7fab0d45fc00f1611c9895ee4c2"
|
||||
|
||||
[metadata.files]
|
||||
attrs = [
|
||||
@@ -1732,6 +1757,10 @@ deprecated = [
|
||||
{file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"},
|
||||
{file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"},
|
||||
]
|
||||
dictdiffer = [
|
||||
{file = "dictdiffer-0.9.0-py2.py3-none-any.whl", hash = "sha256:442bfc693cfcadaf46674575d2eba1c53b42f5e404218ca2c2ff549f2df56595"},
|
||||
{file = "dictdiffer-0.9.0.tar.gz", hash = "sha256:17bacf5fbfe613ccf1b6d512bd766e6b21fb798822a133aa86098b8ac9997578"},
|
||||
]
|
||||
docutils = [
|
||||
{file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
|
||||
{file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
|
||||
@@ -1753,23 +1782,23 @@ flake8-comprehensions = [
|
||||
{file = "flake8_comprehensions-3.8.0-py3-none-any.whl", hash = "sha256:9406314803abe1193c064544ab14fdc43c58424c0882f6ff8a581eb73fc9bb58"},
|
||||
]
|
||||
frozendict = [
|
||||
{file = "frozendict-2.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39942914c1217a5a49c7551495a103b3dbd216e19413687e003b859c6b0ebc12"},
|
||||
{file = "frozendict-2.3.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5589256058b31f2b91419fa30b8dc62dbdefe7710e688a3fd5b43849161eecc9"},
|
||||
{file = "frozendict-2.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:35eb7e59e287c41f4f712d4d3d2333354175b155d217b97c99c201d2d8920790"},
|
||||
{file = "frozendict-2.3.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:310aaf81793abf4f471895e6fe65e0e74a28a2aaf7b25c2ba6ccd4e35af06842"},
|
||||
{file = "frozendict-2.3.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c353c11010a986566a0cb37f9a783c560ffff7d67d5e7fd52221fb03757cdc43"},
|
||||
{file = "frozendict-2.3.3-cp36-cp36m-win_amd64.whl", hash = "sha256:15b5f82aad108125336593cec1b6420c638bf45f449c57e50949fc7654ea5a41"},
|
||||
{file = "frozendict-2.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a4737e5257756bd6b877504ff50185b705db577b5330d53040a6cf6417bb3cdb"},
|
||||
{file = "frozendict-2.3.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80a14c11e33e8b0bc09e07bba3732c77a502c39edb8c3959fd9a0e490e031158"},
|
||||
{file = "frozendict-2.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:027952d1698ac9c766ef43711226b178cdd49d2acbdff396936639ad1d2a5615"},
|
||||
{file = "frozendict-2.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ef818d66c85098a37cf42509545a4ba7dd0c4c679d6262123a8dc14cc474bab7"},
|
||||
{file = "frozendict-2.3.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:812279f2b270c980112dc4e367b168054f937108f8044eced4199e0ab2945a37"},
|
||||
{file = "frozendict-2.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:c1fb7efbfebc2075f781be3d9774e4ba6ce4fc399148b02097f68d4b3c4bc00a"},
|
||||
{file = "frozendict-2.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a0b46d4bf95bce843c0151959d54c3e5b8d0ce29cb44794e820b3ec980d63eee"},
|
||||
{file = "frozendict-2.3.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38c4660f37fcc70a32ff997fe58e40b3fcc60b2017b286e33828efaa16b01308"},
|
||||
{file = "frozendict-2.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:919e3609844fece11ab18bcbf28a3ed20f8108ad4149d7927d413687f281c6c9"},
|
||||
{file = "frozendict-2.3.3-py3-none-any.whl", hash = "sha256:f988b482d08972a196664718167a993a61c9e9f6fe7b0ca2443570b5f20ca44a"},
|
||||
{file = "frozendict-2.3.3.tar.gz", hash = "sha256:398539c52af3c647d103185bbaa1291679f0507ad035fe3bab2a8b0366d52cf1"},
|
||||
{file = "frozendict-2.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e18e2abd144a9433b0a8334582843b2aa0d3b9ac8b209aaa912ad365115fe2e1"},
|
||||
{file = "frozendict-2.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96dc7a02e78da5725e5e642269bb7ae792e0c9f13f10f2e02689175ebbfedb35"},
|
||||
{file = "frozendict-2.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:752a6dcfaf9bb20a7ecab24980e4dbe041f154509c989207caf185522ef85461"},
|
||||
{file = "frozendict-2.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:5346d9fc1c936c76d33975a9a9f1a067342963105d9a403a99e787c939cc2bb2"},
|
||||
{file = "frozendict-2.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60dd2253f1bacb63a7c486ec541a968af4f985ffb06602ee8954a3d39ec6bd2e"},
|
||||
{file = "frozendict-2.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:b2e044602ce17e5cd86724add46660fb9d80169545164e763300a3b839cb1b79"},
|
||||
{file = "frozendict-2.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a27a69b1ac3591e4258325108aee62b53c0eeb6ad0a993ae68d3c7eaea980420"},
|
||||
{file = "frozendict-2.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f45ef5f6b184d84744fff97b61f6b9a855e24d36b713ea2352fc723a047afa5"},
|
||||
{file = "frozendict-2.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2d3f5016650c0e9a192f5024e68fb4d63f670d0ee58b099ed3f5b4c62ea30ecb"},
|
||||
{file = "frozendict-2.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6cf605916f50aabaaba5624c81eb270200f6c2c466c46960237a125ec8fe3ae0"},
|
||||
{file = "frozendict-2.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6da06e44904beae4412199d7e49be4f85c6cc168ab06b77c735ea7da5ce3454"},
|
||||
{file = "frozendict-2.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:1f34793fb409c4fa70ffd25bea87b01f3bd305fb1c6b09e7dff085b126302206"},
|
||||
{file = "frozendict-2.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fd72494a559bdcd28aa71f4aa81860269cd0b7c45fff3e2614a0a053ecfd2a13"},
|
||||
{file = "frozendict-2.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00ea9166aa68cc5feed05986206fdbf35e838a09cb3feef998cf35978ff8a803"},
|
||||
{file = "frozendict-2.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9ffaf440648b44e0bc694c1a4701801941378ba3ba6541e17750ae4b4aeeb116"},
|
||||
{file = "frozendict-2.3.0-py3-none-any.whl", hash = "sha256:8578fe06815fcdcc672bd5603eebc98361a5317c1c3a13b28c6c810f6ea3b323"},
|
||||
{file = "frozendict-2.3.0.tar.gz", hash = "sha256:da4231adefc5928e7810da2732269d3ad7b5616295b3e693746392a8205ea0b5"},
|
||||
]
|
||||
gitdb = [
|
||||
{file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"},
|
||||
@@ -1937,76 +1966,67 @@ ldap3 = [
|
||||
{file = "ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"},
|
||||
]
|
||||
lxml = [
|
||||
{file = "lxml-4.9.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-win32.whl", hash = "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3"},
|
||||
{file = "lxml-4.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627"},
|
||||
{file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84"},
|
||||
{file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-win32.whl", hash = "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7"},
|
||||
{file = "lxml-4.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b"},
|
||||
{file = "lxml-4.9.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d"},
|
||||
{file = "lxml-4.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3"},
|
||||
{file = "lxml-4.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-win32.whl", hash = "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7"},
|
||||
{file = "lxml-4.9.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-win32.whl", hash = "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e"},
|
||||
{file = "lxml-4.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-win32.whl", hash = "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a"},
|
||||
{file = "lxml-4.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-win32.whl", hash = "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94"},
|
||||
{file = "lxml-4.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-win32.whl", hash = "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb"},
|
||||
{file = "lxml-4.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d"},
|
||||
{file = "lxml-4.9.1-pp37-pypy37_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c"},
|
||||
{file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b"},
|
||||
{file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc"},
|
||||
{file = "lxml-4.9.1-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b"},
|
||||
{file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2"},
|
||||
{file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73"},
|
||||
{file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c"},
|
||||
{file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9"},
|
||||
{file = "lxml-4.9.1.tar.gz", hash = "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f"},
|
||||
{file = "lxml-4.8.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:e1ab2fac607842ac36864e358c42feb0960ae62c34aa4caaf12ada0a1fb5d99b"},
|
||||
{file = "lxml-4.8.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28d1af847786f68bec57961f31221125c29d6f52d9187c01cd34dc14e2b29430"},
|
||||
{file = "lxml-4.8.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b92d40121dcbd74831b690a75533da703750f7041b4bf951befc657c37e5695a"},
|
||||
{file = "lxml-4.8.0-cp27-cp27m-win32.whl", hash = "sha256:e01f9531ba5420838c801c21c1b0f45dbc9607cb22ea2cf132844453bec863a5"},
|
||||
{file = "lxml-4.8.0-cp27-cp27m-win_amd64.whl", hash = "sha256:6259b511b0f2527e6d55ad87acc1c07b3cbffc3d5e050d7e7bcfa151b8202df9"},
|
||||
{file = "lxml-4.8.0-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1010042bfcac2b2dc6098260a2ed022968dbdfaf285fc65a3acf8e4eb1ffd1bc"},
|
||||
{file = "lxml-4.8.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fa56bb08b3dd8eac3a8c5b7d075c94e74f755fd9d8a04543ae8d37b1612dd170"},
|
||||
{file = "lxml-4.8.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:31ba2cbc64516dcdd6c24418daa7abff989ddf3ba6d3ea6f6ce6f2ed6e754ec9"},
|
||||
{file = "lxml-4.8.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:31499847fc5f73ee17dbe1b8e24c6dafc4e8d5b48803d17d22988976b0171f03"},
|
||||
{file = "lxml-4.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5f7d7d9afc7b293147e2d506a4596641d60181a35279ef3aa5778d0d9d9123fe"},
|
||||
{file = "lxml-4.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a3c5f1a719aa11866ffc530d54ad965063a8cbbecae6515acbd5f0fae8f48eaa"},
|
||||
{file = "lxml-4.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6268e27873a3d191849204d00d03f65c0e343b3bcb518a6eaae05677c95621d1"},
|
||||
{file = "lxml-4.8.0-cp310-cp310-win32.whl", hash = "sha256:330bff92c26d4aee79c5bc4d9967858bdbe73fdbdbacb5daf623a03a914fe05b"},
|
||||
{file = "lxml-4.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:b2582b238e1658c4061ebe1b4df53c435190d22457642377fd0cb30685cdfb76"},
|
||||
{file = "lxml-4.8.0-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a2bfc7e2a0601b475477c954bf167dee6d0f55cb167e3f3e7cefad906e7759f6"},
|
||||
{file = "lxml-4.8.0-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a1547ff4b8a833511eeaceacbcd17b043214fcdb385148f9c1bc5556ca9623e2"},
|
||||
{file = "lxml-4.8.0-cp35-cp35m-win32.whl", hash = "sha256:a9f1c3489736ff8e1c7652e9dc39f80cff820f23624f23d9eab6e122ac99b150"},
|
||||
{file = "lxml-4.8.0-cp35-cp35m-win_amd64.whl", hash = "sha256:530f278849031b0eb12f46cca0e5db01cfe5177ab13bd6878c6e739319bae654"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:078306d19a33920004addeb5f4630781aaeabb6a8d01398045fcde085091a169"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:86545e351e879d0b72b620db6a3b96346921fa87b3d366d6c074e5a9a0b8dadb"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24f5c5ae618395ed871b3d8ebfcbb36e3f1091fd847bf54c4de623f9107942f3"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:bbab6faf6568484707acc052f4dfc3802bdb0cafe079383fbaa23f1cdae9ecd4"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7993232bd4044392c47779a3c7e8889fea6883be46281d45a81451acfd704d7e"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6d6483b1229470e1d8835e52e0ff3c6973b9b97b24cd1c116dca90b57a2cc613"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ad4332a532e2d5acb231a2e5d33f943750091ee435daffca3fec0a53224e7e33"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-win32.whl", hash = "sha256:db3535733f59e5605a88a706824dfcb9bd06725e709ecb017e165fc1d6e7d429"},
|
||||
{file = "lxml-4.8.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5f148b0c6133fb928503cfcdfdba395010f997aa44bcf6474fcdd0c5398d9b63"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:8a31f24e2a0b6317f33aafbb2f0895c0bce772980ae60c2c640d82caac49628a"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:719544565c2937c21a6f76d520e6e52b726d132815adb3447ccffbe9f44203c4"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:c0b88ed1ae66777a798dc54f627e32d3b81c8009967c63993c450ee4cbcbec15"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fa9b7c450be85bfc6cd39f6df8c5b8cbd76b5d6fc1f69efec80203f9894b885f"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e9f84ed9f4d50b74fbc77298ee5c870f67cb7e91dcdc1a6915cb1ff6a317476c"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1d650812b52d98679ed6c6b3b55cbb8fe5a5460a0aef29aeb08dc0b44577df85"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:80bbaddf2baab7e6de4bc47405e34948e694a9efe0861c61cdc23aa774fcb141"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-win32.whl", hash = "sha256:6f7b82934c08e28a2d537d870293236b1000d94d0b4583825ab9649aef7ddf63"},
|
||||
{file = "lxml-4.8.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e1fd7d2fe11f1cb63d3336d147c852f6d07de0d0020d704c6031b46a30b02ca8"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:5045ee1ccd45a89c4daec1160217d363fcd23811e26734688007c26f28c9e9e7"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0c1978ff1fd81ed9dcbba4f91cf09faf1f8082c9d72eb122e92294716c605428"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cbf2ff155b19dc4d4100f7442f6a697938bf4493f8d3b0c51d45568d5666b5"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ce13d6291a5f47c1c8dbd375baa78551053bc6b5e5c0e9bb8e39c0a8359fd52f"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11527dc23d5ef44d76fef11213215c34f36af1608074561fcc561d983aeb870"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:60d2f60bd5a2a979df28ab309352cdcf8181bda0cca4529769a945f09aba06f9"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:62f93eac69ec0f4be98d1b96f4d6b964855b8255c345c17ff12c20b93f247b68"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-win32.whl", hash = "sha256:20b8a746a026017acf07da39fdb10aa80ad9877046c9182442bf80c84a1c4696"},
|
||||
{file = "lxml-4.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:891dc8f522d7059ff0024cd3ae79fd224752676447f9c678f2a5c14b84d9a939"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b6fc2e2fb6f532cf48b5fed57567ef286addcef38c28874458a41b7837a57807"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:74eb65ec61e3c7c019d7169387d1b6ffcfea1b9ec5894d116a9a903636e4a0b1"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:627e79894770783c129cc5e89b947e52aa26e8e0557c7e205368a809da4b7939"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:545bd39c9481f2e3f2727c78c169425efbfb3fbba6e7db4f46a80ebb249819ca"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5a58d0b12f5053e270510bf12f753a76aaf3d74c453c00942ed7d2c804ca845c"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec4b4e75fc68da9dc0ed73dcdb431c25c57775383fec325d23a770a64e7ebc87"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5804e04feb4e61babf3911c2a974a5b86f66ee227cc5006230b00ac6d285b3a9"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-win32.whl", hash = "sha256:aa0cf4922da7a3c905d000b35065df6184c0dc1d866dd3b86fd961905bbad2ea"},
|
||||
{file = "lxml-4.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:dd10383f1d6b7edf247d0960a3db274c07e96cf3a3fc7c41c8448f93eac3fb1c"},
|
||||
{file = "lxml-4.8.0-pp37-pypy37_pp73-macosx_10_14_x86_64.whl", hash = "sha256:2403a6d6fb61c285969b71f4a3527873fe93fd0abe0832d858a17fe68c8fa507"},
|
||||
{file = "lxml-4.8.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:986b7a96228c9b4942ec420eff37556c5777bfba6758edcb95421e4a614b57f9"},
|
||||
{file = "lxml-4.8.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6fe4ef4402df0250b75ba876c3795510d782def5c1e63890bde02d622570d39e"},
|
||||
{file = "lxml-4.8.0-pp38-pypy38_pp73-macosx_10_14_x86_64.whl", hash = "sha256:f10ce66fcdeb3543df51d423ede7e238be98412232fca5daec3e54bcd16b8da0"},
|
||||
{file = "lxml-4.8.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:730766072fd5dcb219dd2b95c4c49752a54f00157f322bc6d71f7d2a31fecd79"},
|
||||
{file = "lxml-4.8.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8b99ec73073b37f9ebe8caf399001848fced9c08064effdbfc4da2b5a8d07b93"},
|
||||
{file = "lxml-4.8.0.tar.gz", hash = "sha256:f63f62fc60e6228a4ca9abae28228f35e1bd3ce675013d1dfb828688d50c6e23"},
|
||||
]
|
||||
markupsafe = [
|
||||
{file = "MarkupSafe-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3028252424c72b2602a323f70fbf50aa80a5d3aa616ea6add4ba21ae9cc9da4c"},
|
||||
@@ -2055,8 +2075,8 @@ matrix-common = [
|
||||
{file = "matrix_common-1.2.1.tar.gz", hash = "sha256:a99dcf02a6bd95b24a5a61b354888a2ac92bf2b4b839c727b8dd9da2cdfa3853"},
|
||||
]
|
||||
matrix-synapse-ldap3 = [
|
||||
{file = "matrix-synapse-ldap3-0.2.1.tar.gz", hash = "sha256:bfb4390f4a262ffb0d6f057ff3aeb1e46d4e52ff420a064d795fb4f555f00285"},
|
||||
{file = "matrix_synapse_ldap3-0.2.1-py3-none-any.whl", hash = "sha256:1b3310a60f1d06466f35905a269b6df95747fd1305f2b7fe638f373963b2aa2c"},
|
||||
{file = "matrix-synapse-ldap3-0.2.0.tar.gz", hash = "sha256:91a0715b43a41ec3033244174fca20846836da98fda711fb01687f7199eecd2e"},
|
||||
{file = "matrix_synapse_ldap3-0.2.0-py3-none-any.whl", hash = "sha256:0128ca7c3058987adc2e8a88463bb46879915bfd3d373309632813b353e30f9f"},
|
||||
]
|
||||
mccabe = [
|
||||
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
|
||||
@@ -2260,6 +2280,10 @@ pycparser = [
|
||||
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
pydot = [
|
||||
{file = "pydot-1.4.2-py2.py3-none-any.whl", hash = "sha256:66c98190c65b8d2e2382a441b4c0edfdb4f4c025ef9cb9874de478fb0793a451"},
|
||||
{file = "pydot-1.4.2.tar.gz", hash = "sha256:248081a39bcb56784deb018977e428605c1c758f10897a339fce1dd728ff007d"},
|
||||
]
|
||||
pyflakes = [
|
||||
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
|
||||
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
|
||||
|
||||
@@ -54,7 +54,7 @@ skip_gitignore = true
|
||||
|
||||
[tool.poetry]
|
||||
name = "matrix-synapse"
|
||||
version = "1.64.0"
|
||||
version = "1.63.1"
|
||||
description = "Homeserver for the Matrix decentralised comms protocol"
|
||||
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
|
||||
license = "Apache-2.0"
|
||||
@@ -281,6 +281,10 @@ twine = "*"
|
||||
# Towncrier min version comes from #3425. Rationale unclear.
|
||||
towncrier = ">=18.6.0rc1"
|
||||
|
||||
# Used by the debug_state_res dev script
|
||||
dictdiffer = ">=0.9.0"
|
||||
pydot = ">=1.4.2"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
332
scripts-dev/debug_state_res.py
Executable file
332
scripts-dev/debug_state_res.py
Executable file
@@ -0,0 +1,332 @@
|
||||
#! /usr/bin/env python
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
from pprint import pformat
|
||||
from typing import Awaitable, Callable, Collection, Dict, List, Optional, Tuple, cast
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import dictdiffer
|
||||
import pydot
|
||||
import yaml
|
||||
|
||||
from twisted.internet import task
|
||||
|
||||
from synapse.config._base import RootConfig
|
||||
from synapse.config.cache import CacheConfig
|
||||
from synapse.config.database import DatabaseConfig
|
||||
from synapse.config.workers import WorkerConfig
|
||||
from synapse.events import EventBase
|
||||
from synapse.server import HomeServer
|
||||
from synapse.state import StateResolutionStore
|
||||
from synapse.storage.databases.main.event_federation import EventFederationWorkerStore
|
||||
from synapse.storage.databases.main.events_worker import EventsWorkerStore
|
||||
from synapse.storage.databases.main.room import RoomWorkerStore
|
||||
from synapse.storage.databases.main.state import StateGroupWorkerStore
|
||||
from synapse.storage.state import StateFilter
|
||||
from synapse.types import ISynapseReactor, StateMap
|
||||
|
||||
"""This monstrosity is useful for visualising and debugging state resolution problems.
|
||||
|
||||
|
||||
"""
|
||||
|
||||
logger = logging.getLogger(sys.argv[0])
|
||||
|
||||
|
||||
# Bits of the HomeServer Machinery we need to talk to the DB.
|
||||
class Config(RootConfig):
|
||||
config_classes = [DatabaseConfig, WorkerConfig, CacheConfig]
|
||||
|
||||
|
||||
def load_config(source: str) -> Config:
|
||||
data = yaml.safe_load(source)
|
||||
data["worker_name"] = "stateres-debug"
|
||||
|
||||
config = Config()
|
||||
config.parse_config_dict(data, "DUMMYPATH", "DUMMYPATH")
|
||||
config.key = MagicMock() # Don't bother creating signing keys
|
||||
return config
|
||||
|
||||
|
||||
class DataStore(
|
||||
StateGroupWorkerStore,
|
||||
EventFederationWorkerStore,
|
||||
EventsWorkerStore,
|
||||
RoomWorkerStore,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
class MockHomeserver(HomeServer):
|
||||
DATASTORE_CLASS = DataStore # type: ignore [assignment]
|
||||
|
||||
def __init__(self, config: Config):
|
||||
super(MockHomeserver, self).__init__(
|
||||
hostname="stateres-debug",
|
||||
config=config, # type: ignore[arg-type]
|
||||
)
|
||||
|
||||
|
||||
# Functions for drawing graphviz diagrams via `pydot`.
|
||||
def node(
|
||||
event: EventBase, suffix: Optional[str] = None, **kwargs: object
|
||||
) -> pydot.Node:
|
||||
if "label" not in kwargs:
|
||||
label = (
|
||||
f"{event.event_id}\n{event.sender}: {(event.type,event.get_state_key())}"
|
||||
)
|
||||
if event.type == "m.room.member":
|
||||
label += f" ({event.membership.upper()})"
|
||||
if suffix:
|
||||
label += f"\n{suffix}"
|
||||
kwargs["label"] = label
|
||||
type_to_shape: Dict[str, str] = {} # {"m.room.member": "oval"}
|
||||
if event.type in type_to_shape:
|
||||
kwargs.setdefault("shape", type_to_shape[event.type])
|
||||
|
||||
q = pydot.quote_if_necessary
|
||||
return pydot.Node(q(event.event_id), **kwargs)
|
||||
|
||||
|
||||
def edge(source: EventBase, target: EventBase, **kwargs: object) -> pydot.Edge:
|
||||
return pydot.Edge(
|
||||
pydot.quote_if_necessary(source.event_id),
|
||||
pydot.quote_if_necessary(target.event_id),
|
||||
**kwargs,
|
||||
)
|
||||
|
||||
|
||||
async def dump_mainlines(
|
||||
hs: MockHomeserver,
|
||||
resolve_point: Optional[EventBase],
|
||||
events: Collection[EventBase],
|
||||
extras: Collection[str],
|
||||
watch_func: Optional[Callable[[EventBase], Awaitable[str]]] = None,
|
||||
) -> None:
|
||||
"""Visualise the auth DAG above a given `starting_event`.
|
||||
|
||||
Starting with the given event's parents and any `extras` of interest, we search in
|
||||
their auth events for power levels, join rules and sender membership events.
|
||||
We recursively repeat this process for any events found during the search
|
||||
until we have no more auth-ancestors of interest to find.
|
||||
|
||||
In this way we build up a subset of the auth chain of the `starting_event`.
|
||||
(In particular we omit edges to m.room.create: they are everywhere and convey no
|
||||
information.)
|
||||
|
||||
An optional `watch_func` allows us to annotate the events we see with a string of
|
||||
our choice. This can be useful if we want to track a single piece of state through
|
||||
the auth DAG.
|
||||
"""
|
||||
graph = pydot.Dot(rankdir="BT")
|
||||
graph.set_node_defaults(shape="box", style="filled")
|
||||
|
||||
async def new_node(event: EventBase, **kwargs: object) -> pydot.Node:
|
||||
suffix = await watch_func(event) if watch_func else None
|
||||
return node(event, suffix, **kwargs)
|
||||
|
||||
seen = set()
|
||||
todo: List[EventBase] = []
|
||||
|
||||
if resolve_point:
|
||||
graph.add_node(await new_node(resolve_point, fillcolor="#6699cc"))
|
||||
seen.add(resolve_point.event_id)
|
||||
|
||||
for parent in events:
|
||||
graph.add_node(await new_node(parent, fillcolor="#6699cc"))
|
||||
seen.add(parent.event_id)
|
||||
todo.append(parent)
|
||||
if resolve_point:
|
||||
graph.add_edge(edge(resolve_point, parent, style="dashed"))
|
||||
|
||||
if extras:
|
||||
logger.debug(extras)
|
||||
extra_events = await hs.get_datastores().main.get_events(extras)
|
||||
logger.debug(extra_events)
|
||||
for extra_event in extra_events.values():
|
||||
if extra_event.event_id in seen:
|
||||
continue
|
||||
graph.add_node(await new_node(extra_event, fillcolor="#6699ee"))
|
||||
todo.append(extra_event)
|
||||
|
||||
async def fetch_auth_events(event: EventBase) -> StateMap[EventBase]:
|
||||
return {
|
||||
(e.type, e.state_key): e
|
||||
for e in (
|
||||
await hs.get_datastores().main.get_events(event.auth_event_ids())
|
||||
).values()
|
||||
}
|
||||
|
||||
while todo:
|
||||
event = todo.pop()
|
||||
auth_events = await fetch_auth_events(event)
|
||||
|
||||
for key, edge_style in [
|
||||
(("m.room.power_levels", ""), "solid"),
|
||||
(("m.room.join_rules", ""), "solid"),
|
||||
(("m.room.member", event.sender), "dotted"),
|
||||
# TODO: handle that state_key might be missing
|
||||
# (("m.room.member", event.state_key), "solid"),
|
||||
]:
|
||||
auth_event = auth_events.get(key)
|
||||
if auth_event:
|
||||
if auth_event.event_id not in seen:
|
||||
node_options = {}
|
||||
if key[0] == "m.room.power_levels":
|
||||
node_options["fillcolor"] = "#ffcccc"
|
||||
elif key[0] == "m.room.join_rules":
|
||||
node_options["fillcolor"] = "#cc9966"
|
||||
elif key == ("m.room.member", event.sender):
|
||||
auth_events_2 = await fetch_auth_events(auth_event)
|
||||
if ("m.room.member", event.sender) not in auth_events_2:
|
||||
# auth_event is the first join of that sender
|
||||
node_options["fillcolor"] = "#33ff33"
|
||||
else:
|
||||
node_options["fillcolor"] = "#ccffcc"
|
||||
|
||||
graph.add_node(await new_node(auth_event, **node_options))
|
||||
seen.add(auth_event.event_id)
|
||||
todo.append(auth_event)
|
||||
graph.add_edge(edge(event, auth_event, style=edge_style))
|
||||
|
||||
# TODO: make this location configurable
|
||||
graph.write_svg("mainlines.svg")
|
||||
|
||||
|
||||
# The main logic and the arguments we need to invoke it.
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Debug the stateres calculation of a specific event."
|
||||
)
|
||||
parser.add_argument(
|
||||
"config_file", help="Synapse config file", type=argparse.FileType("r")
|
||||
)
|
||||
parser.add_argument("--verbose", "-v", help="Log verbosely", action="store_true")
|
||||
parser.add_argument("-d", "--draw", help="Render auth DAG", action="store_true")
|
||||
parser.add_argument(
|
||||
"event_ids",
|
||||
help="""\
|
||||
The event ID(s) to be resolved.\
|
||||
|
||||
If a single event is given, resolve across all of its parents to compute the state
|
||||
before the given event. If multiple events are given, resolve across them directly.
|
||||
""",
|
||||
nargs="+",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
"--extra",
|
||||
dest="extras",
|
||||
help=(
|
||||
"An extra event to include in the auth DAG when using the `--draw` flag. "
|
||||
"Can be provided multiple times."
|
||||
),
|
||||
action="append",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--watch",
|
||||
help="Track a piece of state in the auth DAG when using the `--draw` flag.",
|
||||
default=None,
|
||||
nargs=2,
|
||||
metavar=("TYPE", "STATE_KEY"),
|
||||
)
|
||||
|
||||
|
||||
async def debug_specific_stateres(
|
||||
reactor: ISynapseReactor, hs: MockHomeserver, args: argparse.Namespace
|
||||
) -> None:
|
||||
"""Recompute the state at the given event.
|
||||
|
||||
This produces
|
||||
- a file called `mainline.svg` representing the auth chain of the given event,
|
||||
- logging from state resolution calculations, written to stdout,
|
||||
- the recomputed and stored state, written to stdout, and
|
||||
- their difference, written to stdout.
|
||||
"""
|
||||
DEBUG_AT_EVENT = len(args.event_ids) == 1
|
||||
|
||||
if DEBUG_AT_EVENT:
|
||||
resolve_point = await hs.get_datastores().main.get_event(args.event_ids[0])
|
||||
prev_event_ids = resolve_point.prev_event_ids()
|
||||
else:
|
||||
resolve_point = None
|
||||
prev_event_ids = args.event_ids
|
||||
|
||||
parent_events = (await hs.get_datastores().main.get_events(prev_event_ids)).values()
|
||||
sample_event = next(iter(parent_events))
|
||||
|
||||
logger.info("Resolving across %d parents, %s", len(prev_event_ids), prev_event_ids)
|
||||
state_after_parents = [
|
||||
await hs.get_storage_controllers().state.get_state_ids_for_event(prev_event_id)
|
||||
for prev_event_id in prev_event_ids
|
||||
]
|
||||
|
||||
if args.watch is not None:
|
||||
key_pair = cast(Tuple[str, str], tuple(args.watch))
|
||||
filter = StateFilter.from_types([key_pair])
|
||||
|
||||
watch_func: Optional[Callable[[EventBase], Awaitable[str]]]
|
||||
|
||||
async def watch_func(event: EventBase) -> str:
|
||||
try:
|
||||
result = (
|
||||
await hs.get_storage_controllers().state.get_state_ids_for_event(
|
||||
event.event_id, filter
|
||||
)
|
||||
)
|
||||
except RuntimeError:
|
||||
return f"\n{key_pair}: <Event unavailable :(>"
|
||||
else:
|
||||
return f"\n{key_pair}: {result.get(key_pair, '<No event in state>')}"
|
||||
|
||||
else:
|
||||
watch_func = None
|
||||
|
||||
if args.draw:
|
||||
await dump_mainlines(hs, resolve_point, parent_events, args.extras, watch_func)
|
||||
|
||||
result = await hs.get_state_resolution_handler().resolve_events_with_store(
|
||||
sample_event.room_id,
|
||||
sample_event.room_version.identifier,
|
||||
state_after_parents,
|
||||
event_map=None,
|
||||
state_res_store=StateResolutionStore(hs.get_datastores().main),
|
||||
)
|
||||
|
||||
logger.info("State resolved:")
|
||||
logger.info(pformat(result))
|
||||
|
||||
if DEBUG_AT_EVENT:
|
||||
logger.info("Stored state at %s:", sample_event.event_id)
|
||||
stored_state = await hs.get_storage_controllers().state.get_state_ids_for_event(
|
||||
sample_event.event_id
|
||||
)
|
||||
logger.info(pformat(stored_state))
|
||||
|
||||
# TODO make this a like-for-like comparison.
|
||||
logger.info("Diff from stored (after event) to resolved (before event):")
|
||||
for change in dictdiffer.diff(stored_state, result):
|
||||
logger.info(pformat(change))
|
||||
|
||||
|
||||
# Entrypoint.
|
||||
if __name__ == "__main__":
|
||||
args = parser.parse_args()
|
||||
logging.basicConfig(
|
||||
format="%(asctime)s %(name)s:%(lineno)d %(levelname)s %(message)s",
|
||||
level=logging.DEBUG if args.verbose else logging.INFO,
|
||||
stream=sys.stdout,
|
||||
)
|
||||
# Suppress logs we aren't interested in.
|
||||
logging.getLogger("synapse.util").setLevel(logging.ERROR)
|
||||
logging.getLogger("synapse.storage").setLevel(logging.ERROR)
|
||||
|
||||
config = load_config(args.config_file)
|
||||
hs = MockHomeserver(config)
|
||||
# Patch out enough stuff so we can work with a readonly DB connection.
|
||||
with patch("synapse.storage.databases.prepare_database"), patch(
|
||||
"synapse.storage.database.BackgroundUpdater"
|
||||
), patch("synapse.storage.databases.main.events_worker.MultiWriterIdGenerator"):
|
||||
hs.setup()
|
||||
|
||||
task.react(debug_specific_stateres, [hs, parser.parse_args()])
|
||||
@@ -44,7 +44,6 @@ from synapse.app._base import (
|
||||
register_start,
|
||||
)
|
||||
from synapse.config._base import ConfigError, format_config_error
|
||||
from synapse.config.emailconfig import ThreepidBehaviour
|
||||
from synapse.config.homeserver import HomeServerConfig
|
||||
from synapse.config.server import ListenerConfig
|
||||
from synapse.federation.transport.server import TransportLayerServer
|
||||
@@ -202,7 +201,7 @@ class SynapseHomeServer(HomeServer):
|
||||
}
|
||||
)
|
||||
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.config.email.can_verify_email:
|
||||
from synapse.rest.synapse.client.password_reset import (
|
||||
PasswordResetSubmitTokenResource,
|
||||
)
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
import email.utils
|
||||
import logging
|
||||
import os
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
import attr
|
||||
@@ -86,19 +85,14 @@ class EmailConfig(Config):
|
||||
if email_config is None:
|
||||
email_config = {}
|
||||
|
||||
self.force_tls = email_config.get("force_tls", False)
|
||||
self.email_smtp_host = email_config.get("smtp_host", "localhost")
|
||||
self.email_smtp_port = email_config.get(
|
||||
"smtp_port", 465 if self.force_tls else 25
|
||||
)
|
||||
self.email_smtp_port = email_config.get("smtp_port", 25)
|
||||
self.email_smtp_user = email_config.get("smtp_user", None)
|
||||
self.email_smtp_pass = email_config.get("smtp_pass", None)
|
||||
self.require_transport_security = email_config.get(
|
||||
"require_transport_security", False
|
||||
)
|
||||
self.enable_smtp_tls = email_config.get("enable_tls", True)
|
||||
if self.force_tls and not self.enable_smtp_tls:
|
||||
raise ConfigError("email.force_tls requires email.enable_tls to be true")
|
||||
if self.require_transport_security and not self.enable_smtp_tls:
|
||||
raise ConfigError(
|
||||
"email.require_transport_security requires email.enable_tls to be true"
|
||||
@@ -136,40 +130,22 @@ class EmailConfig(Config):
|
||||
|
||||
self.email_enable_notifs = email_config.get("enable_notifs", False)
|
||||
|
||||
self.threepid_behaviour_email = (
|
||||
# Have Synapse handle the email sending if account_threepid_delegates.email
|
||||
# is not defined
|
||||
# msisdn is currently always remote while Synapse does not support any method of
|
||||
# sending SMS messages
|
||||
ThreepidBehaviour.REMOTE
|
||||
if self.root.registration.account_threepid_delegate_email
|
||||
else ThreepidBehaviour.LOCAL
|
||||
)
|
||||
|
||||
if config.get("trust_identity_server_for_password_resets"):
|
||||
raise ConfigError(
|
||||
'The config option "trust_identity_server_for_password_resets" has been removed.'
|
||||
"Please consult the configuration manual at docs/usage/configuration/config_documentation.md for "
|
||||
"details and update your config file."
|
||||
'The config option "trust_identity_server_for_password_resets" '
|
||||
"is no longer supported. Please remove it from the config file."
|
||||
)
|
||||
|
||||
self.local_threepid_handling_disabled_due_to_email_config = False
|
||||
if (
|
||||
self.threepid_behaviour_email == ThreepidBehaviour.LOCAL
|
||||
and email_config == {}
|
||||
):
|
||||
# We cannot warn the user this has happened here
|
||||
# Instead do so when a user attempts to reset their password
|
||||
self.local_threepid_handling_disabled_due_to_email_config = True
|
||||
|
||||
self.threepid_behaviour_email = ThreepidBehaviour.OFF
|
||||
# If we have email config settings, assume that we can verify ownership of
|
||||
# email addresses.
|
||||
self.can_verify_email = email_config != {}
|
||||
|
||||
# Get lifetime of a validation token in milliseconds
|
||||
self.email_validation_token_lifetime = self.parse_duration(
|
||||
email_config.get("validation_token_lifetime", "1h")
|
||||
)
|
||||
|
||||
if self.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.can_verify_email:
|
||||
missing = []
|
||||
if not self.email_notif_from:
|
||||
missing.append("email.notif_from")
|
||||
@@ -360,18 +336,3 @@ class EmailConfig(Config):
|
||||
"Config option email.invite_client_location must be a http or https URL",
|
||||
path=("email", "invite_client_location"),
|
||||
)
|
||||
|
||||
|
||||
class ThreepidBehaviour(Enum):
|
||||
"""
|
||||
Enum to define the behaviour of Synapse with regards to when it contacts an identity
|
||||
server for 3pid registration and password resets
|
||||
|
||||
REMOTE = use an external server to send tokens
|
||||
LOCAL = send tokens ourselves
|
||||
OFF = disable registration via 3pid and password resets
|
||||
"""
|
||||
|
||||
REMOTE = "remote"
|
||||
LOCAL = "local"
|
||||
OFF = "off"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import argparse
|
||||
import logging
|
||||
from typing import Any, Optional
|
||||
|
||||
from synapse.api.constants import RoomCreationPreset
|
||||
@@ -21,15 +20,11 @@ from synapse.config._base import Config, ConfigError
|
||||
from synapse.types import JsonDict, RoomAlias, UserID
|
||||
from synapse.util.stringutils import random_string_with_symbols, strtobool
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
LEGACY_EMAIL_DELEGATE_WARNING = """\
|
||||
Delegation of email verification to an identity server is now deprecated. To
|
||||
NO_EMAIL_DELEGATE_ERROR = """\
|
||||
Delegation of email verification to an identity server is no longer supported. To
|
||||
continue to allow users to add email addresses to their accounts, and use them for
|
||||
password resets, configure Synapse with an SMTP server via the `email` setting, and
|
||||
remove `account_threepid_delegates.email`.
|
||||
|
||||
This will be an error in a future version.
|
||||
"""
|
||||
|
||||
|
||||
@@ -64,9 +59,8 @@ class RegistrationConfig(Config):
|
||||
|
||||
account_threepid_delegates = config.get("account_threepid_delegates") or {}
|
||||
if "email" in account_threepid_delegates:
|
||||
logger.warning(LEGACY_EMAIL_DELEGATE_WARNING)
|
||||
|
||||
self.account_threepid_delegate_email = account_threepid_delegates.get("email")
|
||||
raise ConfigError(NO_EMAIL_DELEGATE_ERROR)
|
||||
# self.account_threepid_delegate_email = account_threepid_delegates.get("email")
|
||||
self.account_threepid_delegate_msisdn = account_threepid_delegates.get("msisdn")
|
||||
self.default_identity_server = config.get("default_identity_server")
|
||||
self.allow_guest_access = config.get("allow_guest_access", False)
|
||||
|
||||
@@ -26,7 +26,6 @@ from synapse.api.errors import (
|
||||
SynapseError,
|
||||
)
|
||||
from synapse.api.ratelimiting import Ratelimiter
|
||||
from synapse.config.emailconfig import ThreepidBehaviour
|
||||
from synapse.http import RequestTimedOutError
|
||||
from synapse.http.client import SimpleHttpClient
|
||||
from synapse.http.site import SynapseRequest
|
||||
@@ -416,48 +415,6 @@ class IdentityHandler:
|
||||
|
||||
return session_id
|
||||
|
||||
async def request_email_token(
|
||||
self,
|
||||
id_server: str,
|
||||
email: str,
|
||||
client_secret: str,
|
||||
send_attempt: int,
|
||||
next_link: Optional[str] = None,
|
||||
) -> JsonDict:
|
||||
"""
|
||||
Request an external server send an email on our behalf for the purposes of threepid
|
||||
validation.
|
||||
|
||||
Args:
|
||||
id_server: The identity server to proxy to
|
||||
email: The email to send the message to
|
||||
client_secret: The unique client_secret sends by the user
|
||||
send_attempt: Which attempt this is
|
||||
next_link: A link to redirect the user to once they submit the token
|
||||
|
||||
Returns:
|
||||
The json response body from the server
|
||||
"""
|
||||
params = {
|
||||
"email": email,
|
||||
"client_secret": client_secret,
|
||||
"send_attempt": send_attempt,
|
||||
}
|
||||
if next_link:
|
||||
params["next_link"] = next_link
|
||||
|
||||
try:
|
||||
data = await self.http_client.post_json_get_json(
|
||||
id_server + "/_matrix/identity/api/v1/validate/email/requestToken",
|
||||
params,
|
||||
)
|
||||
return data
|
||||
except HttpResponseException as e:
|
||||
logger.info("Proxied requestToken failed: %r", e)
|
||||
raise e.to_synapse_error()
|
||||
except RequestTimedOutError:
|
||||
raise SynapseError(500, "Timed out contacting identity server")
|
||||
|
||||
async def requestMsisdnToken(
|
||||
self,
|
||||
id_server: str,
|
||||
@@ -531,18 +488,7 @@ class IdentityHandler:
|
||||
validation_session = None
|
||||
|
||||
# Try to validate as email
|
||||
if self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
|
||||
# Remote emails will only be used if a valid identity server is provided.
|
||||
assert (
|
||||
self.hs.config.registration.account_threepid_delegate_email is not None
|
||||
)
|
||||
|
||||
# Ask our delegated email identity server
|
||||
validation_session = await self.threepid_from_creds(
|
||||
self.hs.config.registration.account_threepid_delegate_email,
|
||||
threepid_creds,
|
||||
)
|
||||
elif self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.hs.config.email.can_verify_email:
|
||||
# Get a validated session matching these details
|
||||
validation_session = await self.store.get_threepid_validation_session(
|
||||
"email", client_secret, sid=sid, validated=True
|
||||
|
||||
@@ -23,12 +23,10 @@ from pkg_resources import parse_version
|
||||
|
||||
import twisted
|
||||
from twisted.internet.defer import Deferred
|
||||
from twisted.internet.interfaces import IOpenSSLContextFactory
|
||||
from twisted.internet.ssl import optionsForClientTLS
|
||||
from twisted.internet.interfaces import IOpenSSLContextFactory, IReactorTCP
|
||||
from twisted.mail.smtp import ESMTPSender, ESMTPSenderFactory
|
||||
|
||||
from synapse.logging.context import make_deferred_yieldable
|
||||
from synapse.types import ISynapseReactor
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.server import HomeServer
|
||||
@@ -50,7 +48,7 @@ class _NoTLSESMTPSender(ESMTPSender):
|
||||
|
||||
|
||||
async def _sendmail(
|
||||
reactor: ISynapseReactor,
|
||||
reactor: IReactorTCP,
|
||||
smtphost: str,
|
||||
smtpport: int,
|
||||
from_addr: str,
|
||||
@@ -61,7 +59,6 @@ async def _sendmail(
|
||||
require_auth: bool = False,
|
||||
require_tls: bool = False,
|
||||
enable_tls: bool = True,
|
||||
force_tls: bool = False,
|
||||
) -> None:
|
||||
"""A simple wrapper around ESMTPSenderFactory, to allow substitution in tests
|
||||
|
||||
@@ -76,9 +73,8 @@ async def _sendmail(
|
||||
password: password to give when authenticating
|
||||
require_auth: if auth is not offered, fail the request
|
||||
require_tls: if TLS is not offered, fail the reqest
|
||||
enable_tls: True to enable STARTTLS. If this is False and require_tls is True,
|
||||
enable_tls: True to enable TLS. If this is False and require_tls is True,
|
||||
the request will fail.
|
||||
force_tls: True to enable Implicit TLS.
|
||||
"""
|
||||
msg = BytesIO(msg_bytes)
|
||||
d: "Deferred[object]" = Deferred()
|
||||
@@ -109,23 +105,13 @@ async def _sendmail(
|
||||
# set to enable TLS.
|
||||
factory = build_sender_factory(hostname=smtphost if enable_tls else None)
|
||||
|
||||
if force_tls:
|
||||
reactor.connectSSL(
|
||||
smtphost,
|
||||
smtpport,
|
||||
factory,
|
||||
optionsForClientTLS(smtphost),
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
else:
|
||||
reactor.connectTCP(
|
||||
smtphost,
|
||||
smtpport,
|
||||
factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
reactor.connectTCP(
|
||||
smtphost,
|
||||
smtpport,
|
||||
factory,
|
||||
timeout=30,
|
||||
bindAddress=None,
|
||||
)
|
||||
|
||||
await make_deferred_yieldable(d)
|
||||
|
||||
@@ -146,7 +132,6 @@ class SendEmailHandler:
|
||||
self._smtp_pass = passwd.encode("utf-8") if passwd is not None else None
|
||||
self._require_transport_security = hs.config.email.require_transport_security
|
||||
self._enable_tls = hs.config.email.enable_smtp_tls
|
||||
self._force_tls = hs.config.email.force_tls
|
||||
|
||||
self._sendmail = _sendmail
|
||||
|
||||
@@ -204,5 +189,4 @@ class SendEmailHandler:
|
||||
require_auth=self._smtp_user is not None,
|
||||
require_tls=self._require_transport_security,
|
||||
enable_tls=self._enable_tls,
|
||||
force_tls=self._force_tls,
|
||||
)
|
||||
|
||||
@@ -19,7 +19,6 @@ from twisted.web.client import PartialDownloadError
|
||||
|
||||
from synapse.api.constants import LoginType
|
||||
from synapse.api.errors import Codes, LoginError, SynapseError
|
||||
from synapse.config.emailconfig import ThreepidBehaviour
|
||||
from synapse.util import json_decoder
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -153,7 +152,7 @@ class _BaseThreepidAuthChecker:
|
||||
|
||||
logger.info("Getting validated threepid. threepidcreds: %r", (threepid_creds,))
|
||||
|
||||
# msisdns are currently always ThreepidBehaviour.REMOTE
|
||||
# msisdns are currently always verified via the IS
|
||||
if medium == "msisdn":
|
||||
if not self.hs.config.registration.account_threepid_delegate_msisdn:
|
||||
raise SynapseError(
|
||||
@@ -164,18 +163,7 @@ class _BaseThreepidAuthChecker:
|
||||
threepid_creds,
|
||||
)
|
||||
elif medium == "email":
|
||||
if (
|
||||
self.hs.config.email.threepid_behaviour_email
|
||||
== ThreepidBehaviour.REMOTE
|
||||
):
|
||||
assert self.hs.config.registration.account_threepid_delegate_email
|
||||
threepid = await identity_handler.threepid_from_creds(
|
||||
self.hs.config.registration.account_threepid_delegate_email,
|
||||
threepid_creds,
|
||||
)
|
||||
elif (
|
||||
self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL
|
||||
):
|
||||
if self.hs.config.email.can_verify_email:
|
||||
threepid = None
|
||||
row = await self.store.get_threepid_validation_session(
|
||||
medium,
|
||||
@@ -227,10 +215,7 @@ class EmailIdentityAuthChecker(UserInteractiveAuthChecker, _BaseThreepidAuthChec
|
||||
_BaseThreepidAuthChecker.__init__(self, hs)
|
||||
|
||||
def is_enabled(self) -> bool:
|
||||
return self.hs.config.email.threepid_behaviour_email in (
|
||||
ThreepidBehaviour.REMOTE,
|
||||
ThreepidBehaviour.LOCAL,
|
||||
)
|
||||
return self.hs.config.email.can_verify_email
|
||||
|
||||
async def check_auth(self, authdict: dict, clientip: str) -> Any:
|
||||
return await self._check_threepid("email", authdict)
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
<div class="username_input" id="username_input">
|
||||
<label for="field-username">Username (required)</label>
|
||||
<div class="prefix">@</div>
|
||||
<input type="text" name="username" id="field-username" value="{{ user_attributes.localpart }}" autofocus autocorrect="off" autocapitalize="none">
|
||||
<input type="text" name="username" id="field-username" value="{{ user_attributes.localpart }}" autofocus>
|
||||
<div class="postfix">:{{ server_name }}</div>
|
||||
</div>
|
||||
<output for="username_input" id="field-username-output"></output>
|
||||
|
||||
@@ -28,7 +28,6 @@ from synapse.api.errors import (
|
||||
SynapseError,
|
||||
ThreepidValidationError,
|
||||
)
|
||||
from synapse.config.emailconfig import ThreepidBehaviour
|
||||
from synapse.handlers.ui_auth import UIAuthSessionDataConstants
|
||||
from synapse.http.server import HttpServer, finish_request, respond_with_html
|
||||
from synapse.http.servlet import (
|
||||
@@ -64,7 +63,7 @@ class EmailPasswordRequestTokenRestServlet(RestServlet):
|
||||
self.config = hs.config
|
||||
self.identity_handler = hs.get_identity_handler()
|
||||
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.config.email.can_verify_email:
|
||||
self.mailer = Mailer(
|
||||
hs=self.hs,
|
||||
app_name=self.config.email.email_app_name,
|
||||
@@ -73,11 +72,10 @@ class EmailPasswordRequestTokenRestServlet(RestServlet):
|
||||
)
|
||||
|
||||
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
|
||||
if self.config.email.local_threepid_handling_disabled_due_to_email_config:
|
||||
logger.warning(
|
||||
"User password resets have been disabled due to lack of email config"
|
||||
)
|
||||
if not self.config.email.can_verify_email:
|
||||
logger.warning(
|
||||
"User password resets have been disabled due to lack of email config"
|
||||
)
|
||||
raise SynapseError(
|
||||
400, "Email-based password resets have been disabled on this server"
|
||||
)
|
||||
@@ -129,35 +127,21 @@ class EmailPasswordRequestTokenRestServlet(RestServlet):
|
||||
|
||||
raise SynapseError(400, "Email not found", Codes.THREEPID_NOT_FOUND)
|
||||
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
|
||||
assert self.hs.config.registration.account_threepid_delegate_email
|
||||
|
||||
# Have the configured identity server handle the request
|
||||
ret = await self.identity_handler.request_email_token(
|
||||
self.hs.config.registration.account_threepid_delegate_email,
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
next_link,
|
||||
)
|
||||
else:
|
||||
# Send password reset emails from Synapse
|
||||
sid = await self.identity_handler.send_threepid_validation(
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
self.mailer.send_password_reset_mail,
|
||||
next_link,
|
||||
)
|
||||
|
||||
# Wrap the session id in a JSON object
|
||||
ret = {"sid": sid}
|
||||
# Send password reset emails from Synapse
|
||||
sid = await self.identity_handler.send_threepid_validation(
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
self.mailer.send_password_reset_mail,
|
||||
next_link,
|
||||
)
|
||||
|
||||
threepid_send_requests.labels(type="email", reason="password_reset").observe(
|
||||
send_attempt
|
||||
)
|
||||
|
||||
return 200, ret
|
||||
# Wrap the session id in a JSON object
|
||||
return 200, {"sid": sid}
|
||||
|
||||
|
||||
class PasswordRestServlet(RestServlet):
|
||||
@@ -349,7 +333,7 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
|
||||
self.identity_handler = hs.get_identity_handler()
|
||||
self.store = self.hs.get_datastores().main
|
||||
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.config.email.can_verify_email:
|
||||
self.mailer = Mailer(
|
||||
hs=self.hs,
|
||||
app_name=self.config.email.email_app_name,
|
||||
@@ -358,11 +342,10 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
|
||||
)
|
||||
|
||||
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
|
||||
if self.config.email.local_threepid_handling_disabled_due_to_email_config:
|
||||
logger.warning(
|
||||
"Adding emails have been disabled due to lack of an email config"
|
||||
)
|
||||
if not self.config.email.can_verify_email:
|
||||
logger.warning(
|
||||
"Adding emails have been disabled due to lack of an email config"
|
||||
)
|
||||
raise SynapseError(
|
||||
400, "Adding an email to your account is disabled on this server"
|
||||
)
|
||||
@@ -413,35 +396,20 @@ class EmailThreepidRequestTokenRestServlet(RestServlet):
|
||||
|
||||
raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE)
|
||||
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
|
||||
assert self.hs.config.registration.account_threepid_delegate_email
|
||||
|
||||
# Have the configured identity server handle the request
|
||||
ret = await self.identity_handler.request_email_token(
|
||||
self.hs.config.registration.account_threepid_delegate_email,
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
next_link,
|
||||
)
|
||||
else:
|
||||
# Send threepid validation emails from Synapse
|
||||
sid = await self.identity_handler.send_threepid_validation(
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
self.mailer.send_add_threepid_mail,
|
||||
next_link,
|
||||
)
|
||||
|
||||
# Wrap the session id in a JSON object
|
||||
ret = {"sid": sid}
|
||||
sid = await self.identity_handler.send_threepid_validation(
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
self.mailer.send_add_threepid_mail,
|
||||
next_link,
|
||||
)
|
||||
|
||||
threepid_send_requests.labels(type="email", reason="add_threepid").observe(
|
||||
send_attempt
|
||||
)
|
||||
|
||||
return 200, ret
|
||||
# Wrap the session id in a JSON object
|
||||
return 200, {"sid": sid}
|
||||
|
||||
|
||||
class MsisdnThreepidRequestTokenRestServlet(RestServlet):
|
||||
@@ -534,25 +502,19 @@ class AddThreepidEmailSubmitTokenServlet(RestServlet):
|
||||
self.config = hs.config
|
||||
self.clock = hs.get_clock()
|
||||
self.store = hs.get_datastores().main
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.config.email.can_verify_email:
|
||||
self._failure_email_template = (
|
||||
self.config.email.email_add_threepid_template_failure_html
|
||||
)
|
||||
|
||||
async def on_GET(self, request: Request) -> None:
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
|
||||
if self.config.email.local_threepid_handling_disabled_due_to_email_config:
|
||||
logger.warning(
|
||||
"Adding emails have been disabled due to lack of an email config"
|
||||
)
|
||||
if not self.config.email.can_verify_email:
|
||||
logger.warning(
|
||||
"Adding emails have been disabled due to lack of an email config"
|
||||
)
|
||||
raise SynapseError(
|
||||
400, "Adding an email to your account is disabled on this server"
|
||||
)
|
||||
elif self.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
|
||||
raise SynapseError(
|
||||
400,
|
||||
"This homeserver is not validating threepids.",
|
||||
)
|
||||
|
||||
sid = parse_string(request, "sid", required=True)
|
||||
token = parse_string(request, "token", required=True)
|
||||
|
||||
@@ -31,7 +31,6 @@ from synapse.api.errors import (
|
||||
)
|
||||
from synapse.api.ratelimiting import Ratelimiter
|
||||
from synapse.config import ConfigError
|
||||
from synapse.config.emailconfig import ThreepidBehaviour
|
||||
from synapse.config.homeserver import HomeServerConfig
|
||||
from synapse.config.ratelimiting import FederationRateLimitConfig
|
||||
from synapse.config.server import is_threepid_reserved
|
||||
@@ -74,7 +73,7 @@ class EmailRegisterRequestTokenRestServlet(RestServlet):
|
||||
self.identity_handler = hs.get_identity_handler()
|
||||
self.config = hs.config
|
||||
|
||||
if self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.hs.config.email.can_verify_email:
|
||||
self.mailer = Mailer(
|
||||
hs=self.hs,
|
||||
app_name=self.config.email.email_app_name,
|
||||
@@ -83,13 +82,10 @@ class EmailRegisterRequestTokenRestServlet(RestServlet):
|
||||
)
|
||||
|
||||
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
if self.hs.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
|
||||
if (
|
||||
self.hs.config.email.local_threepid_handling_disabled_due_to_email_config
|
||||
):
|
||||
logger.warning(
|
||||
"Email registration has been disabled due to lack of email config"
|
||||
)
|
||||
if not self.hs.config.email.can_verify_email:
|
||||
logger.warning(
|
||||
"Email registration has been disabled due to lack of email config"
|
||||
)
|
||||
raise SynapseError(
|
||||
400, "Email-based registration has been disabled on this server"
|
||||
)
|
||||
@@ -138,35 +134,21 @@ class EmailRegisterRequestTokenRestServlet(RestServlet):
|
||||
|
||||
raise SynapseError(400, "Email is already in use", Codes.THREEPID_IN_USE)
|
||||
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.REMOTE:
|
||||
assert self.hs.config.registration.account_threepid_delegate_email
|
||||
|
||||
# Have the configured identity server handle the request
|
||||
ret = await self.identity_handler.request_email_token(
|
||||
self.hs.config.registration.account_threepid_delegate_email,
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
next_link,
|
||||
)
|
||||
else:
|
||||
# Send registration emails from Synapse,
|
||||
# wrapping the session id in a JSON object.
|
||||
ret = {
|
||||
"sid": await self.identity_handler.send_threepid_validation(
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
self.mailer.send_registration_mail,
|
||||
next_link,
|
||||
)
|
||||
}
|
||||
# Send registration emails from Synapse
|
||||
sid = await self.identity_handler.send_threepid_validation(
|
||||
email,
|
||||
client_secret,
|
||||
send_attempt,
|
||||
self.mailer.send_registration_mail,
|
||||
next_link,
|
||||
)
|
||||
|
||||
threepid_send_requests.labels(type="email", reason="register").observe(
|
||||
send_attempt
|
||||
)
|
||||
|
||||
return 200, ret
|
||||
# Wrap the session id in a JSON object
|
||||
return 200, {"sid": sid}
|
||||
|
||||
|
||||
class MsisdnRegisterRequestTokenRestServlet(RestServlet):
|
||||
@@ -260,7 +242,7 @@ class RegistrationSubmitTokenServlet(RestServlet):
|
||||
self.clock = hs.get_clock()
|
||||
self.store = hs.get_datastores().main
|
||||
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL:
|
||||
if self.config.email.can_verify_email:
|
||||
self._failure_email_template = (
|
||||
self.config.email.email_registration_template_failure_html
|
||||
)
|
||||
@@ -270,11 +252,10 @@ class RegistrationSubmitTokenServlet(RestServlet):
|
||||
raise SynapseError(
|
||||
400, "This medium is currently not supported for registration"
|
||||
)
|
||||
if self.config.email.threepid_behaviour_email == ThreepidBehaviour.OFF:
|
||||
if self.config.email.local_threepid_handling_disabled_due_to_email_config:
|
||||
logger.warning(
|
||||
"User registration via email has been disabled due to lack of email config"
|
||||
)
|
||||
if not self.config.email.can_verify_email:
|
||||
logger.warning(
|
||||
"User registration via email has been disabled due to lack of email config"
|
||||
)
|
||||
raise SynapseError(
|
||||
400, "Email-based registration is disabled on this server"
|
||||
)
|
||||
|
||||
@@ -17,7 +17,6 @@ from typing import TYPE_CHECKING, Tuple
|
||||
from twisted.web.server import Request
|
||||
|
||||
from synapse.api.errors import ThreepidValidationError
|
||||
from synapse.config.emailconfig import ThreepidBehaviour
|
||||
from synapse.http.server import DirectServeHtmlResource
|
||||
from synapse.http.servlet import parse_string
|
||||
from synapse.util.stringutils import assert_valid_client_secret
|
||||
@@ -46,9 +45,6 @@ class PasswordResetSubmitTokenResource(DirectServeHtmlResource):
|
||||
self.clock = hs.get_clock()
|
||||
self.store = hs.get_datastores().main
|
||||
|
||||
self._local_threepid_handling_disabled_due_to_email_config = (
|
||||
hs.config.email.local_threepid_handling_disabled_due_to_email_config
|
||||
)
|
||||
self._confirmation_email_template = (
|
||||
hs.config.email.email_password_reset_template_confirmation_html
|
||||
)
|
||||
@@ -59,8 +55,8 @@ class PasswordResetSubmitTokenResource(DirectServeHtmlResource):
|
||||
hs.config.email.email_password_reset_template_failure_html
|
||||
)
|
||||
|
||||
# This resource should not be mounted if threepid behaviour is not LOCAL
|
||||
assert hs.config.email.threepid_behaviour_email == ThreepidBehaviour.LOCAL
|
||||
# This resource should only be mounted if email validation is enabled
|
||||
assert hs.config.email.can_verify_email
|
||||
|
||||
async def _async_render_GET(self, request: Request) -> Tuple[int, bytes]:
|
||||
sid = parse_string(request, "sid", required=True)
|
||||
|
||||
@@ -287,7 +287,9 @@ class StateStorageController:
|
||||
self, event_id: str, state_filter: Optional[StateFilter] = None
|
||||
) -> StateMap[str]:
|
||||
"""
|
||||
Get the state dict corresponding to a particular event
|
||||
Get the state dict corresponding to a particular event.
|
||||
Note that this is the state *after* the event: the event's changes have
|
||||
already taken effect.
|
||||
|
||||
Args:
|
||||
event_id: event whose state should be returned
|
||||
|
||||
@@ -23,7 +23,7 @@ from twisted.internet.defer import ensureDeferred
|
||||
from twisted.mail import interfaces, smtp
|
||||
|
||||
from tests.server import FakeTransport
|
||||
from tests.unittest import HomeserverTestCase, override_config
|
||||
from tests.unittest import HomeserverTestCase
|
||||
|
||||
|
||||
@implementer(interfaces.IMessageDelivery)
|
||||
@@ -110,58 +110,3 @@ class SendEmailHandlerTestCase(HomeserverTestCase):
|
||||
user, msg = message_delivery.messages.pop()
|
||||
self.assertEqual(str(user), "foo@bar.com")
|
||||
self.assertIn(b"Subject: test subject", msg)
|
||||
|
||||
@override_config(
|
||||
{
|
||||
"email": {
|
||||
"notif_from": "noreply@test",
|
||||
"force_tls": True,
|
||||
},
|
||||
}
|
||||
)
|
||||
def test_send_email_force_tls(self):
|
||||
"""Happy-path test that we can send email to an Implicit TLS server."""
|
||||
h = self.hs.get_send_email_handler()
|
||||
d = ensureDeferred(
|
||||
h.send_email(
|
||||
"foo@bar.com", "test subject", "Tests", "HTML content", "Text content"
|
||||
)
|
||||
)
|
||||
# there should be an attempt to connect to localhost:465
|
||||
self.assertEqual(len(self.reactor.sslClients), 1)
|
||||
(
|
||||
host,
|
||||
port,
|
||||
client_factory,
|
||||
contextFactory,
|
||||
_timeout,
|
||||
_bindAddress,
|
||||
) = self.reactor.sslClients[0]
|
||||
self.assertEqual(host, "localhost")
|
||||
self.assertEqual(port, 465)
|
||||
|
||||
# wire it up to an SMTP server
|
||||
message_delivery = _DummyMessageDelivery()
|
||||
server_protocol = smtp.ESMTP()
|
||||
server_protocol.delivery = message_delivery
|
||||
# make sure that the server uses the test reactor to set timeouts
|
||||
server_protocol.callLater = self.reactor.callLater # type: ignore[assignment]
|
||||
|
||||
client_protocol = client_factory.buildProtocol(None)
|
||||
client_protocol.makeConnection(FakeTransport(server_protocol, self.reactor))
|
||||
server_protocol.makeConnection(
|
||||
FakeTransport(
|
||||
client_protocol,
|
||||
self.reactor,
|
||||
peer_address=IPv4Address("TCP", "127.0.0.1", 1234),
|
||||
)
|
||||
)
|
||||
|
||||
# the message should now get delivered
|
||||
self.get_success(d, by=0.1)
|
||||
|
||||
# check it arrived
|
||||
self.assertEqual(len(message_delivery.messages), 1)
|
||||
user, msg = message_delivery.messages.pop()
|
||||
self.assertEqual(str(user), "foo@bar.com")
|
||||
self.assertIn(b"Subject: test subject", msg)
|
||||
|
||||
@@ -586,9 +586,9 @@ class RegisterRestServletTestCase(unittest.HomeserverTestCase):
|
||||
"require_at_registration": True,
|
||||
},
|
||||
"account_threepid_delegates": {
|
||||
"email": "https://id_server",
|
||||
"msisdn": "https://id_server",
|
||||
},
|
||||
"email": {"notif_from": "Synapse <synapse@example.com>"},
|
||||
}
|
||||
)
|
||||
def test_advertised_flows_captcha_and_terms_and_3pids(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user