diff --git a/.github/workflows/docs-pr.yaml b/.github/workflows/docs-pr.yaml
index 3704bd66e2..9cf3d340a4 100644
--- a/.github/workflows/docs-pr.yaml
+++ b/.github/workflows/docs-pr.yaml
@@ -6,6 +6,7 @@ on:
- docs/**
- book.toml
- .github/workflows/docs-pr.yaml
+ - scripts-dev/schema_versions.py
jobs:
pages:
@@ -13,12 +14,22 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
+ with:
+ # Fetch all history so that the schema_versions script works.
+ fetch-depth: 0
- name: Setup mdbook
uses: peaceiris/actions-mdbook@adeb05db28a0c0004681db83893d56c0388ea9ea # v1.2.0
with:
mdbook-version: '0.4.17'
+ - name: Setup python
+ uses: actions/setup-python@v4
+ with:
+ python-version: "3.x"
+
+ - run: "pip install 'packaging>=20.0' 'GitPython>=3.1.20'"
+
- name: Build the documentation
# mdbook will only create an index.html if we're including docs/README.md in SUMMARY.md.
# However, we're using docs/README.md for other purposes and need to pick a new page
diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml
index c7cb2d78e5..31b9dbe3fe 100644
--- a/.github/workflows/docs.yaml
+++ b/.github/workflows/docs.yaml
@@ -51,12 +51,22 @@ jobs:
- pre
steps:
- uses: actions/checkout@v4
+ with:
+ # Fetch all history so that the schema_versions script works.
+ fetch-depth: 0
- name: Setup mdbook
uses: peaceiris/actions-mdbook@adeb05db28a0c0004681db83893d56c0388ea9ea # v1.2.0
with:
mdbook-version: '0.4.17'
+ - name: Setup python
+ uses: actions/setup-python@v4
+ with:
+ python-version: "3.x"
+
+ - run: "pip install 'packaging>=20.0' 'GitPython>=3.1.20'"
+
- name: Build the documentation
# mdbook will only create an index.html if we're including docs/README.md in SUMMARY.md.
# However, we're using docs/README.md for other purposes and need to pick a new page
diff --git a/.github/workflows/fix_lint.yaml b/.github/workflows/fix_lint.yaml
new file mode 100644
index 0000000000..f1e35fcd99
--- /dev/null
+++ b/.github/workflows/fix_lint.yaml
@@ -0,0 +1,52 @@
+# A helper workflow to automatically fixup any linting errors on a PR. Must be
+# triggered manually.
+
+name: Attempt to automatically fix linting errors
+
+on:
+ workflow_dispatch:
+
+jobs:
+ fixup:
+ name: Fix up
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Install Rust
+ uses: dtolnay/rust-toolchain@master
+ with:
+ # We use nightly so that `fmt` correctly groups together imports, and
+ # clippy correctly fixes up the benchmarks.
+ toolchain: nightly-2022-12-01
+ components: rustfmt
+ - uses: Swatinem/rust-cache@v2
+
+ - name: Setup Poetry
+ uses: matrix-org/setup-python-poetry@v1
+ with:
+ install-project: "false"
+
+ - name: Import order (isort)
+ continue-on-error: true
+ run: poetry run isort .
+
+ - name: Code style (black)
+ continue-on-error: true
+ run: poetry run black .
+
+ - name: Semantic checks (ruff)
+ continue-on-error: true
+ run: poetry run ruff --fix .
+
+ - run: cargo clippy --all-features --fix -- -D warnings
+ continue-on-error: true
+
+ - run: cargo fmt
+ continue-on-error: true
+
+ - uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: "Attempt to fix linting"
diff --git a/CHANGES.md b/CHANGES.md
index 9358a22525..bb34267af3 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,79 @@
+# Synapse 1.97.0 (2023-11-28)
+
+Synapse will soon be forked by Element under an AGPLv3.0 licence (with CLA, for
+proprietary dual licensing). You can read more about this here:
+
+ - https://matrix.org/blog/2023/11/06/future-of-synapse-dendrite/
+ - https://element.io/blog/element-to-adopt-agplv3/
+
+The Matrix.org Foundation copy of the project will be archived. Any changes needed
+by server administrators will be communicated via our usual announcements channels,
+but we are striving to make this as seamless as possible.
+
+
+No significant changes since 1.97.0rc1.
+
+
+# Synapse 1.97.0rc1 (2023-11-21)
+
+### Features
+
+- Add support for asynchronous uploads as defined by [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246). Contributed by @sumnerevans at @beeper. ([\#15503](https://github.com/matrix-org/synapse/issues/15503))
+- Improve the performance of some operations in multi-worker deployments. ([\#16613](https://github.com/matrix-org/synapse/issues/16613), [\#16616](https://github.com/matrix-org/synapse/issues/16616))
+
+### Bugfixes
+
+- Fix a long-standing bug where some queries updated the same row twice. Introduced in Synapse 1.57.0. ([\#16609](https://github.com/matrix-org/synapse/issues/16609))
+- Fix a long-standing bug where Synapse would not unbind third-party identifiers for Application Service users when deactivated and would not emit a compliant response. ([\#16617](https://github.com/matrix-org/synapse/issues/16617))
+- Fix sending out of order `POSITION` over replication, causing additional database load. ([\#16639](https://github.com/matrix-org/synapse/issues/16639))
+
+### Improved Documentation
+
+- Note that the option [`outbound_federation_restricted_to`](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#outbound_federation_restricted_to) was added in Synapse 1.89.0, and fix a nearby formatting error. ([\#16628](https://github.com/matrix-org/synapse/issues/16628))
+- Update parameter information for the `/timestamp_to_event` admin API. ([\#16631](https://github.com/matrix-org/synapse/issues/16631))
+- Provide an example for a common encrypted media response from the admin user media API and mention possible null values. ([\#16654](https://github.com/matrix-org/synapse/issues/16654))
+
+### Internal Changes
+
+- Remove whole table locks on push rule modifications. Contributed by Nick @ Beeper (@fizzadar). ([\#16051](https://github.com/matrix-org/synapse/issues/16051))
+- Support reactor tick timings on more types of event loops. ([\#16532](https://github.com/matrix-org/synapse/issues/16532))
+- Improve type hints. ([\#16564](https://github.com/matrix-org/synapse/issues/16564), [\#16611](https://github.com/matrix-org/synapse/issues/16611), [\#16612](https://github.com/matrix-org/synapse/issues/16612))
+- Avoid executing no-op queries. ([\#16583](https://github.com/matrix-org/synapse/issues/16583))
+- Simplify persistence code to be per-room. ([\#16584](https://github.com/matrix-org/synapse/issues/16584))
+- Use standard SQL helpers in persistence code. ([\#16585](https://github.com/matrix-org/synapse/issues/16585))
+- Avoid updating the stream cache unnecessarily. ([\#16586](https://github.com/matrix-org/synapse/issues/16586))
+- Improve performance when using opentracing. ([\#16589](https://github.com/matrix-org/synapse/issues/16589))
+- Run push rule evaluator setup in parallel. ([\#16590](https://github.com/matrix-org/synapse/issues/16590))
+- Improve tests of the SQL generator. ([\#16596](https://github.com/matrix-org/synapse/issues/16596))
+- Use more generic database methods. ([\#16615](https://github.com/matrix-org/synapse/issues/16615))
+- Use `dbname` instead of the deprecated `database` connection parameter for psycopg2. ([\#16618](https://github.com/matrix-org/synapse/issues/16618))
+- Add an internal [Admin API endpoint](https://matrix-org.github.io/synapse/v1.97/usage/configuration/config_documentation.html#allow-replacing-master-cross-signing-key-without-user-interactive-auth) to temporarily grant the ability to update an existing cross-signing key without UIA. ([\#16634](https://github.com/matrix-org/synapse/issues/16634))
+- Improve references to GitHub issues. ([\#16637](https://github.com/matrix-org/synapse/issues/16637), [\#16638](https://github.com/matrix-org/synapse/issues/16638))
+- More efficiently handle no-op `POSITION` over replication. ([\#16640](https://github.com/matrix-org/synapse/issues/16640), [\#16655](https://github.com/matrix-org/synapse/issues/16655))
+- Speed up deleting of device messages when deleting a device. ([\#16643](https://github.com/matrix-org/synapse/issues/16643))
+- Speed up persisting large number of outliers. ([\#16649](https://github.com/matrix-org/synapse/issues/16649))
+- Reduce max concurrency of background tasks, reducing potential max DB load. ([\#16656](https://github.com/matrix-org/synapse/issues/16656), [\#16660](https://github.com/matrix-org/synapse/issues/16660))
+- Speed up purge room by adding an index to `event_push_summary`. ([\#16657](https://github.com/matrix-org/synapse/issues/16657))
+
+
+
+### Updates to locked dependencies
+
+* Bump prometheus-client from 0.17.1 to 0.18.0. ([\#16626](https://github.com/matrix-org/synapse/issues/16626))
+* Bump pyicu from 2.11 to 2.12. ([\#16603](https://github.com/matrix-org/synapse/issues/16603))
+* Bump requests-toolbelt from 0.10.1 to 1.0.0. ([\#16659](https://github.com/matrix-org/synapse/issues/16659))
+* Bump ruff from 0.0.292 to 0.1.4. ([\#16600](https://github.com/matrix-org/synapse/issues/16600))
+* Bump serde from 1.0.190 to 1.0.192. ([\#16627](https://github.com/matrix-org/synapse/issues/16627))
+* Bump serde_json from 1.0.107 to 1.0.108. ([\#16604](https://github.com/matrix-org/synapse/issues/16604))
+* Bump setuptools-rust from 1.8.0 to 1.8.1. ([\#16601](https://github.com/matrix-org/synapse/issues/16601))
+* Bump towncrier from 23.6.0 to 23.11.0. ([\#16622](https://github.com/matrix-org/synapse/issues/16622))
+* Bump treq from 22.2.0 to 23.11.0. ([\#16623](https://github.com/matrix-org/synapse/issues/16623))
+* Bump twisted from 23.8.0 to 23.10.0. ([\#16588](https://github.com/matrix-org/synapse/issues/16588))
+* Bump types-bleach from 6.1.0.0 to 6.1.0.1. ([\#16624](https://github.com/matrix-org/synapse/issues/16624))
+* Bump types-jsonschema from 4.19.0.3 to 4.19.0.4. ([\#16599](https://github.com/matrix-org/synapse/issues/16599))
+* Bump types-pyopenssl from 23.2.0.2 to 23.3.0.0. ([\#16625](https://github.com/matrix-org/synapse/issues/16625))
+* Bump types-pyyaml from 6.0.12.11 to 6.0.12.12. ([\#16602](https://github.com/matrix-org/synapse/issues/16602))
+
# Synapse 1.96.1 (2023-11-17)
Synapse will soon be forked by Element under an AGPLv3.0 licence (with CLA, for
diff --git a/Cargo.lock b/Cargo.lock
index 1b3dade625..d5e77297f4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -91,6 +91,12 @@ dependencies = [
]
[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -98,9 +104,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "indoc"
-version = "1.0.7"
+version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adab1eaa3408fb7f0c777a73e7465fd5656136fc93b670eb6df3c88c2c1344e3"
+checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
[[package]]
name = "itoa"
@@ -191,9 +197,9 @@ dependencies = [
[[package]]
name = "pyo3"
-version = "0.19.2"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38"
+checksum = "04e8453b658fe480c3e70c8ed4e3d3ec33eb74988bd186561b0cc66b85c3bc4b"
dependencies = [
"anyhow",
"cfg-if",
@@ -209,9 +215,9 @@ dependencies = [
[[package]]
name = "pyo3-build-config"
-version = "0.19.2"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5"
+checksum = "a96fe70b176a89cff78f2fa7b3c930081e163d5379b4dcdf993e3ae29ca662e5"
dependencies = [
"once_cell",
"target-lexicon",
@@ -219,9 +225,9 @@ dependencies = [
[[package]]
name = "pyo3-ffi"
-version = "0.19.2"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9"
+checksum = "214929900fd25e6604661ed9cf349727c8920d47deff196c4e28165a6ef2a96b"
dependencies = [
"libc",
"pyo3-build-config",
@@ -229,9 +235,9 @@ dependencies = [
[[package]]
name = "pyo3-log"
-version = "0.8.4"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c09c2b349b6538d8a73d436ca606dab6ce0aaab4dad9e6b7bdd57a4f556c3bc3"
+checksum = "4c10808ee7250403bedb24bc30c32493e93875fef7ba3e4292226fe924f398bd"
dependencies = [
"arc-swap",
"log",
@@ -240,32 +246,33 @@ dependencies = [
[[package]]
name = "pyo3-macros"
-version = "0.19.2"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1"
+checksum = "dac53072f717aa1bfa4db832b39de8c875b7c7af4f4a6fe93cdbf9264cf8383b"
dependencies = [
"proc-macro2",
"pyo3-macros-backend",
"quote",
- "syn 1.0.104",
+ "syn",
]
[[package]]
name = "pyo3-macros-backend"
-version = "0.19.2"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536"
+checksum = "7774b5a8282bd4f25f803b1f0d945120be959a36c72e08e7cd031c792fdfd424"
dependencies = [
+ "heck",
"proc-macro2",
"quote",
- "syn 1.0.104",
+ "syn",
]
[[package]]
name = "pythonize"
-version = "0.19.0"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e35b716d430ace57e2d1b4afb51c9e5b7c46d2bce72926e07f9be6a98ced03e"
+checksum = "ffd1c3ef39c725d63db5f9bc455461bafd80540cb7824c61afb823501921a850"
dependencies = [
"pyo3",
"serde",
@@ -332,22 +339,22 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
-version = "1.0.192"
+version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
+checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.192"
+version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
+checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.28",
+ "syn",
]
[[package]]
@@ -375,17 +382,6 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
-version = "1.0.104"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-ident",
-]
-
-[[package]]
-name = "syn"
version = "2.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
@@ -432,9 +428,9 @@ checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "unindent"
-version = "0.1.10"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58ee9362deb4a96cef4d437d1ad49cffc9b9e92d202b6995674e928ce684f112"
+checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
[[package]]
name = "version_check"
diff --git a/book.toml b/book.toml
index fa83d86ffc..ed3f6151e0 100644
--- a/book.toml
+++ b/book.toml
@@ -36,4 +36,7 @@ additional-css = [
"docs/website_files/indent-section-headers.css",
]
additional-js = ["docs/website_files/table-of-contents.js"]
-theme = "docs/website_files/theme"
\ No newline at end of file
+theme = "docs/website_files/theme"
+
+[preprocessor.schema_versions]
+command = "./scripts-dev/schema_versions.py"
diff --git a/changelog.d/15207.feature b/changelog.d/15207.feature
new file mode 100644
index 0000000000..17790d62eb
--- /dev/null
+++ b/changelog.d/15207.feature
@@ -0,0 +1 @@
+Adds on_user_login ModuleAPI callback allowing to execute custom code after (on) Auth.
\ No newline at end of file
diff --git a/changelog.d/15503.feature b/changelog.d/15503.feature
deleted file mode 100644
index b6ca97a2cf..0000000000
--- a/changelog.d/15503.feature
+++ /dev/null
@@ -1 +0,0 @@
-Add support for asynchronous uploads as defined by [MSC2246](https://github.com/matrix-org/matrix-spec-proposals/pull/2246). Contributed by @sumnerevans at @beeper.
diff --git a/changelog.d/16051.misc b/changelog.d/16051.misc
deleted file mode 100644
index 1420d2eb3f..0000000000
--- a/changelog.d/16051.misc
+++ /dev/null
@@ -1 +0,0 @@
-Remove whole table locks on push rule modifications. Contributed by Nick @ Beeper (@fizzadar).
diff --git a/changelog.d/16522.misc b/changelog.d/16522.misc
new file mode 100644
index 0000000000..26059b108e
--- /dev/null
+++ b/changelog.d/16522.misc
@@ -0,0 +1 @@
+Clean-up unused tables.
diff --git a/changelog.d/16532.misc b/changelog.d/16532.misc
deleted file mode 100644
index 437e00210b..0000000000
--- a/changelog.d/16532.misc
+++ /dev/null
@@ -1 +0,0 @@
-Support reactor tick timings on more types of event loops.
diff --git a/changelog.d/16552.misc b/changelog.d/16552.misc
new file mode 100644
index 0000000000..73a0376df0
--- /dev/null
+++ b/changelog.d/16552.misc
@@ -0,0 +1 @@
+Reduce a little database load while processing state auth chains.
diff --git a/changelog.d/16564.misc b/changelog.d/16564.misc
deleted file mode 100644
index 93ceaeafc9..0000000000
--- a/changelog.d/16564.misc
+++ /dev/null
@@ -1 +0,0 @@
-Improve type hints.
diff --git a/changelog.d/16583.misc b/changelog.d/16583.misc
deleted file mode 100644
index df5b27b112..0000000000
--- a/changelog.d/16583.misc
+++ /dev/null
@@ -1 +0,0 @@
-Avoid executing no-op queries.
diff --git a/changelog.d/16584.misc b/changelog.d/16584.misc
deleted file mode 100644
index beec8f2301..0000000000
--- a/changelog.d/16584.misc
+++ /dev/null
@@ -1 +0,0 @@
-Simplify persistance code to be per-room.
diff --git a/changelog.d/16585.misc b/changelog.d/16585.misc
deleted file mode 100644
index 01f3ecc843..0000000000
--- a/changelog.d/16585.misc
+++ /dev/null
@@ -1 +0,0 @@
-Use standard SQL helpers in persistence code.
\ No newline at end of file
diff --git a/changelog.d/16586.misc b/changelog.d/16586.misc
deleted file mode 100644
index f02c4a2060..0000000000
--- a/changelog.d/16586.misc
+++ /dev/null
@@ -1 +0,0 @@
-Avoid updating the stream cache unnecessarily.
diff --git a/changelog.d/16588.misc b/changelog.d/16588.misc
deleted file mode 100644
index c12b6cfc28..0000000000
--- a/changelog.d/16588.misc
+++ /dev/null
@@ -1 +0,0 @@
-Bump twisted from 23.8.0 to 23.10.0.
diff --git a/changelog.d/16589.misc b/changelog.d/16589.misc
deleted file mode 100644
index 6e69368bbf..0000000000
--- a/changelog.d/16589.misc
+++ /dev/null
@@ -1 +0,0 @@
-Improve performance when using opentracing.
diff --git a/changelog.d/16590.misc b/changelog.d/16590.misc
deleted file mode 100644
index 6db04b0c98..0000000000
--- a/changelog.d/16590.misc
+++ /dev/null
@@ -1 +0,0 @@
-Run push rule evaluator setup in parallel.
diff --git a/changelog.d/16596.misc b/changelog.d/16596.misc
deleted file mode 100644
index fa457b12e5..0000000000
--- a/changelog.d/16596.misc
+++ /dev/null
@@ -1 +0,0 @@
-Improve tests of the SQL generator.
diff --git a/changelog.d/16605.misc b/changelog.d/16605.misc
deleted file mode 100644
index 2db7da5692..0000000000
--- a/changelog.d/16605.misc
+++ /dev/null
@@ -1 +0,0 @@
-Bump setuptools-rust from 1.8.0 to 1.8.1.
diff --git a/changelog.d/16609.bugfix b/changelog.d/16609.bugfix
deleted file mode 100644
index a52d395cd3..0000000000
--- a/changelog.d/16609.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Fix a long-standing bug where some queries updated the same row twice. Introduced in Synapse 1.57.0.
diff --git a/changelog.d/16611.misc b/changelog.d/16611.misc
deleted file mode 100644
index 93ceaeafc9..0000000000
--- a/changelog.d/16611.misc
+++ /dev/null
@@ -1 +0,0 @@
-Improve type hints.
diff --git a/changelog.d/16612.misc b/changelog.d/16612.misc
deleted file mode 100644
index 93ceaeafc9..0000000000
--- a/changelog.d/16612.misc
+++ /dev/null
@@ -1 +0,0 @@
-Improve type hints.
diff --git a/changelog.d/16613.feature b/changelog.d/16613.feature
deleted file mode 100644
index 419c56fb83..0000000000
--- a/changelog.d/16613.feature
+++ /dev/null
@@ -1 +0,0 @@
-Improve the performance of some operations in multi-worker deployments.
diff --git a/changelog.d/16615.misc b/changelog.d/16615.misc
deleted file mode 100644
index 37ab711dc6..0000000000
--- a/changelog.d/16615.misc
+++ /dev/null
@@ -1 +0,0 @@
-Use more generic database methods.
diff --git a/changelog.d/16616.feature b/changelog.d/16616.feature
deleted file mode 100644
index 419c56fb83..0000000000
--- a/changelog.d/16616.feature
+++ /dev/null
@@ -1 +0,0 @@
-Improve the performance of some operations in multi-worker deployments.
diff --git a/changelog.d/16617.bugfix b/changelog.d/16617.bugfix
deleted file mode 100644
index 7e66799a6c..0000000000
--- a/changelog.d/16617.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Fix a long-standing bug where Synapse would not unbind third-party identifiers for Application Service users when deactivated and would not emit a compliant response.
\ No newline at end of file
diff --git a/changelog.d/16618.misc b/changelog.d/16618.misc
deleted file mode 100644
index c026e6b995..0000000000
--- a/changelog.d/16618.misc
+++ /dev/null
@@ -1 +0,0 @@
-Use `dbname` instead of the deprecated `database` connection parameter for psycopg2.
diff --git a/changelog.d/16628.doc b/changelog.d/16628.doc
deleted file mode 100644
index 4dd1e4874e..0000000000
--- a/changelog.d/16628.doc
+++ /dev/null
@@ -1 +0,0 @@
-Note that the option [`outbound_federation_restricted_to`](https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#outbound_federation_restricted_to) was added in Synapse 1.89.0, and fix a nearby formatting error.
diff --git a/changelog.d/16631.doc b/changelog.d/16631.doc
deleted file mode 100644
index 1128a080ea..0000000000
--- a/changelog.d/16631.doc
+++ /dev/null
@@ -1 +0,0 @@
-Update parameter information for the `/timestamp_to_event` admin API.
diff --git a/changelog.d/16634.misc b/changelog.d/16634.misc
deleted file mode 100644
index f81cf39691..0000000000
--- a/changelog.d/16634.misc
+++ /dev/null
@@ -1 +0,0 @@
-Add an internal [Admin API endpoint](https://matrix-org.github.io/synapse/v1.97/usage/configuration/config_documentation.html#allow-replacing-master-cross-signing-key-without-user-interactive-auth) to temporarily grant the ability to update an existing cross-signing key without UIA.
diff --git a/changelog.d/16637.misc b/changelog.d/16637.misc
deleted file mode 100644
index f5068ac291..0000000000
--- a/changelog.d/16637.misc
+++ /dev/null
@@ -1 +0,0 @@
-Improve references to GitHub issues.
diff --git a/changelog.d/16638.misc b/changelog.d/16638.misc
deleted file mode 100644
index f5068ac291..0000000000
--- a/changelog.d/16638.misc
+++ /dev/null
@@ -1 +0,0 @@
-Improve references to GitHub issues.
diff --git a/changelog.d/16639.bugfix b/changelog.d/16639.bugfix
deleted file mode 100644
index 3feff89af6..0000000000
--- a/changelog.d/16639.bugfix
+++ /dev/null
@@ -1 +0,0 @@
-Fix sending out of order `POSITION` over replication, causing additional database load.
diff --git a/changelog.d/16640.misc b/changelog.d/16640.misc
deleted file mode 100644
index 3b1cc2185d..0000000000
--- a/changelog.d/16640.misc
+++ /dev/null
@@ -1 +0,0 @@
-More efficiently handle no-op `POSITION` over replication.
diff --git a/changelog.d/16642.bugfix b/changelog.d/16642.bugfix
new file mode 100644
index 0000000000..e83c8b4f9d
--- /dev/null
+++ b/changelog.d/16642.bugfix
@@ -0,0 +1 @@
+Enable refreshable tokens on the admin registration endpoint.
diff --git a/changelog.d/16643.misc b/changelog.d/16643.misc
deleted file mode 100644
index cc0cf0901f..0000000000
--- a/changelog.d/16643.misc
+++ /dev/null
@@ -1 +0,0 @@
-Speed up deleting of device messages when deleting a device.
diff --git a/changelog.d/16649.misc b/changelog.d/16649.misc
deleted file mode 100644
index cebd6aaee5..0000000000
--- a/changelog.d/16649.misc
+++ /dev/null
@@ -1 +0,0 @@
-Speed up persisting large number of outliers.
diff --git a/changelog.d/16654.doc b/changelog.d/16654.doc
deleted file mode 100644
index 61019e0367..0000000000
--- a/changelog.d/16654.doc
+++ /dev/null
@@ -1 +0,0 @@
-Provide an example for a common encrypted media response from the admin user media API and mention possible null values.
diff --git a/changelog.d/16655.misc b/changelog.d/16655.misc
deleted file mode 100644
index 3b1cc2185d..0000000000
--- a/changelog.d/16655.misc
+++ /dev/null
@@ -1 +0,0 @@
-More efficiently handle no-op `POSITION` over replication.
diff --git a/changelog.d/16656.misc b/changelog.d/16656.misc
deleted file mode 100644
index 6763685b9d..0000000000
--- a/changelog.d/16656.misc
+++ /dev/null
@@ -1 +0,0 @@
-Reduce max concurrency of background tasks, reducing potential max DB load.
diff --git a/changelog.d/16657.misc b/changelog.d/16657.misc
deleted file mode 100644
index c444aa15e4..0000000000
--- a/changelog.d/16657.misc
+++ /dev/null
@@ -1 +0,0 @@
-Speed up purge room by adding an index to `event_push_summary`.
diff --git a/changelog.d/16659.misc b/changelog.d/16659.misc
deleted file mode 100644
index 72079d1f63..0000000000
--- a/changelog.d/16659.misc
+++ /dev/null
@@ -1 +0,0 @@
-Bump requests-toolbelt from 0.10.1 to 1.0.0.
diff --git a/changelog.d/16660.misc b/changelog.d/16660.misc
deleted file mode 100644
index 6763685b9d..0000000000
--- a/changelog.d/16660.misc
+++ /dev/null
@@ -1 +0,0 @@
-Reduce max concurrency of background tasks, reducing potential max DB load.
diff --git a/changelog.d/16661.doc b/changelog.d/16661.doc
new file mode 100644
index 0000000000..74f8fc84b8
--- /dev/null
+++ b/changelog.d/16661.doc
@@ -0,0 +1 @@
+Add schema rollback information to documentation.
diff --git a/changelog.d/16667.misc b/changelog.d/16667.misc
new file mode 100644
index 0000000000..51aeca9243
--- /dev/null
+++ b/changelog.d/16667.misc
@@ -0,0 +1 @@
+Reduce database load of pruning old `user_ips`.
diff --git a/changelog.d/16668.misc b/changelog.d/16668.misc
new file mode 100644
index 0000000000..9ed004d6e4
--- /dev/null
+++ b/changelog.d/16668.misc
@@ -0,0 +1 @@
+Reduce DB load when forget on leave setting is disabled.
diff --git a/changelog.d/16670.bugfix b/changelog.d/16670.bugfix
new file mode 100644
index 0000000000..f1369abc06
--- /dev/null
+++ b/changelog.d/16670.bugfix
@@ -0,0 +1 @@
+Consistently bypass rate limits when using the server notice admin API.
diff --git a/changelog.d/16672.feature b/changelog.d/16672.feature
new file mode 100644
index 0000000000..05ecf22207
--- /dev/null
+++ b/changelog.d/16672.feature
@@ -0,0 +1 @@
+Restore tracking of requests and monthly active users when delegating authentication to an [MSC3861](https://github.com/matrix-org/synapse/pull/16672) OIDC provider.
diff --git a/changelog.d/16673.misc b/changelog.d/16673.misc
new file mode 100644
index 0000000000..8b274ede71
--- /dev/null
+++ b/changelog.d/16673.misc
@@ -0,0 +1 @@
+Bump pyo3 (0.19.2→0.20.0), pythonize (0.19.0→0.20.0) and pyo3-log (0.8.1→0.9.0).
diff --git a/changelog.d/16677.misc b/changelog.d/16677.misc
new file mode 100644
index 0000000000..20c37851c3
--- /dev/null
+++ b/changelog.d/16677.misc
@@ -0,0 +1 @@
+Ignore `encryption_enabled_by_default_for_room_type` setting when creating server notices room, since the notices will be send unencrypted anyway.
diff --git a/changelog.d/16682.misc b/changelog.d/16682.misc
new file mode 100644
index 0000000000..071715e83a
--- /dev/null
+++ b/changelog.d/16682.misc
@@ -0,0 +1 @@
+Correctly read the to-device stream ID on startup using SQLite.
diff --git a/changelog.d/16684.misc b/changelog.d/16684.misc
new file mode 100644
index 0000000000..6fb55c08a5
--- /dev/null
+++ b/changelog.d/16684.misc
@@ -0,0 +1 @@
+Reoranganise test files.
diff --git a/changelog.d/16695.doc b/changelog.d/16695.doc
new file mode 100644
index 0000000000..6cb284c501
--- /dev/null
+++ b/changelog.d/16695.doc
@@ -0,0 +1 @@
+Fix poetry version typo in [contributors' guide](https://matrix-org.github.io/synapse/latest/development/contributing_guide.html).
diff --git a/changelog.d/16697.misc b/changelog.d/16697.misc
new file mode 100644
index 0000000000..02fd236ab4
--- /dev/null
+++ b/changelog.d/16697.misc
@@ -0,0 +1 @@
+Remove old full schema dumps which are no longer used.
diff --git a/changelog.d/16701.feature b/changelog.d/16701.feature
new file mode 100644
index 0000000000..2a66fc932a
--- /dev/null
+++ b/changelog.d/16701.feature
@@ -0,0 +1 @@
+Follow redirects when downloading media over federation (per [MSC3860](https://github.com/matrix-org/matrix-spec-proposals/pull/3860)).
diff --git a/changelog.d/16702.misc b/changelog.d/16702.misc
new file mode 100644
index 0000000000..d97d0a11be
--- /dev/null
+++ b/changelog.d/16702.misc
@@ -0,0 +1 @@
+Raise poetry-core upper bound to <=1.8.1. This allows contributors to import Synapse after `poetry install`ing with Poetry 1.6 and above. Contributed by Mo Balaa.
diff --git a/changelog.d/16704.misc b/changelog.d/16704.misc
new file mode 100644
index 0000000000..4dafb27fd8
--- /dev/null
+++ b/changelog.d/16704.misc
@@ -0,0 +1 @@
+Add a workflow to try and automatically fixup linting in a PR.
diff --git a/changelog.d/16707.feature b/changelog.d/16707.feature
new file mode 100644
index 0000000000..707502d344
--- /dev/null
+++ b/changelog.d/16707.feature
@@ -0,0 +1 @@
+Synapse now declares support for Matrix v1.7, v1.8, and v1.9.
diff --git a/debian/changelog b/debian/changelog
index 1d9a135d98..5ec8771604 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+matrix-synapse-py3 (1.97.0) stable; urgency=medium
+
+ * New Synapse release 1.97.0.
+
+ -- Synapse Packaging team <packages@matrix.org> Tue, 28 Nov 2023 14:08:58 +0000
+
+matrix-synapse-py3 (1.97.0~rc1) stable; urgency=medium
+
+ * New Synapse release 1.97.0rc1.
+
+ -- Synapse Packaging team <packages@matrix.org> Tue, 21 Nov 2023 12:32:03 +0000
+
matrix-synapse-py3 (1.96.1) stable; urgency=medium
* New synapse release 1.96.1.
diff --git a/docs/development/contributing_guide.md b/docs/development/contributing_guide.md
index 2efb4099e5..57cac7ed16 100644
--- a/docs/development/contributing_guide.md
+++ b/docs/development/contributing_guide.md
@@ -66,7 +66,7 @@ Of their installation methods, we recommend
```shell
pip install --user pipx
-pipx install poetry==1.5.2 # Problems with Poetry 1.6, see https://github.com/matrix-org/synapse/issues/16147
+pipx install poetry==1.5.1 # Problems with Poetry 1.6, see https://github.com/matrix-org/synapse/issues/16147
```
but see poetry's [installation instructions](https://python-poetry.org/docs/#installation)
diff --git a/docs/modules/account_validity_callbacks.md b/docs/modules/account_validity_callbacks.md
index 3cd0e72198..f5eefcd7d6 100644
--- a/docs/modules/account_validity_callbacks.md
+++ b/docs/modules/account_validity_callbacks.md
@@ -42,3 +42,16 @@ operations to keep track of them. (e.g. add them to a database table). The user
represented by their Matrix user ID.
If multiple modules implement this callback, Synapse runs them all in order.
+
+### `on_user_login`
+
+_First introduced in Synapse v1.98.0_
+
+```python
+async def on_user_login(user_id: str, auth_provider_type: str, auth_provider_id: str) -> None
+```
+
+Called after successfully login or registration of a user for cases when module needs to perform extra operations after auth.
+represented by their Matrix user ID.
+
+If multiple modules implement this callback, Synapse runs them all in order.
diff --git a/docs/upgrade.md b/docs/upgrade.md
index ba2f7703bc..329c9c7787 100644
--- a/docs/upgrade.md
+++ b/docs/upgrade.md
@@ -88,6 +88,15 @@ process, for example:
dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
```
+Generally Synapse database schemas are compatible across multiple versions, once
+a version of Synapse is deployed you may not be able to rollback automatically.
+The following table gives the version ranges and the earliest version they can
+be rolled back to. E.g. Synapse versions v1.58.0 through v1.61.1 can be rolled
+back safely to v1.57.0, but starting with v1.62.0 it is only safe to rollback to
+v1.61.0.
+
+<!-- REPLACE_WITH_SCHEMA_VERSIONS -->
+
# Upgrading to v1.93.0
## Minimum supported Rust version
diff --git a/poetry.lock b/poetry.lock
index 05899b460e..dd99f39ab7 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
[[package]]
name = "alabaster"
@@ -454,34 +454,34 @@ files = [
[[package]]
name = "cryptography"
-version = "41.0.5"
+version = "41.0.6"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
python-versions = ">=3.7"
files = [
- {file = "cryptography-41.0.5-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:da6a0ff8f1016ccc7477e6339e1d50ce5f59b88905585f77193ebd5068f1e797"},
- {file = "cryptography-41.0.5-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:b948e09fe5fb18517d99994184854ebd50b57248736fd4c720ad540560174ec5"},
- {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d38e6031e113b7421db1de0c1b1f7739564a88f1684c6b89234fbf6c11b75147"},
- {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e270c04f4d9b5671ebcc792b3ba5d4488bf7c42c3c241a3748e2599776f29696"},
- {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ec3b055ff8f1dce8e6ef28f626e0972981475173d7973d63f271b29c8a2897da"},
- {file = "cryptography-41.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7d208c21e47940369accfc9e85f0de7693d9a5d843c2509b3846b2db170dfd20"},
- {file = "cryptography-41.0.5-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:8254962e6ba1f4d2090c44daf50a547cd5f0bf446dc658a8e5f8156cae0d8548"},
- {file = "cryptography-41.0.5-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a48e74dad1fb349f3dc1d449ed88e0017d792997a7ad2ec9587ed17405667e6d"},
- {file = "cryptography-41.0.5-cp37-abi3-win32.whl", hash = "sha256:d3977f0e276f6f5bf245c403156673db103283266601405376f075c849a0b936"},
- {file = "cryptography-41.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:73801ac9736741f220e20435f84ecec75ed70eda90f781a148f1bad546963d81"},
- {file = "cryptography-41.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3be3ca726e1572517d2bef99a818378bbcf7d7799d5372a46c79c29eb8d166c1"},
- {file = "cryptography-41.0.5-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e886098619d3815e0ad5790c973afeee2c0e6e04b4da90b88e6bd06e2a0b1b72"},
- {file = "cryptography-41.0.5-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:573eb7128cbca75f9157dcde974781209463ce56b5804983e11a1c462f0f4e88"},
- {file = "cryptography-41.0.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0c327cac00f082013c7c9fb6c46b7cc9fa3c288ca702c74773968173bda421bf"},
- {file = "cryptography-41.0.5-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:227ec057cd32a41c6651701abc0328135e472ed450f47c2766f23267b792a88e"},
- {file = "cryptography-41.0.5-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:22892cc830d8b2c89ea60148227631bb96a7da0c1b722f2aac8824b1b7c0b6b8"},
- {file = "cryptography-41.0.5-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5a70187954ba7292c7876734183e810b728b4f3965fbe571421cb2434d279179"},
- {file = "cryptography-41.0.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:88417bff20162f635f24f849ab182b092697922088b477a7abd6664ddd82291d"},
- {file = "cryptography-41.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c707f7afd813478e2019ae32a7c49cd932dd60ab2d2a93e796f68236b7e1fbf1"},
- {file = "cryptography-41.0.5-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:580afc7b7216deeb87a098ef0674d6ee34ab55993140838b14c9b83312b37b86"},
- {file = "cryptography-41.0.5-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fba1e91467c65fe64a82c689dc6cf58151158993b13eb7a7f3f4b7f395636723"},
- {file = "cryptography-41.0.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0d2a6a598847c46e3e321a7aef8af1436f11c27f1254933746304ff014664d84"},
- {file = "cryptography-41.0.5.tar.gz", hash = "sha256:392cb88b597247177172e02da6b7a63deeff1937fa6fec3bbf902ebd75d97ec7"},
+ {file = "cryptography-41.0.6-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:0f27acb55a4e77b9be8d550d762b0513ef3fc658cd3eb15110ebbcbd626db12c"},
+ {file = "cryptography-41.0.6-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:ae236bb8760c1e55b7a39b6d4d32d2279bc6c7c8500b7d5a13b6fb9fc97be35b"},
+ {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afda76d84b053923c27ede5edc1ed7d53e3c9f475ebaf63c68e69f1403c405a8"},
+ {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da46e2b5df770070412c46f87bac0849b8d685c5f2679771de277a422c7d0b86"},
+ {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ff369dd19e8fe0528b02e8df9f2aeb2479f89b1270d90f96a63500afe9af5cae"},
+ {file = "cryptography-41.0.6-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b648fe2a45e426aaee684ddca2632f62ec4613ef362f4d681a9a6283d10e079d"},
+ {file = "cryptography-41.0.6-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5daeb18e7886a358064a68dbcaf441c036cbdb7da52ae744e7b9207b04d3908c"},
+ {file = "cryptography-41.0.6-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:068bc551698c234742c40049e46840843f3d98ad7ce265fd2bd4ec0d11306596"},
+ {file = "cryptography-41.0.6-cp37-abi3-win32.whl", hash = "sha256:2132d5865eea673fe6712c2ed5fb4fa49dba10768bb4cc798345748380ee3660"},
+ {file = "cryptography-41.0.6-cp37-abi3-win_amd64.whl", hash = "sha256:48783b7e2bef51224020efb61b42704207dde583d7e371ef8fc2a5fb6c0aabc7"},
+ {file = "cryptography-41.0.6-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:8efb2af8d4ba9dbc9c9dd8f04d19a7abb5b49eab1f3694e7b5a16a5fc2856f5c"},
+ {file = "cryptography-41.0.6-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5a550dc7a3b50b116323e3d376241829fd326ac47bc195e04eb33a8170902a9"},
+ {file = "cryptography-41.0.6-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:85abd057699b98fce40b41737afb234fef05c67e116f6f3650782c10862c43da"},
+ {file = "cryptography-41.0.6-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:f39812f70fc5c71a15aa3c97b2bbe213c3f2a460b79bd21c40d033bb34a9bf36"},
+ {file = "cryptography-41.0.6-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:742ae5e9a2310e9dade7932f9576606836ed174da3c7d26bc3d3ab4bd49b9f65"},
+ {file = "cryptography-41.0.6-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:35f3f288e83c3f6f10752467c48919a7a94b7d88cc00b0668372a0d2ad4f8ead"},
+ {file = "cryptography-41.0.6-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4d03186af98b1c01a4eda396b137f29e4e3fb0173e30f885e27acec8823c1b09"},
+ {file = "cryptography-41.0.6-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b27a7fd4229abef715e064269d98a7e2909ebf92eb6912a9603c7e14c181928c"},
+ {file = "cryptography-41.0.6-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:398ae1fc711b5eb78e977daa3cbf47cec20f2c08c5da129b7a296055fbb22aed"},
+ {file = "cryptography-41.0.6-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7e00fb556bda398b99b0da289ce7053639d33b572847181d6483ad89835115f6"},
+ {file = "cryptography-41.0.6-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:60e746b11b937911dc70d164060d28d273e31853bb359e2b2033c9e93e6f3c43"},
+ {file = "cryptography-41.0.6-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:3288acccef021e3c3c10d58933f44e8602cf04dba96d9796d70d537bb2f4bbc4"},
+ {file = "cryptography-41.0.6.tar.gz", hash = "sha256:422e3e31d63743855e43e5a6fcc8b4acab860f560f9321b0ee6269cc7ed70cc3"},
]
[package.dependencies]
@@ -981,13 +981,13 @@ i18n = ["Babel (>=2.7)"]
[[package]]
name = "jsonschema"
-version = "4.19.1"
+version = "4.20.0"
description = "An implementation of JSON Schema validation for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "jsonschema-4.19.1-py3-none-any.whl", hash = "sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e"},
- {file = "jsonschema-4.19.1.tar.gz", hash = "sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf"},
+ {file = "jsonschema-4.20.0-py3-none-any.whl", hash = "sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3"},
+ {file = "jsonschema-4.20.0.tar.gz", hash = "sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa"},
]
[package.dependencies]
@@ -1729,13 +1729,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytes
[[package]]
name = "prometheus-client"
-version = "0.18.0"
+version = "0.19.0"
description = "Python client for the Prometheus monitoring system."
optional = false
python-versions = ">=3.8"
files = [
- {file = "prometheus_client-0.18.0-py3-none-any.whl", hash = "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184"},
- {file = "prometheus_client-0.18.0.tar.gz", hash = "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17"},
+ {file = "prometheus_client-0.19.0-py3-none-any.whl", hash = "sha256:c88b1e6ecf6b41cd8fb5731c7ae919bf66df6ec6fafa555cd6c0e16ca169ae92"},
+ {file = "prometheus_client-0.19.0.tar.gz", hash = "sha256:4585b0d1223148c27a225b10dbec5ae9bc4c81a99a3fa80774fa6209935324e1"},
]
[package.extras]
@@ -1792,13 +1792,13 @@ psycopg2 = "*"
[[package]]
name = "pyasn1"
-version = "0.5.0"
+version = "0.5.1"
description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
files = [
- {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"},
- {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"},
+ {file = "pyasn1-0.5.1-py2.py3-none-any.whl", hash = "sha256:4439847c58d40b1d0a573d07e3856e95333f1976294494c325775aeca506eb58"},
+ {file = "pyasn1-0.5.1.tar.gz", hash = "sha256:6d391a96e59b23130a5cfa74d6fd7f388dbbe26cc8f1edf39fdddf08d9d6676c"},
]
[[package]]
@@ -1828,18 +1828,18 @@ files = [
[[package]]
name = "pydantic"
-version = "2.4.2"
+version = "2.5.1"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.7"
files = [
- {file = "pydantic-2.4.2-py3-none-any.whl", hash = "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1"},
- {file = "pydantic-2.4.2.tar.gz", hash = "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7"},
+ {file = "pydantic-2.5.1-py3-none-any.whl", hash = "sha256:dc5244a8939e0d9a68f1f1b5f550b2e1c879912033b1becbedb315accc75441b"},
+ {file = "pydantic-2.5.1.tar.gz", hash = "sha256:0b8be5413c06aadfbe56f6dc1d45c9ed25fd43264414c571135c97dd77c2bedb"},
]
[package.dependencies]
annotated-types = ">=0.4.0"
-pydantic-core = "2.10.1"
+pydantic-core = "2.14.3"
typing-extensions = ">=4.6.1"
[package.extras]
@@ -1847,117 +1847,116 @@ email = ["email-validator (>=2.0.0)"]
[[package]]
name = "pydantic-core"
-version = "2.10.1"
+version = "2.14.3"
description = ""
optional = false
python-versions = ">=3.7"
files = [
- {file = "pydantic_core-2.10.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63"},
- {file = "pydantic_core-2.10.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096"},
- {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a"},
- {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175"},
- {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7"},
- {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893"},
- {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e"},
- {file = "pydantic_core-2.10.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e"},
- {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e"},
- {file = "pydantic_core-2.10.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6"},
- {file = "pydantic_core-2.10.1-cp310-none-win32.whl", hash = "sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b"},
- {file = "pydantic_core-2.10.1-cp310-none-win_amd64.whl", hash = "sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0"},
- {file = "pydantic_core-2.10.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea"},
- {file = "pydantic_core-2.10.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4"},
- {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c"},
- {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b"},
- {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f"},
- {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a"},
- {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8"},
- {file = "pydantic_core-2.10.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4"},
- {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607"},
- {file = "pydantic_core-2.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f"},
- {file = "pydantic_core-2.10.1-cp311-none-win32.whl", hash = "sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6"},
- {file = "pydantic_core-2.10.1-cp311-none-win_amd64.whl", hash = "sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27"},
- {file = "pydantic_core-2.10.1-cp311-none-win_arm64.whl", hash = "sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325"},
- {file = "pydantic_core-2.10.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921"},
- {file = "pydantic_core-2.10.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118"},
- {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab"},
- {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff"},
- {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7"},
- {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c"},
- {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901"},
- {file = "pydantic_core-2.10.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d"},
- {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f"},
- {file = "pydantic_core-2.10.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c"},
- {file = "pydantic_core-2.10.1-cp312-none-win32.whl", hash = "sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f"},
- {file = "pydantic_core-2.10.1-cp312-none-win_amd64.whl", hash = "sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430"},
- {file = "pydantic_core-2.10.1-cp312-none-win_arm64.whl", hash = "sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15"},
- {file = "pydantic_core-2.10.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f"},
- {file = "pydantic_core-2.10.1-cp37-none-win32.whl", hash = "sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c"},
- {file = "pydantic_core-2.10.1-cp37-none-win_amd64.whl", hash = "sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e"},
- {file = "pydantic_core-2.10.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc"},
- {file = "pydantic_core-2.10.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a"},
- {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd"},
- {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468"},
- {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6"},
- {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58"},
- {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302"},
- {file = "pydantic_core-2.10.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e"},
- {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561"},
- {file = "pydantic_core-2.10.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de"},
- {file = "pydantic_core-2.10.1-cp38-none-win32.whl", hash = "sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee"},
- {file = "pydantic_core-2.10.1-cp38-none-win_amd64.whl", hash = "sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e"},
- {file = "pydantic_core-2.10.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970"},
- {file = "pydantic_core-2.10.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b"},
- {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875"},
- {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0"},
- {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531"},
- {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c"},
- {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a"},
- {file = "pydantic_core-2.10.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429"},
- {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7"},
- {file = "pydantic_core-2.10.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595"},
- {file = "pydantic_core-2.10.1-cp39-none-win32.whl", hash = "sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a"},
- {file = "pydantic_core-2.10.1-cp39-none-win_amd64.whl", hash = "sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357"},
- {file = "pydantic_core-2.10.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada"},
- {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a"},
- {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f"},
- {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e"},
- {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55"},
- {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514"},
- {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2"},
- {file = "pydantic_core-2.10.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132"},
- {file = "pydantic_core-2.10.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7"},
- {file = "pydantic_core-2.10.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776"},
- {file = "pydantic_core-2.10.1.tar.gz", hash = "sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ba44fad1d114539d6a1509966b20b74d2dec9a5b0ee12dd7fd0a1bb7b8785e5f"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4a70d23eedd88a6484aa79a732a90e36701048a1509078d1b59578ef0ea2cdf5"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7cc24728a1a9cef497697e53b3d085fb4d3bc0ef1ef4d9b424d9cf808f52c146"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab4a2381005769a4af2ffddae74d769e8a4aae42e970596208ec6d615c6fb080"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a12bf088d6fa20e094f9a477bf84bd823651d8b8384f59bcd50eaa92e6a52"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:38aed5a1bbc3025859f56d6a32f6e53ca173283cb95348e03480f333b1091e7d"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1767bd3f6370458e60c1d3d7b1d9c2751cc1ad743434e8ec84625a610c8b9195"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7cb0c397f29688a5bd2c0dbd44451bc44ebb9b22babc90f97db5ec3e5bb69977"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:9ff737f24b34ed26de62d481ef522f233d3c5927279f6b7229de9b0deb3f76b5"},
+ {file = "pydantic_core-2.14.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a1a39fecb5f0b19faee9a8a8176c805ed78ce45d760259a4ff3d21a7daa4dfc1"},
+ {file = "pydantic_core-2.14.3-cp310-none-win32.whl", hash = "sha256:ccbf355b7276593c68fa824030e68cb29f630c50e20cb11ebb0ee450ae6b3d08"},
+ {file = "pydantic_core-2.14.3-cp310-none-win_amd64.whl", hash = "sha256:536e1f58419e1ec35f6d1310c88496f0d60e4f182cacb773d38076f66a60b149"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:f1f46700402312bdc31912f6fc17f5ecaaaa3bafe5487c48f07c800052736289"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:88ec906eb2d92420f5b074f59cf9e50b3bb44f3cb70e6512099fdd4d88c2f87c"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:056ea7cc3c92a7d2a14b5bc9c9fa14efa794d9f05b9794206d089d06d3433dc7"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:076edc972b68a66870cec41a4efdd72a6b655c4098a232314b02d2bfa3bfa157"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e71f666c3bf019f2490a47dddb44c3ccea2e69ac882f7495c68dc14d4065eac2"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f518eac285c9632be337323eef9824a856f2680f943a9b68ac41d5f5bad7df7c"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dbab442a8d9ca918b4ed99db8d89d11b1f067a7dadb642476ad0889560dac79"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0653fb9fc2fa6787f2fa08631314ab7fc8070307bd344bf9471d1b7207c24623"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c54af5069da58ea643ad34ff32fd6bc4eebb8ae0fef9821cd8919063e0aeeaab"},
+ {file = "pydantic_core-2.14.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc956f78651778ec1ab105196e90e0e5f5275884793ab67c60938c75bcca3989"},
+ {file = "pydantic_core-2.14.3-cp311-none-win32.whl", hash = "sha256:5b73441a1159f1fb37353aaefb9e801ab35a07dd93cb8177504b25a317f4215a"},
+ {file = "pydantic_core-2.14.3-cp311-none-win_amd64.whl", hash = "sha256:7349f99f1ef8b940b309179733f2cad2e6037a29560f1b03fdc6aa6be0a8d03c"},
+ {file = "pydantic_core-2.14.3-cp311-none-win_arm64.whl", hash = "sha256:ec79dbe23702795944d2ae4c6925e35a075b88acd0d20acde7c77a817ebbce94"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:8f5624f0f67f2b9ecaa812e1dfd2e35b256487566585160c6c19268bf2ffeccc"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c2d118d1b6c9e2d577e215567eedbe11804c3aafa76d39ec1f8bc74e918fd07"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe863491664c6720d65ae438d4efaa5eca766565a53adb53bf14bc3246c72fe0"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:136bc7247e97a921a020abbd6ef3169af97569869cd6eff41b6a15a73c44ea9b"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aeafc7f5bbddc46213707266cadc94439bfa87ecf699444de8be044d6d6eb26f"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e16aaf788f1de5a85c8f8fcc9c1ca1dd7dd52b8ad30a7889ca31c7c7606615b8"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8fc652c354d3362e2932a79d5ac4bbd7170757a41a62c4fe0f057d29f10bebb"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f1b92e72babfd56585c75caf44f0b15258c58e6be23bc33f90885cebffde3400"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:75f3f534f33651b73f4d3a16d0254de096f43737d51e981478d580f4b006b427"},
+ {file = "pydantic_core-2.14.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c9ffd823c46e05ef3eb28b821aa7bc501efa95ba8880b4a1380068e32c5bed47"},
+ {file = "pydantic_core-2.14.3-cp312-none-win32.whl", hash = "sha256:12e05a76b223577a4696c76d7a6b36a0ccc491ffb3c6a8cf92d8001d93ddfd63"},
+ {file = "pydantic_core-2.14.3-cp312-none-win_amd64.whl", hash = "sha256:1582f01eaf0537a696c846bea92082082b6bfc1103a88e777e983ea9fbdc2a0f"},
+ {file = "pydantic_core-2.14.3-cp312-none-win_arm64.whl", hash = "sha256:96fb679c7ca12a512d36d01c174a4fbfd912b5535cc722eb2c010c7b44eceb8e"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:71ed769b58d44e0bc2701aa59eb199b6665c16e8a5b8b4a84db01f71580ec448"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:5402ee0f61e7798ea93a01b0489520f2abfd9b57b76b82c93714c4318c66ca06"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaab9dc009e22726c62fe3b850b797e7f0e7ba76d245284d1064081f512c7226"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:92486a04d54987054f8b4405a9af9d482e5100d6fe6374fc3303015983fc8bda"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cf08b43d1d5d1678f295f0431a4a7e1707d4652576e1d0f8914b5e0213bfeee5"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8ca13480ce16daad0504be6ce893b0ee8ec34cd43b993b754198a89e2787f7e"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44afa3c18d45053fe8d8228950ee4c8eaf3b5a7f3b64963fdeac19b8342c987f"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56814b41486e2d712a8bc02a7b1f17b87fa30999d2323bbd13cf0e52296813a1"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c3dc2920cc96f9aa40c6dc54256e436cc95c0a15562eb7bd579e1811593c377e"},
+ {file = "pydantic_core-2.14.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e483b8b913fcd3b48badec54185c150cb7ab0e6487914b84dc7cde2365e0c892"},
+ {file = "pydantic_core-2.14.3-cp37-none-win32.whl", hash = "sha256:364dba61494e48f01ef50ae430e392f67ee1ee27e048daeda0e9d21c3ab2d609"},
+ {file = "pydantic_core-2.14.3-cp37-none-win_amd64.whl", hash = "sha256:a402ae1066be594701ac45661278dc4a466fb684258d1a2c434de54971b006ca"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:10904368261e4509c091cbcc067e5a88b070ed9a10f7ad78f3029c175487490f"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:260692420028319e201b8649b13ac0988974eeafaaef95d0dfbf7120c38dc000"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c1bf1a7b05a65d3b37a9adea98e195e0081be6b17ca03a86f92aeb8b110f468"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7abd17a838a52140e3aeca271054e321226f52df7e0a9f0da8f91ea123afe98"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5c51460ede609fbb4fa883a8fe16e749964ddb459966d0518991ec02eb8dfb9"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d06c78074646111fb01836585f1198367b17d57c9f427e07aaa9ff499003e58d"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af452e69446fadf247f18ac5d153b1f7e61ef708f23ce85d8c52833748c58075"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e3ad4968711fb379a67c8c755beb4dae8b721a83737737b7bcee27c05400b047"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c5ea0153482e5b4d601c25465771c7267c99fddf5d3f3bdc238ef930e6d051cf"},
+ {file = "pydantic_core-2.14.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:96eb10ef8920990e703da348bb25fedb8b8653b5966e4e078e5be382b430f9e0"},
+ {file = "pydantic_core-2.14.3-cp38-none-win32.whl", hash = "sha256:ea1498ce4491236d1cffa0eee9ad0968b6ecb0c1cd711699c5677fc689905f00"},
+ {file = "pydantic_core-2.14.3-cp38-none-win_amd64.whl", hash = "sha256:2bc736725f9bd18a60eec0ed6ef9b06b9785454c8d0105f2be16e4d6274e63d0"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:1ea992659c03c3ea811d55fc0a997bec9dde863a617cc7b25cfde69ef32e55af"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d2b53e1f851a2b406bbb5ac58e16c4a5496038eddd856cc900278fa0da97f3fc"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c7f8e8a7cf8e81ca7d44bea4f181783630959d41b4b51d2f74bc50f348a090f"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d3b9c91eeb372a64ec6686c1402afd40cc20f61a0866850f7d989b6bf39a41a"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ef3e2e407e4cad2df3c89488a761ed1f1c33f3b826a2ea9a411b0a7d1cccf1b"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f86f20a9d5bee1a6ede0f2757b917bac6908cde0f5ad9fcb3606db1e2968bcf5"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61beaa79d392d44dc19d6f11ccd824d3cccb865c4372157c40b92533f8d76dd0"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d41df8e10b094640a6b234851b624b76a41552f637b9fb34dc720b9fe4ef3be4"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c08ac60c3caa31f825b5dbac47e4875bd4954d8f559650ad9e0b225eaf8ed0c"},
+ {file = "pydantic_core-2.14.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d8b3932f1a369364606417ded5412c4ffb15bedbcf797c31317e55bd5d920e"},
+ {file = "pydantic_core-2.14.3-cp39-none-win32.whl", hash = "sha256:caa94726791e316f0f63049ee00dff3b34a629b0d099f3b594770f7d0d8f1f56"},
+ {file = "pydantic_core-2.14.3-cp39-none-win_amd64.whl", hash = "sha256:2494d20e4c22beac30150b4be3b8339bf2a02ab5580fa6553ca274bc08681a65"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:fe272a72c7ed29f84c42fedd2d06c2f9858dc0c00dae3b34ba15d6d8ae0fbaaf"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7e63a56eb7fdee1587d62f753ccd6d5fa24fbeea57a40d9d8beaef679a24bdd6"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7692f539a26265cece1e27e366df5b976a6db6b1f825a9e0466395b314ee48b"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af46f0b7a1342b49f208fed31f5a83b8495bb14b652f621e0a6787d2f10f24ee"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e2f9d76c00e805d47f19c7a96a14e4135238a7551a18bfd89bb757993fd0933"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:de52ddfa6e10e892d00f747bf7135d7007302ad82e243cf16d89dd77b03b649d"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:38113856c7fad8c19be7ddd57df0c3e77b1b2336459cb03ee3903ce9d5e236ce"},
+ {file = "pydantic_core-2.14.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:354db020b1f8f11207b35360b92d95725621eb92656725c849a61e4b550f4acc"},
+ {file = "pydantic_core-2.14.3-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:76fc18653a5c95e5301a52d1b5afb27c9adc77175bf00f73e94f501caf0e05ad"},
+ {file = "pydantic_core-2.14.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2646f8270f932d79ba61102a15ea19a50ae0d43b314e22b3f8f4b5fabbfa6e38"},
+ {file = "pydantic_core-2.14.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37dad73a2f82975ed563d6a277fd9b50e5d9c79910c4aec787e2d63547202315"},
+ {file = "pydantic_core-2.14.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:113752a55a8eaece2e4ac96bc8817f134c2c23477e477d085ba89e3aa0f4dc44"},
+ {file = "pydantic_core-2.14.3-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:8488e973547e8fb1b4193fd9faf5236cf1b7cd5e9e6dc7ff6b4d9afdc4c720cb"},
+ {file = "pydantic_core-2.14.3-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3d1dde10bd9962b1434053239b1d5490fc31a2b02d8950a5f731bc584c7a5a0f"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:2c83892c7bf92b91d30faca53bb8ea21f9d7e39f0ae4008ef2c2f91116d0464a"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:849cff945284c577c5f621d2df76ca7b60f803cc8663ff01b778ad0af0e39bb9"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa89919fbd8a553cd7d03bf23d5bc5deee622e1b5db572121287f0e64979476"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf15145b1f8056d12c67255cd3ce5d317cd4450d5ee747760d8d088d85d12a2d"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4cc6bb11f4e8e5ed91d78b9880774fbc0856cb226151b0a93b549c2b26a00c19"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:832d16f248ca0cc96929139734ec32d21c67669dcf8a9f3f733c85054429c012"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b02b5e1f54c3396c48b665050464803c23c685716eb5d82a1d81bf81b5230da4"},
+ {file = "pydantic_core-2.14.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:1f2d4516c32255782153e858f9a900ca6deadfb217fd3fb21bb2b60b4e04d04d"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0a3e51c2be472b7867eb0c5d025b91400c2b73a0823b89d4303a9097e2ec6655"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:df33902464410a1f1a0411a235f0a34e7e129f12cb6340daca0f9d1390f5fe10"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27828f0227b54804aac6fb077b6bb48e640b5435fdd7fbf0c274093a7b78b69c"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2979dc80246e18e348de51246d4c9b410186ffa3c50e77924bec436b1e36cb"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b28996872b48baf829ee75fa06998b607c66a4847ac838e6fd7473a6b2ab68e7"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ca55c9671bb637ce13d18ef352fd32ae7aba21b4402f300a63f1fb1fd18e0364"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:aecd5ed096b0e5d93fb0367fd8f417cef38ea30b786f2501f6c34eabd9062c38"},
+ {file = "pydantic_core-2.14.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:44aaf1a07ad0824e407dafc637a852e9a44d94664293bbe7d8ee549c356c8882"},
+ {file = "pydantic_core-2.14.3.tar.gz", hash = "sha256:3ad083df8fe342d4d8d00cc1d3c1a23f0dc84fce416eb301e69f1ddbbe124d3f"},
]
[package.dependencies]
@@ -2081,20 +2080,20 @@ tests = ["hypothesis (>=3.27.0)", "pytest (>=3.2.1,!=3.3.0)"]
[[package]]
name = "pyopenssl"
-version = "23.2.0"
+version = "23.3.0"
description = "Python wrapper module around the OpenSSL library"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.7"
files = [
- {file = "pyOpenSSL-23.2.0-py3-none-any.whl", hash = "sha256:24f0dc5227396b3e831f4c7f602b950a5e9833d292c8e4a2e06b709292806ae2"},
- {file = "pyOpenSSL-23.2.0.tar.gz", hash = "sha256:276f931f55a452e7dea69c7173e984eb2a4407ce413c918aa34b55f82f9b8bac"},
+ {file = "pyOpenSSL-23.3.0-py3-none-any.whl", hash = "sha256:6756834481d9ed5470f4a9393455154bc92fe7a64b7bc6ee2c804e78c52099b2"},
+ {file = "pyOpenSSL-23.3.0.tar.gz", hash = "sha256:6b2cba5cc46e822750ec3e5a81ee12819850b11303630d575e98108a079c2b12"},
]
[package.dependencies]
-cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42"
+cryptography = ">=41.0.5,<42"
[package.extras]
-docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"]
+docs = ["sphinx (!=5.2.0,!=5.2.0.post0,!=7.2.5)", "sphinx-rtd-theme"]
test = ["flaky", "pretend", "pytest (>=3.0.1)"]
[[package]]
@@ -2426,28 +2425,28 @@ files = [
[[package]]
name = "ruff"
-version = "0.1.4"
+version = "0.1.6"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
- {file = "ruff-0.1.4-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:864958706b669cce31d629902175138ad8a069d99ca53514611521f532d91495"},
- {file = "ruff-0.1.4-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:9fdd61883bb34317c788af87f4cd75dfee3a73f5ded714b77ba928e418d6e39e"},
- {file = "ruff-0.1.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4eaca8c9cc39aa7f0f0d7b8fe24ecb51232d1bb620fc4441a61161be4a17539"},
- {file = "ruff-0.1.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a9a1301dc43cbf633fb603242bccd0aaa34834750a14a4c1817e2e5c8d60de17"},
- {file = "ruff-0.1.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78e8db8ab6f100f02e28b3d713270c857d370b8d61871d5c7d1702ae411df683"},
- {file = "ruff-0.1.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:80fea754eaae06335784b8ea053d6eb8e9aac75359ebddd6fee0858e87c8d510"},
- {file = "ruff-0.1.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6bc02a480d4bfffd163a723698da15d1a9aec2fced4c06f2a753f87f4ce6969c"},
- {file = "ruff-0.1.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9862811b403063765b03e716dac0fda8fdbe78b675cd947ed5873506448acea4"},
- {file = "ruff-0.1.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58826efb8b3efbb59bb306f4b19640b7e366967a31c049d49311d9eb3a4c60cb"},
- {file = "ruff-0.1.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fdfd453fc91d9d86d6aaa33b1bafa69d114cf7421057868f0b79104079d3e66e"},
- {file = "ruff-0.1.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e8791482d508bd0b36c76481ad3117987301b86072158bdb69d796503e1c84a8"},
- {file = "ruff-0.1.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:01206e361021426e3c1b7fba06ddcb20dbc5037d64f6841e5f2b21084dc51800"},
- {file = "ruff-0.1.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:645591a613a42cb7e5c2b667cbefd3877b21e0252b59272ba7212c3d35a5819f"},
- {file = "ruff-0.1.4-py3-none-win32.whl", hash = "sha256:99908ca2b3b85bffe7e1414275d004917d1e0dfc99d497ccd2ecd19ad115fd0d"},
- {file = "ruff-0.1.4-py3-none-win_amd64.whl", hash = "sha256:1dfd6bf8f6ad0a4ac99333f437e0ec168989adc5d837ecd38ddb2cc4a2e3db8a"},
- {file = "ruff-0.1.4-py3-none-win_arm64.whl", hash = "sha256:d98ae9ebf56444e18a3e3652b3383204748f73e247dea6caaf8b52d37e6b32da"},
- {file = "ruff-0.1.4.tar.gz", hash = "sha256:21520ecca4cc555162068d87c747b8f95e1e95f8ecfcbbe59e8dd00710586315"},
+ {file = "ruff-0.1.6-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:88b8cdf6abf98130991cbc9f6438f35f6e8d41a02622cc5ee130a02a0ed28703"},
+ {file = "ruff-0.1.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c549ed437680b6105a1299d2cd30e4964211606eeb48a0ff7a93ef70b902248"},
+ {file = "ruff-0.1.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cf5f701062e294f2167e66d11b092bba7af6a057668ed618a9253e1e90cfd76"},
+ {file = "ruff-0.1.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:05991ee20d4ac4bb78385360c684e4b417edd971030ab12a4fbd075ff535050e"},
+ {file = "ruff-0.1.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87455a0c1f739b3c069e2f4c43b66479a54dea0276dd5d4d67b091265f6fd1dc"},
+ {file = "ruff-0.1.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:683aa5bdda5a48cb8266fcde8eea2a6af4e5700a392c56ea5fb5f0d4bfdc0240"},
+ {file = "ruff-0.1.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:137852105586dcbf80c1717facb6781555c4e99f520c9c827bd414fac67ddfb6"},
+ {file = "ruff-0.1.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd98138a98d48a1c36c394fd6b84cd943ac92a08278aa8ac8c0fdefcf7138f35"},
+ {file = "ruff-0.1.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0cd909d25f227ac5c36d4e7e681577275fb74ba3b11d288aff7ec47e3ae745"},
+ {file = "ruff-0.1.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e8fd1c62a47aa88a02707b5dd20c5ff20d035d634aa74826b42a1da77861b5ff"},
+ {file = "ruff-0.1.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd89b45d374935829134a082617954120d7a1470a9f0ec0e7f3ead983edc48cc"},
+ {file = "ruff-0.1.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:491262006e92f825b145cd1e52948073c56560243b55fb3b4ecb142f6f0e9543"},
+ {file = "ruff-0.1.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ea284789861b8b5ca9d5443591a92a397ac183d4351882ab52f6296b4fdd5462"},
+ {file = "ruff-0.1.6-py3-none-win32.whl", hash = "sha256:1610e14750826dfc207ccbcdd7331b6bd285607d4181df9c1c6ae26646d6848a"},
+ {file = "ruff-0.1.6-py3-none-win_amd64.whl", hash = "sha256:4558b3e178145491e9bc3b2ee3c4b42f19d19384eaa5c59d10acf6e8f8b57e33"},
+ {file = "ruff-0.1.6-py3-none-win_arm64.whl", hash = "sha256:03910e81df0d8db0e30050725a5802441c2022ea3ae4fe0609b76081731accbc"},
+ {file = "ruff-0.1.6.tar.gz", hash = "sha256:1b09f29b16c6ead5ea6b097ef2764b42372aebe363722f1605ecbcd2b9207184"},
]
[[package]]
@@ -2482,13 +2481,13 @@ doc = ["Sphinx", "sphinx-rtd-theme"]
[[package]]
name = "sentry-sdk"
-version = "1.32.0"
+version = "1.35.0"
description = "Python client for Sentry (https://sentry.io)"
optional = true
python-versions = "*"
files = [
- {file = "sentry-sdk-1.32.0.tar.gz", hash = "sha256:935e8fbd7787a3702457393b74b13d89a5afb67185bc0af85c00cb27cbd42e7c"},
- {file = "sentry_sdk-1.32.0-py2.py3-none-any.whl", hash = "sha256:eeb0b3550536f3bbc05bb1c7e0feb3a78d74acb43b607159a606ed2ec0a33a4d"},
+ {file = "sentry-sdk-1.35.0.tar.gz", hash = "sha256:04e392db9a0d59bd49a51b9e3a92410ac5867556820465057c2ef89a38e953e9"},
+ {file = "sentry_sdk-1.35.0-py2.py3-none-any.whl", hash = "sha256:a7865952701e46d38b41315c16c075367675c48d049b90a4cc2e41991ebc7efa"},
]
[package.dependencies]
@@ -3091,24 +3090,24 @@ files = [
[[package]]
name = "types-pillow"
-version = "10.1.0.0"
+version = "10.1.0.2"
description = "Typing stubs for Pillow"
optional = false
python-versions = ">=3.7"
files = [
- {file = "types-Pillow-10.1.0.0.tar.gz", hash = "sha256:0f5e7cf010ed226800cb5821e87781e5d0e81257d948a9459baa74a8c8b7d822"},
- {file = "types_Pillow-10.1.0.0-py3-none-any.whl", hash = "sha256:f97f596b6a39ddfd26da3eb67421062193e10732d2310f33898d36f9694331b5"},
+ {file = "types-Pillow-10.1.0.2.tar.gz", hash = "sha256:525c1c5ee67b0ac1721c40d2bc618226ef2123c347e527e14e05b920721a13b9"},
+ {file = "types_Pillow-10.1.0.2-py3-none-any.whl", hash = "sha256:131078ffa547bf9a201d39ffcdc65633e108148085f4f1b07d4647fcfec6e923"},
]
[[package]]
name = "types-psycopg2"
-version = "2.9.21.15"
+version = "2.9.21.16"
description = "Typing stubs for psycopg2"
optional = false
python-versions = ">=3.7"
files = [
- {file = "types-psycopg2-2.9.21.15.tar.gz", hash = "sha256:cf99b62ab32cd4ef412fc3c4da1c29ca5a130847dff06d709b84a523802406f0"},
- {file = "types_psycopg2-2.9.21.15-py3-none-any.whl", hash = "sha256:cc80479def02e4dd1ef21649d82f04426c73bc0693bcc0a8b5223c7c168472af"},
+ {file = "types-psycopg2-2.9.21.16.tar.gz", hash = "sha256:44a3ae748173bb637cff31654d6bd12de9ad0c7ad73afe737df6152830ed82ed"},
+ {file = "types_psycopg2-2.9.21.16-py3-none-any.whl", hash = "sha256:e2f24b651239ccfda320ab3457099af035cf37962c36c9fa26a4dc65991aebed"},
]
[[package]]
@@ -3152,13 +3151,13 @@ urllib3 = ">=2"
[[package]]
name = "types-setuptools"
-version = "68.2.0.0"
+version = "68.2.0.2"
description = "Typing stubs for setuptools"
optional = false
-python-versions = "*"
+python-versions = ">=3.7"
files = [
- {file = "types-setuptools-68.2.0.0.tar.gz", hash = "sha256:a4216f1e2ef29d089877b3af3ab2acf489eb869ccaf905125c69d2dc3932fd85"},
- {file = "types_setuptools-68.2.0.0-py3-none-any.whl", hash = "sha256:77edcc843e53f8fc83bb1a840684841f3dc804ec94562623bfa2ea70d5a2ba1b"},
+ {file = "types-setuptools-68.2.0.2.tar.gz", hash = "sha256:09efc380ad5c7f78e30bca1546f706469568cf26084cfab73ecf83dea1d28446"},
+ {file = "types_setuptools-68.2.0.2-py3-none-any.whl", hash = "sha256:d5b5ff568ea2474eb573dcb783def7dadfd9b1ff638bb653b3c7051ce5aeb6d1"},
]
[[package]]
@@ -3433,4 +3432,4 @@ user-search = ["pyicu"]
[metadata]
lock-version = "2.0"
python-versions = "^3.8.0"
-content-hash = "369455d6a67753a6bcfbad3cd86801b1dd02896d0180080e2ba9501e007353ec"
+content-hash = "2924e80a14b32b430e70bafbd2b00893a365d9c3836c026296f4af0b9579e604"
diff --git a/pyproject.toml b/pyproject.toml
index 47c255e395..b0ccf82e10 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -96,7 +96,7 @@ module-name = "synapse.synapse_rust"
[tool.poetry]
name = "matrix-synapse"
-version = "1.96.1"
+version = "1.97.0"
description = "Homeserver for the Matrix decentralised comms protocol"
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
license = "Apache-2.0"
@@ -321,7 +321,7 @@ all = [
# This helps prevents merge conflicts when running a batch of dependabot updates.
isort = ">=5.10.1"
black = ">=22.7.0"
-ruff = "0.1.4"
+ruff = "0.1.6"
# Type checking only works with the pydantic.v1 compat module from pydantic v2
pydantic = "^2"
@@ -382,7 +382,7 @@ furo = ">=2022.12.7,<2024.0.0"
# runtime errors caused by build system changes.
# We are happy to raise these upper bounds upon request,
# provided we check that it's safe to do so (i.e. that CI passes).
-requires = ["poetry-core>=1.1.0,<=1.7.0", "setuptools_rust>=1.3,<=1.8.1"]
+requires = ["poetry-core>=1.1.0,<=1.8.1", "setuptools_rust>=1.3,<=1.8.1"]
build-backend = "poetry.core.masonry.api"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index f62da35a6f..cf70a879f6 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -25,14 +25,14 @@ name = "synapse.synapse_rust"
anyhow = "1.0.63"
lazy_static = "1.4.0"
log = "0.4.17"
-pyo3 = { version = "0.19.2", features = [
+pyo3 = { version = "0.20.0", features = [
"macros",
"anyhow",
"abi3",
"abi3-py38",
] }
-pyo3-log = "0.8.1"
-pythonize = "0.19.0"
+pyo3-log = "0.9.0"
+pythonize = "0.20.0"
regex = "1.6.0"
serde = { version = "1.0.144", features = ["derive"] }
serde_json = "1.0.85"
diff --git a/rust/src/push/mod.rs b/rust/src/push/mod.rs
index 5e1e8e1abb..68d4227baa 100644
--- a/rust/src/push/mod.rs
+++ b/rust/src/push/mod.rs
@@ -296,8 +296,7 @@ impl<'source> FromPyObject<'source> for JsonValue {
match l.iter().map(SimpleJsonValue::extract).collect() {
Ok(a) => Ok(JsonValue::Array(a)),
Err(e) => Err(PyTypeError::new_err(format!(
- "Can't convert to JsonValue::Array: {}",
- e
+ "Can't convert to JsonValue::Array: {e}"
))),
}
} else if let Ok(v) = SimpleJsonValue::extract(ob) {
diff --git a/scripts-dev/schema_versions.py b/scripts-dev/schema_versions.py
new file mode 100755
index 0000000000..5fd73251cd
--- /dev/null
+++ b/scripts-dev/schema_versions.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python
+# Copyright 2023 The Matrix.org Foundation C.I.C.
+#
+# 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.
+
+"""A script to calculate which versions of Synapse have backwards-compatible
+database schemas. It creates a Markdown table of Synapse versions and the earliest
+compatible version.
+
+It is compatible with the mdbook protocol for preprocessors (see
+https://rust-lang.github.io/mdBook/for_developers/preprocessors.html#implementing-a-preprocessor-with-a-different-language):
+
+Exit 0 to denote support for all renderers:
+
+ ./scripts-dev/schema_versions.py supports <mdbook renderer>
+
+Parse a JSON list from stdin and add the table to the proper documetnation page:
+
+ ./scripts-dev/schema_versions.py
+
+Additionally, the script supports dumping the table to stdout for debugging:
+
+ ./scripts-dev/schema_versions.py dump
+"""
+
+import io
+import json
+import sys
+from collections import defaultdict
+from typing import Any, Dict, Iterator, Optional, Tuple
+
+import git
+from packaging import version
+
+# The schema version has moved around over the years.
+SCHEMA_VERSION_FILES = (
+ "synapse/storage/schema/__init__.py",
+ "synapse/storage/prepare_database.py",
+ "synapse/storage/__init__.py",
+ "synapse/app/homeserver.py",
+)
+
+
+# Skip versions of Synapse < v1.0, they're old and essentially not
+# compatible with today's federation.
+OLDEST_SHOWN_VERSION = version.parse("v1.0")
+
+
+def get_schema_versions(tag: git.Tag) -> Tuple[Optional[int], Optional[int]]:
+ """Get the schema and schema compat versions for a tag."""
+ schema_version = None
+ schema_compat_version = None
+
+ for file in SCHEMA_VERSION_FILES:
+ try:
+ schema_file = tag.commit.tree / file
+ except KeyError:
+ continue
+
+ # We (usually) can't execute the code since it might have unknown imports.
+ if file != "synapse/storage/schema/__init__.py":
+ with io.BytesIO(schema_file.data_stream.read()) as f:
+ for line in f.readlines():
+ if line.startswith(b"SCHEMA_VERSION"):
+ schema_version = int(line.split()[2])
+
+ # Bail early.
+ break
+ else:
+ # SCHEMA_COMPAT_VERSION is sometimes across multiple lines, the easist
+ # thing to do is exec the code. Luckily it has only ever existed in
+ # a file which imports nothing else from Synapse.
+ locals: Dict[str, Any] = {}
+ exec(schema_file.data_stream.read().decode("utf-8"), {}, locals)
+ schema_version = locals["SCHEMA_VERSION"]
+ schema_compat_version = locals.get("SCHEMA_COMPAT_VERSION")
+
+ return schema_version, schema_compat_version
+
+
+def get_tags(repo: git.Repo) -> Iterator[git.Tag]:
+ """Return an iterator of tags sorted by version."""
+ tags = []
+ for tag in repo.tags:
+ # All "real" Synapse tags are of the form vX.Y.Z.
+ if not tag.name.startswith("v"):
+ continue
+
+ # There's a weird tag from the initial react UI.
+ if tag.name == "v0.1":
+ continue
+
+ try:
+ tag_version = version.parse(tag.name)
+ except version.InvalidVersion:
+ # Skip invalid versions.
+ continue
+
+ # Skip pre- and post-release versions.
+ if tag_version.is_prerelease or tag_version.is_postrelease or tag_version.local:
+ continue
+
+ # Skip old versions.
+ if tag_version < OLDEST_SHOWN_VERSION:
+ continue
+
+ tags.append((tag_version, tag))
+
+ # Sort based on the version number (not lexically).
+ return (tag for _, tag in sorted(tags, key=lambda t: t[0]))
+
+
+def calculate_version_chart() -> str:
+ repo = git.Repo(path=".")
+
+ # Map of schema version -> Synapse versions which are at that schema version.
+ schema_versions = defaultdict(list)
+ # Map of schema version -> Synapse versions which are compatible with that
+ # schema version.
+ schema_compat_versions = defaultdict(list)
+
+ # Find ranges of versions which are compatible with a schema version.
+ #
+ # There are two modes of operation:
+ #
+ # 1. Pre-schema_compat_version (i.e. schema_compat_version of None), then
+ # Synapse is compatible up/downgrading to a version with
+ # schema_version >= its current version.
+ #
+ # 2. Post-schema_compat_version (i.e. schema_compat_version is *not* None),
+ # then Synapse is compatible up/downgrading to a version with
+ # schema version >= schema_compat_version.
+ #
+ # This is more generous and avoids versions that cannot be rolled back.
+ #
+ # See https://github.com/matrix-org/synapse/pull/9933 which was included in v1.37.0.
+ for tag in get_tags(repo):
+ schema_version, schema_compat_version = get_schema_versions(tag)
+
+ # If a schema compat version is given, prefer that over the schema version.
+ schema_versions[schema_version].append(tag.name)
+ schema_compat_versions[schema_compat_version or schema_version].append(tag.name)
+
+ # Generate a table which maps the latest Synapse version compatible with each
+ # schema version.
+ result = f"| {'Versions': ^19} | Compatible version |\n"
+ result += f"|{'-' * (19 + 2)}|{'-' * (18 + 2)}|\n"
+ for schema_version, synapse_versions in schema_compat_versions.items():
+ result += f"| {synapse_versions[0] + ' – ' + synapse_versions[-1]: ^19} | {schema_versions[schema_version][0]: ^18} |\n"
+
+ return result
+
+
+if __name__ == "__main__":
+ if len(sys.argv) == 3 and sys.argv[1] == "supports":
+ # We don't care about the renderer which is being used, which is the second argument.
+ sys.exit(0)
+ elif len(sys.argv) == 2 and sys.argv[1] == "dump":
+ print(calculate_version_chart())
+ else:
+ # Expect JSON data on stdin.
+ context, book = json.load(sys.stdin)
+
+ for section in book["sections"]:
+ if "Chapter" in section and section["Chapter"]["path"] == "upgrade.md":
+ section["Chapter"]["content"] = section["Chapter"]["content"].replace(
+ "<!-- REPLACE_WITH_SCHEMA_VERSIONS -->", calculate_version_chart()
+ )
+
+ # Print the result back out to stdout.
+ print(json.dumps(book))
diff --git a/synapse/api/auth/base.py b/synapse/api/auth/base.py
index 9321d6f186..e2e3dc61b4 100644
--- a/synapse/api/auth/base.py
+++ b/synapse/api/auth/base.py
@@ -27,6 +27,8 @@ from synapse.api.errors import (
UnstableSpecAuthError,
)
from synapse.appservice import ApplicationService
+from synapse.http import get_request_user_agent
+from synapse.http.site import SynapseRequest
from synapse.logging.opentracing import trace
from synapse.types import Requester, create_requester
from synapse.util.cancellation import cancellable
@@ -45,6 +47,9 @@ class BaseAuth:
self.store = hs.get_datastores().main
self._storage_controllers = hs.get_storage_controllers()
+ self._track_appservice_user_ips = hs.config.appservice.track_appservice_user_ips
+ self._track_puppeted_user_ips = hs.config.api.track_puppeted_user_ips
+
async def check_user_in_room(
self,
room_id: str,
@@ -349,3 +354,46 @@ class BaseAuth:
return create_requester(
effective_user_id, app_service=app_service, device_id=effective_device_id
)
+
+ async def _record_request(
+ self, request: SynapseRequest, requester: Requester
+ ) -> None:
+ """Record that this request was made.
+
+ This updates the client_ips and monthly_active_user tables.
+ """
+ ip_addr = request.get_client_ip_if_available()
+
+ if ip_addr and (not requester.app_service or self._track_appservice_user_ips):
+ user_agent = get_request_user_agent(request)
+ access_token = self.get_access_token_from_request(request)
+
+ # XXX(quenting): I'm 95% confident that we could skip setting the
+ # device_id to "dummy-device" for appservices, and that the only impact
+ # would be some rows which whould not deduplicate in the 'user_ips'
+ # table during the transition
+ recorded_device_id = (
+ "dummy-device"
+ if requester.device_id is None and requester.app_service is not None
+ else requester.device_id
+ )
+ await self.store.insert_client_ip(
+ user_id=requester.authenticated_entity,
+ access_token=access_token,
+ ip=ip_addr,
+ user_agent=user_agent,
+ device_id=recorded_device_id,
+ )
+
+ # Track also the puppeted user client IP if enabled and the user is puppeting
+ if (
+ requester.user.to_string() != requester.authenticated_entity
+ and self._track_puppeted_user_ips
+ ):
+ await self.store.insert_client_ip(
+ user_id=requester.user.to_string(),
+ access_token=access_token,
+ ip=ip_addr,
+ user_agent=user_agent,
+ device_id=requester.device_id,
+ )
diff --git a/synapse/api/auth/internal.py b/synapse/api/auth/internal.py
index 36ee9c8b8f..985cbb1278 100644
--- a/synapse/api/auth/internal.py
+++ b/synapse/api/auth/internal.py
@@ -22,7 +22,6 @@ from synapse.api.errors import (
InvalidClientTokenError,
MissingClientTokenError,
)
-from synapse.http import get_request_user_agent
from synapse.http.site import SynapseRequest
from synapse.logging.opentracing import active_span, force_tracing, start_active_span
from synapse.types import Requester, create_requester
@@ -48,8 +47,6 @@ class InternalAuth(BaseAuth):
self._account_validity_handler = hs.get_account_validity_handler()
self._macaroon_generator = hs.get_macaroon_generator()
- self._track_appservice_user_ips = hs.config.appservice.track_appservice_user_ips
- self._track_puppeted_user_ips = hs.config.api.track_puppeted_user_ips
self._force_tracing_for_users = hs.config.tracing.force_tracing_for_users
@cancellable
@@ -115,9 +112,6 @@ class InternalAuth(BaseAuth):
Once get_user_by_req has set up the opentracing span, this does the actual work.
"""
try:
- ip_addr = request.get_client_ip_if_available()
- user_agent = get_request_user_agent(request)
-
access_token = self.get_access_token_from_request(request)
# First check if it could be a request from an appservice
@@ -154,38 +148,7 @@ class InternalAuth(BaseAuth):
errcode=Codes.EXPIRED_ACCOUNT,
)
- if ip_addr and (
- not requester.app_service or self._track_appservice_user_ips
- ):
- # XXX(quenting): I'm 95% confident that we could skip setting the
- # device_id to "dummy-device" for appservices, and that the only impact
- # would be some rows which whould not deduplicate in the 'user_ips'
- # table during the transition
- recorded_device_id = (
- "dummy-device"
- if requester.device_id is None and requester.app_service is not None
- else requester.device_id
- )
- await self.store.insert_client_ip(
- user_id=requester.authenticated_entity,
- access_token=access_token,
- ip=ip_addr,
- user_agent=user_agent,
- device_id=recorded_device_id,
- )
-
- # Track also the puppeted user client IP if enabled and the user is puppeting
- if (
- requester.user.to_string() != requester.authenticated_entity
- and self._track_puppeted_user_ips
- ):
- await self.store.insert_client_ip(
- user_id=requester.user.to_string(),
- access_token=access_token,
- ip=ip_addr,
- user_agent=user_agent,
- device_id=requester.device_id,
- )
+ await self._record_request(request, requester)
if requester.is_guest and not allow_guest:
raise AuthError(
diff --git a/synapse/api/auth/msc3861_delegated.py b/synapse/api/auth/msc3861_delegated.py
index 31bb035cc8..7373d81534 100644
--- a/synapse/api/auth/msc3861_delegated.py
+++ b/synapse/api/auth/msc3861_delegated.py
@@ -227,6 +227,10 @@ class MSC3861DelegatedAuth(BaseAuth):
# so that we don't provision the user if they don't have enough permission:
requester = await self.get_user_by_access_token(access_token, allow_expired)
+ # Do not record requests from MAS using the virtual `__oidc_admin` user.
+ if access_token != self._admin_token:
+ await self._record_request(request, requester)
+
if not allow_guest and requester.is_guest:
raise OAuthInsufficientScopeError([SCOPE_MATRIX_API])
diff --git a/synapse/federation/federation_client.py b/synapse/federation/federation_client.py
index 1a7fa175ec..0ba03b0d05 100644
--- a/synapse/federation/federation_client.py
+++ b/synapse/federation/federation_client.py
@@ -21,6 +21,7 @@ from typing import (
TYPE_CHECKING,
AbstractSet,
Awaitable,
+ BinaryIO,
Callable,
Collection,
Container,
@@ -1862,6 +1863,43 @@ class FederationClient(FederationBase):
return filtered_statuses, filtered_failures
+ async def download_media(
+ self,
+ destination: str,
+ media_id: str,
+ output_stream: BinaryIO,
+ max_size: int,
+ max_timeout_ms: int,
+ ) -> Tuple[int, Dict[bytes, List[bytes]]]:
+ try:
+ return await self.transport_layer.download_media_v3(
+ destination,
+ media_id,
+ output_stream=output_stream,
+ max_size=max_size,
+ max_timeout_ms=max_timeout_ms,
+ )
+ except HttpResponseException as e:
+ # If an error is received that is due to an unrecognised endpoint,
+ # fallback to the r0 endpoint. Otherwise, consider it a legitimate error
+ # and raise.
+ if not is_unknown_endpoint(e):
+ raise
+
+ logger.debug(
+ "Couldn't download media %s/%s with the v3 API, falling back to the r0 API",
+ destination,
+ media_id,
+ )
+
+ return await self.transport_layer.download_media_r0(
+ destination,
+ media_id,
+ output_stream=output_stream,
+ max_size=max_size,
+ max_timeout_ms=max_timeout_ms,
+ )
+
@attr.s(frozen=True, slots=True, auto_attribs=True)
class TimestampToEventResponse:
diff --git a/synapse/federation/transport/client.py b/synapse/federation/transport/client.py
index 8b81d8a09a..cbf969ce33 100644
--- a/synapse/federation/transport/client.py
+++ b/synapse/federation/transport/client.py
@@ -18,6 +18,7 @@ import urllib
from typing import (
TYPE_CHECKING,
Any,
+ BinaryIO,
Callable,
Collection,
Dict,
@@ -804,6 +805,58 @@ class TransportLayerClient:
destination=destination, path=path, data={"user_ids": user_ids}
)
+ async def download_media_r0(
+ self,
+ destination: str,
+ media_id: str,
+ output_stream: BinaryIO,
+ max_size: int,
+ max_timeout_ms: int,
+ ) -> Tuple[int, Dict[bytes, List[bytes]]]:
+ path = f"/_matrix/media/r0/download/{destination}/{media_id}"
+
+ return await self.client.get_file(
+ destination,
+ path,
+ output_stream=output_stream,
+ max_size=max_size,
+ args={
+ # tell the remote server to 404 if it doesn't
+ # recognise the server_name, to make sure we don't
+ # end up with a routing loop.
+ "allow_remote": "false",
+ "timeout_ms": str(max_timeout_ms),
+ },
+ )
+
+ async def download_media_v3(
+ self,
+ destination: str,
+ media_id: str,
+ output_stream: BinaryIO,
+ max_size: int,
+ max_timeout_ms: int,
+ ) -> Tuple[int, Dict[bytes, List[bytes]]]:
+ path = f"/_matrix/media/v3/download/{destination}/{media_id}"
+
+ return await self.client.get_file(
+ destination,
+ path,
+ output_stream=output_stream,
+ max_size=max_size,
+ args={
+ # tell the remote server to 404 if it doesn't
+ # recognise the server_name, to make sure we don't
+ # end up with a routing loop.
+ "allow_remote": "false",
+ "timeout_ms": str(max_timeout_ms),
+ # Matrix 1.7 allows for this to redirect to another URL, this should
+ # just be ignored for an old homeserver, so always provide it.
+ "allow_redirect": "true",
+ },
+ follow_redirects=True,
+ )
+
def _create_path(federation_prefix: str, path: str, *args: str) -> str:
"""
diff --git a/synapse/handlers/account_validity.py b/synapse/handlers/account_validity.py
index 6c2a49a3b9..c66bb6364f 100644
--- a/synapse/handlers/account_validity.py
+++ b/synapse/handlers/account_validity.py
@@ -98,6 +98,22 @@ class AccountValidityHandler:
for callback in self._module_api_callbacks.on_user_registration_callbacks:
await callback(user_id)
+ async def on_user_login(
+ self,
+ user_id: str,
+ auth_provider_type: Optional[str],
+ auth_provider_id: Optional[str],
+ ) -> None:
+ """Tell third-party modules about a user logins.
+
+ Args:
+ user_id: The mxID of the user.
+ auth_provider_type: The type of login.
+ auth_provider_id: The ID of the auth provider.
+ """
+ for callback in self._module_api_callbacks.on_user_login_callbacks:
+ await callback(user_id, auth_provider_type, auth_provider_id)
+
@wrap_as_background_process("send_renewals")
async def _send_renewal_emails(self) -> None:
"""Gets the list of users whose account is expiring in the amount of time
diff --git a/synapse/handlers/auth.py b/synapse/handlers/auth.py
index 2b0c505130..89cbaff864 100644
--- a/synapse/handlers/auth.py
+++ b/synapse/handlers/auth.py
@@ -212,6 +212,7 @@ class AuthHandler:
self._password_enabled_for_reauth = hs.config.auth.password_enabled_for_reauth
self._password_localdb_enabled = hs.config.auth.password_localdb_enabled
self._third_party_rules = hs.get_module_api_callbacks().third_party_event_rules
+ self._account_validity_handler = hs.get_account_validity_handler()
# Ratelimiter for failed auth during UIA. Uses same ratelimit config
# as per `rc_login.failed_attempts`.
@@ -1783,6 +1784,13 @@ class AuthHandler:
client_redirect_url, "loginToken", login_token
)
+ # Run post-login module callback handlers
+ await self._account_validity_handler.on_user_login(
+ user_id=registered_user_id,
+ auth_provider_type=LoginType.SSO,
+ auth_provider_id=auth_provider_id,
+ )
+
# if the client is whitelisted, we can redirect straight to it
if client_redirect_url.startswith(self._whitelisted_sso_clients):
request.redirect(redirect_url)
diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py
index 811a41f161..25dd96416a 100644
--- a/synapse/handlers/message.py
+++ b/synapse/handlers/message.py
@@ -693,13 +693,9 @@ class EventCreationHandler:
if require_consent and not is_exempt:
await self.assert_accepted_privacy_policy(requester)
- # Save the access token ID, the device ID and the transaction ID in the event
- # internal metadata. This is useful to determine if we should echo the
- # transaction_id in events.
+ # Save the the device ID and the transaction ID in the event internal metadata.
+ # This is useful to determine if we should echo the transaction_id in events.
# See `synapse.events.utils.EventClientSerializer.serialize_event`
- if requester.access_token_id is not None:
- builder.internal_metadata.token_id = requester.access_token_id
-
if requester.device_id is not None:
builder.internal_metadata.device_id = requester.device_id
diff --git a/synapse/handlers/room.py b/synapse/handlers/room.py
index afd8138caf..f865bed1ec 100644
--- a/synapse/handlers/room.py
+++ b/synapse/handlers/room.py
@@ -698,6 +698,7 @@ class RoomCreationHandler:
config: JsonDict,
ratelimit: bool = True,
creator_join_profile: Optional[JsonDict] = None,
+ ignore_forced_encryption: bool = False,
) -> Tuple[str, Optional[RoomAlias], int]:
"""Creates a new room.
@@ -714,6 +715,8 @@ class RoomCreationHandler:
derived from the user's profile. If set, should contain the
values to go in the body of the 'join' event (typically
`avatar_url` and/or `displayname`.
+ ignore_forced_encryption:
+ Ignore encryption forced by `encryption_enabled_by_default_for_room_type` setting.
Returns:
A 3-tuple containing:
@@ -1015,6 +1018,7 @@ class RoomCreationHandler:
room_alias: Optional[RoomAlias] = None,
power_level_content_override: Optional[JsonDict] = None,
creator_join_profile: Optional[JsonDict] = None,
+ ignore_forced_encryption: bool = False,
) -> Tuple[int, str, int]:
"""Sends the initial events into a new room. Sends the room creation, membership,
and power level events into the room sequentially, then creates and batches up the
@@ -1049,6 +1053,8 @@ class RoomCreationHandler:
creator_join_profile:
Set to override the displayname and avatar for the creating
user in this room.
+ ignore_forced_encryption:
+ Ignore encryption forced by `encryption_enabled_by_default_for_room_type` setting.
Returns:
A tuple containing the stream ID, event ID and depth of the last
@@ -1251,7 +1257,7 @@ class RoomCreationHandler:
)
events_to_send.append((event, context))
- if config["encrypted"]:
+ if config["encrypted"] and not ignore_forced_encryption:
encryption_event, encryption_context = await create_event(
EventTypes.RoomEncryption,
{"algorithm": RoomEncryptionAlgorithms.DEFAULT},
diff --git a/synapse/handlers/room_member.py b/synapse/handlers/room_member.py
index 3296dad4f0..5d3a5fce5f 100644
--- a/synapse/handlers/room_member.py
+++ b/synapse/handlers/room_member.py
@@ -2125,9 +2125,14 @@ class RoomForgetterHandler(StateDeltasHandler):
self.pos = room_max_stream_ordering
if not self._hs.config.room.forget_on_leave:
- # Update the processing position, so that if the server admin turns the
- # feature on at a later date, we don't decide to forget every room that
- # has ever been left in the past.
+ # Update the processing position, so that if the server admin turns
+ # the feature on at a later date, we don't decide to forget every
+ # room that has ever been left in the past.
+ #
+ # We wait for a short time so that we don't "tight" loop just
+ # keeping the table up to date.
+ await self._clock.sleep(0.5)
+
self.pos = self._store.get_room_max_stream_ordering()
await self._store.update_room_forgetter_stream_pos(self.pos)
return
diff --git a/synapse/http/matrixfederationclient.py b/synapse/http/matrixfederationclient.py
index d5013e8e97..cc1db763ae 100644
--- a/synapse/http/matrixfederationclient.py
+++ b/synapse/http/matrixfederationclient.py
@@ -153,12 +153,18 @@ class MatrixFederationRequest:
"""Query arguments.
"""
- txn_id: Optional[str] = None
- """Unique ID for this request (for logging)
+ txn_id: str = attr.ib(init=False)
+ """Unique ID for this request (for logging), this is autogenerated.
"""
- uri: bytes = attr.ib(init=False)
- """The URI of this request
+ uri: bytes = b""
+ """The URI of this request, usually generated from the above information.
+ """
+
+ _generate_uri: bool = True
+ """True to automatically generate the uri field based on the above information.
+
+ Set to False if manually configuring the URI.
"""
def __attrs_post_init__(self) -> None:
@@ -168,22 +174,23 @@ class MatrixFederationRequest:
object.__setattr__(self, "txn_id", txn_id)
- destination_bytes = self.destination.encode("ascii")
- path_bytes = self.path.encode("ascii")
- query_bytes = encode_query_args(self.query)
-
- # The object is frozen so we can pre-compute this.
- uri = urllib.parse.urlunparse(
- (
- b"matrix-federation",
- destination_bytes,
- path_bytes,
- None,
- query_bytes,
- b"",
+ if self._generate_uri:
+ destination_bytes = self.destination.encode("ascii")
+ path_bytes = self.path.encode("ascii")
+ query_bytes = encode_query_args(self.query)
+
+ # The object is frozen so we can pre-compute this.
+ uri = urllib.parse.urlunparse(
+ (
+ b"matrix-federation",
+ destination_bytes,
+ path_bytes,
+ None,
+ query_bytes,
+ b"",
+ )
)
- )
- object.__setattr__(self, "uri", uri)
+ object.__setattr__(self, "uri", uri)
def get_json(self) -> Optional[JsonDict]:
if self.json_callback:
@@ -513,6 +520,7 @@ class MatrixFederationHttpClient:
ignore_backoff: bool = False,
backoff_on_404: bool = False,
backoff_on_all_error_codes: bool = False,
+ follow_redirects: bool = False,
) -> IResponse:
"""
Sends a request to the given server.
@@ -555,6 +563,9 @@ class MatrixFederationHttpClient:
backoff_on_404: Back off if we get a 404
backoff_on_all_error_codes: Back off if we get any error response
+ follow_redirects: True to follow the Location header of 307/308 redirect
+ responses. This does not recurse.
+
Returns:
Resolves with the HTTP response object on success.
@@ -714,6 +725,26 @@ class MatrixFederationHttpClient:
response.code,
response_phrase,
)
+ elif (
+ response.code in (307, 308)
+ and follow_redirects
+ and response.headers.hasHeader("Location")
+ ):
+ # The Location header *might* be relative so resolve it.
+ location = response.headers.getRawHeaders(b"Location")[0]
+ new_uri = urllib.parse.urljoin(request.uri, location)
+
+ return await self._send_request(
+ attr.evolve(request, uri=new_uri, generate_uri=False),
+ retry_on_dns_fail,
+ timeout,
+ long_retries,
+ ignore_backoff,
+ backoff_on_404,
+ backoff_on_all_error_codes,
+ # Do not continue following redirects.
+ follow_redirects=False,
+ )
else:
logger.info(
"{%s} [%s] Got response headers: %d %s",
@@ -1383,6 +1414,7 @@ class MatrixFederationHttpClient:
retry_on_dns_fail: bool = True,
max_size: Optional[int] = None,
ignore_backoff: bool = False,
+ follow_redirects: bool = False,
) -> Tuple[int, Dict[bytes, List[bytes]]]:
"""GETs a file from a given homeserver
Args:
@@ -1392,6 +1424,8 @@ class MatrixFederationHttpClient:
args: Optional dictionary used to create the query string.
ignore_backoff: true to ignore the historical backoff data
and try the request anyway.
+ follow_redirects: True to follow the Location header of 307/308 redirect
+ responses. This does not recurse.
Returns:
Resolves with an (int,dict) tuple of
@@ -1412,7 +1446,10 @@ class MatrixFederationHttpClient:
)
response = await self._send_request(
- request, retry_on_dns_fail=retry_on_dns_fail, ignore_backoff=ignore_backoff
+ request,
+ retry_on_dns_fail=retry_on_dns_fail,
+ ignore_backoff=ignore_backoff,
+ follow_redirects=follow_redirects,
)
headers = dict(response.headers.getAllRawHeaders())
diff --git a/synapse/media/media_repository.py b/synapse/media/media_repository.py
index bf976b9e7c..d62af22adb 100644
--- a/synapse/media/media_repository.py
+++ b/synapse/media/media_repository.py
@@ -77,7 +77,7 @@ class MediaRepository:
def __init__(self, hs: "HomeServer"):
self.hs = hs
self.auth = hs.get_auth()
- self.client = hs.get_federation_http_client()
+ self.client = hs.get_federation_client()
self.clock = hs.get_clock()
self.server_name = hs.hostname
self.store = hs.get_datastores().main
@@ -644,22 +644,13 @@ class MediaRepository:
file_info = FileInfo(server_name=server_name, file_id=file_id)
with self.media_storage.store_into_file(file_info) as (f, fname, finish):
- request_path = "/".join(
- ("/_matrix/media/r0/download", server_name, media_id)
- )
try:
- length, headers = await self.client.get_file(
+ length, headers = await self.client.download_media(
server_name,
- request_path,
+ media_id,
output_stream=f,
max_size=self.max_upload_size,
- args={
- # tell the remote server to 404 if it doesn't
- # recognise the server_name, to make sure we don't
- # end up with a routing loop.
- "allow_remote": "false",
- "timeout_ms": str(max_timeout_ms),
- },
+ max_timeout_ms=max_timeout_ms,
)
except RequestSendFailed as e:
logger.warning(
diff --git a/synapse/module_api/__init__.py b/synapse/module_api/__init__.py
index 812144a128..6ee53511f2 100644
--- a/synapse/module_api/__init__.py
+++ b/synapse/module_api/__init__.py
@@ -80,6 +80,7 @@ from synapse.module_api.callbacks.account_validity_callbacks import (
ON_LEGACY_ADMIN_REQUEST,
ON_LEGACY_RENEW_CALLBACK,
ON_LEGACY_SEND_MAIL_CALLBACK,
+ ON_USER_LOGIN_CALLBACK,
ON_USER_REGISTRATION_CALLBACK,
)
from synapse.module_api.callbacks.spamchecker_callbacks import (
@@ -334,6 +335,7 @@ class ModuleApi:
*,
is_user_expired: Optional[IS_USER_EXPIRED_CALLBACK] = None,
on_user_registration: Optional[ON_USER_REGISTRATION_CALLBACK] = None,
+ on_user_login: Optional[ON_USER_LOGIN_CALLBACK] = None,
on_legacy_send_mail: Optional[ON_LEGACY_SEND_MAIL_CALLBACK] = None,
on_legacy_renew: Optional[ON_LEGACY_RENEW_CALLBACK] = None,
on_legacy_admin_request: Optional[ON_LEGACY_ADMIN_REQUEST] = None,
@@ -345,6 +347,7 @@ class ModuleApi:
return self._callbacks.account_validity.register_callbacks(
is_user_expired=is_user_expired,
on_user_registration=on_user_registration,
+ on_user_login=on_user_login,
on_legacy_send_mail=on_legacy_send_mail,
on_legacy_renew=on_legacy_renew,
on_legacy_admin_request=on_legacy_admin_request,
diff --git a/synapse/module_api/callbacks/account_validity_callbacks.py b/synapse/module_api/callbacks/account_validity_callbacks.py
index 531d0c9ddc..cbfdfbd3d1 100644
--- a/synapse/module_api/callbacks/account_validity_callbacks.py
+++ b/synapse/module_api/callbacks/account_validity_callbacks.py
@@ -22,6 +22,7 @@ logger = logging.getLogger(__name__)
# Types for callbacks to be registered via the module api
IS_USER_EXPIRED_CALLBACK = Callable[[str], Awaitable[Optional[bool]]]
ON_USER_REGISTRATION_CALLBACK = Callable[[str], Awaitable]
+ON_USER_LOGIN_CALLBACK = Callable[[str, Optional[str], Optional[str]], Awaitable]
# Temporary hooks to allow for a transition from `/_matrix/client` endpoints
# to `/_synapse/client/account_validity`. See `register_callbacks` below.
ON_LEGACY_SEND_MAIL_CALLBACK = Callable[[str], Awaitable]
@@ -33,6 +34,7 @@ class AccountValidityModuleApiCallbacks:
def __init__(self) -> None:
self.is_user_expired_callbacks: List[IS_USER_EXPIRED_CALLBACK] = []
self.on_user_registration_callbacks: List[ON_USER_REGISTRATION_CALLBACK] = []
+ self.on_user_login_callbacks: List[ON_USER_LOGIN_CALLBACK] = []
self.on_legacy_send_mail_callback: Optional[ON_LEGACY_SEND_MAIL_CALLBACK] = None
self.on_legacy_renew_callback: Optional[ON_LEGACY_RENEW_CALLBACK] = None
@@ -44,6 +46,7 @@ class AccountValidityModuleApiCallbacks:
self,
is_user_expired: Optional[IS_USER_EXPIRED_CALLBACK] = None,
on_user_registration: Optional[ON_USER_REGISTRATION_CALLBACK] = None,
+ on_user_login: Optional[ON_USER_LOGIN_CALLBACK] = None,
on_legacy_send_mail: Optional[ON_LEGACY_SEND_MAIL_CALLBACK] = None,
on_legacy_renew: Optional[ON_LEGACY_RENEW_CALLBACK] = None,
on_legacy_admin_request: Optional[ON_LEGACY_ADMIN_REQUEST] = None,
@@ -55,6 +58,9 @@ class AccountValidityModuleApiCallbacks:
if on_user_registration is not None:
self.on_user_registration_callbacks.append(on_user_registration)
+ if on_user_login is not None:
+ self.on_user_login_callbacks.append(on_user_login)
+
# The builtin account validity feature exposes 3 endpoints (send_mail, renew, and
# an admin one). As part of moving the feature into a module, we need to change
# the path from /_matrix/client/unstable/account_validity/... to
diff --git a/synapse/replication/tcp/streams/_base.py b/synapse/replication/tcp/streams/_base.py
index 1f6402c2da..7514429d99 100644
--- a/synapse/replication/tcp/streams/_base.py
+++ b/synapse/replication/tcp/streams/_base.py
@@ -621,7 +621,7 @@ class ToDeviceStream(_StreamFromIdGen):
super().__init__(
hs.get_instance_name(),
store.get_all_new_device_messages,
- store._device_inbox_id_gen,
+ store._to_device_msg_id_gen,
)
diff --git a/synapse/rest/admin/users.py b/synapse/rest/admin/users.py
index 9900498fbe..77446970cb 100644
--- a/synapse/rest/admin/users.py
+++ b/synapse/rest/admin/users.py
@@ -630,6 +630,12 @@ class UserRegisterServlet(RestServlet):
if not hmac.compare_digest(want_mac.encode("ascii"), got_mac.encode("ascii")):
raise SynapseError(HTTPStatus.FORBIDDEN, "HMAC incorrect")
+ should_issue_refresh_token = body.get("refresh_token", False)
+ if not isinstance(should_issue_refresh_token, bool):
+ raise SynapseError(
+ HTTPStatus.BAD_REQUEST, "refresh_token must be a boolean"
+ )
+
# Reuse the parts of RegisterRestServlet to reduce code duplication
from synapse.rest.client.register import RegisterRestServlet
@@ -645,7 +651,9 @@ class UserRegisterServlet(RestServlet):
approved=True,
)
- result = await register._create_registration_details(user_id, body)
+ result = await register._create_registration_details(
+ user_id, body, should_issue_refresh_token=should_issue_refresh_token
+ )
return HTTPStatus.OK, result
diff --git a/synapse/rest/client/login.py b/synapse/rest/client/login.py
index 7be327e26f..546f042f87 100644
--- a/synapse/rest/client/login.py
+++ b/synapse/rest/client/login.py
@@ -115,6 +115,7 @@ class LoginRestServlet(RestServlet):
self.registration_handler = hs.get_registration_handler()
self._sso_handler = hs.get_sso_handler()
self._spam_checker = hs.get_module_api_callbacks().spam_checker
+ self._account_validity_handler = hs.get_account_validity_handler()
self._well_known_builder = WellKnownBuilder(hs)
self._address_ratelimiter = Ratelimiter(
@@ -470,6 +471,13 @@ class LoginRestServlet(RestServlet):
device_id=device_id,
)
+ # execute the callback
+ await self._account_validity_handler.on_user_login(
+ user_id,
+ auth_provider_type=login_submission.get("type"),
+ auth_provider_id=auth_provider_id,
+ )
+
if valid_until_ms is not None:
expires_in_ms = valid_until_ms - self.clock.time_msec()
result["expires_in_ms"] = expires_in_ms
diff --git a/synapse/rest/client/versions.py b/synapse/rest/client/versions.py
index 95400ba570..f4d19e0470 100644
--- a/synapse/rest/client/versions.py
+++ b/synapse/rest/client/versions.py
@@ -80,6 +80,9 @@ class VersionsRestServlet(RestServlet):
"v1.4",
"v1.5",
"v1.6",
+ "v1.7",
+ "v1.8",
+ "v1.9",
],
# as per MSC1497:
"unstable_features": {
diff --git a/synapse/server_notices/server_notices_manager.py b/synapse/server_notices/server_notices_manager.py
index 9732dbdb6e..44b999677a 100644
--- a/synapse/server_notices/server_notices_manager.py
+++ b/synapse/server_notices/server_notices_manager.py
@@ -178,6 +178,8 @@ class ServerNoticesManager:
"avatar_url": self._config.servernotices.server_notices_mxid_avatar_url,
}
+ # `ignore_forced_encryption` is used to bypass `encryption_enabled_by_default_for_room_type`
+ # setting if it set, since the server notices will not be encrypted anyway.
room_id, _, _ = await self._room_creation_handler.create_room(
requester,
config={
@@ -187,6 +189,7 @@ class ServerNoticesManager:
},
ratelimit=False,
creator_join_profile=join_profile,
+ ignore_forced_encryption=True,
)
self.maybe_get_notice_room_for_user.invalidate((user_id,))
@@ -226,6 +229,7 @@ class ServerNoticesManager:
target=UserID.from_string(user_id),
room_id=room_id,
action="invite",
+ ratelimit=False,
)
async def _update_notice_user_profile_if_changed(
@@ -268,5 +272,6 @@ class ServerNoticesManager:
target=UserID.from_string(self.server_notices_mxid),
room_id=room_id,
action="join",
+ ratelimit=False,
content={"displayname": display_name, "avatar_url": avatar_url},
)
diff --git a/synapse/storage/databases/main/client_ips.py b/synapse/storage/databases/main/client_ips.py
index 4ea56331c7..4a57af1a0e 100644
--- a/synapse/storage/databases/main/client_ips.py
+++ b/synapse/storage/databases/main/client_ips.py
@@ -465,18 +465,15 @@ class ClientIpWorkerStore(ClientIpBackgroundUpdateStore, MonthlyActiveUsersWorke
#
# This works by finding the max last_seen that is less than the given
# time, but has no more than N rows before it, deleting all rows with
- # a lesser last_seen time. (We COALESCE so that the sub-SELECT always
- # returns exactly one row).
+ # a lesser last_seen time. (We use an `IN` clause to force postgres to
+ # use the index, otherwise it tends to do a seq scan).
sql = """
DELETE FROM user_ips
- WHERE last_seen <= (
- SELECT COALESCE(MAX(last_seen), -1)
- FROM (
- SELECT last_seen FROM user_ips
- WHERE last_seen <= ?
- ORDER BY last_seen ASC
- LIMIT 5000
- ) AS u
+ WHERE last_seen IN (
+ SELECT last_seen FROM user_ips
+ WHERE last_seen <= ?
+ ORDER BY last_seen ASC
+ LIMIT 5000
)
"""
@@ -589,6 +586,27 @@ class ClientIpWorkerStore(ClientIpBackgroundUpdateStore, MonthlyActiveUsersWorke
device_id: Optional[str],
now: Optional[int] = None,
) -> None:
+ """Record that `user_id` used `access_token` from this `ip` address.
+
+ This method does two things.
+
+ 1. It queues up a row to be upserted into the `client_ips` table. These happen
+ periodically; see _update_client_ips_batch.
+ 2. It immediately records this user as having taken action for the purposes of
+ MAU tracking.
+
+ Any DB writes take place on the background tasks worker, falling back to the
+ main process. If we're not that worker, this method emits a replication payload
+ to run this logic on that worker.
+
+ Two caveats to note:
+
+ - We only take action once per LAST_SEEN_GRANULARITY, to avoid spamming the
+ DB with writes.
+ - Requests using the sliding-sync proxy's user agent are excluded, as its
+ requests are not directly driven by end-users. This is a hack and we're not
+ very proud of it.
+ """
# The sync proxy continuously triggers /sync even if the user is not
# present so should be excluded from user_ips entries.
if user_agent == "sync-v3-proxy-":
diff --git a/synapse/storage/databases/main/deviceinbox.py b/synapse/storage/databases/main/deviceinbox.py
index 659631ab65..d0a2028045 100644
--- a/synapse/storage/databases/main/deviceinbox.py
+++ b/synapse/storage/databases/main/deviceinbox.py
@@ -87,25 +87,32 @@ class DeviceInboxWorkerStore(SQLBaseStore):
self._instance_name in hs.config.worker.writers.to_device
)
- self._device_inbox_id_gen: AbstractStreamIdGenerator = (
+ self._to_device_msg_id_gen: AbstractStreamIdGenerator = (
MultiWriterIdGenerator(
db_conn=db_conn,
db=database,
notifier=hs.get_replication_notifier(),
stream_name="to_device",
instance_name=self._instance_name,
- tables=[("device_inbox", "instance_name", "stream_id")],
+ tables=[
+ ("device_inbox", "instance_name", "stream_id"),
+ ("device_federation_outbox", "instance_name", "stream_id"),
+ ],
sequence_name="device_inbox_sequence",
writers=hs.config.worker.writers.to_device,
)
)
else:
self._can_write_to_device = True
- self._device_inbox_id_gen = StreamIdGenerator(
- db_conn, hs.get_replication_notifier(), "device_inbox", "stream_id"
+ self._to_device_msg_id_gen = StreamIdGenerator(
+ db_conn,
+ hs.get_replication_notifier(),
+ "device_inbox",
+ "stream_id",
+ extra_tables=[("device_federation_outbox", "stream_id")],
)
- max_device_inbox_id = self._device_inbox_id_gen.get_current_token()
+ max_device_inbox_id = self._to_device_msg_id_gen.get_current_token()
device_inbox_prefill, min_device_inbox_id = self.db_pool.get_cache_dict(
db_conn,
"device_inbox",
@@ -145,8 +152,8 @@ class DeviceInboxWorkerStore(SQLBaseStore):
) -> None:
if stream_name == ToDeviceStream.NAME:
# If replication is happening than postgres must be being used.
- assert isinstance(self._device_inbox_id_gen, MultiWriterIdGenerator)
- self._device_inbox_id_gen.advance(instance_name, token)
+ assert isinstance(self._to_device_msg_id_gen, MultiWriterIdGenerator)
+ self._to_device_msg_id_gen.advance(instance_name, token)
for row in rows:
if row.entity.startswith("@"):
self._device_inbox_stream_cache.entity_has_changed(
@@ -162,11 +169,11 @@ class DeviceInboxWorkerStore(SQLBaseStore):
self, stream_name: str, instance_name: str, token: int
) -> None:
if stream_name == ToDeviceStream.NAME:
- self._device_inbox_id_gen.advance(instance_name, token)
+ self._to_device_msg_id_gen.advance(instance_name, token)
super().process_replication_position(stream_name, instance_name, token)
def get_to_device_stream_token(self) -> int:
- return self._device_inbox_id_gen.get_current_token()
+ return self._to_device_msg_id_gen.get_current_token()
async def get_messages_for_user_devices(
self,
@@ -801,7 +808,7 @@ class DeviceInboxWorkerStore(SQLBaseStore):
msg.get(EventContentFields.TO_DEVICE_MSGID),
)
- async with self._device_inbox_id_gen.get_next() as stream_id:
+ async with self._to_device_msg_id_gen.get_next() as stream_id:
now_ms = self._clock.time_msec()
await self.db_pool.runInteraction(
"add_messages_to_device_inbox", add_messages_txn, now_ms, stream_id
@@ -813,7 +820,7 @@ class DeviceInboxWorkerStore(SQLBaseStore):
destination, stream_id
)
- return self._device_inbox_id_gen.get_current_token()
+ return self._to_device_msg_id_gen.get_current_token()
async def add_messages_from_remote_to_device_inbox(
self,
@@ -857,7 +864,7 @@ class DeviceInboxWorkerStore(SQLBaseStore):
txn, stream_id, local_messages_by_user_then_device
)
- async with self._device_inbox_id_gen.get_next() as stream_id:
+ async with self._to_device_msg_id_gen.get_next() as stream_id:
now_ms = self._clock.time_msec()
await self.db_pool.runInteraction(
"add_messages_from_remote_to_device_inbox",
diff --git a/synapse/storage/databases/main/event_federation.py b/synapse/storage/databases/main/event_federation.py
index 7e992ca4a2..d5fb6ecc73 100644
--- a/synapse/storage/databases/main/event_federation.py
+++ b/synapse/storage/databases/main/event_federation.py
@@ -301,6 +301,11 @@ class EventFederationWorkerStore(SignatureWorkerStore, EventsWorkerStore, SQLBas
# Add the initial set of chains, excluding the sequence corresponding to
# initial event.
for chain_id, seq_no in event_chains.items():
+ # Check if the initial event is the first item in the chain. If so, then
+ # there is nothing new to add from this chain.
+ if seq_no == 1:
+ continue
+
chains[chain_id] = max(seq_no - 1, chains.get(chain_id, 0))
# Now for each chain we figure out the maximum sequence number reachable
diff --git a/synapse/storage/schema/__init__.py b/synapse/storage/schema/__init__.py
index 03e5a0f55d..f87629b719 100644
--- a/synapse/storage/schema/__init__.py
+++ b/synapse/storage/schema/__init__.py
@@ -129,8 +129,8 @@ Changes in SCHEMA_VERSION = 83
SCHEMA_COMPAT_VERSION = (
- # The `event_txn_id_device_id` must be written to for new events.
- 80
+ # The event_txn_id table and tables from MSC2716 no longer exist.
+ 83
)
"""Limit on how far the synapse codebase can be rolled back without breaking db compat
diff --git a/synapse/storage/schema/common/full_schemas/54/full.sql b/synapse/storage/schema/common/full_schemas/54/full.sql
deleted file mode 100644
index 1005880466..0000000000
--- a/synapse/storage/schema/common/full_schemas/54/full.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-CREATE TABLE background_updates (
- update_name text NOT NULL,
- progress_json text NOT NULL,
- depends_on text,
- CONSTRAINT background_updates_uniqueness UNIQUE (update_name)
-);
diff --git a/synapse/storage/schema/main/full_schemas/16/room_aliases.sql b/synapse/storage/schema/main/delta/83/01_drop_old_tables.sql
index d47da3b12f..4b4dfe7833 100644
--- a/synapse/storage/schema/main/full_schemas/16/room_aliases.sql
+++ b/synapse/storage/schema/main/delta/83/01_drop_old_tables.sql
@@ -1,4 +1,4 @@
-/* Copyright 2014-2016 OpenMarket Ltd
+/* Copyright 2023 The Matrix.org Foundation C.I.C
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,17 +13,12 @@
* limitations under the License.
*/
-CREATE TABLE IF NOT EXISTS room_aliases(
- room_alias TEXT NOT NULL,
- room_id TEXT NOT NULL,
- UNIQUE (room_alias)
-);
+-- Drop the old event transaction ID table, the event_txn_id_device_id table
+-- should be used instead.
+DROP TABLE IF EXISTS event_txn_id;
-CREATE INDEX room_aliases_id ON room_aliases(room_id);
-
-CREATE TABLE IF NOT EXISTS room_alias_servers(
- room_alias TEXT NOT NULL,
- server TEXT NOT NULL
-);
-
-CREATE INDEX room_alias_servers_alias ON room_alias_servers(room_alias);
+-- Drop tables related to MSC2716 since the implementation is being removed
+DROP TABLE IF EXISTS insertion_events;
+DROP TABLE IF EXISTS insertion_event_edges;
+DROP TABLE IF EXISTS insertion_event_extremities;
+DROP TABLE IF EXISTS batch_events;
diff --git a/synapse/storage/schema/main/full_schemas/16/application_services.sql b/synapse/storage/schema/main/full_schemas/16/application_services.sql
deleted file mode 100644
index 883fcd10b2..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/application_services.sql
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2015, 2016 OpenMarket 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.
- */
-
-/* We used to create tables called application_services and
- * application_services_regex, but these are no longer used and are removed in
- * delta 54.
- */
-
-
-CREATE TABLE IF NOT EXISTS application_services_state(
- as_id TEXT PRIMARY KEY,
- state VARCHAR(5),
- last_txn INTEGER
-);
-
-CREATE TABLE IF NOT EXISTS application_services_txns(
- as_id TEXT NOT NULL,
- txn_id INTEGER NOT NULL,
- event_ids TEXT NOT NULL,
- UNIQUE(as_id, txn_id)
-);
-
-CREATE INDEX application_services_txns_id ON application_services_txns (
- as_id
-);
diff --git a/synapse/storage/schema/main/full_schemas/16/event_edges.sql b/synapse/storage/schema/main/full_schemas/16/event_edges.sql
deleted file mode 100644
index 10ce2aa7a0..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/event_edges.sql
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-
-/* We used to create tables called event_destinations and
- * state_forward_extremities, but these are no longer used and are removed in
- * delta 54.
- */
-
-CREATE TABLE IF NOT EXISTS event_forward_extremities(
- event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- UNIQUE (event_id, room_id)
-);
-
-CREATE INDEX ev_extrem_room ON event_forward_extremities(room_id);
-CREATE INDEX ev_extrem_id ON event_forward_extremities(event_id);
-
-
-CREATE TABLE IF NOT EXISTS event_backward_extremities(
- event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- UNIQUE (event_id, room_id)
-);
-
-CREATE INDEX ev_b_extrem_room ON event_backward_extremities(room_id);
-CREATE INDEX ev_b_extrem_id ON event_backward_extremities(event_id);
-
-
-CREATE TABLE IF NOT EXISTS event_edges(
- event_id TEXT NOT NULL,
- prev_event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- is_state BOOL NOT NULL, -- true if this is a prev_state edge rather than a regular
- -- event dag edge.
- UNIQUE (event_id, prev_event_id, room_id, is_state)
-);
-
-CREATE INDEX ev_edges_id ON event_edges(event_id);
-CREATE INDEX ev_edges_prev_id ON event_edges(prev_event_id);
-
-
-CREATE TABLE IF NOT EXISTS room_depth(
- room_id TEXT NOT NULL,
- min_depth INTEGER NOT NULL,
- UNIQUE (room_id)
-);
-
-CREATE INDEX room_depth_room ON room_depth(room_id);
-
-CREATE TABLE IF NOT EXISTS event_auth(
- event_id TEXT NOT NULL,
- auth_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- UNIQUE (event_id, auth_id, room_id)
-);
-
-CREATE INDEX evauth_edges_id ON event_auth(event_id);
-CREATE INDEX evauth_edges_auth_id ON event_auth(auth_id);
diff --git a/synapse/storage/schema/main/full_schemas/16/event_signatures.sql b/synapse/storage/schema/main/full_schemas/16/event_signatures.sql
deleted file mode 100644
index 95826da431..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/event_signatures.sql
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-
- /* We used to create tables called event_content_hashes and event_edge_hashes,
- * but these are no longer used and are removed in delta 54.
- */
-
-CREATE TABLE IF NOT EXISTS event_reference_hashes (
- event_id TEXT,
- algorithm TEXT,
- hash bytea,
- UNIQUE (event_id, algorithm)
-);
-
-CREATE INDEX event_reference_hashes_id ON event_reference_hashes(event_id);
-
-
-CREATE TABLE IF NOT EXISTS event_signatures (
- event_id TEXT,
- signature_name TEXT,
- key_id TEXT,
- signature bytea,
- UNIQUE (event_id, signature_name, key_id)
-);
-
-CREATE INDEX event_signatures_id ON event_signatures(event_id);
diff --git a/synapse/storage/schema/main/full_schemas/16/im.sql b/synapse/storage/schema/main/full_schemas/16/im.sql
deleted file mode 100644
index a1a2aa8e5b..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/im.sql
+++ /dev/null
@@ -1,120 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-
-/* We used to create tables called room_hosts and feedback,
- * but these are no longer used and are removed in delta 54.
- */
-
-CREATE TABLE IF NOT EXISTS events(
- stream_ordering INTEGER PRIMARY KEY,
- topological_ordering BIGINT NOT NULL,
- event_id TEXT NOT NULL,
- type TEXT NOT NULL,
- room_id TEXT NOT NULL,
-
- -- 'content' used to be created NULLable, but as of delta 50 we drop that constraint.
- -- the hack we use to drop the constraint doesn't work for an in-memory sqlite
- -- database, which breaks the sytests. Hence, we no longer make it nullable.
- content TEXT,
-
- unrecognized_keys TEXT,
- processed BOOL NOT NULL,
- outlier BOOL NOT NULL,
- depth BIGINT DEFAULT 0 NOT NULL,
- UNIQUE (event_id)
-);
-
-CREATE INDEX events_stream_ordering ON events (stream_ordering);
-CREATE INDEX events_topological_ordering ON events (topological_ordering);
-CREATE INDEX events_order ON events (topological_ordering, stream_ordering);
-CREATE INDEX events_room_id ON events (room_id);
-CREATE INDEX events_order_room ON events (
- room_id, topological_ordering, stream_ordering
-);
-
-
-CREATE TABLE IF NOT EXISTS event_json(
- event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- internal_metadata TEXT NOT NULL,
- json TEXT NOT NULL,
- UNIQUE (event_id)
-);
-
-CREATE INDEX event_json_room_id ON event_json(room_id);
-
-
-CREATE TABLE IF NOT EXISTS state_events(
- event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- type TEXT NOT NULL,
- state_key TEXT NOT NULL,
- prev_state TEXT,
- UNIQUE (event_id)
-);
-
-CREATE INDEX state_events_room_id ON state_events (room_id);
-CREATE INDEX state_events_type ON state_events (type);
-CREATE INDEX state_events_state_key ON state_events (state_key);
-
-
-CREATE TABLE IF NOT EXISTS current_state_events(
- event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- type TEXT NOT NULL,
- state_key TEXT NOT NULL,
- UNIQUE (event_id),
- UNIQUE (room_id, type, state_key)
-);
-
-CREATE INDEX current_state_events_room_id ON current_state_events (room_id);
-CREATE INDEX current_state_events_type ON current_state_events (type);
-CREATE INDEX current_state_events_state_key ON current_state_events (state_key);
-
-CREATE TABLE IF NOT EXISTS room_memberships(
- event_id TEXT NOT NULL,
- user_id TEXT NOT NULL,
- sender TEXT NOT NULL,
- room_id TEXT NOT NULL,
- membership TEXT NOT NULL,
- UNIQUE (event_id)
-);
-
-CREATE INDEX room_memberships_room_id ON room_memberships (room_id);
-CREATE INDEX room_memberships_user_id ON room_memberships (user_id);
-
-CREATE TABLE IF NOT EXISTS topics(
- event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- topic TEXT NOT NULL,
- UNIQUE (event_id)
-);
-
-CREATE INDEX topics_room_id ON topics(room_id);
-
-CREATE TABLE IF NOT EXISTS room_names(
- event_id TEXT NOT NULL,
- room_id TEXT NOT NULL,
- name TEXT NOT NULL,
- UNIQUE (event_id)
-);
-
-CREATE INDEX room_names_room_id ON room_names(room_id);
-
-CREATE TABLE IF NOT EXISTS rooms(
- room_id TEXT PRIMARY KEY NOT NULL,
- is_public BOOL,
- creator TEXT
-);
diff --git a/synapse/storage/schema/main/full_schemas/16/keys.sql b/synapse/storage/schema/main/full_schemas/16/keys.sql
deleted file mode 100644
index 11cdffdbb3..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/keys.sql
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-
--- we used to create a table called server_tls_certificates, but this is no
--- longer used, and is removed in delta 54.
-
-CREATE TABLE IF NOT EXISTS server_signature_keys(
- server_name TEXT, -- Server name.
- key_id TEXT, -- Key version.
- from_server TEXT, -- Which key server the key was fetched form.
- ts_added_ms BIGINT, -- When the key was added.
- verify_key bytea, -- NACL verification key.
- UNIQUE (server_name, key_id)
-);
diff --git a/synapse/storage/schema/main/full_schemas/16/media_repository.sql b/synapse/storage/schema/main/full_schemas/16/media_repository.sql
deleted file mode 100644
index 8f3759bb2a..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/media_repository.sql
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-
-CREATE TABLE IF NOT EXISTS local_media_repository (
- media_id TEXT, -- The id used to refer to the media.
- media_type TEXT, -- The MIME-type of the media.
- media_length INTEGER, -- Length of the media in bytes.
- created_ts BIGINT, -- When the content was uploaded in ms.
- upload_name TEXT, -- The name the media was uploaded with.
- user_id TEXT, -- The user who uploaded the file.
- UNIQUE (media_id)
-);
-
-CREATE TABLE IF NOT EXISTS local_media_repository_thumbnails (
- media_id TEXT, -- The id used to refer to the media.
- thumbnail_width INTEGER, -- The width of the thumbnail in pixels.
- thumbnail_height INTEGER, -- The height of the thumbnail in pixels.
- thumbnail_type TEXT, -- The MIME-type of the thumbnail.
- thumbnail_method TEXT, -- The method used to make the thumbnail.
- thumbnail_length INTEGER, -- The length of the thumbnail in bytes.
- UNIQUE (
- media_id, thumbnail_width, thumbnail_height, thumbnail_type
- )
-);
-
-CREATE INDEX local_media_repository_thumbnails_media_id
- ON local_media_repository_thumbnails (media_id);
-
-CREATE TABLE IF NOT EXISTS remote_media_cache (
- media_origin TEXT, -- The remote HS the media came from.
- media_id TEXT, -- The id used to refer to the media on that server.
- media_type TEXT, -- The MIME-type of the media.
- created_ts BIGINT, -- When the content was uploaded in ms.
- upload_name TEXT, -- The name the media was uploaded with.
- media_length INTEGER, -- Length of the media in bytes.
- filesystem_id TEXT, -- The name used to store the media on disk.
- UNIQUE (media_origin, media_id)
-);
-
-CREATE TABLE IF NOT EXISTS remote_media_cache_thumbnails (
- media_origin TEXT, -- The remote HS the media came from.
- media_id TEXT, -- The id used to refer to the media.
- thumbnail_width INTEGER, -- The width of the thumbnail in pixels.
- thumbnail_height INTEGER, -- The height of the thumbnail in pixels.
- thumbnail_method TEXT, -- The method used to make the thumbnail
- thumbnail_type TEXT, -- The MIME-type of the thumbnail.
- thumbnail_length INTEGER, -- The length of the thumbnail in bytes.
- filesystem_id TEXT, -- The name used to store the media on disk.
- UNIQUE (
- media_origin, media_id, thumbnail_width, thumbnail_height,
- thumbnail_type
- )
-);
-
-CREATE INDEX remote_media_cache_thumbnails_media_id
- ON remote_media_cache_thumbnails (media_id);
diff --git a/synapse/storage/schema/main/full_schemas/16/presence.sql b/synapse/storage/schema/main/full_schemas/16/presence.sql
deleted file mode 100644
index 01d2d8f833..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/presence.sql
+++ /dev/null
@@ -1,32 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-CREATE TABLE IF NOT EXISTS presence(
- user_id TEXT NOT NULL,
- state VARCHAR(20),
- status_msg TEXT,
- mtime BIGINT, -- miliseconds since last state change
- UNIQUE (user_id)
-);
-
--- For each of /my/ users which possibly-remote users are allowed to see their
--- presence state
-CREATE TABLE IF NOT EXISTS presence_allow_inbound(
- observed_user_id TEXT NOT NULL,
- observer_user_id TEXT NOT NULL, -- a UserID,
- UNIQUE (observed_user_id, observer_user_id)
-);
-
--- We used to create a table called presence_list, but this is no longer used
--- and is removed in delta 54.
\ No newline at end of file
diff --git a/synapse/storage/schema/main/full_schemas/16/profiles.sql b/synapse/storage/schema/main/full_schemas/16/profiles.sql
deleted file mode 100644
index c04f4747d9..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/profiles.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-CREATE TABLE IF NOT EXISTS profiles(
- user_id TEXT NOT NULL,
- displayname TEXT,
- avatar_url TEXT,
- UNIQUE(user_id)
-);
diff --git a/synapse/storage/schema/main/full_schemas/16/push.sql b/synapse/storage/schema/main/full_schemas/16/push.sql
deleted file mode 100644
index e44465cf45..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/push.sql
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright 2015, 2016 OpenMarket 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.
- */
-
-CREATE TABLE IF NOT EXISTS rejections(
- event_id TEXT NOT NULL,
- reason TEXT NOT NULL,
- last_check TEXT NOT NULL,
- UNIQUE (event_id)
-);
-
--- Push notification endpoints that users have configured
-CREATE TABLE IF NOT EXISTS pushers (
- id BIGINT PRIMARY KEY,
- user_name TEXT NOT NULL,
- access_token BIGINT DEFAULT NULL,
- profile_tag VARCHAR(32) NOT NULL,
- kind VARCHAR(8) NOT NULL,
- app_id VARCHAR(64) NOT NULL,
- app_display_name VARCHAR(64) NOT NULL,
- device_display_name VARCHAR(128) NOT NULL,
- pushkey bytea NOT NULL,
- ts BIGINT NOT NULL,
- lang VARCHAR(8),
- data bytea,
- last_token TEXT,
- last_success BIGINT,
- failing_since BIGINT,
- UNIQUE (app_id, pushkey)
-);
-
-CREATE TABLE IF NOT EXISTS push_rules (
- id BIGINT PRIMARY KEY,
- user_name TEXT NOT NULL,
- rule_id TEXT NOT NULL,
- priority_class SMALLINT NOT NULL,
- priority INTEGER NOT NULL DEFAULT 0,
- conditions TEXT NOT NULL,
- actions TEXT NOT NULL,
- UNIQUE(user_name, rule_id)
-);
-
-CREATE INDEX push_rules_user_name on push_rules (user_name);
-
-CREATE TABLE IF NOT EXISTS user_filters(
- user_id TEXT,
- filter_id BIGINT,
- filter_json bytea
-);
-
-CREATE INDEX user_filters_by_user_id_filter_id ON user_filters(
- user_id, filter_id
-);
-
-CREATE TABLE IF NOT EXISTS push_rules_enable (
- id BIGINT PRIMARY KEY,
- user_name TEXT NOT NULL,
- rule_id TEXT NOT NULL,
- enabled SMALLINT,
- UNIQUE(user_name, rule_id)
-);
-
-CREATE INDEX push_rules_enable_user_name on push_rules_enable (user_name);
diff --git a/synapse/storage/schema/main/full_schemas/16/redactions.sql b/synapse/storage/schema/main/full_schemas/16/redactions.sql
deleted file mode 100644
index 318f0d9aa5..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/redactions.sql
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-CREATE TABLE IF NOT EXISTS redactions (
- event_id TEXT NOT NULL,
- redacts TEXT NOT NULL,
- UNIQUE (event_id)
-);
-
-CREATE INDEX redactions_event_id ON redactions (event_id);
-CREATE INDEX redactions_redacts ON redactions (redacts);
diff --git a/synapse/storage/schema/main/full_schemas/16/state.sql b/synapse/storage/schema/main/full_schemas/16/state.sql
deleted file mode 100644
index 96391a8f0e..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/state.sql
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-
-CREATE TABLE IF NOT EXISTS state_groups(
- id BIGINT PRIMARY KEY,
- room_id TEXT NOT NULL,
- event_id TEXT NOT NULL
-);
-
-CREATE TABLE IF NOT EXISTS state_groups_state(
- state_group BIGINT NOT NULL,
- room_id TEXT NOT NULL,
- type TEXT NOT NULL,
- state_key TEXT NOT NULL,
- event_id TEXT NOT NULL
-);
-
-CREATE TABLE IF NOT EXISTS event_to_state_groups(
- event_id TEXT NOT NULL,
- state_group BIGINT NOT NULL,
- UNIQUE (event_id)
-);
-
-CREATE INDEX state_groups_id ON state_groups(id);
-
-CREATE INDEX state_groups_state_id ON state_groups_state(state_group);
-CREATE INDEX state_groups_state_tuple ON state_groups_state(room_id, type, state_key);
-CREATE INDEX event_to_state_groups_id ON event_to_state_groups(event_id);
diff --git a/synapse/storage/schema/main/full_schemas/16/transactions.sql b/synapse/storage/schema/main/full_schemas/16/transactions.sql
deleted file mode 100644
index 17e67bedac..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/transactions.sql
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
--- Stores what transaction ids we have received and what our response was
-CREATE TABLE IF NOT EXISTS received_transactions(
- transaction_id TEXT,
- origin TEXT,
- ts BIGINT,
- response_code INTEGER,
- response_json bytea,
- has_been_referenced smallint default 0, -- Whether thishas been referenced by a prev_tx
- UNIQUE (transaction_id, origin)
-);
-
-CREATE INDEX transactions_have_ref ON received_transactions(origin, has_been_referenced);-- WHERE has_been_referenced = 0;
-
--- For sent transactions only.
-CREATE TABLE IF NOT EXISTS transaction_id_to_pdu(
- transaction_id INTEGER,
- destination TEXT,
- pdu_id TEXT,
- pdu_origin TEXT,
- UNIQUE (transaction_id, destination)
-);
-
-CREATE INDEX transaction_id_to_pdu_dest ON transaction_id_to_pdu(destination);
-
--- To track destination health
-CREATE TABLE IF NOT EXISTS destinations(
- destination TEXT PRIMARY KEY,
- retry_last_ts BIGINT,
- retry_interval INTEGER
-);
diff --git a/synapse/storage/schema/main/full_schemas/16/users.sql b/synapse/storage/schema/main/full_schemas/16/users.sql
deleted file mode 100644
index f013aa8b18..0000000000
--- a/synapse/storage/schema/main/full_schemas/16/users.sql
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright 2014-2016 OpenMarket 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.
- */
-CREATE TABLE IF NOT EXISTS users(
- name TEXT,
- password_hash TEXT,
- creation_ts BIGINT,
- admin SMALLINT DEFAULT 0 NOT NULL,
- UNIQUE(name)
-);
-
-CREATE TABLE IF NOT EXISTS access_tokens(
- id BIGINT PRIMARY KEY,
- user_id TEXT NOT NULL,
- device_id TEXT,
- token TEXT NOT NULL,
- last_used BIGINT,
- UNIQUE(token)
-);
-
-CREATE TABLE IF NOT EXISTS user_ips (
- user_id TEXT NOT NULL,
- access_token TEXT NOT NULL,
- device_id TEXT,
- ip TEXT NOT NULL,
- user_agent TEXT NOT NULL,
- last_seen BIGINT NOT NULL
-);
-
-CREATE INDEX user_ips_user ON user_ips(user_id);
-CREATE INDEX user_ips_user_ip ON user_ips(user_id, access_token, ip);
diff --git a/synapse/storage/schema/main/full_schemas/54/full.sql.postgres b/synapse/storage/schema/main/full_schemas/54/full.sql.postgres
deleted file mode 100644
index 889a9a0ce4..0000000000
--- a/synapse/storage/schema/main/full_schemas/54/full.sql.postgres
+++ /dev/null
@@ -1,1983 +0,0 @@
-
-
-
-
-
-CREATE TABLE access_tokens (
- id bigint NOT NULL,
- user_id text NOT NULL,
- device_id text,
- token text NOT NULL,
- last_used bigint
-);
-
-
-
-CREATE TABLE account_data (
- user_id text NOT NULL,
- account_data_type text NOT NULL,
- stream_id bigint NOT NULL,
- content text NOT NULL
-);
-
-
-
-CREATE TABLE account_data_max_stream_id (
- lock character(1) DEFAULT 'X'::bpchar NOT NULL,
- stream_id bigint NOT NULL,
- CONSTRAINT private_user_data_max_stream_id_lock_check CHECK ((lock = 'X'::bpchar))
-);
-
-
-
-CREATE TABLE account_validity (
- user_id text NOT NULL,
- expiration_ts_ms bigint NOT NULL,
- email_sent boolean NOT NULL,
- renewal_token text
-);
-
-
-
-CREATE TABLE application_services_state (
- as_id text NOT NULL,
- state character varying(5),
- last_txn integer
-);
-
-
-
-CREATE TABLE application_services_txns (
- as_id text NOT NULL,
- txn_id integer NOT NULL,
- event_ids text NOT NULL
-);
-
-
-
-CREATE TABLE appservice_room_list (
- appservice_id text NOT NULL,
- network_id text NOT NULL,
- room_id text NOT NULL
-);
-
-
-
-CREATE TABLE appservice_stream_position (
- lock character(1) DEFAULT 'X'::bpchar NOT NULL,
- stream_ordering bigint,
- CONSTRAINT appservice_stream_position_lock_check CHECK ((lock = 'X'::bpchar))
-);
-
-
-CREATE TABLE blocked_rooms (
- room_id text NOT NULL,
- user_id text NOT NULL
-);
-
-
-
-CREATE TABLE cache_invalidation_stream (
- stream_id bigint,
- cache_func text,
- keys text[],
- invalidation_ts bigint
-);
-
-
-
-CREATE TABLE current_state_delta_stream (
- stream_id bigint NOT NULL,
- room_id text NOT NULL,
- type text NOT NULL,
- state_key text NOT NULL,
- event_id text,
- prev_event_id text
-);
-
-
-
-CREATE TABLE current_state_events (
- event_id text NOT NULL,
- room_id text NOT NULL,
- type text NOT NULL,
- state_key text NOT NULL
-);
-
-
-
-CREATE TABLE deleted_pushers (
- stream_id bigint NOT NULL,
- app_id text NOT NULL,
- pushkey text NOT NULL,
- user_id text NOT NULL
-);
-
-
-
-CREATE TABLE destinations (
- destination text NOT NULL,
- retry_last_ts bigint,
- retry_interval integer
-);
-
-
-
-CREATE TABLE device_federation_inbox (
- origin text NOT NULL,
- message_id text NOT NULL,
- received_ts bigint NOT NULL
-);
-
-
-
-CREATE TABLE device_federation_outbox (
- destination text NOT NULL,
- stream_id bigint NOT NULL,
- queued_ts bigint NOT NULL,
- messages_json text NOT NULL
-);
-
-
-
-CREATE TABLE device_inbox (
- user_id text NOT NULL,
- device_id text NOT NULL,
- stream_id bigint NOT NULL,
- message_json text NOT NULL
-);
-
-
-
-CREATE TABLE device_lists_outbound_last_success (
- destination text NOT NULL,
- user_id text NOT NULL,
- stream_id bigint NOT NULL
-);
-
-
-
-CREATE TABLE device_lists_outbound_pokes (
- destination text NOT NULL,
- stream_id bigint NOT NULL,
- user_id text NOT NULL,
- device_id text NOT NULL,
- sent boolean NOT NULL,
- ts bigint NOT NULL
-);
-
-
-
-CREATE TABLE device_lists_remote_cache (
- user_id text NOT NULL,
- device_id text NOT NULL,
- content text NOT NULL
-);
-
-
-
-CREATE TABLE device_lists_remote_extremeties (
- user_id text NOT NULL,
- stream_id text NOT NULL
-);
-
-
-
-CREATE TABLE device_lists_stream (
- stream_id bigint NOT NULL,
- user_id text NOT NULL,
- device_id text NOT NULL
-);
-
-
-
-CREATE TABLE device_max_stream_id (
- stream_id bigint NOT NULL
-);
-
-
-
-CREATE TABLE devices (
- user_id text NOT NULL,
- device_id text NOT NULL,
- display_name text
-);
-
-
-
-CREATE TABLE e2e_device_keys_json (
- user_id text NOT NULL,
- device_id text NOT NULL,
- ts_added_ms bigint NOT NULL,
- key_json text NOT NULL
-);
-
-
-
-CREATE TABLE e2e_one_time_keys_json (
- user_id text NOT NULL,
- device_id text NOT NULL,
- algorithm text NOT NULL,
- key_id text NOT NULL,
- ts_added_ms bigint NOT NULL,
- key_json text NOT NULL
-);
-
-
-
-CREATE TABLE e2e_room_keys (
- user_id text NOT NULL,
- room_id text NOT NULL,
- session_id text NOT NULL,
- version bigint NOT NULL,
- first_message_index integer,
- forwarded_count integer,
- is_verified boolean,
- session_data text NOT NULL
-);
-
-
-
-CREATE TABLE e2e_room_keys_versions (
- user_id text NOT NULL,
- version bigint NOT NULL,
- algorithm text NOT NULL,
- auth_data text NOT NULL,
- deleted smallint DEFAULT 0 NOT NULL
-);
-
-
-
-CREATE TABLE erased_users (
- user_id text NOT NULL
-);
-
-
-
-CREATE TABLE event_auth (
- event_id text NOT NULL,
- auth_id text NOT NULL,
- room_id text NOT NULL
-);
-
-
-
-CREATE TABLE event_backward_extremities (
- event_id text NOT NULL,
- room_id text NOT NULL
-);
-
-
-
-CREATE TABLE event_edges (
- event_id text NOT NULL,
- prev_event_id text NOT NULL,
- room_id text NOT NULL,
- is_state boolean NOT NULL
-);
-
-
-
-CREATE TABLE event_forward_extremities (
- event_id text NOT NULL,
- room_id text NOT NULL
-);
-
-
-
-CREATE TABLE event_json (
- event_id text NOT NULL,
- room_id text NOT NULL,
- internal_metadata text NOT NULL,
- json text NOT NULL,
- format_version integer
-);
-
-
-
-CREATE TABLE event_push_actions (
- room_id text NOT NULL,
- event_id text NOT NULL,
- user_id text NOT NULL,
- profile_tag character varying(32),
- actions text NOT NULL,
- topological_ordering bigint,
- stream_ordering bigint,
- notif smallint,
- highlight smallint
-);
-
-
-
-CREATE TABLE event_push_actions_staging (
- event_id text NOT NULL,
- user_id text NOT NULL,
- actions text NOT NULL,
- notif smallint NOT NULL,
- highlight smallint NOT NULL
-);
-
-
-
-CREATE TABLE event_push_summary (
- user_id text NOT NULL,
- room_id text NOT NULL,
- notif_count bigint NOT NULL,
- stream_ordering bigint NOT NULL
-);
-
-
-
-CREATE TABLE event_push_summary_stream_ordering (
- lock character(1) DEFAULT 'X'::bpchar NOT NULL,
- stream_ordering bigint NOT NULL,
- CONSTRAINT event_push_summary_stream_ordering_lock_check CHECK ((lock = 'X'::bpchar))
-);
-
-
-
-CREATE TABLE event_reference_hashes (
- event_id text,
- algorithm text,
- hash bytea
-);
-
-
-
-CREATE TABLE event_relations (
- event_id text NOT NULL,
- relates_to_id text NOT NULL,
- relation_type text NOT NULL,
- aggregation_key text
-);
-
-
-
-CREATE TABLE event_reports (
- id bigint NOT NULL,
- received_ts bigint NOT NULL,
- room_id text NOT NULL,
- event_id text NOT NULL,
- user_id text NOT NULL,
- reason text,
- content text
-);
-
-
-
-CREATE TABLE event_search (
- event_id text,
- room_id text,
- sender text,
- key text,
- vector tsvector,
- origin_server_ts bigint,
- stream_ordering bigint
-);
-
-
-
-CREATE TABLE event_to_state_groups (
- event_id text NOT NULL,
- state_group bigint NOT NULL
-);
-
-
-
-CREATE TABLE events (
- stream_ordering integer NOT NULL,
- topological_ordering bigint NOT NULL,
- event_id text NOT NULL,
- type text NOT NULL,
- room_id text NOT NULL,
- content text,
- unrecognized_keys text,
- processed boolean NOT NULL,
- outlier boolean NOT NULL,
- depth bigint DEFAULT 0 NOT NULL,
- origin_server_ts bigint,
- received_ts bigint,
- sender text,
- contains_url boolean
-);
-
-
-
-CREATE TABLE ex_outlier_stream (
- event_stream_ordering bigint NOT NULL,
- event_id text NOT NULL,
- state_group bigint NOT NULL
-);
-
-
-
-CREATE TABLE federation_stream_position (
- type text NOT NULL,
- stream_id integer NOT NULL
-);
-
-
-
-CREATE TABLE group_attestations_remote (
- group_id text NOT NULL,
- user_id text NOT NULL,
- valid_until_ms bigint NOT NULL,
- attestation_json text NOT NULL
-);
-
-
-
-CREATE TABLE group_attestations_renewals (
- group_id text NOT NULL,
- user_id text NOT NULL,
- valid_until_ms bigint NOT NULL
-);
-
-
-
-CREATE TABLE group_invites (
- group_id text NOT NULL,
- user_id text NOT NULL
-);
-
-
-
-CREATE TABLE group_roles (
- group_id text NOT NULL,
- role_id text NOT NULL,
- profile text NOT NULL,
- is_public boolean NOT NULL
-);
-
-
-
-CREATE TABLE group_room_categories (
- group_id text NOT NULL,
- category_id text NOT NULL,
- profile text NOT NULL,
- is_public boolean NOT NULL
-);
-
-
-
-CREATE TABLE group_rooms (
- group_id text NOT NULL,
- room_id text NOT NULL,
- is_public boolean NOT NULL
-);
-
-
-
-CREATE TABLE group_summary_roles (
- group_id text NOT NULL,
- role_id text NOT NULL,
- role_order bigint NOT NULL,
- CONSTRAINT group_summary_roles_role_order_check CHECK ((role_order > 0))
-);
-
-
-
-CREATE TABLE group_summary_room_categories (
- group_id text NOT NULL,
- category_id text NOT NULL,
- cat_order bigint NOT NULL,
- CONSTRAINT group_summary_room_categories_cat_order_check CHECK ((cat_order > 0))
-);
-
-
-
-CREATE TABLE group_summary_rooms (
- group_id text NOT NULL,
- room_id text NOT NULL,
- category_id text NOT NULL,
- room_order bigint NOT NULL,
- is_public boolean NOT NULL,
- CONSTRAINT group_summary_rooms_room_order_check CHECK ((room_order > 0))
-);
-
-
-
-CREATE TABLE group_summary_users (
- group_id text NOT NULL,
- user_id text NOT NULL,
- role_id text NOT NULL,
- user_order bigint NOT NULL,
- is_public boolean NOT NULL
-);
-
-
-
-CREATE TABLE group_users (
- group_id text NOT NULL,
- user_id text NOT NULL,
- is_admin boolean NOT NULL,
- is_public boolean NOT NULL
-);
-
-
-
-CREATE TABLE groups (
- group_id text NOT NULL,
- name text,
- avatar_url text,
- short_description text,
- long_description text,
- is_public boolean NOT NULL,
- join_policy text DEFAULT 'invite'::text NOT NULL
-);
-
-
-
-CREATE TABLE guest_access (
- event_id text NOT NULL,
- room_id text NOT NULL,
- guest_access text NOT NULL
-);
-
-
-
-CREATE TABLE history_visibility (
- event_id text NOT NULL,
- room_id text NOT NULL,
- history_visibility text NOT NULL
-);
-
-
-
-CREATE TABLE local_group_membership (
- group_id text NOT NULL,
- user_id text NOT NULL,
- is_admin boolean NOT NULL,
- membership text NOT NULL,
- is_publicised boolean NOT NULL,
- content text NOT NULL
-);
-
-
-
-CREATE TABLE local_group_updates (
- stream_id bigint NOT NULL,
- group_id text NOT NULL,
- user_id text NOT NULL,
- type text NOT NULL,
- content text NOT NULL
-);
-
-
-
-CREATE TABLE local_invites (
- stream_id bigint NOT NULL,
- inviter text NOT NULL,
- invitee text NOT NULL,
- event_id text NOT NULL,
- room_id text NOT NULL,
- locally_rejected text,
- replaced_by text
-);
-
-
-
-CREATE TABLE local_media_repository (
- media_id text,
- media_type text,
- media_length integer,
- created_ts bigint,
- upload_name text,
- user_id text,
- quarantined_by text,
- url_cache text,
- last_access_ts bigint
-);
-
-
-
-CREATE TABLE local_media_repository_thumbnails (
- media_id text,
- thumbnail_width integer,
- thumbnail_height integer,
- thumbnail_type text,
- thumbnail_method text,
- thumbnail_length integer
-);
-
-
-
-CREATE TABLE local_media_repository_url_cache (
- url text,
- response_code integer,
- etag text,
- expires_ts bigint,
- og text,
- media_id text,
- download_ts bigint
-);
-
-
-
-CREATE TABLE monthly_active_users (
- user_id text NOT NULL,
- "timestamp" bigint NOT NULL
-);
-
-
-
-CREATE TABLE open_id_tokens (
- token text NOT NULL,
- ts_valid_until_ms bigint NOT NULL,
- user_id text NOT NULL
-);
-
-
-
-CREATE TABLE presence (
- user_id text NOT NULL,
- state character varying(20),
- status_msg text,
- mtime bigint
-);
-
-
-
-CREATE TABLE presence_allow_inbound (
- observed_user_id text NOT NULL,
- observer_user_id text NOT NULL
-);
-
-
-
-CREATE TABLE presence_stream (
- stream_id bigint,
- user_id text,
- state text,
- last_active_ts bigint,
- last_federation_update_ts bigint,
- last_user_sync_ts bigint,
- status_msg text,
- currently_active boolean
-);
-
-
-
-CREATE TABLE profiles (
- user_id text NOT NULL,
- displayname text,
- avatar_url text
-);
-
-
-
-CREATE TABLE public_room_list_stream (
- stream_id bigint NOT NULL,
- room_id text NOT NULL,
- visibility boolean NOT NULL,
- appservice_id text,
- network_id text
-);
-
-
-
-CREATE TABLE push_rules (
- id bigint NOT NULL,
- user_name text NOT NULL,
- rule_id text NOT NULL,
- priority_class smallint NOT NULL,
- priority integer DEFAULT 0 NOT NULL,
- conditions text NOT NULL,
- actions text NOT NULL
-);
-
-
-
-CREATE TABLE push_rules_enable (
- id bigint NOT NULL,
- user_name text NOT NULL,
- rule_id text NOT NULL,
- enabled smallint
-);
-
-
-
-CREATE TABLE push_rules_stream (
- stream_id bigint NOT NULL,
- event_stream_ordering bigint NOT NULL,
- user_id text NOT NULL,
- rule_id text NOT NULL,
- op text NOT NULL,
- priority_class smallint,
- priority integer,
- conditions text,
- actions text
-);
-
-
-
-CREATE TABLE pusher_throttle (
- pusher bigint NOT NULL,
- room_id text NOT NULL,
- last_sent_ts bigint,
- throttle_ms bigint
-);
-
-
-
-CREATE TABLE pushers (
- id bigint NOT NULL,
- user_name text NOT NULL,
- access_token bigint,
- profile_tag text NOT NULL,
- kind text NOT NULL,
- app_id text NOT NULL,
- app_display_name text NOT NULL,
- device_display_name text NOT NULL,
- pushkey text NOT NULL,
- ts bigint NOT NULL,
- lang text,
- data text,
- last_stream_ordering integer,
- last_success bigint,
- failing_since bigint
-);
-
-
-
-CREATE TABLE ratelimit_override (
- user_id text NOT NULL,
- messages_per_second bigint,
- burst_count bigint
-);
-
-
-
-CREATE TABLE receipts_graph (
- room_id text NOT NULL,
- receipt_type text NOT NULL,
- user_id text NOT NULL,
- event_ids text NOT NULL,
- data text NOT NULL
-);
-
-
-
-CREATE TABLE receipts_linearized (
- stream_id bigint NOT NULL,
- room_id text NOT NULL,
- receipt_type text NOT NULL,
- user_id text NOT NULL,
- event_id text NOT NULL,
- data text NOT NULL
-);
-
-
-
-CREATE TABLE received_transactions (
- transaction_id text,
- origin text,
- ts bigint,
- response_code integer,
- response_json bytea,
- has_been_referenced smallint DEFAULT 0
-);
-
-
-
-CREATE TABLE redactions (
- event_id text NOT NULL,
- redacts text NOT NULL
-);
-
-
-
-CREATE TABLE rejections (
- event_id text NOT NULL,
- reason text NOT NULL,
- last_check text NOT NULL
-);
-
-
-
-CREATE TABLE remote_media_cache (
- media_origin text,
- media_id text,
- media_type text,
- created_ts bigint,
- upload_name text,
- media_length integer,
- filesystem_id text,
- last_access_ts bigint,
- quarantined_by text
-);
-
-
-
-CREATE TABLE remote_media_cache_thumbnails (
- media_origin text,
- media_id text,
- thumbnail_width integer,
- thumbnail_height integer,
- thumbnail_method text,
- thumbnail_type text,
- thumbnail_length integer,
- filesystem_id text
-);
-
-
-
-CREATE TABLE remote_profile_cache (
- user_id text NOT NULL,
- displayname text,
- avatar_url text,
- last_check bigint NOT NULL
-);
-
-
-
-CREATE TABLE room_account_data (
- user_id text NOT NULL,
- room_id text NOT NULL,
- account_data_type text NOT NULL,
- stream_id bigint NOT NULL,
- content text NOT NULL
-);
-
-
-
-CREATE TABLE room_alias_servers (
- room_alias text NOT NULL,
- server text NOT NULL
-);
-
-
-
-CREATE TABLE room_aliases (
- room_alias text NOT NULL,
- room_id text NOT NULL,
- creator text
-);
-
-
-
-CREATE TABLE room_depth (
- room_id text NOT NULL,
- min_depth integer NOT NULL
-);
-
-
-
-CREATE TABLE room_memberships (
- event_id text NOT NULL,
- user_id text NOT NULL,
- sender text NOT NULL,
- room_id text NOT NULL,
- membership text NOT NULL,
- forgotten integer DEFAULT 0,
- display_name text,
- avatar_url text
-);
-
-
-
-CREATE TABLE room_names (
- event_id text NOT NULL,
- room_id text NOT NULL,
- name text NOT NULL
-);
-
-
-
-CREATE TABLE room_state (
- room_id text NOT NULL,
- join_rules text,
- history_visibility text,
- encryption text,
- name text,
- topic text,
- avatar text,
- canonical_alias text
-);
-
-
-
-CREATE TABLE room_stats (
- room_id text NOT NULL,
- ts bigint NOT NULL,
- bucket_size integer NOT NULL,
- current_state_events integer NOT NULL,
- joined_members integer NOT NULL,
- invited_members integer NOT NULL,
- left_members integer NOT NULL,
- banned_members integer NOT NULL,
- state_events integer NOT NULL
-);
-
-
-
-CREATE TABLE room_stats_earliest_token (
- room_id text NOT NULL,
- token bigint NOT NULL
-);
-
-
-
-CREATE TABLE room_tags (
- user_id text NOT NULL,
- room_id text NOT NULL,
- tag text NOT NULL,
- content text NOT NULL
-);
-
-
-
-CREATE TABLE room_tags_revisions (
- user_id text NOT NULL,
- room_id text NOT NULL,
- stream_id bigint NOT NULL
-);
-
-
-
-CREATE TABLE rooms (
- room_id text NOT NULL,
- is_public boolean,
- creator text
-);
-
-
-
-CREATE TABLE server_keys_json (
- server_name text NOT NULL,
- key_id text NOT NULL,
- from_server text NOT NULL,
- ts_added_ms bigint NOT NULL,
- ts_valid_until_ms bigint NOT NULL,
- key_json bytea NOT NULL
-);
-
-
-
-CREATE TABLE server_signature_keys (
- server_name text,
- key_id text,
- from_server text,
- ts_added_ms bigint,
- verify_key bytea,
- ts_valid_until_ms bigint
-);
-
-
-
-CREATE TABLE state_events (
- event_id text NOT NULL,
- room_id text NOT NULL,
- type text NOT NULL,
- state_key text NOT NULL,
- prev_state text
-);
-
-
-
-CREATE TABLE stats_stream_pos (
- lock character(1) DEFAULT 'X'::bpchar NOT NULL,
- stream_id bigint,
- CONSTRAINT stats_stream_pos_lock_check CHECK ((lock = 'X'::bpchar))
-);
-
-
-
-CREATE TABLE stream_ordering_to_exterm (
- stream_ordering bigint NOT NULL,
- room_id text NOT NULL,
- event_id text NOT NULL
-);
-
-
-
-CREATE TABLE threepid_guest_access_tokens (
- medium text,
- address text,
- guest_access_token text,
- first_inviter text
-);
-
-
-
-CREATE TABLE topics (
- event_id text NOT NULL,
- room_id text NOT NULL,
- topic text NOT NULL
-);
-
-
-
-CREATE TABLE user_daily_visits (
- user_id text NOT NULL,
- device_id text,
- "timestamp" bigint NOT NULL
-);
-
-
-
-CREATE TABLE user_directory (
- user_id text NOT NULL,
- room_id text,
- display_name text,
- avatar_url text
-);
-
-
-
-CREATE TABLE user_directory_search (
- user_id text NOT NULL,
- vector tsvector
-);
-
-
-
-CREATE TABLE user_directory_stream_pos (
- lock character(1) DEFAULT 'X'::bpchar NOT NULL,
- stream_id bigint,
- CONSTRAINT user_directory_stream_pos_lock_check CHECK ((lock = 'X'::bpchar))
-);
-
-
-
-CREATE TABLE user_filters (
- user_id text,
- filter_id bigint,
- filter_json bytea
-);
-
-
-
-CREATE TABLE user_ips (
- user_id text NOT NULL,
- access_token text NOT NULL,
- device_id text,
- ip text NOT NULL,
- user_agent text NOT NULL,
- last_seen bigint NOT NULL
-);
-
-
-
-CREATE TABLE user_stats (
- user_id text NOT NULL,
- ts bigint NOT NULL,
- bucket_size integer NOT NULL,
- public_rooms integer NOT NULL,
- private_rooms integer NOT NULL
-);
-
-
-
-CREATE TABLE user_threepid_id_server (
- user_id text NOT NULL,
- medium text NOT NULL,
- address text NOT NULL,
- id_server text NOT NULL
-);
-
-
-
-CREATE TABLE user_threepids (
- user_id text NOT NULL,
- medium text NOT NULL,
- address text NOT NULL,
- validated_at bigint NOT NULL,
- added_at bigint NOT NULL
-);
-
-
-
-CREATE TABLE users (
- name text,
- password_hash text,
- creation_ts bigint,
- admin smallint DEFAULT 0 NOT NULL,
- upgrade_ts bigint,
- is_guest smallint DEFAULT 0 NOT NULL,
- appservice_id text,
- consent_version text,
- consent_server_notice_sent text,
- user_type text
-);
-
-
-
-CREATE TABLE users_in_public_rooms (
- user_id text NOT NULL,
- room_id text NOT NULL
-);
-
-
-
-CREATE TABLE users_pending_deactivation (
- user_id text NOT NULL
-);
-
-
-
-CREATE TABLE users_who_share_private_rooms (
- user_id text NOT NULL,
- other_user_id text NOT NULL,
- room_id text NOT NULL
-);
-
-
-
-ALTER TABLE ONLY access_tokens
- ADD CONSTRAINT access_tokens_pkey PRIMARY KEY (id);
-
-
-
-ALTER TABLE ONLY access_tokens
- ADD CONSTRAINT access_tokens_token_key UNIQUE (token);
-
-
-
-ALTER TABLE ONLY account_data
- ADD CONSTRAINT account_data_uniqueness UNIQUE (user_id, account_data_type);
-
-
-
-ALTER TABLE ONLY account_validity
- ADD CONSTRAINT account_validity_pkey PRIMARY KEY (user_id);
-
-
-
-ALTER TABLE ONLY application_services_state
- ADD CONSTRAINT application_services_state_pkey PRIMARY KEY (as_id);
-
-
-
-ALTER TABLE ONLY application_services_txns
- ADD CONSTRAINT application_services_txns_as_id_txn_id_key UNIQUE (as_id, txn_id);
-
-
-
-ALTER TABLE ONLY appservice_stream_position
- ADD CONSTRAINT appservice_stream_position_lock_key UNIQUE (lock);
-
-
-
-ALTER TABLE ONLY current_state_events
- ADD CONSTRAINT current_state_events_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY current_state_events
- ADD CONSTRAINT current_state_events_room_id_type_state_key_key UNIQUE (room_id, type, state_key);
-
-
-
-ALTER TABLE ONLY destinations
- ADD CONSTRAINT destinations_pkey PRIMARY KEY (destination);
-
-
-
-ALTER TABLE ONLY devices
- ADD CONSTRAINT device_uniqueness UNIQUE (user_id, device_id);
-
-
-
-ALTER TABLE ONLY e2e_device_keys_json
- ADD CONSTRAINT e2e_device_keys_json_uniqueness UNIQUE (user_id, device_id);
-
-
-
-ALTER TABLE ONLY e2e_one_time_keys_json
- ADD CONSTRAINT e2e_one_time_keys_json_uniqueness UNIQUE (user_id, device_id, algorithm, key_id);
-
-
-
-ALTER TABLE ONLY event_backward_extremities
- ADD CONSTRAINT event_backward_extremities_event_id_room_id_key UNIQUE (event_id, room_id);
-
-
-
-ALTER TABLE ONLY event_edges
- ADD CONSTRAINT event_edges_event_id_prev_event_id_room_id_is_state_key UNIQUE (event_id, prev_event_id, room_id, is_state);
-
-
-
-ALTER TABLE ONLY event_forward_extremities
- ADD CONSTRAINT event_forward_extremities_event_id_room_id_key UNIQUE (event_id, room_id);
-
-
-
-ALTER TABLE ONLY event_push_actions
- ADD CONSTRAINT event_id_user_id_profile_tag_uniqueness UNIQUE (room_id, event_id, user_id, profile_tag);
-
-
-
-ALTER TABLE ONLY event_json
- ADD CONSTRAINT event_json_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY event_push_summary_stream_ordering
- ADD CONSTRAINT event_push_summary_stream_ordering_lock_key UNIQUE (lock);
-
-
-
-ALTER TABLE ONLY event_reference_hashes
- ADD CONSTRAINT event_reference_hashes_event_id_algorithm_key UNIQUE (event_id, algorithm);
-
-
-
-ALTER TABLE ONLY event_reports
- ADD CONSTRAINT event_reports_pkey PRIMARY KEY (id);
-
-
-
-ALTER TABLE ONLY event_to_state_groups
- ADD CONSTRAINT event_to_state_groups_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY events
- ADD CONSTRAINT events_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY events
- ADD CONSTRAINT events_pkey PRIMARY KEY (stream_ordering);
-
-
-
-ALTER TABLE ONLY ex_outlier_stream
- ADD CONSTRAINT ex_outlier_stream_pkey PRIMARY KEY (event_stream_ordering);
-
-
-
-ALTER TABLE ONLY group_roles
- ADD CONSTRAINT group_roles_group_id_role_id_key UNIQUE (group_id, role_id);
-
-
-
-ALTER TABLE ONLY group_room_categories
- ADD CONSTRAINT group_room_categories_group_id_category_id_key UNIQUE (group_id, category_id);
-
-
-
-ALTER TABLE ONLY group_summary_roles
- ADD CONSTRAINT group_summary_roles_group_id_role_id_role_order_key UNIQUE (group_id, role_id, role_order);
-
-
-
-ALTER TABLE ONLY group_summary_room_categories
- ADD CONSTRAINT group_summary_room_categories_group_id_category_id_cat_orde_key UNIQUE (group_id, category_id, cat_order);
-
-
-
-ALTER TABLE ONLY group_summary_rooms
- ADD CONSTRAINT group_summary_rooms_group_id_category_id_room_id_room_order_key UNIQUE (group_id, category_id, room_id, room_order);
-
-
-
-ALTER TABLE ONLY guest_access
- ADD CONSTRAINT guest_access_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY history_visibility
- ADD CONSTRAINT history_visibility_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY local_media_repository
- ADD CONSTRAINT local_media_repository_media_id_key UNIQUE (media_id);
-
-
-
-ALTER TABLE ONLY local_media_repository_thumbnails
- ADD CONSTRAINT local_media_repository_thumbn_media_id_thumbnail_width_thum_key UNIQUE (media_id, thumbnail_width, thumbnail_height, thumbnail_type);
-
-
-
-ALTER TABLE ONLY user_threepids
- ADD CONSTRAINT medium_address UNIQUE (medium, address);
-
-
-
-ALTER TABLE ONLY open_id_tokens
- ADD CONSTRAINT open_id_tokens_pkey PRIMARY KEY (token);
-
-
-
-ALTER TABLE ONLY presence_allow_inbound
- ADD CONSTRAINT presence_allow_inbound_observed_user_id_observer_user_id_key UNIQUE (observed_user_id, observer_user_id);
-
-
-
-ALTER TABLE ONLY presence
- ADD CONSTRAINT presence_user_id_key UNIQUE (user_id);
-
-
-
-ALTER TABLE ONLY account_data_max_stream_id
- ADD CONSTRAINT private_user_data_max_stream_id_lock_key UNIQUE (lock);
-
-
-
-ALTER TABLE ONLY profiles
- ADD CONSTRAINT profiles_user_id_key UNIQUE (user_id);
-
-
-
-ALTER TABLE ONLY push_rules_enable
- ADD CONSTRAINT push_rules_enable_pkey PRIMARY KEY (id);
-
-
-
-ALTER TABLE ONLY push_rules_enable
- ADD CONSTRAINT push_rules_enable_user_name_rule_id_key UNIQUE (user_name, rule_id);
-
-
-
-ALTER TABLE ONLY push_rules
- ADD CONSTRAINT push_rules_pkey PRIMARY KEY (id);
-
-
-
-ALTER TABLE ONLY push_rules
- ADD CONSTRAINT push_rules_user_name_rule_id_key UNIQUE (user_name, rule_id);
-
-
-
-ALTER TABLE ONLY pusher_throttle
- ADD CONSTRAINT pusher_throttle_pkey PRIMARY KEY (pusher, room_id);
-
-
-
-ALTER TABLE ONLY pushers
- ADD CONSTRAINT pushers2_app_id_pushkey_user_name_key UNIQUE (app_id, pushkey, user_name);
-
-
-
-ALTER TABLE ONLY pushers
- ADD CONSTRAINT pushers2_pkey PRIMARY KEY (id);
-
-
-
-ALTER TABLE ONLY receipts_graph
- ADD CONSTRAINT receipts_graph_uniqueness UNIQUE (room_id, receipt_type, user_id);
-
-
-
-ALTER TABLE ONLY receipts_linearized
- ADD CONSTRAINT receipts_linearized_uniqueness UNIQUE (room_id, receipt_type, user_id);
-
-
-
-ALTER TABLE ONLY received_transactions
- ADD CONSTRAINT received_transactions_transaction_id_origin_key UNIQUE (transaction_id, origin);
-
-
-
-ALTER TABLE ONLY redactions
- ADD CONSTRAINT redactions_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY rejections
- ADD CONSTRAINT rejections_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY remote_media_cache
- ADD CONSTRAINT remote_media_cache_media_origin_media_id_key UNIQUE (media_origin, media_id);
-
-
-
-ALTER TABLE ONLY remote_media_cache_thumbnails
- ADD CONSTRAINT remote_media_cache_thumbnails_media_origin_media_id_thumbna_key UNIQUE (media_origin, media_id, thumbnail_width, thumbnail_height, thumbnail_type);
-
-
-
-ALTER TABLE ONLY room_account_data
- ADD CONSTRAINT room_account_data_uniqueness UNIQUE (user_id, room_id, account_data_type);
-
-
-
-ALTER TABLE ONLY room_aliases
- ADD CONSTRAINT room_aliases_room_alias_key UNIQUE (room_alias);
-
-
-
-ALTER TABLE ONLY room_depth
- ADD CONSTRAINT room_depth_room_id_key UNIQUE (room_id);
-
-
-
-ALTER TABLE ONLY room_memberships
- ADD CONSTRAINT room_memberships_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY room_names
- ADD CONSTRAINT room_names_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY room_tags_revisions
- ADD CONSTRAINT room_tag_revisions_uniqueness UNIQUE (user_id, room_id);
-
-
-
-ALTER TABLE ONLY room_tags
- ADD CONSTRAINT room_tag_uniqueness UNIQUE (user_id, room_id, tag);
-
-
-
-ALTER TABLE ONLY rooms
- ADD CONSTRAINT rooms_pkey PRIMARY KEY (room_id);
-
-
-
-ALTER TABLE ONLY server_keys_json
- ADD CONSTRAINT server_keys_json_uniqueness UNIQUE (server_name, key_id, from_server);
-
-
-
-ALTER TABLE ONLY server_signature_keys
- ADD CONSTRAINT server_signature_keys_server_name_key_id_key UNIQUE (server_name, key_id);
-
-
-
-ALTER TABLE ONLY state_events
- ADD CONSTRAINT state_events_event_id_key UNIQUE (event_id);
-
-
-ALTER TABLE ONLY stats_stream_pos
- ADD CONSTRAINT stats_stream_pos_lock_key UNIQUE (lock);
-
-
-
-ALTER TABLE ONLY topics
- ADD CONSTRAINT topics_event_id_key UNIQUE (event_id);
-
-
-
-ALTER TABLE ONLY user_directory_stream_pos
- ADD CONSTRAINT user_directory_stream_pos_lock_key UNIQUE (lock);
-
-
-
-ALTER TABLE ONLY users
- ADD CONSTRAINT users_name_key UNIQUE (name);
-
-
-
-CREATE INDEX access_tokens_device_id ON access_tokens USING btree (user_id, device_id);
-
-
-
-CREATE INDEX account_data_stream_id ON account_data USING btree (user_id, stream_id);
-
-
-
-CREATE INDEX application_services_txns_id ON application_services_txns USING btree (as_id);
-
-
-
-CREATE UNIQUE INDEX appservice_room_list_idx ON appservice_room_list USING btree (appservice_id, network_id, room_id);
-
-
-
-CREATE UNIQUE INDEX blocked_rooms_idx ON blocked_rooms USING btree (room_id);
-
-
-
-CREATE INDEX cache_invalidation_stream_id ON cache_invalidation_stream USING btree (stream_id);
-
-
-
-CREATE INDEX current_state_delta_stream_idx ON current_state_delta_stream USING btree (stream_id);
-
-
-
-CREATE INDEX current_state_events_member_index ON current_state_events USING btree (state_key) WHERE (type = 'm.room.member'::text);
-
-
-
-CREATE INDEX deleted_pushers_stream_id ON deleted_pushers USING btree (stream_id);
-
-
-
-CREATE INDEX device_federation_inbox_sender_id ON device_federation_inbox USING btree (origin, message_id);
-
-
-
-CREATE INDEX device_federation_outbox_destination_id ON device_federation_outbox USING btree (destination, stream_id);
-
-
-
-CREATE INDEX device_federation_outbox_id ON device_federation_outbox USING btree (stream_id);
-
-
-
-CREATE INDEX device_inbox_stream_id_user_id ON device_inbox USING btree (stream_id, user_id);
-
-
-
-CREATE INDEX device_inbox_user_stream_id ON device_inbox USING btree (user_id, device_id, stream_id);
-
-
-
-CREATE INDEX device_lists_outbound_last_success_idx ON device_lists_outbound_last_success USING btree (destination, user_id, stream_id);
-
-
-
-CREATE INDEX device_lists_outbound_pokes_id ON device_lists_outbound_pokes USING btree (destination, stream_id);
-
-
-
-CREATE INDEX device_lists_outbound_pokes_stream ON device_lists_outbound_pokes USING btree (stream_id);
-
-
-
-CREATE INDEX device_lists_outbound_pokes_user ON device_lists_outbound_pokes USING btree (destination, user_id);
-
-
-
-CREATE UNIQUE INDEX device_lists_remote_cache_unique_id ON device_lists_remote_cache USING btree (user_id, device_id);
-
-
-
-CREATE UNIQUE INDEX device_lists_remote_extremeties_unique_idx ON device_lists_remote_extremeties USING btree (user_id);
-
-
-
-CREATE INDEX device_lists_stream_id ON device_lists_stream USING btree (stream_id, user_id);
-
-
-
-CREATE INDEX device_lists_stream_user_id ON device_lists_stream USING btree (user_id, device_id);
-
-
-
-CREATE UNIQUE INDEX e2e_room_keys_idx ON e2e_room_keys USING btree (user_id, room_id, session_id);
-
-
-
-CREATE UNIQUE INDEX e2e_room_keys_versions_idx ON e2e_room_keys_versions USING btree (user_id, version);
-
-
-
-CREATE UNIQUE INDEX erased_users_user ON erased_users USING btree (user_id);
-
-
-
-CREATE INDEX ev_b_extrem_id ON event_backward_extremities USING btree (event_id);
-
-
-
-CREATE INDEX ev_b_extrem_room ON event_backward_extremities USING btree (room_id);
-
-
-
-CREATE INDEX ev_edges_id ON event_edges USING btree (event_id);
-
-
-
-CREATE INDEX ev_edges_prev_id ON event_edges USING btree (prev_event_id);
-
-
-
-CREATE INDEX ev_extrem_id ON event_forward_extremities USING btree (event_id);
-
-
-
-CREATE INDEX ev_extrem_room ON event_forward_extremities USING btree (room_id);
-
-
-
-CREATE INDEX evauth_edges_id ON event_auth USING btree (event_id);
-
-
-
-CREATE INDEX event_contains_url_index ON events USING btree (room_id, topological_ordering, stream_ordering) WHERE ((contains_url = true) AND (outlier = false));
-
-
-
-CREATE INDEX event_json_room_id ON event_json USING btree (room_id);
-
-
-
-CREATE INDEX event_push_actions_highlights_index ON event_push_actions USING btree (user_id, room_id, topological_ordering, stream_ordering) WHERE (highlight = 1);
-
-
-
-CREATE INDEX event_push_actions_rm_tokens ON event_push_actions USING btree (user_id, room_id, topological_ordering, stream_ordering);
-
-
-
-CREATE INDEX event_push_actions_room_id_user_id ON event_push_actions USING btree (room_id, user_id);
-
-
-
-CREATE INDEX event_push_actions_staging_id ON event_push_actions_staging USING btree (event_id);
-
-
-
-CREATE INDEX event_push_actions_stream_ordering ON event_push_actions USING btree (stream_ordering, user_id);
-
-
-
-CREATE INDEX event_push_actions_u_highlight ON event_push_actions USING btree (user_id, stream_ordering);
-
-
-
-CREATE INDEX event_push_summary_user_rm ON event_push_summary USING btree (user_id, room_id);
-
-
-
-CREATE INDEX event_reference_hashes_id ON event_reference_hashes USING btree (event_id);
-
-
-
-CREATE UNIQUE INDEX event_relations_id ON event_relations USING btree (event_id);
-
-
-
-CREATE INDEX event_relations_relates ON event_relations USING btree (relates_to_id, relation_type, aggregation_key);
-
-
-
-CREATE INDEX event_search_ev_ridx ON event_search USING btree (room_id);
-
-
-
-CREATE UNIQUE INDEX event_search_event_id_idx ON event_search USING btree (event_id);
-
-
-
-CREATE INDEX event_search_fts_idx ON event_search USING gin (vector);
-
-
-
-CREATE INDEX event_to_state_groups_sg_index ON event_to_state_groups USING btree (state_group);
-
-
-
-CREATE INDEX events_order_room ON events USING btree (room_id, topological_ordering, stream_ordering);
-
-
-
-CREATE INDEX events_room_stream ON events USING btree (room_id, stream_ordering);
-
-
-
-CREATE INDEX events_ts ON events USING btree (origin_server_ts, stream_ordering);
-
-
-
-CREATE INDEX group_attestations_remote_g_idx ON group_attestations_remote USING btree (group_id, user_id);
-
-
-
-CREATE INDEX group_attestations_remote_u_idx ON group_attestations_remote USING btree (user_id);
-
-
-
-CREATE INDEX group_attestations_remote_v_idx ON group_attestations_remote USING btree (valid_until_ms);
-
-
-
-CREATE INDEX group_attestations_renewals_g_idx ON group_attestations_renewals USING btree (group_id, user_id);
-
-
-
-CREATE INDEX group_attestations_renewals_u_idx ON group_attestations_renewals USING btree (user_id);
-
-
-
-CREATE INDEX group_attestations_renewals_v_idx ON group_attestations_renewals USING btree (valid_until_ms);
-
-
-
-CREATE UNIQUE INDEX group_invites_g_idx ON group_invites USING btree (group_id, user_id);
-
-
-
-CREATE INDEX group_invites_u_idx ON group_invites USING btree (user_id);
-
-
-
-CREATE UNIQUE INDEX group_rooms_g_idx ON group_rooms USING btree (group_id, room_id);
-
-
-
-CREATE INDEX group_rooms_r_idx ON group_rooms USING btree (room_id);
-
-
-
-CREATE UNIQUE INDEX group_summary_rooms_g_idx ON group_summary_rooms USING btree (group_id, room_id, category_id);
-
-
-
-CREATE INDEX group_summary_users_g_idx ON group_summary_users USING btree (group_id);
-
-
-
-CREATE UNIQUE INDEX group_users_g_idx ON group_users USING btree (group_id, user_id);
-
-
-
-CREATE INDEX group_users_u_idx ON group_users USING btree (user_id);
-
-
-
-CREATE UNIQUE INDEX groups_idx ON groups USING btree (group_id);
-
-
-
-CREATE INDEX local_group_membership_g_idx ON local_group_membership USING btree (group_id);
-
-
-
-CREATE INDEX local_group_membership_u_idx ON local_group_membership USING btree (user_id, group_id);
-
-
-
-CREATE INDEX local_invites_for_user_idx ON local_invites USING btree (invitee, locally_rejected, replaced_by, room_id);
-
-
-
-CREATE INDEX local_invites_id ON local_invites USING btree (stream_id);
-
-
-
-CREATE INDEX local_media_repository_thumbnails_media_id ON local_media_repository_thumbnails USING btree (media_id);
-
-
-
-CREATE INDEX local_media_repository_url_cache_by_url_download_ts ON local_media_repository_url_cache USING btree (url, download_ts);
-
-
-
-CREATE INDEX local_media_repository_url_cache_expires_idx ON local_media_repository_url_cache USING btree (expires_ts);
-
-
-
-CREATE INDEX local_media_repository_url_cache_media_idx ON local_media_repository_url_cache USING btree (media_id);
-
-
-
-CREATE INDEX local_media_repository_url_idx ON local_media_repository USING btree (created_ts) WHERE (url_cache IS NOT NULL);
-
-
-
-CREATE INDEX monthly_active_users_time_stamp ON monthly_active_users USING btree ("timestamp");
-
-
-
-CREATE UNIQUE INDEX monthly_active_users_users ON monthly_active_users USING btree (user_id);
-
-
-
-CREATE INDEX open_id_tokens_ts_valid_until_ms ON open_id_tokens USING btree (ts_valid_until_ms);
-
-
-
-CREATE INDEX presence_stream_id ON presence_stream USING btree (stream_id, user_id);
-
-
-
-CREATE INDEX presence_stream_user_id ON presence_stream USING btree (user_id);
-
-
-
-CREATE INDEX public_room_index ON rooms USING btree (is_public);
-
-
-
-CREATE INDEX public_room_list_stream_idx ON public_room_list_stream USING btree (stream_id);
-
-
-
-CREATE INDEX public_room_list_stream_rm_idx ON public_room_list_stream USING btree (room_id, stream_id);
-
-
-
-CREATE INDEX push_rules_enable_user_name ON push_rules_enable USING btree (user_name);
-
-
-
-CREATE INDEX push_rules_stream_id ON push_rules_stream USING btree (stream_id);
-
-
-
-CREATE INDEX push_rules_stream_user_stream_id ON push_rules_stream USING btree (user_id, stream_id);
-
-
-
-CREATE INDEX push_rules_user_name ON push_rules USING btree (user_name);
-
-
-
-CREATE UNIQUE INDEX ratelimit_override_idx ON ratelimit_override USING btree (user_id);
-
-
-
-CREATE INDEX receipts_linearized_id ON receipts_linearized USING btree (stream_id);
-
-
-
-CREATE INDEX receipts_linearized_room_stream ON receipts_linearized USING btree (room_id, stream_id);
-
-
-
-CREATE INDEX receipts_linearized_user ON receipts_linearized USING btree (user_id);
-
-
-
-CREATE INDEX received_transactions_ts ON received_transactions USING btree (ts);
-
-
-
-CREATE INDEX redactions_redacts ON redactions USING btree (redacts);
-
-
-
-CREATE INDEX remote_profile_cache_time ON remote_profile_cache USING btree (last_check);
-
-
-
-CREATE UNIQUE INDEX remote_profile_cache_user_id ON remote_profile_cache USING btree (user_id);
-
-
-
-CREATE INDEX room_account_data_stream_id ON room_account_data USING btree (user_id, stream_id);
-
-
-
-CREATE INDEX room_alias_servers_alias ON room_alias_servers USING btree (room_alias);
-
-
-
-CREATE INDEX room_aliases_id ON room_aliases USING btree (room_id);
-
-
-
-CREATE INDEX room_depth_room ON room_depth USING btree (room_id);
-
-
-
-CREATE INDEX room_memberships_room_id ON room_memberships USING btree (room_id);
-
-
-
-CREATE INDEX room_memberships_user_id ON room_memberships USING btree (user_id);
-
-
-
-CREATE INDEX room_names_room_id ON room_names USING btree (room_id);
-
-
-
-CREATE UNIQUE INDEX room_state_room ON room_state USING btree (room_id);
-
-
-
-CREATE UNIQUE INDEX room_stats_earliest_token_idx ON room_stats_earliest_token USING btree (room_id);
-
-
-
-CREATE UNIQUE INDEX room_stats_room_ts ON room_stats USING btree (room_id, ts);
-
-
-
-CREATE INDEX stream_ordering_to_exterm_idx ON stream_ordering_to_exterm USING btree (stream_ordering);
-
-
-
-CREATE INDEX stream_ordering_to_exterm_rm_idx ON stream_ordering_to_exterm USING btree (room_id, stream_ordering);
-
-
-
-CREATE UNIQUE INDEX threepid_guest_access_tokens_index ON threepid_guest_access_tokens USING btree (medium, address);
-
-
-
-CREATE INDEX topics_room_id ON topics USING btree (room_id);
-
-
-
-CREATE INDEX user_daily_visits_ts_idx ON user_daily_visits USING btree ("timestamp");
-
-
-
-CREATE INDEX user_daily_visits_uts_idx ON user_daily_visits USING btree (user_id, "timestamp");
-
-
-
-CREATE INDEX user_directory_room_idx ON user_directory USING btree (room_id);
-
-
-
-CREATE INDEX user_directory_search_fts_idx ON user_directory_search USING gin (vector);
-
-
-
-CREATE UNIQUE INDEX user_directory_search_user_idx ON user_directory_search USING btree (user_id);
-
-
-
-CREATE UNIQUE INDEX user_directory_user_idx ON user_directory USING btree (user_id);
-
-
-
-CREATE INDEX user_filters_by_user_id_filter_id ON user_filters USING btree (user_id, filter_id);
-
-
-
-CREATE INDEX user_ips_device_id ON user_ips USING btree (user_id, device_id, last_seen);
-
-
-
-CREATE INDEX user_ips_last_seen ON user_ips USING btree (user_id, last_seen);
-
-
-
-CREATE INDEX user_ips_last_seen_only ON user_ips USING btree (last_seen);
-
-
-
-CREATE UNIQUE INDEX user_ips_user_token_ip_unique_index ON user_ips USING btree (user_id, access_token, ip);
-
-
-
-CREATE UNIQUE INDEX user_stats_user_ts ON user_stats USING btree (user_id, ts);
-
-
-
-CREATE UNIQUE INDEX user_threepid_id_server_idx ON user_threepid_id_server USING btree (user_id, medium, address, id_server);
-
-
-
-CREATE INDEX user_threepids_medium_address ON user_threepids USING btree (medium, address);
-
-
-
-CREATE INDEX user_threepids_user_id ON user_threepids USING btree (user_id);
-
-
-
-CREATE INDEX users_creation_ts ON users USING btree (creation_ts);
-
-
-
-CREATE UNIQUE INDEX users_in_public_rooms_u_idx ON users_in_public_rooms USING btree (user_id, room_id);
-
-
-
-CREATE INDEX users_who_share_private_rooms_o_idx ON users_who_share_private_rooms USING btree (other_user_id);
-
-
-
-CREATE INDEX users_who_share_private_rooms_r_idx ON users_who_share_private_rooms USING btree (room_id);
-
-
-
-CREATE UNIQUE INDEX users_who_share_private_rooms_u_idx ON users_who_share_private_rooms USING btree (user_id, other_user_id, room_id);
diff --git a/synapse/storage/schema/main/full_schemas/54/full.sql.sqlite b/synapse/storage/schema/main/full_schemas/54/full.sql.sqlite
deleted file mode 100644
index 308124e531..0000000000
--- a/synapse/storage/schema/main/full_schemas/54/full.sql.sqlite
+++ /dev/null
@@ -1,243 +0,0 @@
-CREATE TABLE application_services_state( as_id TEXT PRIMARY KEY, state VARCHAR(5), last_txn INTEGER );
-CREATE TABLE application_services_txns( as_id TEXT NOT NULL, txn_id INTEGER NOT NULL, event_ids TEXT NOT NULL, UNIQUE(as_id, txn_id) );
-CREATE INDEX application_services_txns_id ON application_services_txns ( as_id );
-CREATE TABLE presence( user_id TEXT NOT NULL, state VARCHAR(20), status_msg TEXT, mtime BIGINT, UNIQUE (user_id) );
-CREATE TABLE presence_allow_inbound( observed_user_id TEXT NOT NULL, observer_user_id TEXT NOT NULL, UNIQUE (observed_user_id, observer_user_id) );
-CREATE TABLE users( name TEXT, password_hash TEXT, creation_ts BIGINT, admin SMALLINT DEFAULT 0 NOT NULL, upgrade_ts BIGINT, is_guest SMALLINT DEFAULT 0 NOT NULL, appservice_id TEXT, consent_version TEXT, consent_server_notice_sent TEXT, user_type TEXT DEFAULT NULL, UNIQUE(name) );
-CREATE TABLE access_tokens( id BIGINT PRIMARY KEY, user_id TEXT NOT NULL, device_id TEXT, token TEXT NOT NULL, last_used BIGINT, UNIQUE(token) );
-CREATE TABLE user_ips ( user_id TEXT NOT NULL, access_token TEXT NOT NULL, device_id TEXT, ip TEXT NOT NULL, user_agent TEXT NOT NULL, last_seen BIGINT NOT NULL );
-CREATE TABLE profiles( user_id TEXT NOT NULL, displayname TEXT, avatar_url TEXT, UNIQUE(user_id) );
-CREATE TABLE received_transactions( transaction_id TEXT, origin TEXT, ts BIGINT, response_code INTEGER, response_json bytea, has_been_referenced smallint default 0, UNIQUE (transaction_id, origin) );
-CREATE TABLE destinations( destination TEXT PRIMARY KEY, retry_last_ts BIGINT, retry_interval INTEGER );
-CREATE TABLE events( stream_ordering INTEGER PRIMARY KEY, topological_ordering BIGINT NOT NULL, event_id TEXT NOT NULL, type TEXT NOT NULL, room_id TEXT NOT NULL, content TEXT, unrecognized_keys TEXT, processed BOOL NOT NULL, outlier BOOL NOT NULL, depth BIGINT DEFAULT 0 NOT NULL, origin_server_ts BIGINT, received_ts BIGINT, sender TEXT, contains_url BOOLEAN, UNIQUE (event_id) );
-CREATE INDEX events_order_room ON events ( room_id, topological_ordering, stream_ordering );
-CREATE TABLE event_json( event_id TEXT NOT NULL, room_id TEXT NOT NULL, internal_metadata TEXT NOT NULL, json TEXT NOT NULL, format_version INTEGER, UNIQUE (event_id) );
-CREATE INDEX event_json_room_id ON event_json(room_id);
-CREATE TABLE state_events( event_id TEXT NOT NULL, room_id TEXT NOT NULL, type TEXT NOT NULL, state_key TEXT NOT NULL, prev_state TEXT, UNIQUE (event_id) );
-CREATE TABLE current_state_events( event_id TEXT NOT NULL, room_id TEXT NOT NULL, type TEXT NOT NULL, state_key TEXT NOT NULL, UNIQUE (event_id), UNIQUE (room_id, type, state_key) );
-CREATE TABLE room_memberships( event_id TEXT NOT NULL, user_id TEXT NOT NULL, sender TEXT NOT NULL, room_id TEXT NOT NULL, membership TEXT NOT NULL, forgotten INTEGER DEFAULT 0, display_name TEXT, avatar_url TEXT, UNIQUE (event_id) );
-CREATE INDEX room_memberships_room_id ON room_memberships (room_id);
-CREATE INDEX room_memberships_user_id ON room_memberships (user_id);
-CREATE TABLE topics( event_id TEXT NOT NULL, room_id TEXT NOT NULL, topic TEXT NOT NULL, UNIQUE (event_id) );
-CREATE INDEX topics_room_id ON topics(room_id);
-CREATE TABLE room_names( event_id TEXT NOT NULL, room_id TEXT NOT NULL, name TEXT NOT NULL, UNIQUE (event_id) );
-CREATE INDEX room_names_room_id ON room_names(room_id);
-CREATE TABLE rooms( room_id TEXT PRIMARY KEY NOT NULL, is_public BOOL, creator TEXT );
-CREATE TABLE server_signature_keys( server_name TEXT, key_id TEXT, from_server TEXT, ts_added_ms BIGINT, verify_key bytea, ts_valid_until_ms BIGINT, UNIQUE (server_name, key_id) );
-CREATE TABLE rejections( event_id TEXT NOT NULL, reason TEXT NOT NULL, last_check TEXT NOT NULL, UNIQUE (event_id) );
-CREATE TABLE push_rules ( id BIGINT PRIMARY KEY, user_name TEXT NOT NULL, rule_id TEXT NOT NULL, priority_class SMALLINT NOT NULL, priority INTEGER NOT NULL DEFAULT 0, conditions TEXT NOT NULL, actions TEXT NOT NULL, UNIQUE(user_name, rule_id) );
-CREATE INDEX push_rules_user_name on push_rules (user_name);
-CREATE TABLE user_filters( user_id TEXT, filter_id BIGINT, filter_json bytea );
-CREATE INDEX user_filters_by_user_id_filter_id ON user_filters( user_id, filter_id );
-CREATE TABLE push_rules_enable ( id BIGINT PRIMARY KEY, user_name TEXT NOT NULL, rule_id TEXT NOT NULL, enabled SMALLINT, UNIQUE(user_name, rule_id) );
-CREATE INDEX push_rules_enable_user_name on push_rules_enable (user_name);
-CREATE TABLE event_forward_extremities( event_id TEXT NOT NULL, room_id TEXT NOT NULL, UNIQUE (event_id, room_id) );
-CREATE INDEX ev_extrem_room ON event_forward_extremities(room_id);
-CREATE INDEX ev_extrem_id ON event_forward_extremities(event_id);
-CREATE TABLE event_backward_extremities( event_id TEXT NOT NULL, room_id TEXT NOT NULL, UNIQUE (event_id, room_id) );
-CREATE INDEX ev_b_extrem_room ON event_backward_extremities(room_id);
-CREATE INDEX ev_b_extrem_id ON event_backward_extremities(event_id);
-CREATE TABLE event_edges( event_id TEXT NOT NULL, prev_event_id TEXT NOT NULL, room_id TEXT NOT NULL, is_state BOOL NOT NULL, UNIQUE (event_id, prev_event_id, room_id, is_state) );
-CREATE INDEX ev_edges_id ON event_edges(event_id);
-CREATE INDEX ev_edges_prev_id ON event_edges(prev_event_id);
-CREATE TABLE room_depth( room_id TEXT NOT NULL, min_depth INTEGER NOT NULL, UNIQUE (room_id) );
-CREATE INDEX room_depth_room ON room_depth(room_id);
-CREATE TABLE event_to_state_groups( event_id TEXT NOT NULL, state_group BIGINT NOT NULL, UNIQUE (event_id) );
-CREATE TABLE local_media_repository ( media_id TEXT, media_type TEXT, media_length INTEGER, created_ts BIGINT, upload_name TEXT, user_id TEXT, quarantined_by TEXT, url_cache TEXT, last_access_ts BIGINT, UNIQUE (media_id) );
-CREATE TABLE local_media_repository_thumbnails ( media_id TEXT, thumbnail_width INTEGER, thumbnail_height INTEGER, thumbnail_type TEXT, thumbnail_method TEXT, thumbnail_length INTEGER, UNIQUE ( media_id, thumbnail_width, thumbnail_height, thumbnail_type ) );
-CREATE INDEX local_media_repository_thumbnails_media_id ON local_media_repository_thumbnails (media_id);
-CREATE TABLE remote_media_cache ( media_origin TEXT, media_id TEXT, media_type TEXT, created_ts BIGINT, upload_name TEXT, media_length INTEGER, filesystem_id TEXT, last_access_ts BIGINT, quarantined_by TEXT, UNIQUE (media_origin, media_id) );
-CREATE TABLE remote_media_cache_thumbnails ( media_origin TEXT, media_id TEXT, thumbnail_width INTEGER, thumbnail_height INTEGER, thumbnail_method TEXT, thumbnail_type TEXT, thumbnail_length INTEGER, filesystem_id TEXT, UNIQUE ( media_origin, media_id, thumbnail_width, thumbnail_height, thumbnail_type ) );
-CREATE TABLE redactions ( event_id TEXT NOT NULL, redacts TEXT NOT NULL, UNIQUE (event_id) );
-CREATE INDEX redactions_redacts ON redactions (redacts);
-CREATE TABLE room_aliases( room_alias TEXT NOT NULL, room_id TEXT NOT NULL, creator TEXT, UNIQUE (room_alias) );
-CREATE INDEX room_aliases_id ON room_aliases(room_id);
-CREATE TABLE room_alias_servers( room_alias TEXT NOT NULL, server TEXT NOT NULL );
-CREATE INDEX room_alias_servers_alias ON room_alias_servers(room_alias);
-CREATE TABLE event_reference_hashes ( event_id TEXT, algorithm TEXT, hash bytea, UNIQUE (event_id, algorithm) );
-CREATE INDEX event_reference_hashes_id ON event_reference_hashes(event_id);
-CREATE TABLE IF NOT EXISTS "server_keys_json" ( server_name TEXT NOT NULL, key_id TEXT NOT NULL, from_server TEXT NOT NULL, ts_added_ms BIGINT NOT NULL, ts_valid_until_ms BIGINT NOT NULL, key_json bytea NOT NULL, CONSTRAINT server_keys_json_uniqueness UNIQUE (server_name, key_id, from_server) );
-CREATE TABLE e2e_device_keys_json ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, ts_added_ms BIGINT NOT NULL, key_json TEXT NOT NULL, CONSTRAINT e2e_device_keys_json_uniqueness UNIQUE (user_id, device_id) );
-CREATE TABLE e2e_one_time_keys_json ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, algorithm TEXT NOT NULL, key_id TEXT NOT NULL, ts_added_ms BIGINT NOT NULL, key_json TEXT NOT NULL, CONSTRAINT e2e_one_time_keys_json_uniqueness UNIQUE (user_id, device_id, algorithm, key_id) );
-CREATE TABLE receipts_graph( room_id TEXT NOT NULL, receipt_type TEXT NOT NULL, user_id TEXT NOT NULL, event_ids TEXT NOT NULL, data TEXT NOT NULL, CONSTRAINT receipts_graph_uniqueness UNIQUE (room_id, receipt_type, user_id) );
-CREATE TABLE receipts_linearized ( stream_id BIGINT NOT NULL, room_id TEXT NOT NULL, receipt_type TEXT NOT NULL, user_id TEXT NOT NULL, event_id TEXT NOT NULL, data TEXT NOT NULL, CONSTRAINT receipts_linearized_uniqueness UNIQUE (room_id, receipt_type, user_id) );
-CREATE INDEX receipts_linearized_id ON receipts_linearized( stream_id );
-CREATE INDEX receipts_linearized_room_stream ON receipts_linearized( room_id, stream_id );
-CREATE TABLE IF NOT EXISTS "user_threepids" ( user_id TEXT NOT NULL, medium TEXT NOT NULL, address TEXT NOT NULL, validated_at BIGINT NOT NULL, added_at BIGINT NOT NULL, CONSTRAINT medium_address UNIQUE (medium, address) );
-CREATE INDEX user_threepids_user_id ON user_threepids(user_id);
-CREATE VIRTUAL TABLE event_search USING fts4 ( event_id, room_id, sender, key, value )
-/* event_search(event_id,room_id,sender,"key",value) */;
-CREATE TABLE guest_access( event_id TEXT NOT NULL, room_id TEXT NOT NULL, guest_access TEXT NOT NULL, UNIQUE (event_id) );
-CREATE TABLE history_visibility( event_id TEXT NOT NULL, room_id TEXT NOT NULL, history_visibility TEXT NOT NULL, UNIQUE (event_id) );
-CREATE TABLE room_tags( user_id TEXT NOT NULL, room_id TEXT NOT NULL, tag TEXT NOT NULL, content TEXT NOT NULL, CONSTRAINT room_tag_uniqueness UNIQUE (user_id, room_id, tag) );
-CREATE TABLE room_tags_revisions ( user_id TEXT NOT NULL, room_id TEXT NOT NULL, stream_id BIGINT NOT NULL, CONSTRAINT room_tag_revisions_uniqueness UNIQUE (user_id, room_id) );
-CREATE TABLE IF NOT EXISTS "account_data_max_stream_id"( Lock CHAR(1) NOT NULL DEFAULT 'X' UNIQUE, stream_id BIGINT NOT NULL, CHECK (Lock='X') );
-CREATE TABLE account_data( user_id TEXT NOT NULL, account_data_type TEXT NOT NULL, stream_id BIGINT NOT NULL, content TEXT NOT NULL, CONSTRAINT account_data_uniqueness UNIQUE (user_id, account_data_type) );
-CREATE TABLE room_account_data( user_id TEXT NOT NULL, room_id TEXT NOT NULL, account_data_type TEXT NOT NULL, stream_id BIGINT NOT NULL, content TEXT NOT NULL, CONSTRAINT room_account_data_uniqueness UNIQUE (user_id, room_id, account_data_type) );
-CREATE INDEX account_data_stream_id on account_data(user_id, stream_id);
-CREATE INDEX room_account_data_stream_id on room_account_data(user_id, stream_id);
-CREATE INDEX events_ts ON events(origin_server_ts, stream_ordering);
-CREATE TABLE event_push_actions( room_id TEXT NOT NULL, event_id TEXT NOT NULL, user_id TEXT NOT NULL, profile_tag VARCHAR(32), actions TEXT NOT NULL, topological_ordering BIGINT, stream_ordering BIGINT, notif SMALLINT, highlight SMALLINT, CONSTRAINT event_id_user_id_profile_tag_uniqueness UNIQUE (room_id, event_id, user_id, profile_tag) );
-CREATE INDEX event_push_actions_room_id_user_id on event_push_actions(room_id, user_id);
-CREATE INDEX events_room_stream on events(room_id, stream_ordering);
-CREATE INDEX public_room_index on rooms(is_public);
-CREATE INDEX receipts_linearized_user ON receipts_linearized( user_id );
-CREATE INDEX event_push_actions_rm_tokens on event_push_actions( user_id, room_id, topological_ordering, stream_ordering );
-CREATE TABLE presence_stream( stream_id BIGINT, user_id TEXT, state TEXT, last_active_ts BIGINT, last_federation_update_ts BIGINT, last_user_sync_ts BIGINT, status_msg TEXT, currently_active BOOLEAN );
-CREATE INDEX presence_stream_id ON presence_stream(stream_id, user_id);
-CREATE INDEX presence_stream_user_id ON presence_stream(user_id);
-CREATE TABLE push_rules_stream( stream_id BIGINT NOT NULL, event_stream_ordering BIGINT NOT NULL, user_id TEXT NOT NULL, rule_id TEXT NOT NULL, op TEXT NOT NULL, priority_class SMALLINT, priority INTEGER, conditions TEXT, actions TEXT );
-CREATE INDEX push_rules_stream_id ON push_rules_stream(stream_id);
-CREATE INDEX push_rules_stream_user_stream_id on push_rules_stream(user_id, stream_id);
-CREATE TABLE ex_outlier_stream( event_stream_ordering BIGINT PRIMARY KEY NOT NULL, event_id TEXT NOT NULL, state_group BIGINT NOT NULL );
-CREATE TABLE threepid_guest_access_tokens( medium TEXT, address TEXT, guest_access_token TEXT, first_inviter TEXT );
-CREATE UNIQUE INDEX threepid_guest_access_tokens_index ON threepid_guest_access_tokens(medium, address);
-CREATE TABLE local_invites( stream_id BIGINT NOT NULL, inviter TEXT NOT NULL, invitee TEXT NOT NULL, event_id TEXT NOT NULL, room_id TEXT NOT NULL, locally_rejected TEXT, replaced_by TEXT );
-CREATE INDEX local_invites_id ON local_invites(stream_id);
-CREATE INDEX local_invites_for_user_idx ON local_invites(invitee, locally_rejected, replaced_by, room_id);
-CREATE INDEX event_push_actions_stream_ordering on event_push_actions( stream_ordering, user_id );
-CREATE TABLE open_id_tokens ( token TEXT NOT NULL PRIMARY KEY, ts_valid_until_ms bigint NOT NULL, user_id TEXT NOT NULL, UNIQUE (token) );
-CREATE INDEX open_id_tokens_ts_valid_until_ms ON open_id_tokens(ts_valid_until_ms);
-CREATE TABLE pusher_throttle( pusher BIGINT NOT NULL, room_id TEXT NOT NULL, last_sent_ts BIGINT, throttle_ms BIGINT, PRIMARY KEY (pusher, room_id) );
-CREATE TABLE event_reports( id BIGINT NOT NULL PRIMARY KEY, received_ts BIGINT NOT NULL, room_id TEXT NOT NULL, event_id TEXT NOT NULL, user_id TEXT NOT NULL, reason TEXT, content TEXT );
-CREATE TABLE devices ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, display_name TEXT, CONSTRAINT device_uniqueness UNIQUE (user_id, device_id) );
-CREATE TABLE appservice_stream_position( Lock CHAR(1) NOT NULL DEFAULT 'X' UNIQUE, stream_ordering BIGINT, CHECK (Lock='X') );
-CREATE TABLE device_inbox ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, stream_id BIGINT NOT NULL, message_json TEXT NOT NULL );
-CREATE INDEX device_inbox_user_stream_id ON device_inbox(user_id, device_id, stream_id);
-CREATE INDEX received_transactions_ts ON received_transactions(ts);
-CREATE TABLE device_federation_outbox ( destination TEXT NOT NULL, stream_id BIGINT NOT NULL, queued_ts BIGINT NOT NULL, messages_json TEXT NOT NULL );
-CREATE INDEX device_federation_outbox_destination_id ON device_federation_outbox(destination, stream_id);
-CREATE TABLE device_federation_inbox ( origin TEXT NOT NULL, message_id TEXT NOT NULL, received_ts BIGINT NOT NULL );
-CREATE INDEX device_federation_inbox_sender_id ON device_federation_inbox(origin, message_id);
-CREATE TABLE device_max_stream_id ( stream_id BIGINT NOT NULL );
-CREATE TABLE public_room_list_stream ( stream_id BIGINT NOT NULL, room_id TEXT NOT NULL, visibility BOOLEAN NOT NULL , appservice_id TEXT, network_id TEXT);
-CREATE INDEX public_room_list_stream_idx on public_room_list_stream( stream_id );
-CREATE INDEX public_room_list_stream_rm_idx on public_room_list_stream( room_id, stream_id );
-CREATE TABLE stream_ordering_to_exterm ( stream_ordering BIGINT NOT NULL, room_id TEXT NOT NULL, event_id TEXT NOT NULL );
-CREATE INDEX stream_ordering_to_exterm_idx on stream_ordering_to_exterm( stream_ordering );
-CREATE INDEX stream_ordering_to_exterm_rm_idx on stream_ordering_to_exterm( room_id, stream_ordering );
-CREATE TABLE IF NOT EXISTS "event_auth"( event_id TEXT NOT NULL, auth_id TEXT NOT NULL, room_id TEXT NOT NULL );
-CREATE INDEX evauth_edges_id ON event_auth(event_id);
-CREATE INDEX user_threepids_medium_address on user_threepids (medium, address);
-CREATE TABLE appservice_room_list( appservice_id TEXT NOT NULL, network_id TEXT NOT NULL, room_id TEXT NOT NULL );
-CREATE UNIQUE INDEX appservice_room_list_idx ON appservice_room_list( appservice_id, network_id, room_id );
-CREATE INDEX device_federation_outbox_id ON device_federation_outbox(stream_id);
-CREATE TABLE federation_stream_position( type TEXT NOT NULL, stream_id INTEGER NOT NULL );
-CREATE TABLE device_lists_remote_cache ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, content TEXT NOT NULL );
-CREATE TABLE device_lists_remote_extremeties ( user_id TEXT NOT NULL, stream_id TEXT NOT NULL );
-CREATE TABLE device_lists_stream ( stream_id BIGINT NOT NULL, user_id TEXT NOT NULL, device_id TEXT NOT NULL );
-CREATE INDEX device_lists_stream_id ON device_lists_stream(stream_id, user_id);
-CREATE TABLE device_lists_outbound_pokes ( destination TEXT NOT NULL, stream_id BIGINT NOT NULL, user_id TEXT NOT NULL, device_id TEXT NOT NULL, sent BOOLEAN NOT NULL, ts BIGINT NOT NULL );
-CREATE INDEX device_lists_outbound_pokes_id ON device_lists_outbound_pokes(destination, stream_id);
-CREATE INDEX device_lists_outbound_pokes_user ON device_lists_outbound_pokes(destination, user_id);
-CREATE TABLE event_push_summary ( user_id TEXT NOT NULL, room_id TEXT NOT NULL, notif_count BIGINT NOT NULL, stream_ordering BIGINT NOT NULL );
-CREATE INDEX event_push_summary_user_rm ON event_push_summary(user_id, room_id);
-CREATE TABLE event_push_summary_stream_ordering ( Lock CHAR(1) NOT NULL DEFAULT 'X' UNIQUE, stream_ordering BIGINT NOT NULL, CHECK (Lock='X') );
-CREATE TABLE IF NOT EXISTS "pushers" ( id BIGINT PRIMARY KEY, user_name TEXT NOT NULL, access_token BIGINT DEFAULT NULL, profile_tag TEXT NOT NULL, kind TEXT NOT NULL, app_id TEXT NOT NULL, app_display_name TEXT NOT NULL, device_display_name TEXT NOT NULL, pushkey TEXT NOT NULL, ts BIGINT NOT NULL, lang TEXT, data TEXT, last_stream_ordering INTEGER, last_success BIGINT, failing_since BIGINT, UNIQUE (app_id, pushkey, user_name) );
-CREATE INDEX device_lists_outbound_pokes_stream ON device_lists_outbound_pokes(stream_id);
-CREATE TABLE ratelimit_override ( user_id TEXT NOT NULL, messages_per_second BIGINT, burst_count BIGINT );
-CREATE UNIQUE INDEX ratelimit_override_idx ON ratelimit_override(user_id);
-CREATE TABLE current_state_delta_stream ( stream_id BIGINT NOT NULL, room_id TEXT NOT NULL, type TEXT NOT NULL, state_key TEXT NOT NULL, event_id TEXT, prev_event_id TEXT );
-CREATE INDEX current_state_delta_stream_idx ON current_state_delta_stream(stream_id);
-CREATE TABLE device_lists_outbound_last_success ( destination TEXT NOT NULL, user_id TEXT NOT NULL, stream_id BIGINT NOT NULL );
-CREATE INDEX device_lists_outbound_last_success_idx ON device_lists_outbound_last_success( destination, user_id, stream_id );
-CREATE TABLE user_directory_stream_pos ( Lock CHAR(1) NOT NULL DEFAULT 'X' UNIQUE, stream_id BIGINT, CHECK (Lock='X') );
-CREATE VIRTUAL TABLE user_directory_search USING fts4 ( user_id, value )
-/* user_directory_search(user_id,value) */;
-CREATE TABLE blocked_rooms ( room_id TEXT NOT NULL, user_id TEXT NOT NULL );
-CREATE UNIQUE INDEX blocked_rooms_idx ON blocked_rooms(room_id);
-CREATE TABLE IF NOT EXISTS "local_media_repository_url_cache"( url TEXT, response_code INTEGER, etag TEXT, expires_ts BIGINT, og TEXT, media_id TEXT, download_ts BIGINT );
-CREATE INDEX local_media_repository_url_cache_expires_idx ON local_media_repository_url_cache(expires_ts);
-CREATE INDEX local_media_repository_url_cache_by_url_download_ts ON local_media_repository_url_cache(url, download_ts);
-CREATE INDEX local_media_repository_url_cache_media_idx ON local_media_repository_url_cache(media_id);
-CREATE TABLE group_users ( group_id TEXT NOT NULL, user_id TEXT NOT NULL, is_admin BOOLEAN NOT NULL, is_public BOOLEAN NOT NULL );
-CREATE TABLE group_invites ( group_id TEXT NOT NULL, user_id TEXT NOT NULL );
-CREATE TABLE group_rooms ( group_id TEXT NOT NULL, room_id TEXT NOT NULL, is_public BOOLEAN NOT NULL );
-CREATE TABLE group_summary_rooms ( group_id TEXT NOT NULL, room_id TEXT NOT NULL, category_id TEXT NOT NULL, room_order BIGINT NOT NULL, is_public BOOLEAN NOT NULL, UNIQUE (group_id, category_id, room_id, room_order), CHECK (room_order > 0) );
-CREATE UNIQUE INDEX group_summary_rooms_g_idx ON group_summary_rooms(group_id, room_id, category_id);
-CREATE TABLE group_summary_room_categories ( group_id TEXT NOT NULL, category_id TEXT NOT NULL, cat_order BIGINT NOT NULL, UNIQUE (group_id, category_id, cat_order), CHECK (cat_order > 0) );
-CREATE TABLE group_room_categories ( group_id TEXT NOT NULL, category_id TEXT NOT NULL, profile TEXT NOT NULL, is_public BOOLEAN NOT NULL, UNIQUE (group_id, category_id) );
-CREATE TABLE group_summary_users ( group_id TEXT NOT NULL, user_id TEXT NOT NULL, role_id TEXT NOT NULL, user_order BIGINT NOT NULL, is_public BOOLEAN NOT NULL );
-CREATE INDEX group_summary_users_g_idx ON group_summary_users(group_id);
-CREATE TABLE group_summary_roles ( group_id TEXT NOT NULL, role_id TEXT NOT NULL, role_order BIGINT NOT NULL, UNIQUE (group_id, role_id, role_order), CHECK (role_order > 0) );
-CREATE TABLE group_roles ( group_id TEXT NOT NULL, role_id TEXT NOT NULL, profile TEXT NOT NULL, is_public BOOLEAN NOT NULL, UNIQUE (group_id, role_id) );
-CREATE TABLE group_attestations_renewals ( group_id TEXT NOT NULL, user_id TEXT NOT NULL, valid_until_ms BIGINT NOT NULL );
-CREATE INDEX group_attestations_renewals_g_idx ON group_attestations_renewals(group_id, user_id);
-CREATE INDEX group_attestations_renewals_u_idx ON group_attestations_renewals(user_id);
-CREATE INDEX group_attestations_renewals_v_idx ON group_attestations_renewals(valid_until_ms);
-CREATE TABLE group_attestations_remote ( group_id TEXT NOT NULL, user_id TEXT NOT NULL, valid_until_ms BIGINT NOT NULL, attestation_json TEXT NOT NULL );
-CREATE INDEX group_attestations_remote_g_idx ON group_attestations_remote(group_id, user_id);
-CREATE INDEX group_attestations_remote_u_idx ON group_attestations_remote(user_id);
-CREATE INDEX group_attestations_remote_v_idx ON group_attestations_remote(valid_until_ms);
-CREATE TABLE local_group_membership ( group_id TEXT NOT NULL, user_id TEXT NOT NULL, is_admin BOOLEAN NOT NULL, membership TEXT NOT NULL, is_publicised BOOLEAN NOT NULL, content TEXT NOT NULL );
-CREATE INDEX local_group_membership_u_idx ON local_group_membership(user_id, group_id);
-CREATE INDEX local_group_membership_g_idx ON local_group_membership(group_id);
-CREATE TABLE local_group_updates ( stream_id BIGINT NOT NULL, group_id TEXT NOT NULL, user_id TEXT NOT NULL, type TEXT NOT NULL, content TEXT NOT NULL );
-CREATE TABLE remote_profile_cache ( user_id TEXT NOT NULL, displayname TEXT, avatar_url TEXT, last_check BIGINT NOT NULL );
-CREATE UNIQUE INDEX remote_profile_cache_user_id ON remote_profile_cache(user_id);
-CREATE INDEX remote_profile_cache_time ON remote_profile_cache(last_check);
-CREATE TABLE IF NOT EXISTS "deleted_pushers" ( stream_id BIGINT NOT NULL, app_id TEXT NOT NULL, pushkey TEXT NOT NULL, user_id TEXT NOT NULL );
-CREATE INDEX deleted_pushers_stream_id ON deleted_pushers (stream_id);
-CREATE TABLE IF NOT EXISTS "groups" ( group_id TEXT NOT NULL, name TEXT, avatar_url TEXT, short_description TEXT, long_description TEXT, is_public BOOL NOT NULL , join_policy TEXT NOT NULL DEFAULT 'invite');
-CREATE UNIQUE INDEX groups_idx ON groups(group_id);
-CREATE TABLE IF NOT EXISTS "user_directory" ( user_id TEXT NOT NULL, room_id TEXT, display_name TEXT, avatar_url TEXT );
-CREATE INDEX user_directory_room_idx ON user_directory(room_id);
-CREATE UNIQUE INDEX user_directory_user_idx ON user_directory(user_id);
-CREATE TABLE event_push_actions_staging ( event_id TEXT NOT NULL, user_id TEXT NOT NULL, actions TEXT NOT NULL, notif SMALLINT NOT NULL, highlight SMALLINT NOT NULL );
-CREATE INDEX event_push_actions_staging_id ON event_push_actions_staging(event_id);
-CREATE TABLE users_pending_deactivation ( user_id TEXT NOT NULL );
-CREATE UNIQUE INDEX group_invites_g_idx ON group_invites(group_id, user_id);
-CREATE UNIQUE INDEX group_users_g_idx ON group_users(group_id, user_id);
-CREATE INDEX group_users_u_idx ON group_users(user_id);
-CREATE INDEX group_invites_u_idx ON group_invites(user_id);
-CREATE UNIQUE INDEX group_rooms_g_idx ON group_rooms(group_id, room_id);
-CREATE INDEX group_rooms_r_idx ON group_rooms(room_id);
-CREATE TABLE user_daily_visits ( user_id TEXT NOT NULL, device_id TEXT, timestamp BIGINT NOT NULL );
-CREATE INDEX user_daily_visits_uts_idx ON user_daily_visits(user_id, timestamp);
-CREATE INDEX user_daily_visits_ts_idx ON user_daily_visits(timestamp);
-CREATE TABLE erased_users ( user_id TEXT NOT NULL );
-CREATE UNIQUE INDEX erased_users_user ON erased_users(user_id);
-CREATE TABLE monthly_active_users ( user_id TEXT NOT NULL, timestamp BIGINT NOT NULL );
-CREATE UNIQUE INDEX monthly_active_users_users ON monthly_active_users(user_id);
-CREATE INDEX monthly_active_users_time_stamp ON monthly_active_users(timestamp);
-CREATE TABLE IF NOT EXISTS "e2e_room_keys_versions" ( user_id TEXT NOT NULL, version BIGINT NOT NULL, algorithm TEXT NOT NULL, auth_data TEXT NOT NULL, deleted SMALLINT DEFAULT 0 NOT NULL );
-CREATE UNIQUE INDEX e2e_room_keys_versions_idx ON e2e_room_keys_versions(user_id, version);
-CREATE TABLE IF NOT EXISTS "e2e_room_keys" ( user_id TEXT NOT NULL, room_id TEXT NOT NULL, session_id TEXT NOT NULL, version BIGINT NOT NULL, first_message_index INT, forwarded_count INT, is_verified BOOLEAN, session_data TEXT NOT NULL );
-CREATE UNIQUE INDEX e2e_room_keys_idx ON e2e_room_keys(user_id, room_id, session_id);
-CREATE TABLE users_who_share_private_rooms ( user_id TEXT NOT NULL, other_user_id TEXT NOT NULL, room_id TEXT NOT NULL );
-CREATE UNIQUE INDEX users_who_share_private_rooms_u_idx ON users_who_share_private_rooms(user_id, other_user_id, room_id);
-CREATE INDEX users_who_share_private_rooms_r_idx ON users_who_share_private_rooms(room_id);
-CREATE INDEX users_who_share_private_rooms_o_idx ON users_who_share_private_rooms(other_user_id);
-CREATE TABLE user_threepid_id_server ( user_id TEXT NOT NULL, medium TEXT NOT NULL, address TEXT NOT NULL, id_server TEXT NOT NULL );
-CREATE UNIQUE INDEX user_threepid_id_server_idx ON user_threepid_id_server( user_id, medium, address, id_server );
-CREATE TABLE users_in_public_rooms ( user_id TEXT NOT NULL, room_id TEXT NOT NULL );
-CREATE UNIQUE INDEX users_in_public_rooms_u_idx ON users_in_public_rooms(user_id, room_id);
-CREATE TABLE account_validity ( user_id TEXT PRIMARY KEY, expiration_ts_ms BIGINT NOT NULL, email_sent BOOLEAN NOT NULL, renewal_token TEXT );
-CREATE TABLE event_relations ( event_id TEXT NOT NULL, relates_to_id TEXT NOT NULL, relation_type TEXT NOT NULL, aggregation_key TEXT );
-CREATE UNIQUE INDEX event_relations_id ON event_relations(event_id);
-CREATE INDEX event_relations_relates ON event_relations(relates_to_id, relation_type, aggregation_key);
-CREATE TABLE stats_stream_pos ( Lock CHAR(1) NOT NULL DEFAULT 'X' UNIQUE, stream_id BIGINT, CHECK (Lock='X') );
-CREATE TABLE user_stats ( user_id TEXT NOT NULL, ts BIGINT NOT NULL, bucket_size INT NOT NULL, public_rooms INT NOT NULL, private_rooms INT NOT NULL );
-CREATE UNIQUE INDEX user_stats_user_ts ON user_stats(user_id, ts);
-CREATE TABLE room_stats ( room_id TEXT NOT NULL, ts BIGINT NOT NULL, bucket_size INT NOT NULL, current_state_events INT NOT NULL, joined_members INT NOT NULL, invited_members INT NOT NULL, left_members INT NOT NULL, banned_members INT NOT NULL, state_events INT NOT NULL );
-CREATE UNIQUE INDEX room_stats_room_ts ON room_stats(room_id, ts);
-CREATE TABLE room_state ( room_id TEXT NOT NULL, join_rules TEXT, history_visibility TEXT, encryption TEXT, name TEXT, topic TEXT, avatar TEXT, canonical_alias TEXT );
-CREATE UNIQUE INDEX room_state_room ON room_state(room_id);
-CREATE TABLE room_stats_earliest_token ( room_id TEXT NOT NULL, token BIGINT NOT NULL );
-CREATE UNIQUE INDEX room_stats_earliest_token_idx ON room_stats_earliest_token(room_id);
-CREATE INDEX access_tokens_device_id ON access_tokens (user_id, device_id);
-CREATE INDEX user_ips_device_id ON user_ips (user_id, device_id, last_seen);
-CREATE INDEX event_contains_url_index ON events (room_id, topological_ordering, stream_ordering);
-CREATE INDEX event_push_actions_u_highlight ON event_push_actions (user_id, stream_ordering);
-CREATE INDEX event_push_actions_highlights_index ON event_push_actions (user_id, room_id, topological_ordering, stream_ordering);
-CREATE INDEX current_state_events_member_index ON current_state_events (state_key);
-CREATE INDEX device_inbox_stream_id_user_id ON device_inbox (stream_id, user_id);
-CREATE INDEX device_lists_stream_user_id ON device_lists_stream (user_id, device_id);
-CREATE INDEX local_media_repository_url_idx ON local_media_repository (created_ts);
-CREATE INDEX user_ips_last_seen ON user_ips (user_id, last_seen);
-CREATE INDEX user_ips_last_seen_only ON user_ips (last_seen);
-CREATE INDEX users_creation_ts ON users (creation_ts);
-CREATE INDEX event_to_state_groups_sg_index ON event_to_state_groups (state_group);
-CREATE UNIQUE INDEX device_lists_remote_cache_unique_id ON device_lists_remote_cache (user_id, device_id);
-CREATE UNIQUE INDEX device_lists_remote_extremeties_unique_idx ON device_lists_remote_extremeties (user_id);
-CREATE UNIQUE INDEX user_ips_user_token_ip_unique_index ON user_ips (user_id, access_token, ip);
diff --git a/synapse/storage/schema/main/full_schemas/54/stream_positions.sql b/synapse/storage/schema/main/full_schemas/54/stream_positions.sql
deleted file mode 100644
index 91d21b2921..0000000000
--- a/synapse/storage/schema/main/full_schemas/54/stream_positions.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-
-INSERT INTO appservice_stream_position (stream_ordering) SELECT COALESCE(MAX(stream_ordering), 0) FROM events;
-INSERT INTO federation_stream_position (type, stream_id) VALUES ('federation', -1);
-INSERT INTO federation_stream_position (type, stream_id) SELECT 'events', coalesce(max(stream_ordering), -1) FROM events;
-INSERT INTO user_directory_stream_pos (stream_id) VALUES (0);
-INSERT INTO stats_stream_pos (stream_id) VALUES (0);
-INSERT INTO event_push_summary_stream_ordering (stream_ordering) VALUES (0);
--- device_max_stream_id is handled separately in 56/device_stream_id_insert.sql
\ No newline at end of file
diff --git a/synapse/storage/schema/state/full_schemas/54/full.sql b/synapse/storage/schema/state/full_schemas/54/full.sql
deleted file mode 100644
index 35f97d6b3d..0000000000
--- a/synapse/storage/schema/state/full_schemas/54/full.sql
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Copyright 2019 The Matrix.org Foundation C.I.C
- *
- * 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.
- */
-
-CREATE TABLE state_groups (
- id BIGINT PRIMARY KEY,
- room_id TEXT NOT NULL,
- event_id TEXT NOT NULL
-);
-
-CREATE TABLE state_groups_state (
- state_group BIGINT NOT NULL,
- room_id TEXT NOT NULL,
- type TEXT NOT NULL,
- state_key TEXT NOT NULL,
- event_id TEXT NOT NULL
-);
-
-CREATE TABLE state_group_edges (
- state_group BIGINT NOT NULL,
- prev_state_group BIGINT NOT NULL
-);
-
-CREATE INDEX state_group_edges_idx ON state_group_edges (state_group);
-CREATE INDEX state_group_edges_prev_idx ON state_group_edges (prev_state_group);
-CREATE INDEX state_groups_state_type_idx ON state_groups_state (state_group, type, state_key);
diff --git a/synapse/storage/schema/state/full_schemas/54/sequence.sql.postgres b/synapse/storage/schema/state/full_schemas/54/sequence.sql.postgres
deleted file mode 100644
index fcd926c9fb..0000000000
--- a/synapse/storage/schema/state/full_schemas/54/sequence.sql.postgres
+++ /dev/null
@@ -1,21 +0,0 @@
-/* Copyright 2019 The Matrix.org Foundation C.I.C
- *
- * 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.
- */
-
-CREATE SEQUENCE state_group_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
diff --git a/tests/config/test_oauth_delegation.py b/tests/config/test_oauth_delegation.py
index 5c91031746..b1a9db0210 100644
--- a/tests/config/test_oauth_delegation.py
+++ b/tests/config/test_oauth_delegation.py
@@ -22,15 +22,7 @@ from synapse.types import JsonDict
from tests.server import get_clock, setup_test_homeserver
from tests.unittest import TestCase, skip_unless
-from tests.utils import default_config
-
-try:
- import authlib # noqa: F401
-
- HAS_AUTHLIB = True
-except ImportError:
- HAS_AUTHLIB = False
-
+from tests.utils import HAS_AUTHLIB, default_config
# These are a few constants that are used as config parameters in the tests.
SERVER_NAME = "test"
diff --git a/tests/handlers/test_oauth_delegation.py b/tests/handlers/test_oauth_delegation.py
index a72ecfdc97..a2b8e3d562 100644
--- a/tests/handlers/test_oauth_delegation.py
+++ b/tests/handlers/test_oauth_delegation.py
@@ -13,7 +13,8 @@
# limitations under the License.
from http import HTTPStatus
-from typing import Any, Dict, Union
+from io import BytesIO
+from typing import Any, Dict, Optional, Union
from unittest.mock import ANY, AsyncMock, Mock
from urllib.parse import parse_qs
@@ -25,6 +26,8 @@ from signedjson.key import (
from signedjson.sign import sign_json
from twisted.test.proto_helpers import MemoryReactor
+from twisted.web.http_headers import Headers
+from twisted.web.iweb import IResponse
from synapse.api.errors import (
AuthError,
@@ -33,23 +36,17 @@ from synapse.api.errors import (
OAuthInsufficientScopeError,
SynapseError,
)
+from synapse.http.site import SynapseRequest
from synapse.rest import admin
from synapse.rest.client import account, devices, keys, login, logout, register
from synapse.server import HomeServer
-from synapse.types import JsonDict
+from synapse.types import JsonDict, UserID
from synapse.util import Clock
+from tests.server import FakeChannel
from tests.test_utils import FakeResponse, get_awaitable_result
-from tests.unittest import HomeserverTestCase, skip_unless
-from tests.utils import mock_getRawHeaders
-
-try:
- import authlib # noqa: F401
-
- HAS_AUTHLIB = True
-except ImportError:
- HAS_AUTHLIB = False
-
+from tests.unittest import HomeserverTestCase, override_config, skip_unless
+from tests.utils import HAS_AUTHLIB, checked_cast, mock_getRawHeaders
# These are a few constants that are used as config parameters in the tests.
SERVER_NAME = "test"
@@ -75,6 +72,7 @@ MATRIX_DEVICE_SCOPE = MATRIX_DEVICE_SCOPE_PREFIX + DEVICE
SUBJECT = "abc-def-ghi"
USERNAME = "test-user"
USER_ID = "@" + USERNAME + ":" + SERVER_NAME
+OIDC_ADMIN_USERID = f"@__oidc_admin:{SERVER_NAME}"
async def get_json(url: str) -> JsonDict:
@@ -134,7 +132,10 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
hs = self.setup_test_homeserver(proxied_http_client=self.http_client)
- self.auth = hs.get_auth()
+ # Import this here so that we've checked that authlib is available.
+ from synapse.api.auth.msc3861_delegated import MSC3861DelegatedAuth
+
+ self.auth = checked_cast(MSC3861DelegatedAuth, hs.get_auth())
return hs
@@ -675,7 +676,8 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
request.requestHeaders.getRawHeaders = mock_getRawHeaders()
requester = self.get_success(self.auth.get_user_by_req(request))
self.assertEqual(
- requester.user.to_string(), "@%s:%s" % ("__oidc_admin", SERVER_NAME)
+ requester.user.to_string(),
+ OIDC_ADMIN_USERID,
)
self.assertEqual(requester.is_guest, False)
self.assertEqual(requester.device_id, None)
@@ -685,3 +687,102 @@ class MSC3861OAuthDelegation(HomeserverTestCase):
# There should be no call to the introspection endpoint
self.http_client.request.assert_not_called()
+
+ @override_config({"mau_stats_only": True})
+ def test_request_tracking(self) -> None:
+ """Using an access token should update the client_ips and MAU tables."""
+ # To start, there are no MAU users.
+ store = self.hs.get_datastores().main
+ mau = self.get_success(store.get_monthly_active_count())
+ self.assertEqual(mau, 0)
+
+ known_token = "token-token-GOOD-:)"
+
+ async def mock_http_client_request(
+ method: str,
+ uri: str,
+ data: Optional[bytes] = None,
+ headers: Optional[Headers] = None,
+ ) -> IResponse:
+ """Mocked auth provider response."""
+ assert method == "POST"
+ token = parse_qs(data)[b"token"][0].decode("utf-8")
+ if token == known_token:
+ return FakeResponse.json(
+ code=200,
+ payload={
+ "active": True,
+ "scope": MATRIX_USER_SCOPE,
+ "sub": SUBJECT,
+ "username": USERNAME,
+ },
+ )
+
+ return FakeResponse.json(code=200, payload={"active": False})
+
+ self.http_client.request = mock_http_client_request
+
+ EXAMPLE_IPV4_ADDR = "123.123.123.123"
+ EXAMPLE_USER_AGENT = "httprettygood"
+
+ # First test a known access token
+ channel = FakeChannel(self.site, self.reactor)
+ # type-ignore: FakeChannel is a mock of an HTTPChannel, not a proper HTTPChannel
+ req = SynapseRequest(channel, self.site) # type: ignore[arg-type]
+ req.client.host = EXAMPLE_IPV4_ADDR
+ req.requestHeaders.addRawHeader("Authorization", f"Bearer {known_token}")
+ req.requestHeaders.addRawHeader("User-Agent", EXAMPLE_USER_AGENT)
+ req.content = BytesIO(b"")
+ req.requestReceived(
+ b"GET",
+ b"/_matrix/client/v3/account/whoami",
+ b"1.1",
+ )
+ channel.await_result()
+ self.assertEqual(channel.code, HTTPStatus.OK, channel.json_body)
+ self.assertEqual(channel.json_body["user_id"], USER_ID, channel.json_body)
+
+ # Expect to see one MAU entry, from the first request
+ mau = self.get_success(store.get_monthly_active_count())
+ self.assertEqual(mau, 1)
+
+ conn_infos = self.get_success(
+ store.get_user_ip_and_agents(UserID.from_string(USER_ID))
+ )
+ self.assertEqual(len(conn_infos), 1, conn_infos)
+ conn_info = conn_infos[0]
+ self.assertEqual(conn_info["access_token"], known_token)
+ self.assertEqual(conn_info["ip"], EXAMPLE_IPV4_ADDR)
+ self.assertEqual(conn_info["user_agent"], EXAMPLE_USER_AGENT)
+
+ # Now test MAS making a request using the special __oidc_admin token
+ MAS_IPV4_ADDR = "127.0.0.1"
+ MAS_USER_AGENT = "masmasmas"
+
+ channel = FakeChannel(self.site, self.reactor)
+ req = SynapseRequest(channel, self.site) # type: ignore[arg-type]
+ req.client.host = MAS_IPV4_ADDR
+ req.requestHeaders.addRawHeader(
+ "Authorization", f"Bearer {self.auth._admin_token}"
+ )
+ req.requestHeaders.addRawHeader("User-Agent", MAS_USER_AGENT)
+ req.content = BytesIO(b"")
+ req.requestReceived(
+ b"GET",
+ b"/_matrix/client/v3/account/whoami",
+ b"1.1",
+ )
+ channel.await_result()
+ self.assertEqual(channel.code, HTTPStatus.OK, channel.json_body)
+ self.assertEqual(
+ channel.json_body["user_id"], OIDC_ADMIN_USERID, channel.json_body
+ )
+
+ # Still expect to see one MAU entry, from the first request
+ mau = self.get_success(store.get_monthly_active_count())
+ self.assertEqual(mau, 1)
+
+ conn_infos = self.get_success(
+ store.get_user_ip_and_agents(UserID.from_string(OIDC_ADMIN_USERID))
+ )
+ self.assertEqual(conn_infos, [])
diff --git a/tests/rest/media/test_media_retention.py b/tests/media/test_media_retention.py
index 27a663a23b..27a663a23b 100644
--- a/tests/rest/media/test_media_retention.py
+++ b/tests/media/test_media_retention.py
diff --git a/tests/media/test_media_storage.py b/tests/media/test_media_storage.py
index f262304c3d..f981d1c0d8 100644
--- a/tests/media/test_media_storage.py
+++ b/tests/media/test_media_storage.py
@@ -27,10 +27,11 @@ from typing_extensions import Literal
from twisted.internet import defer
from twisted.internet.defer import Deferred
+from twisted.python.failure import Failure
from twisted.test.proto_helpers import MemoryReactor
from twisted.web.resource import Resource
-from synapse.api.errors import Codes
+from synapse.api.errors import Codes, HttpResponseException
from synapse.events import EventBase
from synapse.http.types import QueryParams
from synapse.logging.context import make_deferred_yieldable
@@ -247,6 +248,7 @@ class MediaRepoTests(unittest.HomeserverTestCase):
retry_on_dns_fail: bool = True,
max_size: Optional[int] = None,
ignore_backoff: bool = False,
+ follow_redirects: bool = False,
) -> "Deferred[Tuple[int, Dict[bytes, List[bytes]]]]":
"""A mock for MatrixFederationHttpClient.get_file."""
@@ -257,10 +259,15 @@ class MediaRepoTests(unittest.HomeserverTestCase):
output_stream.write(data)
return response
+ def write_err(f: Failure) -> Failure:
+ f.trap(HttpResponseException)
+ output_stream.write(f.value.response)
+ return f
+
d: Deferred[Tuple[bytes, Tuple[int, Dict[bytes, List[bytes]]]]] = Deferred()
self.fetches.append((d, destination, path, args))
# Note that this callback changes the value held by d.
- d_after_callback = d.addCallback(write_to)
+ d_after_callback = d.addCallbacks(write_to, write_err)
return make_deferred_yieldable(d_after_callback)
# Mock out the homeserver's MatrixFederationHttpClient
@@ -316,10 +323,11 @@ class MediaRepoTests(unittest.HomeserverTestCase):
self.assertEqual(len(self.fetches), 1)
self.assertEqual(self.fetches[0][1], "example.com")
self.assertEqual(
- self.fetches[0][2], "/_matrix/media/r0/download/" + self.media_id
+ self.fetches[0][2], "/_matrix/media/v3/download/" + self.media_id
)
self.assertEqual(
- self.fetches[0][3], {"allow_remote": "false", "timeout_ms": "20000"}
+ self.fetches[0][3],
+ {"allow_remote": "false", "timeout_ms": "20000", "allow_redirect": "true"},
)
headers = {
@@ -671,6 +679,52 @@ class MediaRepoTests(unittest.HomeserverTestCase):
[b"cross-origin"],
)
+ def test_unknown_v3_endpoint(self) -> None:
+ """
+ If the v3 endpoint fails, try the r0 one.
+ """
+ channel = self.make_request(
+ "GET",
+ f"/_matrix/media/v3/download/{self.media_id}",
+ shorthand=False,
+ await_result=False,
+ )
+ self.pump()
+
+ # We've made one fetch, to example.com, using the media URL, and asking
+ # the other server not to do a remote fetch
+ self.assertEqual(len(self.fetches), 1)
+ self.assertEqual(self.fetches[0][1], "example.com")
+ self.assertEqual(
+ self.fetches[0][2], "/_matrix/media/v3/download/" + self.media_id
+ )
+
+ # The result which says the endpoint is unknown.
+ unknown_endpoint = b'{"errcode":"M_UNRECOGNIZED","error":"Unknown request"}'
+ self.fetches[0][0].errback(
+ HttpResponseException(404, "NOT FOUND", unknown_endpoint)
+ )
+
+ self.pump()
+
+ # There should now be another request to the r0 URL.
+ self.assertEqual(len(self.fetches), 2)
+ self.assertEqual(self.fetches[1][1], "example.com")
+ self.assertEqual(
+ self.fetches[1][2], f"/_matrix/media/r0/download/{self.media_id}"
+ )
+
+ headers = {
+ b"Content-Length": [b"%d" % (len(self.test_image.data))],
+ }
+
+ self.fetches[1][0].callback(
+ (self.test_image.data, (len(self.test_image.data), headers))
+ )
+
+ self.pump()
+ self.assertEqual(channel.code, 200)
+
class TestSpamCheckerLegacy:
"""A spam checker module that rejects all media that includes the bytes
diff --git a/tests/replication/test_multi_media_repo.py b/tests/replication/test_multi_media_repo.py
index 1e9994cc0b..9a7b675f54 100644
--- a/tests/replication/test_multi_media_repo.py
+++ b/tests/replication/test_multi_media_repo.py
@@ -133,7 +133,7 @@ class MediaRepoShardTestCase(BaseMultiWorkerStreamTestCase):
self.assertEqual(request.method, b"GET")
self.assertEqual(
request.path,
- f"/_matrix/media/r0/download/{target}/{media_id}".encode(),
+ f"/_matrix/media/v3/download/{target}/{media_id}".encode(),
)
self.assertEqual(
request.requestHeaders.getRawHeaders(b"host"), [target.encode("utf-8")]
diff --git a/tests/rest/admin/test_jwks.py b/tests/rest/admin/test_jwks.py
index a9a6191c73..842e92c3d0 100644
--- a/tests/rest/admin/test_jwks.py
+++ b/tests/rest/admin/test_jwks.py
@@ -19,13 +19,7 @@ from twisted.web.resource import Resource
from synapse.rest.synapse.client import build_synapse_client_resource_tree
from tests.unittest import HomeserverTestCase, override_config, skip_unless
-
-try:
- import authlib # noqa: F401
-
- HAS_AUTHLIB = True
-except ImportError:
- HAS_AUTHLIB = False
+from tests.utils import HAS_AUTHLIB
@skip_unless(HAS_AUTHLIB, "requires authlib")
diff --git a/tests/rest/client/test_keys.py b/tests/rest/client/test_keys.py
index 9f81a695fa..a6023dff7a 100644
--- a/tests/rest/client/test_keys.py
+++ b/tests/rest/client/test_keys.py
@@ -30,13 +30,7 @@ from synapse.types import JsonDict, Requester, create_requester
from tests import unittest
from tests.http.server._base import make_request_with_cancellation_test
from tests.unittest import override_config
-
-try:
- import authlib # noqa: F401
-
- HAS_AUTHLIB = True
-except ImportError:
- HAS_AUTHLIB = False
+from tests.utils import HAS_AUTHLIB
class KeyQueryTestCase(unittest.HomeserverTestCase):
diff --git a/tests/rest/test_well_known.py b/tests/rest/test_well_known.py
index 377243a170..7931a70abb 100644
--- a/tests/rest/test_well_known.py
+++ b/tests/rest/test_well_known.py
@@ -16,13 +16,7 @@ from twisted.web.resource import Resource
from synapse.rest.well_known import well_known_resource
from tests import unittest
-
-try:
- import authlib # noqa: F401
-
- HAS_AUTHLIB = True
-except ImportError:
- HAS_AUTHLIB = False
+from tests.utils import HAS_AUTHLIB
class WellKnownTests(unittest.HomeserverTestCase):
diff --git a/tests/utils.py b/tests/utils.py
index a0c87ad628..e0066fe15a 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -30,6 +30,13 @@ from synapse.storage.database import LoggingDatabaseConnection
from synapse.storage.engines import create_engine
from synapse.storage.prepare_database import prepare_database
+try:
+ import authlib # noqa: F401
+
+ HAS_AUTHLIB = True
+except ImportError:
+ HAS_AUTHLIB = False
+
# set this to True to run the tests against postgres instead of sqlite.
#
# When running under postgres, we first create a base database with the name
|