Merge branch 'develop' into madlittlemods/deflake-msc3030-backfill-test-with-workers
Conflicts: scripts-dev/complement.sh
This commit is contained in:
@@ -21,7 +21,7 @@ endblock
|
||||
|
||||
block Install Complement Dependencies
|
||||
sudo apt-get -qq update && sudo apt-get install -qqy libolm3 libolm-dev
|
||||
go get -v github.com/haveyoudebuggedit/gotestfmt/v2/cmd/gotestfmt@latest
|
||||
go get -v github.com/gotesttools/gotestfmt/v2/cmd/gotestfmt@latest
|
||||
endblock
|
||||
|
||||
block Install custom gotestfmt template
|
||||
|
||||
5
.github/dependabot.yml
vendored
5
.github/dependabot.yml
vendored
@@ -15,3 +15,8 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
- package-ecosystem: "cargo"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
20
CHANGES.md
20
CHANGES.md
@@ -1,12 +1,28 @@
|
||||
Synapse 1.69.0rc1 (2022-10-04)
|
||||
Synapse 1.69.0rc2 (2022-10-06)
|
||||
==============================
|
||||
|
||||
|
||||
Please note that legacy Prometheus metric names are now deprecated and will be removed in Synapse 1.73.0.
|
||||
Server administrators should update their dashboards and alerting rules to avoid using the deprecated metric names.
|
||||
See the [upgrade notes](https://matrix-org.github.io/synapse/v1.69/upgrade.html#upgrading-to-v1690) for more details.
|
||||
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Deprecate the `generate_short_term_login_token` method in favor of an async `create_login_token` method in the Module API. ([\#13842](https://github.com/matrix-org/synapse/issues/13842))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Ensure Synapse v1.69 works with upcoming database changes in v1.70. ([\#14045](https://github.com/matrix-org/synapse/issues/14045))
|
||||
- Fix a bug introduced in Synapse v1.68.0 where messages could not be sent in rooms with non-integer `notifications` power level. ([\#14073](https://github.com/matrix-org/synapse/issues/14073))
|
||||
- Temporarily pin build-system requirements to workaround an incompatibility with poetry-core 1.3.0. This will be reverted before the v1.69.0 release proper, see [\#14079](https://github.com/matrix-org/synapse/issues/14079). ([\#14080](https://github.com/matrix-org/synapse/issues/14080))
|
||||
|
||||
|
||||
Synapse 1.69.0rc1 (2022-10-04)
|
||||
==============================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
|
||||
56
Cargo.lock
generated
56
Cargo.lock
generated
@@ -104,9 +104,9 @@ checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
@@ -116,15 +116,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.132"
|
||||
version = "0.2.135"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8371e4e5341c3a96db127eb2465ac681ced4c433e01dd0e938adbef26ba93ba5"
|
||||
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.7"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
|
||||
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
@@ -156,9 +156,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.13.1"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "074864da206b4973b84eb91683020dbefd6a8c3f0f38e054d93954e891935e4e"
|
||||
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
@@ -185,18 +185,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.43"
|
||||
version = "1.0.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab"
|
||||
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.17.1"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12f72538a0230791398a0986a6518ebd88abc3fded89007b506ed072acc831e1"
|
||||
checksum = "201b6887e5576bf2f945fe65172c1fcbf3fcf285b23e4d71eb171d9736e38d32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
@@ -212,9 +212,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.17.1"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc4cf18c20f4f09995f3554e6bcf9b09bd5e4d6b67c562fdfaafa644526ba479"
|
||||
checksum = "bf0708c9ed01692635cbf056e286008e5a2927ab1a5e48cdd3aeb1ba5a6fef47"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
@@ -222,9 +222,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.17.1"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a41877f28d8ebd600b6aa21a17b40c3b0fc4dfe73a27b6e81ab3d895e401b0e9"
|
||||
checksum = "90352dea4f486932b72ddf776264d293f85b79a1d214de1d023927b41461132d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
@@ -243,9 +243,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.17.1"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e81c8d4bcc2f216dc1b665412df35e46d12ee8d3d046b381aad05f1fcf30547"
|
||||
checksum = "7eb24b804a2d9e88bfcc480a5a6dd76f006c1e3edaf064e8250423336e2cd79d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
@@ -255,9 +255,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.17.1"
|
||||
version = "0.17.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85752a767ee19399a78272cc2ab625cd7d373b2e112b4b13db28de71fa892784"
|
||||
checksum = "f22bb49f6a7348c253d7ac67a6875f2dc65f36c2ae64a82c381d528972bea6d6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -343,9 +343,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.85"
|
||||
version = "1.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
||||
checksum = "41feea4228a6f1cd09ec7a3593a682276702cd67b5273544757dae23c096f074"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@@ -354,9 +354,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.9.0"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
@@ -366,9 +366,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.99"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13"
|
||||
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -406,9 +406,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.3"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4f5b37a154999a8f3f98cc23a628d850e154479cd94decf3414696e12e31aaf"
|
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||
|
||||
[[package]]
|
||||
name = "unindent"
|
||||
|
||||
@@ -1 +1 @@
|
||||
Experimental support for thread-specific notifications ([MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
|
||||
1
changelog.d/13813.bugfix
Normal file
1
changelog.d/13813.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a long-standing bug where redactions were not being sent over federation if we did not have the original event.
|
||||
@@ -1 +1 @@
|
||||
Experimental support for thread-specific receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771)).
|
||||
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
|
||||
@@ -1 +1 @@
|
||||
Experimental support for thread-specific receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771)).
|
||||
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
|
||||
@@ -1 +1 @@
|
||||
Experimental support for thread-specific receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771)).
|
||||
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
|
||||
1
changelog.d/13955.docker
Normal file
1
changelog.d/13955.docker
Normal file
@@ -0,0 +1 @@
|
||||
Update the version of frozendict in Docker images and Debian packages from 2.3.3 to 2.3.4, which may fix memory leak problems.
|
||||
1
changelog.d/14007.misc
Normal file
1
changelog.d/14007.misc
Normal file
@@ -0,0 +1 @@
|
||||
Make `parse_server_name` consistent in handling invalid server names.
|
||||
1
changelog.d/14033.misc
Normal file
1
changelog.d/14033.misc
Normal file
@@ -0,0 +1 @@
|
||||
Don't repeatedly wake up the same users for batched events.
|
||||
1
changelog.d/14034.bugfix
Normal file
1
changelog.d/14034.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a long-standing bug where edits of non-`m.room.message` events would not be correctly bundled or have their new content applied.
|
||||
1
changelog.d/14040.misc
Normal file
1
changelog.d/14040.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump msgpack from 1.0.3 to 1.0.4.
|
||||
1
changelog.d/14043.misc
Normal file
1
changelog.d/14043.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump phonenumbers from 8.12.44 to 8.12.56.
|
||||
1
changelog.d/14044.misc
Normal file
1
changelog.d/14044.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump pydantic from 1.9.1 to 1.10.2.
|
||||
1
changelog.d/14050.feature
Normal file
1
changelog.d/14050.feature
Normal file
@@ -0,0 +1 @@
|
||||
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
1
changelog.d/14053.bugfix
Normal file
1
changelog.d/14053.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in Synapse 1.53.0 when querying `/publicRooms` with both a `room_type` filter and a `third_party_instance_id`.
|
||||
1
changelog.d/14054.feature
Normal file
1
changelog.d/14054.feature
Normal file
@@ -0,0 +1 @@
|
||||
Improve validation of request bodies for the [Device Management](https://spec.matrix.org/v1.4/client-server-api/#device-management) and [MSC2697 Device Dehyrdation](https://github.com/matrix-org/matrix-spec-proposals/pull/2697) client-server API endpoints.
|
||||
1
changelog.d/14063.misc
Normal file
1
changelog.d/14063.misc
Normal file
@@ -0,0 +1 @@
|
||||
Complement test image: capture logs from nginx.
|
||||
1
changelog.d/14065.misc
Normal file
1
changelog.d/14065.misc
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in Synapse 1.35.0 where errors parsing a `/send_join` or `/state` response would produce excessive, low-quality Sentry events.
|
||||
1
changelog.d/14072.misc
Normal file
1
changelog.d/14072.misc
Normal file
@@ -0,0 +1 @@
|
||||
Don't create noisy Sentry events when a requester drops connection to the metrics server mid-request.
|
||||
1
changelog.d/14077.doc
Normal file
1
changelog.d/14077.doc
Normal file
@@ -0,0 +1 @@
|
||||
Add sample worker files for `pusher` and `federation_sender`.
|
||||
1
changelog.d/14078.doc
Normal file
1
changelog.d/14078.doc
Normal file
@@ -0,0 +1 @@
|
||||
Improve the listener example on the metrics documentation.
|
||||
1
changelog.d/14081.doc
Normal file
1
changelog.d/14081.doc
Normal file
@@ -0,0 +1 @@
|
||||
Expand Google OpenID Connect example config to map email attribute. Contributed by @ptman.
|
||||
1
changelog.d/14087.doc
Normal file
1
changelog.d/14087.doc
Normal file
@@ -0,0 +1 @@
|
||||
The changelog entry ending in a full stop or exclamation mark is not optional.
|
||||
1
changelog.d/14089.bugfix
Normal file
1
changelog.d/14089.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug where invalid oEmbed fields would cause the entire response to be discarded. Introduced in Synapse 1.18.0.
|
||||
1
changelog.d/14092.misc
Normal file
1
changelog.d/14092.misc
Normal file
@@ -0,0 +1 @@
|
||||
Run the integration test suites with the asyncio reactor enabled in CI.
|
||||
1
changelog.d/14093.doc
Normal file
1
changelog.d/14093.doc
Normal file
@@ -0,0 +1 @@
|
||||
Fix links to jemalloc documentation, which were broken in #13491.
|
||||
1
changelog.d/14094.removal
Normal file
1
changelog.d/14094.removal
Normal file
@@ -0,0 +1 @@
|
||||
Remove the experimental implementation of [MSC3772](https://github.com/matrix-org/matrix-spec-proposals/pull/3772).
|
||||
1
changelog.d/14097.misc
Normal file
1
changelog.d/14097.misc
Normal file
@@ -0,0 +1 @@
|
||||
Indicate what endpoint came back with a JSON response we were unable to parse.
|
||||
1
changelog.d/14102.bugfix
Normal file
1
changelog.d/14102.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in Synapse v1.37.0 in which an incorrect key name was used for sending and receiving room metadata when knocking on a room.
|
||||
1
changelog.d/14106.removal
Normal file
1
changelog.d/14106.removal
Normal file
@@ -0,0 +1 @@
|
||||
Remove the unstable identifier for [MSC3715](https://github.com/matrix-org/matrix-doc/pull/3715).
|
||||
1
changelog.d/14109.misc
Normal file
1
changelog.d/14109.misc
Normal file
@@ -0,0 +1 @@
|
||||
Break up calls to fetch rooms for many users. Contributed by Nick @ Beeper (@fizzadar).
|
||||
1
changelog.d/14113.misc
Normal file
1
changelog.d/14113.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump types-pillow from 9.0.15 to 9.2.2.
|
||||
1
changelog.d/14114.misc
Normal file
1
changelog.d/14114.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump types-psycopg2 from 2.9.9 to 2.9.21.1.
|
||||
1
changelog.d/14115.misc
Normal file
1
changelog.d/14115.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump idna from 3.3 to 3.4.
|
||||
1
changelog.d/14116.misc
Normal file
1
changelog.d/14116.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump bleach from 4.1.0 to 5.0.1.
|
||||
1
changelog.d/14124.doc
Normal file
1
changelog.d/14124.doc
Normal file
@@ -0,0 +1 @@
|
||||
Fix name of `alias_creation_rules` option in the config manual documentation.
|
||||
1
changelog.d/14125.bugfix
Normal file
1
changelog.d/14125.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in v1.69.0rc1 where the joined hosts for a given event were not being properly cached.
|
||||
1
changelog.d/14132.misc
Normal file
1
changelog.d/14132.misc
Normal file
@@ -0,0 +1 @@
|
||||
Enable dependabot for Rust dependencies.
|
||||
1
changelog.d/14134.misc
Normal file
1
changelog.d/14134.misc
Normal file
@@ -0,0 +1 @@
|
||||
Bump typing-extensions from 4.1.1 to 4.4.0.
|
||||
1
changelog.d/14140.feature
Normal file
1
changelog.d/14140.feature
Normal file
@@ -0,0 +1 @@
|
||||
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
1
changelog.d/14141.docker
Normal file
1
changelog.d/14141.docker
Normal file
@@ -0,0 +1 @@
|
||||
Use the `minimal` Rust profile when building Synapse.
|
||||
1
changelog.d/14141.misc
Normal file
1
changelog.d/14141.misc
Normal file
@@ -0,0 +1 @@
|
||||
Use the `minimal` Rust profile when building Synapse.
|
||||
1
changelog.d/14142.misc
Normal file
1
changelog.d/14142.misc
Normal file
@@ -0,0 +1 @@
|
||||
Remove unused configuration code.
|
||||
1
changelog.d/14144.misc
Normal file
1
changelog.d/14144.misc
Normal file
@@ -0,0 +1 @@
|
||||
Prepare for the [`gotestfmt` repository move](https://github.com/GoTestTools/gotestfmt/discussions/46).
|
||||
1
changelog.d/14159.feature
Normal file
1
changelog.d/14159.feature
Normal file
@@ -0,0 +1 @@
|
||||
Support for thread-specific notifications & receipts ([MSC3771](https://github.com/matrix-org/matrix-spec-proposals/pull/3771) and [MSC3773](https://github.com/matrix-org/matrix-spec-proposals/pull/3773)).
|
||||
6
debian/changelog
vendored
6
debian/changelog
vendored
@@ -1,3 +1,9 @@
|
||||
matrix-synapse-py3 (1.69.0~rc2) stable; urgency=medium
|
||||
|
||||
* New Synapse release 1.69.0rc2.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Thu, 06 Oct 2022 14:45:00 +0100
|
||||
|
||||
matrix-synapse-py3 (1.69.0~rc1) stable; urgency=medium
|
||||
|
||||
* The man page for the hash_password script has been updated to reflect
|
||||
|
||||
@@ -106,7 +106,7 @@ ENV CARGO_HOME=/cargo
|
||||
ENV PATH=/cargo/bin:/rust/bin:$PATH
|
||||
RUN mkdir /rust /cargo
|
||||
|
||||
RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable
|
||||
RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable --profile minimal
|
||||
|
||||
# To speed up rebuilds, install all of the dependencies before we copy over
|
||||
# the whole synapse project, so that this layer in the Docker cache can be
|
||||
|
||||
@@ -92,7 +92,7 @@ ENV CARGO_HOME=/cargo
|
||||
ENV PATH=/cargo/bin:/rust/bin:$PATH
|
||||
RUN mkdir /rust /cargo
|
||||
|
||||
RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable
|
||||
RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path --default-toolchain stable --profile minimal
|
||||
|
||||
|
||||
COPY --from=builder /dh-virtualenv_1.2.2-1_all.deb /
|
||||
|
||||
@@ -40,7 +40,11 @@ FROM matrixdotorg/synapse:$SYNAPSE_VERSION
|
||||
COPY --from=deps_base /etc/nginx /etc/nginx
|
||||
RUN rm /etc/nginx/sites-enabled/default
|
||||
RUN mkdir /var/log/nginx /var/lib/nginx
|
||||
RUN chown www-data /var/log/nginx /var/lib/nginx
|
||||
RUN chown www-data /var/lib/nginx
|
||||
|
||||
# have nginx log to stderr/out
|
||||
RUN ln -sf /dev/stdout /var/log/nginx/access.log
|
||||
RUN ln -sf /dev/stderr /var/log/nginx/error.log
|
||||
|
||||
# Copy Synapse worker, nginx and supervisord configuration template files
|
||||
COPY ./docker/conf-workers/* /conf/
|
||||
|
||||
@@ -241,4 +241,4 @@ healthcheck:
|
||||
|
||||
Jemalloc is embedded in the image and will be used instead of the default allocator.
|
||||
You can read about jemalloc by reading the Synapse
|
||||
[README](https://github.com/matrix-org/synapse/blob/HEAD/README.rst#help-synapse-is-slow-and-eats-all-my-ram-cpu).
|
||||
[Admin FAQ](https://matrix-org.github.io/synapse/latest/usage/administration/admin_faq.html#help-synapse-is-slow-and-eats-all-my-ramcpu).
|
||||
|
||||
@@ -333,7 +333,7 @@ SYNAPSE_TEST_LOG_LEVEL=DEBUG COMPLEMENT_DIR=../complement ./scripts-dev/compleme
|
||||
### Prettier formatting with `gotestfmt`
|
||||
|
||||
If you want to format the output of the tests the same way as it looks in CI,
|
||||
install [gotestfmt](https://github.com/haveyoudebuggedit/gotestfmt).
|
||||
install [gotestfmt](https://github.com/GoTestTools/gotestfmt).
|
||||
|
||||
You can then use this incantation to format the tests appropriately:
|
||||
|
||||
@@ -390,7 +390,7 @@ This file will become part of our [changelog](
|
||||
https://github.com/matrix-org/synapse/blob/master/CHANGES.md) at the next
|
||||
release, so the content of the file should be a short description of your
|
||||
change in the same style as the rest of the changelog. The file can contain Markdown
|
||||
formatting, and should end with a full stop (.) or an exclamation mark (!) for
|
||||
formatting, and must end with a full stop (.) or an exclamation mark (!) for
|
||||
consistency.
|
||||
|
||||
Adding credits to the changelog is encouraged, we value your
|
||||
|
||||
@@ -16,14 +16,21 @@
|
||||
There are two methods of enabling the metrics endpoint in Synapse.
|
||||
|
||||
The first serves the metrics as a part of the usual web server and
|
||||
can be enabled by adding the \"metrics\" resource to the existing
|
||||
listener as such:
|
||||
can be enabled by adding the `metrics` resource to the existing
|
||||
listener as such as in this example:
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
- names:
|
||||
- client
|
||||
- metrics
|
||||
listeners:
|
||||
- port: 8008
|
||||
tls: false
|
||||
type: http
|
||||
x_forwarded: true
|
||||
bind_addresses: ['::1', '127.0.0.1']
|
||||
|
||||
resources:
|
||||
# added "metrics" in this line
|
||||
- names: [client, federation, metrics]
|
||||
compress: false
|
||||
```
|
||||
|
||||
This provides a simple way of adding metrics to your Synapse
|
||||
@@ -37,14 +44,24 @@
|
||||
to just internal networks easier. The served metrics are available
|
||||
over HTTP only, and will be available at `/_synapse/metrics`.
|
||||
|
||||
Add a new listener to homeserver.yaml:
|
||||
Add a new listener to homeserver.yaml as in this example:
|
||||
|
||||
```yaml
|
||||
listeners:
|
||||
- type: metrics
|
||||
port: 9000
|
||||
bind_addresses:
|
||||
- '0.0.0.0'
|
||||
listeners:
|
||||
- port: 8008
|
||||
tls: false
|
||||
type: http
|
||||
x_forwarded: true
|
||||
bind_addresses: ['::1', '127.0.0.1']
|
||||
|
||||
resources:
|
||||
- names: [client, federation]
|
||||
compress: false
|
||||
|
||||
# beginning of the new metrics listener
|
||||
- port: 9000
|
||||
type: metrics
|
||||
bind_addresses: ['::1', '127.0.0.1']
|
||||
```
|
||||
|
||||
1. Restart Synapse.
|
||||
|
||||
@@ -336,11 +336,12 @@ oidc_providers:
|
||||
issuer: "https://accounts.google.com/"
|
||||
client_id: "your-client-id" # TO BE FILLED
|
||||
client_secret: "your-client-secret" # TO BE FILLED
|
||||
scopes: ["openid", "profile"]
|
||||
scopes: ["openid", "profile", "email"] # email is optional, read below
|
||||
user_mapping_provider:
|
||||
config:
|
||||
localpart_template: "{{ user.given_name|lower }}"
|
||||
display_name_template: "{{ user.name }}"
|
||||
email_template: "{{ user.email }}" # needs "email" in scopes above
|
||||
```
|
||||
4. Back in the Google console, add this Authorized redirect URI: `[synapse
|
||||
public baseurl]/_synapse/client/oidc/callback`.
|
||||
@@ -423,7 +424,7 @@ Synapse config:
|
||||
user_mapping_provider:
|
||||
config:
|
||||
display_name_template: "{{ user.name }}"
|
||||
email_template: "{{ '{{ user.email }}' }}"
|
||||
email_template: "{{ user.email }}"
|
||||
```
|
||||
|
||||
Relevant documents:
|
||||
|
||||
8
docs/systemd-with-workers/workers/federation_sender.yaml
Normal file
8
docs/systemd-with-workers/workers/federation_sender.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
worker_app: synapse.app.federation_sender
|
||||
worker_name: federation_sender1
|
||||
|
||||
# The replication listener on the main synapse process.
|
||||
worker_replication_host: 127.0.0.1
|
||||
worker_replication_http_port: 9093
|
||||
|
||||
worker_log_config: /etc/matrix-synapse/federation-sender-log.yaml
|
||||
8
docs/systemd-with-workers/workers/pusher_worker.yaml
Normal file
8
docs/systemd-with-workers/workers/pusher_worker.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
worker_app: synapse.app.pusher
|
||||
worker_name: pusher_worker1
|
||||
|
||||
# The replication listener on the main synapse process.
|
||||
worker_replication_host: 127.0.0.1
|
||||
worker_replication_http_port: 9093
|
||||
|
||||
worker_log_config: /etc/matrix-synapse/pusher-worker-log.yaml
|
||||
@@ -128,6 +128,39 @@ you may specify `enable_legacy_metrics: false` in your homeserver configuration.
|
||||
A list of affected metrics is available on the [Metrics How-to page](https://matrix-org.github.io/synapse/v1.69/metrics-howto.html?highlight=metrics%20deprecated#renaming-of-metrics--deprecation-of-old-names-in-12).
|
||||
|
||||
|
||||
## Deprecation of the `generate_short_term_login_token` module API method
|
||||
|
||||
The following method of the module API has been deprecated, and is scheduled to
|
||||
be remove in v1.71.0:
|
||||
|
||||
```python
|
||||
def generate_short_term_login_token(
|
||||
self,
|
||||
user_id: str,
|
||||
duration_in_ms: int = (2 * 60 * 1000),
|
||||
auth_provider_id: str = "",
|
||||
auth_provider_session_id: Optional[str] = None,
|
||||
) -> str:
|
||||
...
|
||||
```
|
||||
|
||||
It has been replaced by an asynchronous equivalent:
|
||||
|
||||
```python
|
||||
async def create_login_token(
|
||||
self,
|
||||
user_id: str,
|
||||
duration_in_ms: int = (2 * 60 * 1000),
|
||||
auth_provider_id: Optional[str] = None,
|
||||
auth_provider_session_id: Optional[str] = None,
|
||||
) -> str:
|
||||
...
|
||||
```
|
||||
|
||||
Synapse will log a warning when a module uses the deprecated method, to help
|
||||
administrators find modules using it.
|
||||
|
||||
|
||||
# Upgrading to v1.68.0
|
||||
|
||||
Two changes announced in the upgrade notes for v1.67.0 have now landed in v1.68.0.
|
||||
|
||||
@@ -1139,7 +1139,7 @@ number of entries that can be stored.
|
||||
|
||||
* `cache_autotuning` and its sub-options `max_cache_memory_usage`, `target_cache_memory_usage`, and
|
||||
`min_cache_ttl` work in conjunction with each other to maintain a balance between cache memory
|
||||
usage and cache entry availability. You must be using [jemalloc](https://github.com/matrix-org/synapse#help-synapse-is-slow-and-eats-all-my-ramcpu)
|
||||
usage and cache entry availability. You must be using [jemalloc](../administration/admin_faq.md#help-synapse-is-slow-and-eats-all-my-ramcpu)
|
||||
to utilize this option, and all three of the options must be specified for this feature to work. This option
|
||||
defaults to off, enable it by providing values for the sub-options listed below. Please note that the feature will not work
|
||||
and may cause unstable behavior (such as excessive emptying of caches or exceptions) if all of the values are not provided.
|
||||
@@ -3541,9 +3541,9 @@ Example configuration:
|
||||
enable_room_list_search: false
|
||||
```
|
||||
---
|
||||
### `alias_creation`
|
||||
### `alias_creation_rules`
|
||||
|
||||
The `alias_creation` option controls who is allowed to create aliases
|
||||
The `alias_creation_rules` option controls who is allowed to create aliases
|
||||
on this server.
|
||||
|
||||
The format of this option is a list of rules that contain globs that
|
||||
|
||||
@@ -489,6 +489,12 @@ pusher_instances:
|
||||
- pusher_worker2
|
||||
```
|
||||
|
||||
An example for a pusher instance:
|
||||
|
||||
```yaml
|
||||
{{#include systemd-with-workers/workers/pusher_worker.yaml}}
|
||||
```
|
||||
|
||||
|
||||
### `synapse.app.appservice`
|
||||
|
||||
@@ -519,6 +525,12 @@ federation_sender_instances:
|
||||
- federation_sender2
|
||||
```
|
||||
|
||||
An example for a federation sender instance:
|
||||
|
||||
```yaml
|
||||
{{#include systemd-with-workers/workers/federation_sender.yaml}}
|
||||
```
|
||||
|
||||
### `synapse.app.media_repository`
|
||||
|
||||
Handles the media repository. It can handle all endpoints starting with:
|
||||
|
||||
3
mypy.ini
3
mypy.ini
@@ -106,6 +106,9 @@ disallow_untyped_defs = False
|
||||
[mypy-tests.handlers.test_user_directory]
|
||||
disallow_untyped_defs = True
|
||||
|
||||
[mypy-tests.push.test_bulk_push_rule_evaluator]
|
||||
disallow_untyped_defs = True
|
||||
|
||||
[mypy-tests.test_server]
|
||||
disallow_untyped_defs = True
|
||||
|
||||
|
||||
254
poetry.lock
generated
254
poetry.lock
generated
@@ -79,17 +79,20 @@ uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "bleach"
|
||||
version = "4.1.0"
|
||||
version = "5.0.1"
|
||||
description = "An easy safelist-based HTML-sanitizing tool."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
packaging = "*"
|
||||
six = ">=1.9.0"
|
||||
webencodings = "*"
|
||||
|
||||
[package.extras]
|
||||
css = ["tinycss2 (>=1.1.0,<1.2)"]
|
||||
dev = ["Sphinx (==4.3.2)", "black (==22.3.0)", "build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "mypy (==0.961)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "canonicaljson"
|
||||
version = "1.6.3"
|
||||
@@ -288,7 +291,7 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
|
||||
|
||||
[[package]]
|
||||
name = "frozendict"
|
||||
version = "2.3.3"
|
||||
version = "2.3.4"
|
||||
description = "A simple immutable dictionary"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -338,7 +341,7 @@ idna = ">=2.5"
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.3"
|
||||
version = "3.4"
|
||||
description = "Internationalized Domain Names in Applications (IDNA)"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -564,8 +567,8 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "msgpack"
|
||||
version = "1.0.3"
|
||||
description = "MessagePack (de)serializer."
|
||||
version = "1.0.4"
|
||||
description = "MessagePack serializer"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
@@ -664,7 +667,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "phonenumbers"
|
||||
version = "8.12.44"
|
||||
version = "8.12.56"
|
||||
description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -788,14 +791,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "1.9.1"
|
||||
version = "1.10.2"
|
||||
description = "Data validation and settings management using python type hints"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.1"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = ">=3.7.4.3"
|
||||
typing-extensions = ">=4.1.0"
|
||||
|
||||
[package.extras]
|
||||
dotenv = ["python-dotenv (>=0.10.4)"]
|
||||
@@ -1433,8 +1436,8 @@ optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-pillow"
|
||||
version = "9.0.15"
|
||||
name = "types-Pillow"
|
||||
version = "9.2.2"
|
||||
description = "Typing stubs for Pillow"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -1442,7 +1445,7 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "types-psycopg2"
|
||||
version = "2.9.9"
|
||||
version = "2.9.21.1"
|
||||
description = "Typing stubs for psycopg2"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -1496,11 +1499,11 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.1.1"
|
||||
description = "Backported and Experimental Type Hints for Python 3.6+"
|
||||
version = "4.4.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "unpaddedbase64"
|
||||
@@ -1686,8 +1689,8 @@ black = [
|
||||
{file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"},
|
||||
]
|
||||
bleach = [
|
||||
{file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"},
|
||||
{file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"},
|
||||
{file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"},
|
||||
{file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"},
|
||||
]
|
||||
canonicaljson = [
|
||||
{file = "canonicaljson-1.6.3-py3-none-any.whl", hash = "sha256:6ba3cf1702fa3d209b3e915a4e9a3e4ef194f1e8fca189c1f0b7a2a7686a27e6"},
|
||||
@@ -1823,23 +1826,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.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a3b32d47282ae0098b9239a6d53ec539da720258bd762d62191b46f2f87c5fc"},
|
||||
{file = "frozendict-2.3.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84c9887179a245a66a50f52afa08d4d92ae0f269839fab82285c70a0fa0dd782"},
|
||||
{file = "frozendict-2.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:b98a0d65a59af6da03f794f90b0c3085a7ee14e7bf8f0ef36b079ee8aa992439"},
|
||||
{file = "frozendict-2.3.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d8042b7dab5e992e30889c9b71b781d5feef19b372d47d735e4d7d45846fd4a"},
|
||||
{file = "frozendict-2.3.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25a6d2e8b7cf6b6e5677a1a4b53b4073e5d9ec640d1db30dc679627668d25e90"},
|
||||
{file = "frozendict-2.3.4-cp36-cp36m-win_amd64.whl", hash = "sha256:dbbe1339ac2646523e0bb00d1896085d1f70de23780e4927ca82b36ab8a044d3"},
|
||||
{file = "frozendict-2.3.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95bac22f7f09d81f378f2b3f672b7a50a974ca180feae1507f5e21bc147e8bc8"},
|
||||
{file = "frozendict-2.3.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dae686722c144b333c4dbdc16323a5de11406d26b76d2be1cc175f90afacb5ba"},
|
||||
{file = "frozendict-2.3.4-cp37-cp37m-win_amd64.whl", hash = "sha256:389f395a74eb16992217ac1521e689c1dea2d70113bcb18714669ace1ed623b9"},
|
||||
{file = "frozendict-2.3.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ccb6450a416c9cc9acef7683e637e28356e3ceeabf83521f74cc2718883076b7"},
|
||||
{file = "frozendict-2.3.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca59108b77cadc13ba7dfea7e8f50811208c7652a13dc6c7f92d7782a24d299"},
|
||||
{file = "frozendict-2.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:3ec86ebf143dd685184215c27ec416c36e0ba1b80d81b1b9482f7d380c049b4e"},
|
||||
{file = "frozendict-2.3.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5809e6ff6b7257043a486f7a3b73a7da71cf69a38980b4171e4741291d0d9eb3"},
|
||||
{file = "frozendict-2.3.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c550ed7fdf1962984bec21630c584d722b3ee5d5f57a0ae2527a0121dc0414a"},
|
||||
{file = "frozendict-2.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:3e93aebc6e69a8ef329bbe9afb8342bd33c7b5c7a0c480cb9f7e60b0cbe48072"},
|
||||
{file = "frozendict-2.3.4-py3-none-any.whl", hash = "sha256:d722f3d89db6ae35ef35ecc243c40c800eb344848c83dba4798353312cd37b15"},
|
||||
{file = "frozendict-2.3.4.tar.gz", hash = "sha256:15b4b18346259392b0d27598f240e9390fafbff882137a9c48a1e0104fb17f78"},
|
||||
]
|
||||
gitdb = [
|
||||
{file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"},
|
||||
@@ -1897,8 +1900,8 @@ hyperlink = [
|
||||
{file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"},
|
||||
]
|
||||
idna = [
|
||||
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
|
||||
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
|
||||
{file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
|
||||
{file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
|
||||
]
|
||||
ijson = [
|
||||
{file = "ijson-3.1.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:6c1a777096be5f75ffebb335c6d2ebc0e489b231496b7f2ca903aa061fe7d381"},
|
||||
@@ -2130,40 +2133,58 @@ mccabe = [
|
||||
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
||||
]
|
||||
msgpack = [
|
||||
{file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:96acc674bb9c9be63fa8b6dabc3248fdc575c4adc005c440ad02f87ca7edd079"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c3ca57c96c8e69c1a0d2926a6acf2d9a522b41dc4253a8945c4c6cd4981a4e3"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0a792c091bac433dfe0a70ac17fc2087d4595ab835b47b89defc8bbabcf5c73"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c58cdec1cb5fcea8c2f1771d7b5fec79307d056874f746690bd2bdd609ab147"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f97c0f35b3b096a330bb4a1a9247d0bd7e1f3a2eba7ab69795501504b1c2c39"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-win32.whl", hash = "sha256:36a64a10b16c2ab31dcd5f32d9787ed41fe68ab23dd66957ca2826c7f10d0b85"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c1ba333b4024c17c7591f0f372e2daa3c31db495a9b2af3cf664aef3c14354f7"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c2140cf7a3ec475ef0938edb6eb363fa704159e0bf71dde15d953bacc1cf9d7d"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f4c22717c74d44bcd7af353024ce71c6b55346dad5e2cc1ddc17ce8c4507c6b"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d733a15ade190540c703de209ffbc42a3367600421b62ac0c09fde594da6ec"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7e03b06f2982aa98d4ddd082a210c3db200471da523f9ac197f2828e80e7770"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-win32.whl", hash = "sha256:3d875631ecab42f65f9dce6f55ce6d736696ced240f2634633188de2f5f21af9"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:40fb89b4625d12d6027a19f4df18a4de5c64f6f3314325049f219683e07e678a"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6eef0cf8db3857b2b556213d97dd82de76e28a6524853a9beb3264983391dc1a"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d8c332f53ffff01953ad25131272506500b14750c1d0ce8614b17d098252fbc"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c0903bd93cbd34653dd63bbfcb99d7539c372795201f39d16fdfde4418de43a"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf1e6bfed4860d72106f4e0a1ab519546982b45689937b40257cfd820650b920"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-win32.whl", hash = "sha256:d02cea2252abc3756b2ac31f781f7a98e89ff9759b2e7450a1c7a0d13302ff50"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2f30dd0dc4dfe6231ad253b6f9f7128ac3202ae49edd3f10d311adc358772dba"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f201d34dc89342fabb2a10ed7c9a9aaaed9b7af0f16a5923f1ae562b31258dea"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bb87f23ae7d14b7b3c21009c4b1705ec107cb21ee71975992f6aca571fb4a42a"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a3a5c4b16e9d0edb823fe54b59b5660cc8d4782d7bf2c214cb4b91a1940a8ef"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74da1e5fcf20ade12c6bf1baa17a2dc3604958922de8dc83cbe3eff22e8b611"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73a80bd6eb6bcb338c1ec0da273f87420829c266379c8c82fa14c23fb586cfa1"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-win32.whl", hash = "sha256:9fce00156e79af37bb6db4e7587b30d11e7ac6a02cb5bac387f023808cd7d7f4"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:9b6f2d714c506e79cbead331de9aae6837c8dd36190d02da74cb409b36162e8a"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:89908aea5f46ee1474cc37fbc146677f8529ac99201bc2faf4ef8edc023c2bf3"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:973ad69fd7e31159eae8f580f3f707b718b61141838321c6fa4d891c4a2cca52"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da24375ab4c50e5b7486c115a3198d207954fe10aaa5708f7b65105df09109b2"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a598d0685e4ae07a0672b59792d2cc767d09d7a7f39fd9bd37ff84e060b1a996"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4c309a68cb5d6bbd0c50d5c71a25ae81f268c2dc675c6f4ea8ab2feec2ac4e2"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-win32.whl", hash = "sha256:494471d65b25a8751d19c83f1a482fd411d7ca7a3b9e17d25980a74075ba0e88"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:f01b26c2290cbd74316990ba84a14ac3d599af9cebefc543d241a66e785cf17d"},
|
||||
{file = "msgpack-1.0.3.tar.gz", hash = "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ab251d229d10498e9a2f3b1e68ef64cb393394ec477e3370c457f9430ce9250"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:112b0f93202d7c0fef0b7810d465fde23c746a2d482e1e2de2aafd2ce1492c88"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:002b5c72b6cd9b4bafd790f364b8480e859b4712e91f43014fe01e4f957b8467"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35bc0faa494b0f1d851fd29129b2575b2e26d41d177caacd4206d81502d4c6a6"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4733359808c56d5d7756628736061c432ded018e7a1dff2d35a02439043321aa"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb514ad14edf07a1dbe63761fd30f89ae79b42625731e1ccf5e1f1092950eaa6"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c23080fdeec4716aede32b4e0ef7e213c7b1093eede9ee010949f2a418ced6ba"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:49565b0e3d7896d9ea71d9095df15b7f75a035c49be733051c34762ca95bbf7e"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:aca0f1644d6b5a73eb3e74d4d64d5d8c6c3d577e753a04c9e9c87d07692c58db"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-win32.whl", hash = "sha256:0dfe3947db5fb9ce52aaea6ca28112a170db9eae75adf9339a1aec434dc954ef"},
|
||||
{file = "msgpack-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dea20515f660aa6b7e964433b1808d098dcfcabbebeaaad240d11f909298075"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e83f80a7fec1a62cf4e6c9a660e39c7f878f603737a0cdac8c13131d11d97f52"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c11a48cf5e59026ad7cb0dc29e29a01b5a66a3e333dc11c04f7e991fc5510a9"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1276e8f34e139aeff1c77a3cefb295598b504ac5314d32c8c3d54d24fadb94c9"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c9566f2c39ccced0a38d37c26cc3570983b97833c365a6044edef3574a00c08"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fcb8a47f43acc113e24e910399376f7277cf8508b27e5b88499f053de6b115a8"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:76ee788122de3a68a02ed6f3a16bbcd97bc7c2e39bd4d94be2f1821e7c4a64e6"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0a68d3ac0104e2d3510de90a1091720157c319ceeb90d74f7b5295a6bee51bae"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-win32.whl", hash = "sha256:85f279d88d8e833ec015650fd15ae5eddce0791e1e8a59165318f371158efec6"},
|
||||
{file = "msgpack-1.0.4-cp36-cp36m-win_amd64.whl", hash = "sha256:c1683841cd4fa45ac427c18854c3ec3cd9b681694caf5bff04edb9387602d661"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a75dfb03f8b06f4ab093dafe3ddcc2d633259e6c3f74bb1b01996f5d8aa5868c"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9667bdfdf523c40d2511f0e98a6c9d3603be6b371ae9a238b7ef2dc4e7a427b0"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11184bc7e56fd74c00ead4f9cc9a3091d62ecb96e97653add7a879a14b003227"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac5bd7901487c4a1dd51a8c58f2632b15d838d07ceedaa5e4c080f7190925bff"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1e91d641d2bfe91ba4c52039adc5bccf27c335356055825c7f88742c8bb900dd"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2a2df1b55a78eb5f5b7d2a4bb221cd8363913830145fad05374a80bf0877cb1e"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:545e3cf0cf74f3e48b470f68ed19551ae6f9722814ea969305794645da091236"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-win32.whl", hash = "sha256:2cc5ca2712ac0003bcb625c96368fd08a0f86bbc1a5578802512d87bc592fe44"},
|
||||
{file = "msgpack-1.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:eba96145051ccec0ec86611fe9cf693ce55f2a3ce89c06ed307de0e085730ec1"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7760f85956c415578c17edb39eed99f9181a48375b0d4a94076d84148cf67b2d"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:449e57cc1ff18d3b444eb554e44613cffcccb32805d16726a5494038c3b93dab"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d603de2b8d2ea3f3bcb2efe286849aa7a81531abc52d8454da12f46235092bcb"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f5d88c99f64c456413d74a975bd605a9b0526293218a3b77220a2c15458ba9"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6916c78f33602ecf0509cc40379271ba0f9ab572b066bd4bdafd7434dee4bc6e"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81fc7ba725464651190b196f3cd848e8553d4d510114a954681fd0b9c479d7e1"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d5b5b962221fa2c5d3a7f8133f9abffc114fe218eb4365e40f17732ade576c8e"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77ccd2af37f3db0ea59fb280fa2165bf1b096510ba9fe0cc2bf8fa92a22fdb43"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b17be2478b622939e39b816e0aa8242611cc8d3583d1cd8ec31b249f04623243"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-win32.whl", hash = "sha256:2bb8cdf50dd623392fa75525cce44a65a12a00c98e1e37bf0fb08ddce2ff60d2"},
|
||||
{file = "msgpack-1.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:26b8feaca40a90cbe031b03d82b2898bf560027160d3eae1423f4a67654ec5d6"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:462497af5fd4e0edbb1559c352ad84f6c577ffbbb708566a0abaaa84acd9f3ae"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2999623886c5c02deefe156e8f869c3b0aaeba14bfc50aa2486a0415178fce55"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f0029245c51fd9473dc1aede1160b0a29f4a912e6b1dd353fa6d317085b219da"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed6f7b854a823ea44cf94919ba3f727e230da29feb4a99711433f25800cf747f"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0df96d6eaf45ceca04b3f3b4b111b86b33785683d682c655063ef8057d61fd92"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a4192b1ab40f8dca3f2877b70e63799d95c62c068c84dc028b40a6cb03ccd0f"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0e3590f9fb9f7fbc36df366267870e77269c03172d086fa76bb4eba8b2b46624"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1576bd97527a93c44fa856770197dec00d223b0b9f36ef03f65bac60197cedf8"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:63e29d6e8c9ca22b21846234913c3466b7e4ee6e422f205a2988083de3b08cae"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-win32.whl", hash = "sha256:fb62ea4b62bfcb0b380d5680f9a4b3f9a2d166d9394e9bbd9666c0ee09a3645c"},
|
||||
{file = "msgpack-1.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:4d5834a2a48965a349da1c5a79760d94a1a0172fbb5ab6b5b33cbf8447e109ce"},
|
||||
{file = "msgpack-1.0.4.tar.gz", hash = "sha256:f5d869c18f030202eb412f08b28d2afeea553d6613aee89e200d7aca7ef01f5f"},
|
||||
]
|
||||
mypy = [
|
||||
{file = "mypy-0.981-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4bc460e43b7785f78862dab78674e62ec3cd523485baecfdf81a555ed29ecfa0"},
|
||||
@@ -2219,8 +2240,8 @@ pathspec = [
|
||||
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
|
||||
]
|
||||
phonenumbers = [
|
||||
{file = "phonenumbers-8.12.44-py2.py3-none-any.whl", hash = "sha256:cc1299cf37b309ecab6214297663ab86cb3d64ae37fd5b88e904fe7983a874a6"},
|
||||
{file = "phonenumbers-8.12.44.tar.gz", hash = "sha256:26cfd0257d1704fe2f88caff2caabb70d16a877b1e65b6aae51f9fbbe10aa8ce"},
|
||||
{file = "phonenumbers-8.12.56-py2.py3-none-any.whl", hash = "sha256:80a7422cf0999a6f9b7a2e6cfbdbbfcc56ab5b75414dc3b805bbec91276b64a3"},
|
||||
{file = "phonenumbers-8.12.56.tar.gz", hash = "sha256:82a4f226c930d02dcdf6d4b29e4cfd8678991fe65c2efd5fdd143557186f0868"},
|
||||
]
|
||||
pillow = [
|
||||
{file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"},
|
||||
@@ -2311,41 +2332,42 @@ pycparser = [
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
pydantic = [
|
||||
{file = "pydantic-1.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8098a724c2784bf03e8070993f6d46aa2eeca031f8d8a048dff277703e6e193"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c320c64dd876e45254bdd350f0179da737463eea41c43bacbee9d8c9d1021f11"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18f3e912f9ad1bdec27fb06b8198a2ccc32f201e24174cec1b3424dda605a310"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c11951b404e08b01b151222a1cb1a9f0a860a8153ce8334149ab9199cd198131"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8bc541a405423ce0e51c19f637050acdbdf8feca34150e0d17f675e72d119580"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e565a785233c2d03724c4dc55464559639b1ba9ecf091288dd47ad9c629433bd"},
|
||||
{file = "pydantic-1.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:a4a88dcd6ff8fd47c18b3a3709a89adb39a6373f4482e04c1b765045c7e282fd"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:447d5521575f18e18240906beadc58551e97ec98142266e521c34968c76c8761"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:985ceb5d0a86fcaa61e45781e567a59baa0da292d5ed2e490d612d0de5796918"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059b6c1795170809103a1538255883e1983e5b831faea6558ef873d4955b4a74"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d12f96b5b64bec3f43c8e82b4aab7599d0157f11c798c9f9c528a72b9e0b339a"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ae72f8098acb368d877b210ebe02ba12585e77bd0db78ac04a1ee9b9f5dd2166"},
|
||||
{file = "pydantic-1.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:79b485767c13788ee314669008d01f9ef3bc05db9ea3298f6a50d3ef596a154b"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:494f7c8537f0c02b740c229af4cb47c0d39840b829ecdcfc93d91dcbb0779892"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0f047e11febe5c3198ed346b507e1d010330d56ad615a7e0a89fae604065a0e"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:969dd06110cb780da01336b281f53e2e7eb3a482831df441fb65dd30403f4608"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:177071dfc0df6248fd22b43036f936cfe2508077a72af0933d0c1fa269b18537"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:9bcf8b6e011be08fb729d110f3e22e654a50f8a826b0575c7196616780683380"},
|
||||
{file = "pydantic-1.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a955260d47f03df08acf45689bd163ed9df82c0e0124beb4251b1290fa7ae728"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9ce157d979f742a915b75f792dbd6aa63b8eccaf46a1005ba03aa8a986bde34a"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0bf07cab5b279859c253d26a9194a8906e6f4a210063b84b433cf90a569de0c1"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d93d4e95eacd313d2c765ebe40d49ca9dd2ed90e5b37d0d421c597af830c195"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1542636a39c4892c4f4fa6270696902acb186a9aaeac6f6cf92ce6ae2e88564b"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a9af62e9b5b9bc67b2a195ebc2c2662fdf498a822d62f902bf27cccb52dbbf49"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fe4670cb32ea98ffbf5a1262f14c3e102cccd92b1869df3bb09538158ba90fe6"},
|
||||
{file = "pydantic-1.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:9f659a5ee95c8baa2436d392267988fd0f43eb774e5eb8739252e5a7e9cf07e0"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b83ba3825bc91dfa989d4eed76865e71aea3a6ca1388b59fc801ee04c4d8d0d6"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1dd8fecbad028cd89d04a46688d2fcc14423e8a196d5b0a5c65105664901f810"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02eefd7087268b711a3ff4db528e9916ac9aa18616da7bca69c1871d0b7a091f"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7eb57ba90929bac0b6cc2af2373893d80ac559adda6933e562dcfb375029acee"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4ce9ae9e91f46c344bec3b03d6ee9612802682c1551aaf627ad24045ce090761"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72ccb318bf0c9ab97fc04c10c37683d9eea952ed526707fabf9ac5ae59b701fd"},
|
||||
{file = "pydantic-1.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:61b6760b08b7c395975d893e0b814a11cf011ebb24f7d869e7118f5a339a82e1"},
|
||||
{file = "pydantic-1.9.1-py3-none-any.whl", hash = "sha256:4988c0f13c42bfa9ddd2fe2f569c9d54646ce84adc5de84228cfe83396f3bd58"},
|
||||
{file = "pydantic-1.9.1.tar.gz", hash = "sha256:1ed987c3ff29fff7fd8c3ea3a3ea877ad310aae2ef9889a119e22d3f2db0691a"},
|
||||
{file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"},
|
||||
{file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"},
|
||||
{file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"},
|
||||
{file = "pydantic-1.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559"},
|
||||
{file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"},
|
||||
{file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c"},
|
||||
{file = "pydantic-1.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644"},
|
||||
{file = "pydantic-1.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f"},
|
||||
{file = "pydantic-1.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a"},
|
||||
{file = "pydantic-1.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525"},
|
||||
{file = "pydantic-1.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283"},
|
||||
{file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42"},
|
||||
{file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52"},
|
||||
{file = "pydantic-1.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c"},
|
||||
{file = "pydantic-1.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5"},
|
||||
{file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c"},
|
||||
{file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254"},
|
||||
{file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5"},
|
||||
{file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d"},
|
||||
{file = "pydantic-1.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2"},
|
||||
{file = "pydantic-1.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13"},
|
||||
{file = "pydantic-1.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116"},
|
||||
{file = "pydantic-1.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624"},
|
||||
{file = "pydantic-1.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1"},
|
||||
{file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9"},
|
||||
{file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965"},
|
||||
{file = "pydantic-1.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e"},
|
||||
{file = "pydantic-1.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488"},
|
||||
{file = "pydantic-1.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41"},
|
||||
{file = "pydantic-1.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b"},
|
||||
{file = "pydantic-1.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe"},
|
||||
{file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d"},
|
||||
{file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda"},
|
||||
{file = "pydantic-1.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6"},
|
||||
{file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"},
|
||||
{file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"},
|
||||
]
|
||||
pyflakes = [
|
||||
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
|
||||
@@ -2740,13 +2762,13 @@ types-opentracing = [
|
||||
{file = "types-opentracing-2.4.7.tar.gz", hash = "sha256:be60e9618355aa892571ace002e6b353702538b1c0dc4fbc1c921219d6658830"},
|
||||
{file = "types_opentracing-2.4.7-py3-none-any.whl", hash = "sha256:861fb8103b07cf717f501dd400cb274ca9992552314d4d6c7a824b11a215e512"},
|
||||
]
|
||||
types-pillow = [
|
||||
{file = "types-Pillow-9.0.15.tar.gz", hash = "sha256:d2e385fe5c192e75970f18accce69f5c2a9f186f3feb578a9b91cd6fdf64211d"},
|
||||
{file = "types_Pillow-9.0.15-py3-none-any.whl", hash = "sha256:c9646595dfafdf8b63d4b1443292ead17ee0fc7b18a143e497b68e0ea2dc1eb6"},
|
||||
types-Pillow = [
|
||||
{file = "types-Pillow-9.2.2.tar.gz", hash = "sha256:6b525b0951ada076f3aefe2347e0bff6231283ce959ad8577a4416604acc673c"},
|
||||
{file = "types_Pillow-9.2.2-py3-none-any.whl", hash = "sha256:bfe14afa1e9047a52b3dc326c93b4f57db72641794e194f11b511f68b0061814"},
|
||||
]
|
||||
types-psycopg2 = [
|
||||
{file = "types-psycopg2-2.9.9.tar.gz", hash = "sha256:4f9d4d52eeb343dc00fd5ed4f1513a8a5c18efba0a072eb82706d15cf4f20a2e"},
|
||||
{file = "types_psycopg2-2.9.9-py3-none-any.whl", hash = "sha256:cec9291d4318ad70b407310f8304b3d40f6d0358f09870448f7a65e3027c80af"},
|
||||
{file = "types-psycopg2-2.9.21.1.tar.gz", hash = "sha256:f5532cf15afdc6b5ebb1e59b7d896617217321f488fd1fbd74e7efb94decfab6"},
|
||||
{file = "types_psycopg2-2.9.21.1-py3-none-any.whl", hash = "sha256:858838f1972f39da2a6e28274201fed8619a40a235dd86e7f66f4548ec474395"},
|
||||
]
|
||||
types-pyOpenSSL = [
|
||||
{file = "types-pyOpenSSL-22.0.10.tar.gz", hash = "sha256:f943b834f5b97e5e808764c2f6e37be1a2e226c46792296f61558196acfcc3a1"},
|
||||
@@ -2769,8 +2791,8 @@ types-urllib3 = [
|
||||
{file = "types_urllib3-1.26.10-py3-none-any.whl", hash = "sha256:d755278d5ecd7a7a6479a190e54230f241f1a99c19b81518b756b19dc69e518c"},
|
||||
]
|
||||
typing-extensions = [
|
||||
{file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"},
|
||||
{file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"},
|
||||
{file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"},
|
||||
{file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"},
|
||||
]
|
||||
unpaddedbase64 = [
|
||||
{file = "unpaddedbase64-2.1.0-py3-none-any.whl", hash = "sha256:485eff129c30175d2cd6f0cd8d2310dff51e666f7f36175f738d75dfdbd0b1c6"},
|
||||
|
||||
@@ -57,7 +57,7 @@ manifest-path = "rust/Cargo.toml"
|
||||
|
||||
[tool.poetry]
|
||||
name = "matrix-synapse"
|
||||
version = "1.69.0rc1"
|
||||
version = "1.69.0rc2"
|
||||
description = "Homeserver for the Matrix decentralised comms protocol"
|
||||
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
|
||||
license = "Apache-2.0"
|
||||
@@ -307,7 +307,7 @@ twine = "*"
|
||||
towncrier = ">=18.6.0rc1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0", "setuptools_rust>=1.3"]
|
||||
requires = ["poetry-core==1.2.0", "setuptools_rust==1.5.2"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@ build-backend = "poetry.core.masonry.api"
|
||||
skip = "cp36* *-musllinux_i686"
|
||||
|
||||
# We need a rust compiler
|
||||
before-all = "curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y"
|
||||
before-all = "curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y --profile minimal"
|
||||
environment= { PATH = "$PATH:$HOME/.cargo/bin" }
|
||||
|
||||
# For some reason if we don't manually clean the build directory we
|
||||
|
||||
@@ -257,19 +257,6 @@ pub const BASE_APPEND_UNDERRIDE_RULES: &[PushRule] = &[
|
||||
default: true,
|
||||
default_enabled: true,
|
||||
},
|
||||
PushRule {
|
||||
rule_id: Cow::Borrowed("global/underride/.org.matrix.msc3772.thread_reply"),
|
||||
priority_class: 1,
|
||||
conditions: Cow::Borrowed(&[Condition::Known(KnownCondition::RelationMatch {
|
||||
rel_type: Cow::Borrowed("m.thread"),
|
||||
event_type_pattern: None,
|
||||
sender: None,
|
||||
sender_type: Some(Cow::Borrowed("user_id")),
|
||||
})]),
|
||||
actions: Cow::Borrowed(&[Action::Notify, HIGHLIGHT_FALSE_ACTION]),
|
||||
default: true,
|
||||
default_enabled: true,
|
||||
},
|
||||
PushRule {
|
||||
rule_id: Cow::Borrowed("global/underride/.m.rule.message"),
|
||||
priority_class: 1,
|
||||
|
||||
@@ -12,10 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{BTreeMap, BTreeSet},
|
||||
};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use anyhow::{Context, Error};
|
||||
use lazy_static::lazy_static;
|
||||
@@ -49,13 +46,6 @@ pub struct PushRuleEvaluator {
|
||||
/// The `notifications` section of the current power levels in the room.
|
||||
notification_power_levels: BTreeMap<String, i64>,
|
||||
|
||||
/// The relations related to the event as a mapping from relation type to
|
||||
/// set of sender/event type 2-tuples.
|
||||
relations: BTreeMap<String, BTreeSet<(String, String)>>,
|
||||
|
||||
/// Is running "relation" conditions enabled?
|
||||
relation_match_enabled: bool,
|
||||
|
||||
/// The power level of the sender of the event, or None if event is an
|
||||
/// outlier.
|
||||
sender_power_level: Option<i64>,
|
||||
@@ -70,8 +60,6 @@ impl PushRuleEvaluator {
|
||||
room_member_count: u64,
|
||||
sender_power_level: Option<i64>,
|
||||
notification_power_levels: BTreeMap<String, i64>,
|
||||
relations: BTreeMap<String, BTreeSet<(String, String)>>,
|
||||
relation_match_enabled: bool,
|
||||
) -> Result<Self, Error> {
|
||||
let body = flattened_keys
|
||||
.get("content.body")
|
||||
@@ -83,8 +71,6 @@ impl PushRuleEvaluator {
|
||||
body,
|
||||
room_member_count,
|
||||
notification_power_levels,
|
||||
relations,
|
||||
relation_match_enabled,
|
||||
sender_power_level,
|
||||
})
|
||||
}
|
||||
@@ -203,89 +189,11 @@ impl PushRuleEvaluator {
|
||||
false
|
||||
}
|
||||
}
|
||||
KnownCondition::RelationMatch {
|
||||
rel_type,
|
||||
event_type_pattern,
|
||||
sender,
|
||||
sender_type,
|
||||
} => {
|
||||
self.match_relations(rel_type, sender, sender_type, user_id, event_type_pattern)?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Evaluates a relation condition.
|
||||
fn match_relations(
|
||||
&self,
|
||||
rel_type: &str,
|
||||
sender: &Option<Cow<str>>,
|
||||
sender_type: &Option<Cow<str>>,
|
||||
user_id: Option<&str>,
|
||||
event_type_pattern: &Option<Cow<str>>,
|
||||
) -> Result<bool, Error> {
|
||||
// First check if relation matching is enabled...
|
||||
if !self.relation_match_enabled {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
// ... and if there are any relations to match against.
|
||||
let relations = if let Some(relations) = self.relations.get(rel_type) {
|
||||
relations
|
||||
} else {
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
// Extract the sender pattern from the condition
|
||||
let sender_pattern = if let Some(sender) = sender {
|
||||
Some(sender.as_ref())
|
||||
} else if let Some(sender_type) = sender_type {
|
||||
if sender_type == "user_id" {
|
||||
if let Some(user_id) = user_id {
|
||||
Some(user_id)
|
||||
} else {
|
||||
return Ok(false);
|
||||
}
|
||||
} else {
|
||||
warn!("Unrecognized sender_type: {sender_type}");
|
||||
return Ok(false);
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut sender_compiled_pattern = if let Some(pattern) = sender_pattern {
|
||||
Some(get_glob_matcher(pattern, GlobMatchType::Whole)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut type_compiled_pattern = if let Some(pattern) = event_type_pattern {
|
||||
Some(get_glob_matcher(pattern, GlobMatchType::Whole)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
for (relation_sender, event_type) in relations {
|
||||
if let Some(pattern) = &mut sender_compiled_pattern {
|
||||
if !pattern.is_match(relation_sender)? {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(pattern) = &mut type_compiled_pattern {
|
||||
if !pattern.is_match(event_type)? {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
/// Evaluates a `event_match` condition.
|
||||
fn match_event_match(
|
||||
&self,
|
||||
@@ -359,15 +267,8 @@ impl PushRuleEvaluator {
|
||||
fn push_rule_evaluator() {
|
||||
let mut flattened_keys = BTreeMap::new();
|
||||
flattened_keys.insert("content.body".to_string(), "foo bar bob hello".to_string());
|
||||
let evaluator = PushRuleEvaluator::py_new(
|
||||
flattened_keys,
|
||||
10,
|
||||
Some(0),
|
||||
BTreeMap::new(),
|
||||
BTreeMap::new(),
|
||||
true,
|
||||
)
|
||||
.unwrap();
|
||||
let evaluator =
|
||||
PushRuleEvaluator::py_new(flattened_keys, 10, Some(0), BTreeMap::new()).unwrap();
|
||||
|
||||
let result = evaluator.run(&FilteredPushRules::default(), None, Some("bob"));
|
||||
assert_eq!(result.len(), 3);
|
||||
|
||||
@@ -275,16 +275,6 @@ pub enum KnownCondition {
|
||||
SenderNotificationPermission {
|
||||
key: Cow<'static, str>,
|
||||
},
|
||||
#[serde(rename = "org.matrix.msc3772.relation_match")]
|
||||
RelationMatch {
|
||||
rel_type: Cow<'static, str>,
|
||||
#[serde(skip_serializing_if = "Option::is_none", rename = "type")]
|
||||
event_type_pattern: Option<Cow<'static, str>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
sender: Option<Cow<'static, str>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
sender_type: Option<Cow<'static, str>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl IntoPy<PyObject> for Condition {
|
||||
@@ -401,21 +391,15 @@ impl PushRules {
|
||||
pub struct FilteredPushRules {
|
||||
push_rules: PushRules,
|
||||
enabled_map: BTreeMap<String, bool>,
|
||||
msc3772_enabled: bool,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl FilteredPushRules {
|
||||
#[new]
|
||||
pub fn py_new(
|
||||
push_rules: PushRules,
|
||||
enabled_map: BTreeMap<String, bool>,
|
||||
msc3772_enabled: bool,
|
||||
) -> Self {
|
||||
pub fn py_new(push_rules: PushRules, enabled_map: BTreeMap<String, bool>) -> Self {
|
||||
Self {
|
||||
push_rules,
|
||||
enabled_map,
|
||||
msc3772_enabled,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,25 +414,13 @@ impl FilteredPushRules {
|
||||
/// Iterates over all the rules and their enabled state, including base
|
||||
/// rules, in the order they should be executed in.
|
||||
fn iter(&self) -> impl Iterator<Item = (&PushRule, bool)> {
|
||||
self.push_rules
|
||||
.iter()
|
||||
.filter(|rule| {
|
||||
// Ignore disabled experimental push rules
|
||||
if !self.msc3772_enabled
|
||||
&& rule.rule_id == "global/underride/.org.matrix.msc3772.thread_reply"
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
})
|
||||
.map(|r| {
|
||||
let enabled = *self
|
||||
.enabled_map
|
||||
.get(&*r.rule_id)
|
||||
.unwrap_or(&r.default_enabled);
|
||||
(r, enabled)
|
||||
})
|
||||
self.push_rules.iter().map(|r| {
|
||||
let enabled = *self
|
||||
.enabled_map
|
||||
.get(&*r.rule_id)
|
||||
.unwrap_or(&r.default_enabled);
|
||||
(r, enabled)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,8 +159,13 @@ else
|
||||
# We only test faster room joins on monoliths, because they are purposefully
|
||||
# being developed without worker support to start with.
|
||||
#
|
||||
<<<<<<< HEAD
|
||||
# Importing historical history and jump to date also only support monoliths,
|
||||
# currently.
|
||||
=======
|
||||
# The tests for importing historical messages (MSC2716) and jump to date (MSC3030)
|
||||
# also only pass with monoliths, currently.
|
||||
>>>>>>> develop
|
||||
test_tags="$test_tags,faster_joins,msc2716,msc3030"
|
||||
fi
|
||||
|
||||
|
||||
@@ -25,9 +25,7 @@ class PushRules:
|
||||
def rules(self) -> Collection[PushRule]: ...
|
||||
|
||||
class FilteredPushRules:
|
||||
def __init__(
|
||||
self, push_rules: PushRules, enabled_map: Dict[str, bool], msc3772_enabled: bool
|
||||
): ...
|
||||
def __init__(self, push_rules: PushRules, enabled_map: Dict[str, bool]): ...
|
||||
def rules(self) -> Collection[Tuple[PushRule, bool]]: ...
|
||||
|
||||
def get_base_rule_ids() -> Collection[str]: ...
|
||||
@@ -39,8 +37,6 @@ class PushRuleEvaluator:
|
||||
room_member_count: int,
|
||||
sender_power_level: Optional[int],
|
||||
notification_power_levels: Mapping[str, int],
|
||||
relations: Mapping[str, Set[Tuple[str, str]]],
|
||||
relation_match_enabled: bool,
|
||||
): ...
|
||||
def run(
|
||||
self,
|
||||
|
||||
@@ -21,6 +21,7 @@ import os
|
||||
import sys
|
||||
|
||||
from synapse.util.rust import check_rust_lib_up_to_date
|
||||
from synapse.util.stringutils import strtobool
|
||||
|
||||
# Check that we're not running on an unsupported Python version.
|
||||
if sys.version_info < (3, 7):
|
||||
@@ -28,25 +29,22 @@ if sys.version_info < (3, 7):
|
||||
sys.exit(1)
|
||||
|
||||
# Allow using the asyncio reactor via env var.
|
||||
if bool(os.environ.get("SYNAPSE_ASYNC_IO_REACTOR", False)):
|
||||
try:
|
||||
from incremental import Version
|
||||
if strtobool(os.environ.get("SYNAPSE_ASYNC_IO_REACTOR", "0")):
|
||||
from incremental import Version
|
||||
|
||||
import twisted
|
||||
import twisted
|
||||
|
||||
# We need a bugfix that is included in Twisted 21.2.0:
|
||||
# https://twistedmatrix.com/trac/ticket/9787
|
||||
if twisted.version < Version("Twisted", 21, 2, 0):
|
||||
print("Using asyncio reactor requires Twisted>=21.2.0")
|
||||
sys.exit(1)
|
||||
# We need a bugfix that is included in Twisted 21.2.0:
|
||||
# https://twistedmatrix.com/trac/ticket/9787
|
||||
if twisted.version < Version("Twisted", 21, 2, 0):
|
||||
print("Using asyncio reactor requires Twisted>=21.2.0")
|
||||
sys.exit(1)
|
||||
|
||||
import asyncio
|
||||
import asyncio
|
||||
|
||||
from twisted.internet import asyncioreactor
|
||||
from twisted.internet import asyncioreactor
|
||||
|
||||
asyncioreactor.install(asyncio.get_event_loop())
|
||||
except ImportError:
|
||||
pass
|
||||
asyncioreactor.install(asyncio.get_event_loop())
|
||||
|
||||
# Twisted and canonicaljson will fail to import when this file is executed to
|
||||
# get the __version__ during a fresh install. That's OK and subsequent calls to
|
||||
|
||||
@@ -84,6 +84,7 @@ ROOM_EVENT_FILTER_SCHEMA = {
|
||||
"contains_url": {"type": "boolean"},
|
||||
"lazy_load_members": {"type": "boolean"},
|
||||
"include_redundant_members": {"type": "boolean"},
|
||||
"unread_thread_notifications": {"type": "boolean"},
|
||||
"org.matrix.msc3773.unread_thread_notifications": {"type": "boolean"},
|
||||
# Include or exclude events with the provided labels.
|
||||
# cf https://github.com/matrix-org/matrix-doc/pull/2326
|
||||
@@ -308,12 +309,16 @@ class Filter:
|
||||
self.include_redundant_members = filter_json.get(
|
||||
"include_redundant_members", False
|
||||
)
|
||||
if hs.config.experimental.msc3773_enabled:
|
||||
self.unread_thread_notifications: bool = filter_json.get(
|
||||
self.unread_thread_notifications: bool = filter_json.get(
|
||||
"unread_thread_notifications", False
|
||||
)
|
||||
if (
|
||||
not self.unread_thread_notifications
|
||||
and hs.config.experimental.msc3773_enabled
|
||||
):
|
||||
self.unread_thread_notifications = filter_json.get(
|
||||
"org.matrix.msc3773.unread_thread_notifications", False
|
||||
)
|
||||
else:
|
||||
self.unread_thread_notifications = False
|
||||
|
||||
self.types = filter_json.get("types", None)
|
||||
self.not_types = filter_json.get("not_types", [])
|
||||
|
||||
@@ -95,16 +95,9 @@ class ExperimentalConfig(Config):
|
||||
# MSC2815 (allow room moderators to view redacted event content)
|
||||
self.msc2815_enabled: bool = experimental.get("msc2815_enabled", False)
|
||||
|
||||
# MSC3771: Thread read receipts
|
||||
self.msc3771_enabled: bool = experimental.get("msc3771_enabled", False)
|
||||
# MSC3772: A push rule for mutual relations.
|
||||
self.msc3772_enabled: bool = experimental.get("msc3772_enabled", False)
|
||||
# MSC3773: Thread notifications
|
||||
self.msc3773_enabled: bool = experimental.get("msc3773_enabled", False)
|
||||
|
||||
# MSC3715: dir param on /relations.
|
||||
self.msc3715_enabled: bool = experimental.get("msc3715_enabled", False)
|
||||
|
||||
# MSC3848: Introduce errcodes for specific event sending failures
|
||||
self.msc3848_enabled: bool = experimental.get("msc3848_enabled", False)
|
||||
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# Copyright 2017 New Vector Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from typing import Any
|
||||
|
||||
from synapse.types import JsonDict
|
||||
|
||||
from ._base import Config
|
||||
|
||||
|
||||
class GroupsConfig(Config):
|
||||
section = "groups"
|
||||
|
||||
def read_config(self, config: JsonDict, **kwargs: Any) -> None:
|
||||
self.enable_group_creation = config.get("enable_group_creation", False)
|
||||
self.group_creation_prefix = config.get("group_creation_prefix", "")
|
||||
@@ -326,6 +326,8 @@ def setup_logging(
|
||||
logBeginner: The Twisted logBeginner to use.
|
||||
|
||||
"""
|
||||
from twisted.internet import reactor
|
||||
|
||||
log_config_path = (
|
||||
config.worker.worker_log_config
|
||||
if use_worker_options
|
||||
@@ -348,3 +350,4 @@ def setup_logging(
|
||||
)
|
||||
logging.info("Server hostname: %s", config.server.server_name)
|
||||
logging.info("Instance name: %s", hs.get_instance_name())
|
||||
logging.info("Twisted reactor: %s", type(reactor).__name__)
|
||||
|
||||
@@ -1294,7 +1294,7 @@ class FederationClient(FederationBase):
|
||||
return resp[1]
|
||||
|
||||
async def send_knock(self, destinations: List[str], pdu: EventBase) -> JsonDict:
|
||||
"""Attempts to send a knock event to given a list of servers. Iterates
|
||||
"""Attempts to send a knock event to a given list of servers. Iterates
|
||||
through the list until one attempt succeeds.
|
||||
|
||||
Doing so will cause the remote server to add the event to the graph,
|
||||
|
||||
@@ -824,7 +824,14 @@ class FederationServer(FederationBase):
|
||||
context, self._room_prejoin_state_types
|
||||
)
|
||||
)
|
||||
return {"knock_state_events": stripped_room_state}
|
||||
return {
|
||||
"knock_room_state": stripped_room_state,
|
||||
# Since v1.37, Synapse incorrectly used "knock_state_events" for this field.
|
||||
# Thus, we also populate a 'knock_state_events' with the same content to
|
||||
# support old instances.
|
||||
# See https://github.com/matrix-org/synapse/issues/14088.
|
||||
"knock_state_events": stripped_room_state,
|
||||
}
|
||||
|
||||
async def _on_send_membership_event(
|
||||
self, origin: str, content: JsonDict, membership_type: str, room_id: str
|
||||
|
||||
@@ -353,21 +353,25 @@ class FederationSender(AbstractFederationSender):
|
||||
last_token = await self.store.get_federation_out_pos("events")
|
||||
(
|
||||
next_token,
|
||||
events,
|
||||
event_to_received_ts,
|
||||
) = await self.store.get_all_new_events_stream(
|
||||
) = await self.store.get_all_new_event_ids_stream(
|
||||
last_token, self._last_poked_id, limit=100
|
||||
)
|
||||
|
||||
event_ids = event_to_received_ts.keys()
|
||||
event_entries = await self.store.get_unredacted_events_from_cache_or_db(
|
||||
event_ids
|
||||
)
|
||||
|
||||
logger.debug(
|
||||
"Handling %i -> %i: %i events to send (current id %i)",
|
||||
last_token,
|
||||
next_token,
|
||||
len(events),
|
||||
len(event_entries),
|
||||
self._last_poked_id,
|
||||
)
|
||||
|
||||
if not events and next_token >= self._last_poked_id:
|
||||
if not event_entries and next_token >= self._last_poked_id:
|
||||
logger.debug("All events processed")
|
||||
break
|
||||
|
||||
@@ -508,8 +512,14 @@ class FederationSender(AbstractFederationSender):
|
||||
await handle_event(event)
|
||||
|
||||
events_by_room: Dict[str, List[EventBase]] = {}
|
||||
for event in events:
|
||||
events_by_room.setdefault(event.room_id, []).append(event)
|
||||
|
||||
for event_id in event_ids:
|
||||
# `event_entries` is unsorted, so we have to iterate over `event_ids`
|
||||
# to ensure the events are in the right order
|
||||
event_cache = event_entries.get(event_id)
|
||||
if event_cache:
|
||||
event = event_cache.event
|
||||
events_by_room.setdefault(event.room_id, []).append(event)
|
||||
|
||||
await make_deferred_yieldable(
|
||||
defer.gatherResults(
|
||||
@@ -524,9 +534,10 @@ class FederationSender(AbstractFederationSender):
|
||||
logger.debug("Successfully handled up to %i", next_token)
|
||||
await self.store.update_federation_out_pos("events", next_token)
|
||||
|
||||
if events:
|
||||
if event_entries:
|
||||
now = self.clock.time_msec()
|
||||
ts = event_to_received_ts[events[-1].event_id]
|
||||
last_id = next(reversed(event_ids))
|
||||
ts = event_to_received_ts[last_id]
|
||||
assert ts is not None
|
||||
|
||||
synapse.metrics.event_processing_lag.labels(
|
||||
@@ -536,7 +547,7 @@ class FederationSender(AbstractFederationSender):
|
||||
"federation_sender"
|
||||
).set(ts)
|
||||
|
||||
events_processed_counter.inc(len(events))
|
||||
events_processed_counter.inc(len(event_entries))
|
||||
|
||||
event_processing_loop_room_count.labels("federation_sender").inc(
|
||||
len(events_by_room)
|
||||
|
||||
@@ -45,6 +45,7 @@ from synapse.federation.units import Transaction
|
||||
from synapse.http.matrixfederationclient import ByteParser
|
||||
from synapse.http.types import QueryParams
|
||||
from synapse.types import JsonDict
|
||||
from synapse.util import ExceptionBundle
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -926,8 +927,7 @@ class SendJoinParser(ByteParser[SendJoinResponse]):
|
||||
return len(data)
|
||||
|
||||
def finish(self) -> SendJoinResponse:
|
||||
for c in self._coros:
|
||||
c.close()
|
||||
_close_coros(self._coros)
|
||||
|
||||
if self._response.event_dict:
|
||||
self._response.event = make_event_from_dict(
|
||||
@@ -970,6 +970,27 @@ class _StateParser(ByteParser[StateRequestResponse]):
|
||||
return len(data)
|
||||
|
||||
def finish(self) -> StateRequestResponse:
|
||||
for c in self._coros:
|
||||
c.close()
|
||||
_close_coros(self._coros)
|
||||
return self._response
|
||||
|
||||
|
||||
def _close_coros(coros: Iterable[Generator[None, bytes, None]]) -> None:
|
||||
"""Close each of the given coroutines.
|
||||
|
||||
Always calls .close() on each coroutine, even if doing so raises an exception.
|
||||
Any exceptions raised are aggregated into an ExceptionBundle.
|
||||
|
||||
:raises ExceptionBundle: if at least one coroutine fails to close.
|
||||
"""
|
||||
exceptions = []
|
||||
for c in coros:
|
||||
try:
|
||||
c.close()
|
||||
except Exception as e:
|
||||
exceptions.append(e)
|
||||
|
||||
if exceptions:
|
||||
# raise from the first exception so that the traceback has slightly more context
|
||||
raise ExceptionBundle(
|
||||
f"There were {len(exceptions)} errors closing coroutines", exceptions
|
||||
) from exceptions[0]
|
||||
|
||||
@@ -109,10 +109,13 @@ class ApplicationServicesHandler:
|
||||
last_token = await self.store.get_appservice_last_pos()
|
||||
(
|
||||
upper_bound,
|
||||
events,
|
||||
event_to_received_ts,
|
||||
) = await self.store.get_all_new_events_stream(
|
||||
last_token, self.current_max, limit=100, get_prev_content=True
|
||||
) = await self.store.get_all_new_event_ids_stream(
|
||||
last_token, self.current_max, limit=100
|
||||
)
|
||||
|
||||
events = await self.store.get_events_as_list(
|
||||
event_to_received_ts.keys(), get_prev_content=True
|
||||
)
|
||||
|
||||
events_by_room: Dict[str, List[EventBase]] = {}
|
||||
|
||||
@@ -781,15 +781,27 @@ class FederationHandler:
|
||||
|
||||
# Send the signed event back to the room, and potentially receive some
|
||||
# further information about the room in the form of partial state events
|
||||
stripped_room_state = await self.federation_client.send_knock(
|
||||
target_hosts, event
|
||||
)
|
||||
knock_response = await self.federation_client.send_knock(target_hosts, event)
|
||||
|
||||
# Store any stripped room state events in the "unsigned" key of the event.
|
||||
# This is a bit of a hack and is cribbing off of invites. Basically we
|
||||
# store the room state here and retrieve it again when this event appears
|
||||
# in the invitee's sync stream. It is stripped out for all other local users.
|
||||
event.unsigned["knock_room_state"] = stripped_room_state["knock_state_events"]
|
||||
stripped_room_state = (
|
||||
knock_response.get("knock_room_state")
|
||||
# Since v1.37, Synapse incorrectly used "knock_state_events" for this field.
|
||||
# Thus, we also check for a 'knock_state_events' to support old instances.
|
||||
# See https://github.com/matrix-org/synapse/issues/14088.
|
||||
or knock_response.get("knock_state_events")
|
||||
)
|
||||
|
||||
if stripped_room_state is None:
|
||||
raise KeyError(
|
||||
"Missing 'knock_room_state' (or legacy 'knock_state_events') field in "
|
||||
"send_knock response"
|
||||
)
|
||||
|
||||
event.unsigned["knock_room_state"] = stripped_room_state
|
||||
|
||||
context = EventContext.for_outlier(self._storage_controllers)
|
||||
stream_id = await self._federation_event_handler.persist_events_and_notify(
|
||||
|
||||
@@ -414,7 +414,9 @@ class FederationEventHandler:
|
||||
|
||||
# First, precalculate the joined hosts so that the federation sender doesn't
|
||||
# need to.
|
||||
await self._event_creation_handler.cache_joined_hosts_for_event(event, context)
|
||||
await self._event_creation_handler.cache_joined_hosts_for_events(
|
||||
[(event, context)]
|
||||
)
|
||||
|
||||
await self._check_for_soft_fail(event, context=context, origin=origin)
|
||||
await self._run_push_actions_and_persist_event(event, context)
|
||||
@@ -2240,8 +2242,8 @@ class FederationEventHandler:
|
||||
event_pos = PersistedEventPosition(
|
||||
self._instance_name, event.internal_metadata.stream_ordering
|
||||
)
|
||||
await self._notifier.on_new_room_event(
|
||||
event, event_pos, max_stream_token, extra_users=extra_users
|
||||
await self._notifier.on_new_room_events(
|
||||
[(event, event_pos)], max_stream_token, extra_users=extra_users
|
||||
)
|
||||
|
||||
if event.type == EventTypes.Member and event.membership == Membership.JOIN:
|
||||
|
||||
@@ -1390,7 +1390,7 @@ class EventCreationHandler:
|
||||
extra_users=extra_users,
|
||||
),
|
||||
run_in_background(
|
||||
self.cache_joined_hosts_for_event, event, context
|
||||
self.cache_joined_hosts_for_events, events_and_context
|
||||
).addErrback(
|
||||
log_failure, "cache_joined_hosts_for_event failed"
|
||||
),
|
||||
@@ -1491,62 +1491,65 @@ class EventCreationHandler:
|
||||
await self.store.remove_push_actions_from_staging(event.event_id)
|
||||
raise
|
||||
|
||||
async def cache_joined_hosts_for_event(
|
||||
self, event: EventBase, context: EventContext
|
||||
async def cache_joined_hosts_for_events(
|
||||
self, events_and_context: List[Tuple[EventBase, EventContext]]
|
||||
) -> None:
|
||||
"""Precalculate the joined hosts at the event, when using Redis, so that
|
||||
"""Precalculate the joined hosts at each of the given events, when using Redis, so that
|
||||
external federation senders don't have to recalculate it themselves.
|
||||
"""
|
||||
|
||||
if not self._external_cache.is_enabled():
|
||||
return
|
||||
|
||||
# If external cache is enabled we should always have this.
|
||||
assert self._external_cache_joined_hosts_updates is not None
|
||||
|
||||
# We actually store two mappings, event ID -> prev state group,
|
||||
# state group -> joined hosts, which is much more space efficient
|
||||
# than event ID -> joined hosts.
|
||||
#
|
||||
# Note: We have to cache event ID -> prev state group, as we don't
|
||||
# store that in the DB.
|
||||
#
|
||||
# Note: We set the state group -> joined hosts cache if it hasn't been
|
||||
# set for a while, so that the expiry time is reset.
|
||||
|
||||
state_entry = await self.state.resolve_state_groups_for_events(
|
||||
event.room_id, event_ids=event.prev_event_ids()
|
||||
)
|
||||
|
||||
if state_entry.state_group:
|
||||
await self._external_cache.set(
|
||||
"event_to_prev_state_group",
|
||||
event.event_id,
|
||||
state_entry.state_group,
|
||||
expiry_ms=60 * 60 * 1000,
|
||||
)
|
||||
|
||||
if state_entry.state_group in self._external_cache_joined_hosts_updates:
|
||||
for event, _ in events_and_context:
|
||||
if not self._external_cache.is_enabled():
|
||||
return
|
||||
|
||||
state = await state_entry.get_state(
|
||||
self._storage_controllers.state, StateFilter.all()
|
||||
# If external cache is enabled we should always have this.
|
||||
assert self._external_cache_joined_hosts_updates is not None
|
||||
|
||||
# We actually store two mappings, event ID -> prev state group,
|
||||
# state group -> joined hosts, which is much more space efficient
|
||||
# than event ID -> joined hosts.
|
||||
#
|
||||
# Note: We have to cache event ID -> prev state group, as we don't
|
||||
# store that in the DB.
|
||||
#
|
||||
# Note: We set the state group -> joined hosts cache if it hasn't been
|
||||
# set for a while, so that the expiry time is reset.
|
||||
|
||||
state_entry = await self.state.resolve_state_groups_for_events(
|
||||
event.room_id, event_ids=event.prev_event_ids()
|
||||
)
|
||||
with opentracing.start_active_span("get_joined_hosts"):
|
||||
joined_hosts = await self.store.get_joined_hosts(
|
||||
event.room_id, state, state_entry
|
||||
|
||||
if state_entry.state_group:
|
||||
await self._external_cache.set(
|
||||
"event_to_prev_state_group",
|
||||
event.event_id,
|
||||
state_entry.state_group,
|
||||
expiry_ms=60 * 60 * 1000,
|
||||
)
|
||||
|
||||
# Note that the expiry times must be larger than the expiry time in
|
||||
# _external_cache_joined_hosts_updates.
|
||||
await self._external_cache.set(
|
||||
"get_joined_hosts",
|
||||
str(state_entry.state_group),
|
||||
list(joined_hosts),
|
||||
expiry_ms=60 * 60 * 1000,
|
||||
)
|
||||
if state_entry.state_group in self._external_cache_joined_hosts_updates:
|
||||
return
|
||||
|
||||
self._external_cache_joined_hosts_updates[state_entry.state_group] = None
|
||||
state = await state_entry.get_state(
|
||||
self._storage_controllers.state, StateFilter.all()
|
||||
)
|
||||
with opentracing.start_active_span("get_joined_hosts"):
|
||||
joined_hosts = await self.store.get_joined_hosts(
|
||||
event.room_id, state, state_entry
|
||||
)
|
||||
|
||||
# Note that the expiry times must be larger than the expiry time in
|
||||
# _external_cache_joined_hosts_updates.
|
||||
await self._external_cache.set(
|
||||
"get_joined_hosts",
|
||||
str(state_entry.state_group),
|
||||
list(joined_hosts),
|
||||
expiry_ms=60 * 60 * 1000,
|
||||
)
|
||||
|
||||
self._external_cache_joined_hosts_updates[
|
||||
state_entry.state_group
|
||||
] = None
|
||||
|
||||
async def _validate_canonical_alias(
|
||||
self,
|
||||
@@ -1872,6 +1875,7 @@ class EventCreationHandler:
|
||||
events_and_context, backfilled=backfilled
|
||||
)
|
||||
|
||||
events_and_pos = []
|
||||
for event in persisted_events:
|
||||
if self._ephemeral_events_enabled:
|
||||
# If there's an expiry timestamp on the event, schedule its expiry.
|
||||
@@ -1880,25 +1884,23 @@ class EventCreationHandler:
|
||||
stream_ordering = event.internal_metadata.stream_ordering
|
||||
assert stream_ordering is not None
|
||||
pos = PersistedEventPosition(self._instance_name, stream_ordering)
|
||||
|
||||
async def _notify() -> None:
|
||||
try:
|
||||
await self.notifier.on_new_room_event(
|
||||
event, pos, max_stream_token, extra_users=extra_users
|
||||
)
|
||||
except Exception:
|
||||
logger.exception(
|
||||
"Error notifying about new room event %s",
|
||||
event.event_id,
|
||||
)
|
||||
|
||||
run_in_background(_notify)
|
||||
events_and_pos.append((event, pos))
|
||||
|
||||
if event.type == EventTypes.Message:
|
||||
# We don't want to block sending messages on any presence code. This
|
||||
# matters as sometimes presence code can take a while.
|
||||
run_in_background(self._bump_active_time, requester.user)
|
||||
|
||||
async def _notify() -> None:
|
||||
try:
|
||||
await self.notifier.on_new_room_events(
|
||||
events_and_pos, max_stream_token, extra_users=extra_users
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Error notifying about new room events")
|
||||
|
||||
run_in_background(_notify)
|
||||
|
||||
return persisted_events[-1]
|
||||
|
||||
async def _maybe_kick_guest_users(
|
||||
|
||||
@@ -63,8 +63,6 @@ class ReceiptsHandler:
|
||||
self.clock = self.hs.get_clock()
|
||||
self.state = hs.get_state_handler()
|
||||
|
||||
self._msc3771_enabled = hs.config.experimental.msc3771_enabled
|
||||
|
||||
async def _received_remote_receipt(self, origin: str, content: JsonDict) -> None:
|
||||
"""Called when we receive an EDU of type m.receipt from a remote HS."""
|
||||
receipts = []
|
||||
@@ -96,11 +94,10 @@ class ReceiptsHandler:
|
||||
# Check if these receipts apply to a thread.
|
||||
thread_id = None
|
||||
data = user_values.get("data", {})
|
||||
if self._msc3771_enabled and isinstance(data, dict):
|
||||
thread_id = data.get("thread_id")
|
||||
# If the thread ID is invalid, consider it missing.
|
||||
if not isinstance(thread_id, str):
|
||||
thread_id = None
|
||||
thread_id = data.get("thread_id")
|
||||
# If the thread ID is invalid, consider it missing.
|
||||
if not isinstance(thread_id, str):
|
||||
thread_id = None
|
||||
|
||||
receipts.append(
|
||||
ReadReceipt(
|
||||
|
||||
@@ -21,6 +21,7 @@ from synapse.api.errors import SynapseError
|
||||
from synapse.events import EventBase, relation_from_event
|
||||
from synapse.logging.opentracing import trace
|
||||
from synapse.storage.databases.main.relations import _RelatedEvent
|
||||
from synapse.streams.config import PaginationConfig
|
||||
from synapse.types import JsonDict, Requester, StreamToken, UserID
|
||||
from synapse.visibility import filter_events_for_client
|
||||
|
||||
@@ -72,13 +73,10 @@ class RelationsHandler:
|
||||
requester: Requester,
|
||||
event_id: str,
|
||||
room_id: str,
|
||||
pagin_config: PaginationConfig,
|
||||
include_original_event: bool,
|
||||
relation_type: Optional[str] = None,
|
||||
event_type: Optional[str] = None,
|
||||
limit: int = 5,
|
||||
direction: str = "b",
|
||||
from_token: Optional[StreamToken] = None,
|
||||
to_token: Optional[StreamToken] = None,
|
||||
include_original_event: bool = False,
|
||||
) -> JsonDict:
|
||||
"""Get related events of a event, ordered by topological ordering.
|
||||
|
||||
@@ -88,14 +86,10 @@ class RelationsHandler:
|
||||
requester: The user requesting the relations.
|
||||
event_id: Fetch events that relate to this event ID.
|
||||
room_id: The room the event belongs to.
|
||||
pagin_config: The pagination config rules to apply, if any.
|
||||
include_original_event: Whether to include the parent event.
|
||||
relation_type: Only fetch events with this relation type, if given.
|
||||
event_type: Only fetch events with this event type, if given.
|
||||
limit: Only fetch the most recent `limit` events.
|
||||
direction: Whether to fetch the most recent first (`"b"`) or the
|
||||
oldest first (`"f"`).
|
||||
from_token: Fetch rows from the given token, or from the start if None.
|
||||
to_token: Fetch rows up to the given token, or up to the end if None.
|
||||
include_original_event: Whether to include the parent event.
|
||||
|
||||
Returns:
|
||||
The pagination chunk.
|
||||
@@ -114,6 +108,9 @@ class RelationsHandler:
|
||||
if event is None:
|
||||
raise SynapseError(404, "Unknown parent event.")
|
||||
|
||||
# TODO Update pagination config to not allow None limits.
|
||||
assert pagin_config.limit is not None
|
||||
|
||||
# Note that ignored users are not passed into get_relations_for_event
|
||||
# below. Ignored users are handled in filter_events_for_client (and by
|
||||
# not passing them in here we should get a better cache hit rate).
|
||||
@@ -123,10 +120,10 @@ class RelationsHandler:
|
||||
room_id=room_id,
|
||||
relation_type=relation_type,
|
||||
event_type=event_type,
|
||||
limit=limit,
|
||||
direction=direction,
|
||||
from_token=from_token,
|
||||
to_token=to_token,
|
||||
limit=pagin_config.limit,
|
||||
direction=pagin_config.direction,
|
||||
from_token=pagin_config.from_token,
|
||||
to_token=pagin_config.to_token,
|
||||
)
|
||||
|
||||
events = await self._main_store.get_events_as_list(
|
||||
@@ -162,8 +159,10 @@ class RelationsHandler:
|
||||
if next_token:
|
||||
return_value["next_batch"] = await next_token.to_string(self._main_store)
|
||||
|
||||
if from_token:
|
||||
return_value["prev_batch"] = await from_token.to_string(self._main_store)
|
||||
if pagin_config.from_token:
|
||||
return_value["prev_batch"] = await pagin_config.from_token.to_string(
|
||||
self._main_store
|
||||
)
|
||||
|
||||
return return_value
|
||||
|
||||
|
||||
@@ -279,8 +279,6 @@ class SyncHandler:
|
||||
|
||||
self.rooms_to_exclude = hs.config.server.rooms_to_exclude_from_sync
|
||||
|
||||
self._msc3773_enabled = hs.config.experimental.msc3773_enabled
|
||||
|
||||
async def wait_for_sync_for_user(
|
||||
self,
|
||||
requester: Requester,
|
||||
@@ -2412,10 +2410,7 @@ class SyncHandler:
|
||||
unread_count = notifs.main_timeline.unread_count
|
||||
|
||||
# Check the sync configuration.
|
||||
if (
|
||||
self._msc3773_enabled
|
||||
and sync_config.filter_collection.unread_thread_notifications()
|
||||
):
|
||||
if sync_config.filter_collection.unread_thread_notifications():
|
||||
# And add info for each thread.
|
||||
room_sync.unread_thread_notifications = {
|
||||
thread_id: {
|
||||
|
||||
@@ -35,6 +35,7 @@ from typing_extensions import Literal
|
||||
from twisted.web.server import Request
|
||||
|
||||
from synapse.api.errors import Codes, SynapseError
|
||||
from synapse.http import redact_uri
|
||||
from synapse.http.server import HttpServer
|
||||
from synapse.types import JsonDict, RoomAlias, RoomID
|
||||
from synapse.util import json_decoder
|
||||
@@ -664,7 +665,13 @@ def parse_json_value_from_request(
|
||||
try:
|
||||
content = json_decoder.decode(content_bytes.decode("utf-8"))
|
||||
except Exception as e:
|
||||
logger.warning("Unable to parse JSON: %s (%s)", e, content_bytes)
|
||||
logger.warning(
|
||||
"Unable to parse JSON from %s %s response: %s (%s)",
|
||||
request.method.decode("ascii", errors="replace"),
|
||||
redact_uri(request.uri.decode("ascii", errors="replace")),
|
||||
e,
|
||||
content_bytes,
|
||||
)
|
||||
raise SynapseError(
|
||||
HTTPStatus.BAD_REQUEST, "Content not JSON.", errcode=Codes.NOT_JSON
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ Due to the renaming of metrics in prometheus_client 0.4.0, this customised
|
||||
vendoring of the code will emit both the old versions that Synapse dashboards
|
||||
expect, and the newer "best practice" version of the up-to-date official client.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import math
|
||||
import threading
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
@@ -34,6 +34,7 @@ from prometheus_client.core import Sample
|
||||
from twisted.web.resource import Resource
|
||||
from twisted.web.server import Request
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
CONTENT_TYPE_LATEST = "text/plain; version=0.0.4; charset=utf-8"
|
||||
|
||||
|
||||
@@ -219,11 +220,16 @@ class MetricsHandler(BaseHTTPRequestHandler):
|
||||
except Exception:
|
||||
self.send_error(500, "error generating metric output")
|
||||
raise
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", CONTENT_TYPE_LATEST)
|
||||
self.send_header("Content-Length", str(len(output)))
|
||||
self.end_headers()
|
||||
self.wfile.write(output)
|
||||
try:
|
||||
self.send_response(200)
|
||||
self.send_header("Content-Type", CONTENT_TYPE_LATEST)
|
||||
self.send_header("Content-Length", str(len(output)))
|
||||
self.end_headers()
|
||||
self.wfile.write(output)
|
||||
except BrokenPipeError as e:
|
||||
logger.warning(
|
||||
"BrokenPipeError when serving metrics (%s). Did Prometheus restart?", e
|
||||
)
|
||||
|
||||
def log_message(self, format: str, *args: Any) -> None:
|
||||
"""Log nothing."""
|
||||
|
||||
@@ -748,6 +748,40 @@ class ModuleApi:
|
||||
)
|
||||
)
|
||||
|
||||
async def create_login_token(
|
||||
self,
|
||||
user_id: str,
|
||||
duration_in_ms: int = (2 * 60 * 1000),
|
||||
auth_provider_id: Optional[str] = None,
|
||||
auth_provider_session_id: Optional[str] = None,
|
||||
) -> str:
|
||||
"""Create a login token suitable for m.login.token authentication
|
||||
|
||||
Added in Synapse v1.69.0.
|
||||
|
||||
Args:
|
||||
user_id: gives the ID of the user that the token is for
|
||||
|
||||
duration_in_ms: the time that the token will be valid for
|
||||
|
||||
auth_provider_id: the ID of the SSO IdP that the user used to authenticate
|
||||
to get this token, if any. This is encoded in the token so that
|
||||
/login can report stats on number of successful logins by IdP.
|
||||
|
||||
auth_provider_session_id: The session ID got during login from the SSO IdP,
|
||||
if any.
|
||||
"""
|
||||
# The deprecated `generate_short_term_login_token` method defaulted to an empty
|
||||
# string for the `auth_provider_id` because of how the underlying macaroon was
|
||||
# generated. This will change to a proper NULL-able field when the tokens get
|
||||
# moved to the database.
|
||||
return self._hs.get_macaroon_generator().generate_short_term_login_token(
|
||||
user_id,
|
||||
auth_provider_id or "",
|
||||
auth_provider_session_id,
|
||||
duration_in_ms,
|
||||
)
|
||||
|
||||
def generate_short_term_login_token(
|
||||
self,
|
||||
user_id: str,
|
||||
@@ -759,6 +793,9 @@ class ModuleApi:
|
||||
|
||||
Added in Synapse v1.9.0.
|
||||
|
||||
This was deprecated in Synapse v1.69.0 in favor of create_login_token, and will
|
||||
be removed in Synapse 1.71.0.
|
||||
|
||||
Args:
|
||||
user_id: gives the ID of the user that the token is for
|
||||
|
||||
@@ -768,6 +805,11 @@ class ModuleApi:
|
||||
to get this token, if any. This is encoded in the token so that
|
||||
/login can report stats on number of successful logins by IdP.
|
||||
"""
|
||||
logger.warn(
|
||||
"A module configured on this server uses ModuleApi.generate_short_term_login_token(), "
|
||||
"which is deprecated in favor of ModuleApi.create_login_token(), and will be removed in "
|
||||
"Synapse 1.71.0",
|
||||
)
|
||||
return self._hs.get_macaroon_generator().generate_short_term_login_token(
|
||||
user_id,
|
||||
auth_provider_id,
|
||||
|
||||
@@ -294,35 +294,31 @@ class Notifier:
|
||||
"""
|
||||
self._new_join_in_room_callbacks.append(cb)
|
||||
|
||||
async def on_new_room_event(
|
||||
async def on_new_room_events(
|
||||
self,
|
||||
event: EventBase,
|
||||
event_pos: PersistedEventPosition,
|
||||
events_and_pos: List[Tuple[EventBase, PersistedEventPosition]],
|
||||
max_room_stream_token: RoomStreamToken,
|
||||
extra_users: Optional[Collection[UserID]] = None,
|
||||
) -> None:
|
||||
"""Unwraps event and calls `on_new_room_event_args`."""
|
||||
await self.on_new_room_event_args(
|
||||
event_pos=event_pos,
|
||||
room_id=event.room_id,
|
||||
event_id=event.event_id,
|
||||
event_type=event.type,
|
||||
state_key=event.get("state_key"),
|
||||
membership=event.content.get("membership"),
|
||||
max_room_stream_token=max_room_stream_token,
|
||||
extra_users=extra_users or [],
|
||||
)
|
||||
"""Creates a _PendingRoomEventEntry for each of the listed events and calls
|
||||
notify_new_room_events with the results."""
|
||||
event_entries = []
|
||||
for event, pos in events_and_pos:
|
||||
entry = self.create_pending_room_event_entry(
|
||||
pos,
|
||||
extra_users,
|
||||
event.room_id,
|
||||
event.type,
|
||||
event.get("state_key"),
|
||||
event.content.get("membership"),
|
||||
)
|
||||
event_entries.append((entry, event.event_id))
|
||||
await self.notify_new_room_events(event_entries, max_room_stream_token)
|
||||
|
||||
async def on_new_room_event_args(
|
||||
async def notify_new_room_events(
|
||||
self,
|
||||
room_id: str,
|
||||
event_id: str,
|
||||
event_type: str,
|
||||
state_key: Optional[str],
|
||||
membership: Optional[str],
|
||||
event_pos: PersistedEventPosition,
|
||||
event_entries: List[Tuple[_PendingRoomEventEntry, str]],
|
||||
max_room_stream_token: RoomStreamToken,
|
||||
extra_users: Optional[Collection[UserID]] = None,
|
||||
) -> None:
|
||||
"""Used by handlers to inform the notifier something has happened
|
||||
in the room, room event wise.
|
||||
@@ -338,22 +334,33 @@ class Notifier:
|
||||
until all previous events have been persisted before notifying
|
||||
the client streams.
|
||||
"""
|
||||
self.pending_new_room_events.append(
|
||||
_PendingRoomEventEntry(
|
||||
event_pos=event_pos,
|
||||
extra_users=extra_users or [],
|
||||
room_id=room_id,
|
||||
type=event_type,
|
||||
state_key=state_key,
|
||||
membership=membership,
|
||||
)
|
||||
)
|
||||
for event_entry, event_id in event_entries:
|
||||
self.pending_new_room_events.append(event_entry)
|
||||
await self._third_party_rules.on_new_event(event_id)
|
||||
|
||||
self._notify_pending_new_room_events(max_room_stream_token)
|
||||
|
||||
await self._third_party_rules.on_new_event(event_id)
|
||||
|
||||
self.notify_replication()
|
||||
|
||||
def create_pending_room_event_entry(
|
||||
self,
|
||||
event_pos: PersistedEventPosition,
|
||||
extra_users: Optional[Collection[UserID]],
|
||||
room_id: str,
|
||||
event_type: str,
|
||||
state_key: Optional[str],
|
||||
membership: Optional[str],
|
||||
) -> _PendingRoomEventEntry:
|
||||
"""Creates and returns a _PendingRoomEventEntry"""
|
||||
return _PendingRoomEventEntry(
|
||||
event_pos=event_pos,
|
||||
extra_users=extra_users or [],
|
||||
room_id=room_id,
|
||||
type=event_type,
|
||||
state_key=state_key,
|
||||
membership=membership,
|
||||
)
|
||||
|
||||
def _notify_pending_new_room_events(
|
||||
self, max_room_stream_token: RoomStreamToken
|
||||
) -> None:
|
||||
|
||||
@@ -13,18 +13,15 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import itertools
|
||||
import logging
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
Collection,
|
||||
Dict,
|
||||
Iterable,
|
||||
List,
|
||||
Mapping,
|
||||
Optional,
|
||||
Set,
|
||||
Tuple,
|
||||
Union,
|
||||
)
|
||||
@@ -38,7 +35,7 @@ from synapse.events.snapshot import EventContext
|
||||
from synapse.state import POWER_KEY
|
||||
from synapse.storage.databases.main.roommember import EventIdMembership
|
||||
from synapse.storage.state import StateFilter
|
||||
from synapse.synapse_rust.push import FilteredPushRules, PushRule, PushRuleEvaluator
|
||||
from synapse.synapse_rust.push import FilteredPushRules, PushRuleEvaluator
|
||||
from synapse.util.caches import register_cache
|
||||
from synapse.util.metrics import measure_func
|
||||
from synapse.visibility import filter_event_for_clients_with_state
|
||||
@@ -117,9 +114,6 @@ class BulkPushRuleEvaluator:
|
||||
resizable=False,
|
||||
)
|
||||
|
||||
# Whether to support MSC3772 is supported.
|
||||
self._relations_match_enabled = self.hs.config.experimental.msc3772_enabled
|
||||
|
||||
async def _get_rules_for_event(
|
||||
self,
|
||||
event: EventBase,
|
||||
@@ -200,51 +194,6 @@ class BulkPushRuleEvaluator:
|
||||
|
||||
return pl_event.content if pl_event else {}, sender_level
|
||||
|
||||
async def _get_mutual_relations(
|
||||
self, parent_id: str, rules: Iterable[Tuple[PushRule, bool]]
|
||||
) -> Dict[str, Set[Tuple[str, str]]]:
|
||||
"""
|
||||
Fetch event metadata for events which related to the same event as the given event.
|
||||
|
||||
If the given event has no relation information, returns an empty dictionary.
|
||||
|
||||
Args:
|
||||
parent_id: The event ID which is targeted by relations.
|
||||
rules: The push rules which will be processed for this event.
|
||||
|
||||
Returns:
|
||||
A dictionary of relation type to:
|
||||
A set of tuples of:
|
||||
The sender
|
||||
The event type
|
||||
"""
|
||||
|
||||
# If the experimental feature is not enabled, skip fetching relations.
|
||||
if not self._relations_match_enabled:
|
||||
return {}
|
||||
|
||||
# Pre-filter to figure out which relation types are interesting.
|
||||
rel_types = set()
|
||||
for rule, enabled in rules:
|
||||
if not enabled:
|
||||
continue
|
||||
|
||||
for condition in rule.conditions:
|
||||
if condition["kind"] != "org.matrix.msc3772.relation_match":
|
||||
continue
|
||||
|
||||
# rel_type is required.
|
||||
rel_type = condition.get("rel_type")
|
||||
if rel_type:
|
||||
rel_types.add(rel_type)
|
||||
|
||||
# If no valid rules were found, no mutual relations.
|
||||
if not rel_types:
|
||||
return {}
|
||||
|
||||
# If any valid rules were found, fetch the mutual relations.
|
||||
return await self.store.get_mutual_event_relations(parent_id, rel_types)
|
||||
|
||||
@measure_func("action_for_event_by_user")
|
||||
async def action_for_event_by_user(
|
||||
self, event: EventBase, context: EventContext
|
||||
@@ -276,31 +225,31 @@ class BulkPushRuleEvaluator:
|
||||
sender_power_level,
|
||||
) = await self._get_power_levels_and_sender_level(event, context)
|
||||
|
||||
# Find the event's thread ID.
|
||||
relation = relation_from_event(event)
|
||||
# If the event does not have a relation, then cannot have any mutual
|
||||
# relations or thread ID.
|
||||
relations = {}
|
||||
# If the event does not have a relation, then it cannot have a thread ID.
|
||||
thread_id = MAIN_TIMELINE
|
||||
if relation:
|
||||
relations = await self._get_mutual_relations(
|
||||
relation.parent_id,
|
||||
itertools.chain(*(r.rules() for r in rules_by_user.values())),
|
||||
)
|
||||
# Recursively attempt to find the thread this event relates to.
|
||||
if relation.rel_type == RelationTypes.THREAD:
|
||||
thread_id = relation.parent_id
|
||||
else:
|
||||
# Since the event has not yet been persisted we check whether
|
||||
# the parent is part of a thread.
|
||||
thread_id = await self.store.get_thread_id(relation.parent_id) or "main"
|
||||
thread_id = await self.store.get_thread_id(relation.parent_id)
|
||||
|
||||
# It's possible that old room versions have non-integer power levels (floats or
|
||||
# strings). Workaround this by explicitly converting to int.
|
||||
notification_levels = power_levels.get("notifications", {})
|
||||
if not event.room_version.msc3667_int_only_power_levels:
|
||||
for user_id, level in notification_levels.items():
|
||||
notification_levels[user_id] = int(level)
|
||||
|
||||
evaluator = PushRuleEvaluator(
|
||||
_flatten_dict(event),
|
||||
room_member_count,
|
||||
sender_power_level,
|
||||
power_levels.get("notifications", {}),
|
||||
relations,
|
||||
self._relations_match_enabled,
|
||||
notification_levels,
|
||||
)
|
||||
|
||||
users = rules_by_user.keys()
|
||||
|
||||
@@ -210,15 +210,16 @@ class ReplicationDataHandler:
|
||||
|
||||
max_token = self.store.get_room_max_token()
|
||||
event_pos = PersistedEventPosition(instance_name, token)
|
||||
await self.notifier.on_new_room_event_args(
|
||||
event_pos=event_pos,
|
||||
max_room_stream_token=max_token,
|
||||
extra_users=extra_users,
|
||||
room_id=row.data.room_id,
|
||||
event_id=row.data.event_id,
|
||||
event_type=row.data.type,
|
||||
state_key=row.data.state_key,
|
||||
membership=row.data.membership,
|
||||
event_entry = self.notifier.create_pending_room_event_entry(
|
||||
event_pos,
|
||||
extra_users,
|
||||
row.data.room_id,
|
||||
row.data.type,
|
||||
row.data.state_key,
|
||||
row.data.membership,
|
||||
)
|
||||
await self.notifier.notify_new_room_events(
|
||||
[(event_entry, row.data.event_id)], max_token
|
||||
)
|
||||
|
||||
# If this event is a join, make a note of it so we have an accurate
|
||||
|
||||
@@ -14,18 +14,21 @@
|
||||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Tuple
|
||||
from typing import TYPE_CHECKING, List, Optional, Tuple
|
||||
|
||||
from pydantic import Extra, StrictStr
|
||||
|
||||
from synapse.api import errors
|
||||
from synapse.api.errors import NotFoundError
|
||||
from synapse.http.server import HttpServer
|
||||
from synapse.http.servlet import (
|
||||
RestServlet,
|
||||
assert_params_in_dict,
|
||||
parse_json_object_from_request,
|
||||
parse_and_validate_json_object_from_request,
|
||||
)
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.rest.client._base import client_patterns, interactive_auth_handler
|
||||
from synapse.rest.client.models import AuthenticationData
|
||||
from synapse.rest.models import RequestBodyModel
|
||||
from synapse.types import JsonDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -80,27 +83,29 @@ class DeleteDevicesRestServlet(RestServlet):
|
||||
self.device_handler = hs.get_device_handler()
|
||||
self.auth_handler = hs.get_auth_handler()
|
||||
|
||||
class PostBody(RequestBodyModel):
|
||||
auth: Optional[AuthenticationData]
|
||||
devices: List[StrictStr]
|
||||
|
||||
@interactive_auth_handler
|
||||
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
requester = await self.auth.get_user_by_req(request)
|
||||
|
||||
try:
|
||||
body = parse_json_object_from_request(request)
|
||||
body = parse_and_validate_json_object_from_request(request, self.PostBody)
|
||||
except errors.SynapseError as e:
|
||||
if e.errcode == errors.Codes.NOT_JSON:
|
||||
# DELETE
|
||||
# TODO: Can/should we remove this fallback now?
|
||||
# deal with older clients which didn't pass a JSON dict
|
||||
# the same as those that pass an empty dict
|
||||
body = {}
|
||||
body = self.PostBody.parse_obj({})
|
||||
else:
|
||||
raise e
|
||||
|
||||
assert_params_in_dict(body, ["devices"])
|
||||
|
||||
await self.auth_handler.validate_user_via_ui_auth(
|
||||
requester,
|
||||
request,
|
||||
body,
|
||||
body.dict(exclude_unset=True),
|
||||
"remove device(s) from your account",
|
||||
# Users might call this multiple times in a row while cleaning up
|
||||
# devices, allow a single UI auth session to be re-used.
|
||||
@@ -108,7 +113,7 @@ class DeleteDevicesRestServlet(RestServlet):
|
||||
)
|
||||
|
||||
await self.device_handler.delete_devices(
|
||||
requester.user.to_string(), body["devices"]
|
||||
requester.user.to_string(), body.devices
|
||||
)
|
||||
return 200, {}
|
||||
|
||||
@@ -147,6 +152,9 @@ class DeviceRestServlet(RestServlet):
|
||||
|
||||
return 200, device
|
||||
|
||||
class DeleteBody(RequestBodyModel):
|
||||
auth: Optional[AuthenticationData]
|
||||
|
||||
@interactive_auth_handler
|
||||
async def on_DELETE(
|
||||
self, request: SynapseRequest, device_id: str
|
||||
@@ -154,20 +162,21 @@ class DeviceRestServlet(RestServlet):
|
||||
requester = await self.auth.get_user_by_req(request)
|
||||
|
||||
try:
|
||||
body = parse_json_object_from_request(request)
|
||||
body = parse_and_validate_json_object_from_request(request, self.DeleteBody)
|
||||
|
||||
except errors.SynapseError as e:
|
||||
if e.errcode == errors.Codes.NOT_JSON:
|
||||
# TODO: can/should we remove this fallback now?
|
||||
# deal with older clients which didn't pass a JSON dict
|
||||
# the same as those that pass an empty dict
|
||||
body = {}
|
||||
body = self.DeleteBody.parse_obj({})
|
||||
else:
|
||||
raise
|
||||
|
||||
await self.auth_handler.validate_user_via_ui_auth(
|
||||
requester,
|
||||
request,
|
||||
body,
|
||||
body.dict(exclude_unset=True),
|
||||
"remove a device from your account",
|
||||
# Users might call this multiple times in a row while cleaning up
|
||||
# devices, allow a single UI auth session to be re-used.
|
||||
@@ -179,18 +188,33 @@ class DeviceRestServlet(RestServlet):
|
||||
)
|
||||
return 200, {}
|
||||
|
||||
class PutBody(RequestBodyModel):
|
||||
display_name: Optional[StrictStr]
|
||||
|
||||
async def on_PUT(
|
||||
self, request: SynapseRequest, device_id: str
|
||||
) -> Tuple[int, JsonDict]:
|
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True)
|
||||
|
||||
body = parse_json_object_from_request(request)
|
||||
body = parse_and_validate_json_object_from_request(request, self.PutBody)
|
||||
await self.device_handler.update_device(
|
||||
requester.user.to_string(), device_id, body
|
||||
requester.user.to_string(), device_id, body.dict()
|
||||
)
|
||||
return 200, {}
|
||||
|
||||
|
||||
class DehydratedDeviceDataModel(RequestBodyModel):
|
||||
"""JSON blob describing a dehydrated device to be stored.
|
||||
|
||||
Expects other freeform fields. Use .dict() to access them.
|
||||
"""
|
||||
|
||||
class Config:
|
||||
extra = Extra.allow
|
||||
|
||||
algorithm: StrictStr
|
||||
|
||||
|
||||
class DehydratedDeviceServlet(RestServlet):
|
||||
"""Retrieve or store a dehydrated device.
|
||||
|
||||
@@ -246,27 +270,19 @@ class DehydratedDeviceServlet(RestServlet):
|
||||
else:
|
||||
raise errors.NotFoundError("No dehydrated device available")
|
||||
|
||||
async def on_PUT(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
submission = parse_json_object_from_request(request)
|
||||
requester = await self.auth.get_user_by_req(request)
|
||||
class PutBody(RequestBodyModel):
|
||||
device_id: StrictStr
|
||||
device_data: DehydratedDeviceDataModel
|
||||
initial_device_display_name: Optional[StrictStr]
|
||||
|
||||
if "device_data" not in submission:
|
||||
raise errors.SynapseError(
|
||||
400,
|
||||
"device_data missing",
|
||||
errcode=errors.Codes.MISSING_PARAM,
|
||||
)
|
||||
elif not isinstance(submission["device_data"], dict):
|
||||
raise errors.SynapseError(
|
||||
400,
|
||||
"device_data must be an object",
|
||||
errcode=errors.Codes.INVALID_PARAM,
|
||||
)
|
||||
async def on_PUT(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
submission = parse_and_validate_json_object_from_request(request, self.PutBody)
|
||||
requester = await self.auth.get_user_by_req(request)
|
||||
|
||||
device_id = await self.device_handler.store_dehydrated_device(
|
||||
requester.user.to_string(),
|
||||
submission["device_data"],
|
||||
submission.get("initial_device_display_name", None),
|
||||
submission.device_data,
|
||||
submission.initial_device_display_name,
|
||||
)
|
||||
return 200, {"device_id": device_id}
|
||||
|
||||
@@ -300,28 +316,18 @@ class ClaimDehydratedDeviceServlet(RestServlet):
|
||||
self.auth = hs.get_auth()
|
||||
self.device_handler = hs.get_device_handler()
|
||||
|
||||
class PostBody(RequestBodyModel):
|
||||
device_id: StrictStr
|
||||
|
||||
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
requester = await self.auth.get_user_by_req(request)
|
||||
|
||||
submission = parse_json_object_from_request(request)
|
||||
|
||||
if "device_id" not in submission:
|
||||
raise errors.SynapseError(
|
||||
400,
|
||||
"device_id missing",
|
||||
errcode=errors.Codes.MISSING_PARAM,
|
||||
)
|
||||
elif not isinstance(submission["device_id"], str):
|
||||
raise errors.SynapseError(
|
||||
400,
|
||||
"device_id must be a string",
|
||||
errcode=errors.Codes.INVALID_PARAM,
|
||||
)
|
||||
submission = parse_and_validate_json_object_from_request(request, self.PostBody)
|
||||
|
||||
result = await self.device_handler.rehydrate_device(
|
||||
requester.user.to_string(),
|
||||
self.auth.get_access_token_from_request(request),
|
||||
submission["device_id"],
|
||||
submission.device_id,
|
||||
)
|
||||
|
||||
return 200, result
|
||||
|
||||
@@ -50,7 +50,6 @@ class ReceiptRestServlet(RestServlet):
|
||||
ReceiptTypes.READ_PRIVATE,
|
||||
ReceiptTypes.FULLY_READ,
|
||||
}
|
||||
self._msc3771_enabled = hs.config.experimental.msc3771_enabled
|
||||
|
||||
async def on_POST(
|
||||
self, request: SynapseRequest, room_id: str, receipt_type: str, event_id: str
|
||||
@@ -67,30 +66,29 @@ class ReceiptRestServlet(RestServlet):
|
||||
|
||||
# Pull the thread ID, if one exists.
|
||||
thread_id = None
|
||||
if self._msc3771_enabled:
|
||||
if "thread_id" in body:
|
||||
thread_id = body.get("thread_id")
|
||||
if not thread_id or not isinstance(thread_id, str):
|
||||
raise SynapseError(
|
||||
400,
|
||||
"thread_id field must be a non-empty string",
|
||||
Codes.INVALID_PARAM,
|
||||
)
|
||||
if "thread_id" in body:
|
||||
thread_id = body.get("thread_id")
|
||||
if not thread_id or not isinstance(thread_id, str):
|
||||
raise SynapseError(
|
||||
400,
|
||||
"thread_id field must be a non-empty string",
|
||||
Codes.INVALID_PARAM,
|
||||
)
|
||||
|
||||
if receipt_type == ReceiptTypes.FULLY_READ:
|
||||
raise SynapseError(
|
||||
400,
|
||||
f"thread_id is not compatible with {ReceiptTypes.FULLY_READ} receipts.",
|
||||
Codes.INVALID_PARAM,
|
||||
)
|
||||
if receipt_type == ReceiptTypes.FULLY_READ:
|
||||
raise SynapseError(
|
||||
400,
|
||||
f"thread_id is not compatible with {ReceiptTypes.FULLY_READ} receipts.",
|
||||
Codes.INVALID_PARAM,
|
||||
)
|
||||
|
||||
# Ensure the event ID roughly correlates to the thread ID.
|
||||
if thread_id != await self._main_store.get_thread_id(event_id):
|
||||
raise SynapseError(
|
||||
400,
|
||||
f"event_id {event_id} is not related to thread {thread_id}",
|
||||
Codes.INVALID_PARAM,
|
||||
)
|
||||
# Ensure the event ID roughly correlates to the thread ID.
|
||||
if thread_id != await self._main_store.get_thread_id(event_id):
|
||||
raise SynapseError(
|
||||
400,
|
||||
f"event_id {event_id} is not related to thread {thread_id}",
|
||||
Codes.INVALID_PARAM,
|
||||
)
|
||||
|
||||
await self.presence_handler.bump_presence_active_time(requester.user)
|
||||
|
||||
|
||||
@@ -16,10 +16,11 @@ import logging
|
||||
from typing import TYPE_CHECKING, Optional, Tuple
|
||||
|
||||
from synapse.http.server import HttpServer
|
||||
from synapse.http.servlet import RestServlet, parse_integer, parse_string
|
||||
from synapse.http.servlet import RestServlet
|
||||
from synapse.http.site import SynapseRequest
|
||||
from synapse.rest.client._base import client_patterns
|
||||
from synapse.types import JsonDict, StreamToken
|
||||
from synapse.streams.config import PaginationConfig
|
||||
from synapse.types import JsonDict
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.server import HomeServer
|
||||
@@ -41,9 +42,8 @@ class RelationPaginationServlet(RestServlet):
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
super().__init__()
|
||||
self.auth = hs.get_auth()
|
||||
self.store = hs.get_datastores().main
|
||||
self._store = hs.get_datastores().main
|
||||
self._relations_handler = hs.get_relations_handler()
|
||||
self._msc3715_enabled = hs.config.experimental.msc3715_enabled
|
||||
|
||||
async def on_GET(
|
||||
self,
|
||||
@@ -55,49 +55,24 @@ class RelationPaginationServlet(RestServlet):
|
||||
) -> Tuple[int, JsonDict]:
|
||||
requester = await self.auth.get_user_by_req(request, allow_guest=True)
|
||||
|
||||
limit = parse_integer(request, "limit", default=5)
|
||||
# Fetch the direction parameter, if provided.
|
||||
#
|
||||
# TODO Use PaginationConfig.from_request when the unstable parameter is
|
||||
# no longer needed.
|
||||
direction = parse_string(request, "dir", allowed_values=["f", "b"])
|
||||
if direction is None:
|
||||
if self._msc3715_enabled:
|
||||
direction = parse_string(
|
||||
request,
|
||||
"org.matrix.msc3715.dir",
|
||||
default="b",
|
||||
allowed_values=["f", "b"],
|
||||
)
|
||||
else:
|
||||
direction = "b"
|
||||
from_token_str = parse_string(request, "from")
|
||||
to_token_str = parse_string(request, "to")
|
||||
|
||||
# Return the relations
|
||||
from_token = None
|
||||
if from_token_str:
|
||||
from_token = await StreamToken.from_string(self.store, from_token_str)
|
||||
to_token = None
|
||||
if to_token_str:
|
||||
to_token = await StreamToken.from_string(self.store, to_token_str)
|
||||
pagination_config = await PaginationConfig.from_request(
|
||||
self._store, request, default_limit=5, default_dir="b"
|
||||
)
|
||||
|
||||
# The unstable version of this API returns an extra field for client
|
||||
# compatibility, see https://github.com/matrix-org/synapse/issues/12930.
|
||||
assert request.path is not None
|
||||
include_original_event = request.path.startswith(b"/_matrix/client/unstable/")
|
||||
|
||||
# Return the relations
|
||||
result = await self._relations_handler.get_relations(
|
||||
requester=requester,
|
||||
event_id=parent_id,
|
||||
room_id=room_id,
|
||||
pagin_config=pagination_config,
|
||||
include_original_event=include_original_event,
|
||||
relation_type=relation_type,
|
||||
event_type=event_type,
|
||||
limit=limit,
|
||||
direction=direction,
|
||||
from_token=from_token,
|
||||
to_token=to_token,
|
||||
include_original_event=include_original_event,
|
||||
)
|
||||
|
||||
return 200, result
|
||||
|
||||
@@ -100,6 +100,7 @@ class SyncRestServlet(RestServlet):
|
||||
self._server_notices_sender = hs.get_server_notices_sender()
|
||||
self._event_serializer = hs.get_event_client_serializer()
|
||||
self._msc2654_enabled = hs.config.experimental.msc2654_enabled
|
||||
self._msc3773_enabled = hs.config.experimental.msc3773_enabled
|
||||
|
||||
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||
# This will always be set by the time Twisted calls us.
|
||||
@@ -510,9 +511,11 @@ class SyncRestServlet(RestServlet):
|
||||
result["ephemeral"] = {"events": ephemeral_events}
|
||||
result["unread_notifications"] = room.unread_notifications
|
||||
if room.unread_thread_notifications:
|
||||
result[
|
||||
"org.matrix.msc3773.unread_thread_notifications"
|
||||
] = room.unread_thread_notifications
|
||||
result["unread_thread_notifications"] = room.unread_thread_notifications
|
||||
if self._msc3773_enabled:
|
||||
result[
|
||||
"org.matrix.msc3773.unread_thread_notifications"
|
||||
] = room.unread_thread_notifications
|
||||
result["summary"] = room.summary
|
||||
if self._msc2654_enabled:
|
||||
result["org.matrix.msc2654.unread_count"] = room.unread_count
|
||||
|
||||
@@ -105,7 +105,7 @@ class VersionsRestServlet(RestServlet):
|
||||
# Adds support for thread relations, per MSC3440.
|
||||
"org.matrix.msc3440.stable": True, # TODO: remove when "v1.3" is added above
|
||||
# Support for thread read receipts & notification counts.
|
||||
"org.matrix.msc3771": self.config.experimental.msc3771_enabled,
|
||||
"org.matrix.msc3771": True,
|
||||
"org.matrix.msc3773": self.config.experimental.msc3773_enabled,
|
||||
# Allows moderators to fetch redacted event content as described in MSC2815
|
||||
"fi.mau.msc2815": self.config.experimental.msc2815_enabled,
|
||||
|
||||
@@ -139,66 +139,73 @@ class OEmbedProvider:
|
||||
try:
|
||||
# oEmbed responses *must* be UTF-8 according to the spec.
|
||||
oembed = json_decoder.decode(raw_body.decode("utf-8"))
|
||||
except ValueError:
|
||||
return OEmbedResult({}, None, None)
|
||||
|
||||
# The version is a required string field, but not always provided,
|
||||
# or sometimes provided as a float. Be lenient.
|
||||
oembed_version = oembed.get("version", "1.0")
|
||||
if oembed_version != "1.0" and oembed_version != 1:
|
||||
raise RuntimeError(f"Invalid oEmbed version: {oembed_version}")
|
||||
# The version is a required string field, but not always provided,
|
||||
# or sometimes provided as a float. Be lenient.
|
||||
oembed_version = oembed.get("version", "1.0")
|
||||
if oembed_version != "1.0" and oembed_version != 1:
|
||||
return OEmbedResult({}, None, None)
|
||||
|
||||
# Ensure the cache age is None or an int.
|
||||
cache_age = oembed.get("cache_age")
|
||||
if cache_age:
|
||||
cache_age = int(cache_age) * 1000
|
||||
|
||||
# The results.
|
||||
open_graph_response = {
|
||||
"og:url": url,
|
||||
}
|
||||
|
||||
title = oembed.get("title")
|
||||
if title:
|
||||
open_graph_response["og:title"] = title
|
||||
|
||||
author_name = oembed.get("author_name")
|
||||
|
||||
# Use the provider name and as the site.
|
||||
provider_name = oembed.get("provider_name")
|
||||
if provider_name:
|
||||
open_graph_response["og:site_name"] = provider_name
|
||||
|
||||
# If a thumbnail exists, use it. Note that dimensions will be calculated later.
|
||||
if "thumbnail_url" in oembed:
|
||||
open_graph_response["og:image"] = oembed["thumbnail_url"]
|
||||
|
||||
# Process each type separately.
|
||||
oembed_type = oembed["type"]
|
||||
if oembed_type == "rich":
|
||||
calc_description_and_urls(open_graph_response, oembed["html"])
|
||||
|
||||
elif oembed_type == "photo":
|
||||
# If this is a photo, use the full image, not the thumbnail.
|
||||
open_graph_response["og:image"] = oembed["url"]
|
||||
|
||||
elif oembed_type == "video":
|
||||
open_graph_response["og:type"] = "video.other"
|
||||
calc_description_and_urls(open_graph_response, oembed["html"])
|
||||
open_graph_response["og:video:width"] = oembed["width"]
|
||||
open_graph_response["og:video:height"] = oembed["height"]
|
||||
|
||||
elif oembed_type == "link":
|
||||
open_graph_response["og:type"] = "website"
|
||||
|
||||
else:
|
||||
raise RuntimeError(f"Unknown oEmbed type: {oembed_type}")
|
||||
|
||||
except Exception as e:
|
||||
# Trap any exception and let the code follow as usual.
|
||||
logger.warning("Error parsing oEmbed metadata from %s: %r", url, e)
|
||||
open_graph_response = {}
|
||||
author_name = None
|
||||
# Attempt to parse the cache age, if possible.
|
||||
try:
|
||||
cache_age = int(oembed.get("cache_age")) * 1000
|
||||
except (TypeError, ValueError):
|
||||
# If the cache age cannot be parsed (e.g. wrong type or invalid
|
||||
# string), ignore it.
|
||||
cache_age = None
|
||||
|
||||
# The oEmbed response converted to Open Graph.
|
||||
open_graph_response: JsonDict = {"og:url": url}
|
||||
|
||||
title = oembed.get("title")
|
||||
if title and isinstance(title, str):
|
||||
open_graph_response["og:title"] = title
|
||||
|
||||
author_name = oembed.get("author_name")
|
||||
if not isinstance(author_name, str):
|
||||
author_name = None
|
||||
|
||||
# Use the provider name and as the site.
|
||||
provider_name = oembed.get("provider_name")
|
||||
if provider_name and isinstance(provider_name, str):
|
||||
open_graph_response["og:site_name"] = provider_name
|
||||
|
||||
# If a thumbnail exists, use it. Note that dimensions will be calculated later.
|
||||
thumbnail_url = oembed.get("thumbnail_url")
|
||||
if thumbnail_url and isinstance(thumbnail_url, str):
|
||||
open_graph_response["og:image"] = thumbnail_url
|
||||
|
||||
# Process each type separately.
|
||||
oembed_type = oembed.get("type")
|
||||
if oembed_type == "rich":
|
||||
html = oembed.get("html")
|
||||
if isinstance(html, str):
|
||||
calc_description_and_urls(open_graph_response, html)
|
||||
|
||||
elif oembed_type == "photo":
|
||||
# If this is a photo, use the full image, not the thumbnail.
|
||||
url = oembed.get("url")
|
||||
if url and isinstance(url, str):
|
||||
open_graph_response["og:image"] = url
|
||||
|
||||
elif oembed_type == "video":
|
||||
open_graph_response["og:type"] = "video.other"
|
||||
html = oembed.get("html")
|
||||
if html and isinstance(html, str):
|
||||
calc_description_and_urls(open_graph_response, oembed["html"])
|
||||
for size in ("width", "height"):
|
||||
val = oembed.get(size)
|
||||
if val is not None and isinstance(val, int):
|
||||
open_graph_response[f"og:video:{size}"] = val
|
||||
|
||||
elif oembed_type == "link":
|
||||
open_graph_response["og:type"] = "website"
|
||||
|
||||
else:
|
||||
logger.warning("Unknown oEmbed type: %s", oembed_type)
|
||||
|
||||
return OEmbedResult(open_graph_response, author_name, cache_age)
|
||||
|
||||
|
||||
|
||||
@@ -259,9 +259,6 @@ class CacheInvalidationWorkerStore(SQLBaseStore):
|
||||
self._attempt_to_invalidate_cache("get_applicable_edit", (relates_to,))
|
||||
self._attempt_to_invalidate_cache("get_thread_summary", (relates_to,))
|
||||
self._attempt_to_invalidate_cache("get_thread_participated", (relates_to,))
|
||||
self._attempt_to_invalidate_cache(
|
||||
"get_mutual_event_relations_for_rel_type", (relates_to,)
|
||||
)
|
||||
|
||||
async def invalidate_cache_and_stream(
|
||||
self, cache_name: str, keys: Tuple[Any, ...]
|
||||
|
||||
@@ -2024,11 +2024,6 @@ class PersistEventsStore:
|
||||
self.store._invalidate_cache_and_stream(
|
||||
txn, self.store.get_thread_participated, (redacted_relates_to,)
|
||||
)
|
||||
self.store._invalidate_cache_and_stream(
|
||||
txn,
|
||||
self.store.get_mutual_event_relations_for_rel_type,
|
||||
(redacted_relates_to,),
|
||||
)
|
||||
|
||||
self.db_pool.simple_delete_txn(
|
||||
txn, table="event_relations", keyvalues={"event_id": redacted_event_id}
|
||||
|
||||
@@ -474,7 +474,7 @@ class EventsWorkerStore(SQLBaseStore):
|
||||
return []
|
||||
|
||||
# there may be duplicates so we cast the list to a set
|
||||
event_entry_map = await self._get_events_from_cache_or_db(
|
||||
event_entry_map = await self.get_unredacted_events_from_cache_or_db(
|
||||
set(event_ids), allow_rejected=allow_rejected
|
||||
)
|
||||
|
||||
@@ -509,7 +509,9 @@ class EventsWorkerStore(SQLBaseStore):
|
||||
continue
|
||||
|
||||
redacted_event_id = entry.event.redacts
|
||||
event_map = await self._get_events_from_cache_or_db([redacted_event_id])
|
||||
event_map = await self.get_unredacted_events_from_cache_or_db(
|
||||
[redacted_event_id]
|
||||
)
|
||||
original_event_entry = event_map.get(redacted_event_id)
|
||||
if not original_event_entry:
|
||||
# we don't have the redacted event (or it was rejected).
|
||||
@@ -588,11 +590,16 @@ class EventsWorkerStore(SQLBaseStore):
|
||||
return events
|
||||
|
||||
@cancellable
|
||||
async def _get_events_from_cache_or_db(
|
||||
self, event_ids: Iterable[str], allow_rejected: bool = False
|
||||
async def get_unredacted_events_from_cache_or_db(
|
||||
self,
|
||||
event_ids: Iterable[str],
|
||||
allow_rejected: bool = False,
|
||||
) -> Dict[str, EventCacheEntry]:
|
||||
"""Fetch a bunch of events from the cache or the database.
|
||||
|
||||
Note that the events pulled by this function will not have any redactions
|
||||
applied, and no guarantee is made about the ordering of the events returned.
|
||||
|
||||
If events are pulled from the database, they will be cached for future lookups.
|
||||
|
||||
Unknown events are omitted from the response.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user