mirror of
https://github.com/element-hq/synapse.git
synced 2025-07-04 00:00:27 -04:00
Compare commits
37 Commits
32e51121ff
...
d3c904ab37
Author | SHA1 | Date | |
---|---|---|---|
|
d3c904ab37 | ||
|
87fc518e0c | ||
|
3bd476eb0d | ||
|
717f67f3d3 | ||
|
c2108948a3 | ||
|
cb4b5585a4 | ||
|
a3ec2d3b3f | ||
|
81ca2923d1 | ||
|
2372f3e6b7 | ||
|
82757144e9 | ||
|
2f9c9d5eba | ||
|
6ddbb03612 | ||
|
cc8da2c5ed | ||
|
c17fd947f3 | ||
|
24bcdb3f3c | ||
|
e3ed93adf3 | ||
|
214ac2f005 | ||
|
c471e84697 | ||
|
291880012f | ||
|
a2bee2f255 | ||
|
3878699df7 | ||
|
b35c6483d5 | ||
|
bfb3a6e700 | ||
|
8afea3d51d | ||
|
db710cf29b | ||
|
de29c13d41 | ||
|
434e38941a | ||
|
b1396475c4 | ||
|
b088194f48 | ||
|
2f21b27465 | ||
|
3807fd42e1 | ||
|
99474e7fdf | ||
|
ec13ed4169 | ||
|
62b5b0b962 | ||
|
0779587f9f | ||
|
0c7d9919fa | ||
|
6fabf82f4f |
6
.github/workflows/docker.yml
vendored
6
.github/workflows/docker.yml
vendored
@ -24,13 +24,13 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
- name: Inspect builder
|
- name: Inspect builder
|
||||||
run: docker buildx inspect
|
run: docker buildx inspect
|
||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
uses: sigstore/cosign-installer@3454372f43399081ed03b604cb2d021dabca52bb # v3.8.2
|
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
@ -72,7 +72,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build and push all platforms
|
- name: Build and push all platforms
|
||||||
id: build-and-push
|
id: build-and-push
|
||||||
uses: docker/build-push-action@1dc73863535b631f98b2378be8619f83b136f4a0 # v6.17.0
|
uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0
|
||||||
with:
|
with:
|
||||||
push: true
|
push: true
|
||||||
labels: |
|
labels: |
|
||||||
|
4
.github/workflows/fix_lint.yaml
vendored
4
.github/workflows/fix_lint.yaml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
components: clippy, rustfmt
|
components: clippy, rustfmt
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- name: Setup Poetry
|
- name: Setup Poetry
|
||||||
uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
@ -47,6 +47,6 @@ jobs:
|
|||||||
- run: cargo fmt
|
- run: cargo fmt
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@b863ae1933cb653a53c021fe36dbb774e1fb9403 # v5.2.0
|
- uses: stefanzweifel/git-auto-commit-action@778341af668090896ca464160c2def5d1d1a3eb0 # v6.0.1
|
||||||
with:
|
with:
|
||||||
commit_message: "Attempt to fix linting"
|
commit_message: "Attempt to fix linting"
|
||||||
|
6
.github/workflows/latest_deps.yml
vendored
6
.github/workflows/latest_deps.yml
vendored
@ -47,7 +47,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
# The dev dependencies aren't exposed in the wheel metadata (at least with current
|
# The dev dependencies aren't exposed in the wheel metadata (at least with current
|
||||||
# poetry-core versions), so we install with poetry.
|
# poetry-core versions), so we install with poetry.
|
||||||
@ -83,7 +83,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- run: sudo apt-get -qq install xmlsec1
|
- run: sudo apt-get -qq install xmlsec1
|
||||||
- name: Set up PostgreSQL ${{ matrix.postgres-version }}
|
- name: Set up PostgreSQL ${{ matrix.postgres-version }}
|
||||||
@ -158,7 +158,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- name: Ensure sytest runs `pip install`
|
- name: Ensure sytest runs `pip install`
|
||||||
# Delete the lockfile so sytest will `pip install` rather than `poetry install`
|
# Delete the lockfile so sytest will `pip install` rather than `poetry install`
|
||||||
|
6
.github/workflows/release-artifacts.yml
vendored
6
.github/workflows/release-artifacts.yml
vendored
@ -61,7 +61,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
id: buildx
|
id: buildx
|
||||||
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3.10.0
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
with:
|
with:
|
||||||
install: true
|
install: true
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-22.04, macos-13]
|
os: [ubuntu-24.04, macos-13]
|
||||||
arch: [x86_64, aarch64]
|
arch: [x86_64, aarch64]
|
||||||
# is_pr is a flag used to exclude certain jobs from the matrix on PRs.
|
# is_pr is a flag used to exclude certain jobs from the matrix on PRs.
|
||||||
# It is not read by the rest of the workflow.
|
# It is not read by the rest of the workflow.
|
||||||
@ -139,7 +139,7 @@ jobs:
|
|||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|
||||||
- name: Install cibuildwheel
|
- name: Install cibuildwheel
|
||||||
run: python -m pip install cibuildwheel==2.23.0
|
run: python -m pip install cibuildwheel==3.0.0
|
||||||
|
|
||||||
- name: Set up QEMU to emulate aarch64
|
- name: Set up QEMU to emulate aarch64
|
||||||
if: matrix.arch == 'aarch64'
|
if: matrix.arch == 'aarch64'
|
||||||
|
24
.github/workflows/tests.yml
vendored
24
.github/workflows/tests.yml
vendored
@ -91,7 +91,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@ -157,7 +157,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- name: Setup Poetry
|
- name: Setup Poetry
|
||||||
uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
@ -220,7 +220,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
with:
|
with:
|
||||||
poetry-version: "2.1.1"
|
poetry-version: "2.1.1"
|
||||||
@ -240,7 +240,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
components: clippy
|
components: clippy
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- run: cargo clippy -- -D warnings
|
- run: cargo clippy -- -D warnings
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
toolchain: nightly-2025-04-23
|
toolchain: nightly-2025-04-23
|
||||||
components: clippy
|
components: clippy
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- run: cargo clippy --all-features -- -D warnings
|
- run: cargo clippy --all-features -- -D warnings
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ jobs:
|
|||||||
# We use nightly so that it correctly groups together imports
|
# We use nightly so that it correctly groups together imports
|
||||||
toolchain: nightly-2025-04-23
|
toolchain: nightly-2025-04-23
|
||||||
components: rustfmt
|
components: rustfmt
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- run: cargo fmt --check
|
- run: cargo fmt --check
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
with:
|
with:
|
||||||
@ -419,7 +419,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
# There aren't wheels for some of the older deps, so we need to install
|
# There aren't wheels for some of the older deps, so we need to install
|
||||||
# their build dependencies
|
# their build dependencies
|
||||||
@ -536,7 +536,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- name: Run SyTest
|
- name: Run SyTest
|
||||||
run: /bootstrap.sh synapse
|
run: /bootstrap.sh synapse
|
||||||
@ -682,7 +682,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- name: Prepare Complement's Prerequisites
|
- name: Prepare Complement's Prerequisites
|
||||||
run: synapse/.ci/scripts/setup_complement_prerequisites.sh
|
run: synapse/.ci/scripts/setup_complement_prerequisites.sh
|
||||||
@ -716,7 +716,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- run: cargo test
|
- run: cargo test
|
||||||
|
|
||||||
@ -736,7 +736,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: nightly-2022-12-01
|
toolchain: nightly-2022-12-01
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- run: cargo bench --no-run
|
- run: cargo bench --no-run
|
||||||
|
|
||||||
|
6
.github/workflows/twisted_trunk.yml
vendored
6
.github/workflows/twisted_trunk.yml
vendored
@ -49,7 +49,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
with:
|
with:
|
||||||
@ -77,7 +77,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
with:
|
with:
|
||||||
@ -123,7 +123,7 @@ jobs:
|
|||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ env.RUST_VERSION }}
|
toolchain: ${{ env.RUST_VERSION }}
|
||||||
- uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 # v2.7.8
|
- uses: Swatinem/rust-cache@98c8021b550208e191a6a3145459bfc9fb29c4c0 # v2.8.0
|
||||||
|
|
||||||
- name: Patch dependencies
|
- name: Patch dependencies
|
||||||
# Note: The poetry commands want to create a virtualenv in /src/.venv/,
|
# Note: The poetry commands want to create a virtualenv in /src/.venv/,
|
||||||
|
18
CHANGES.md
18
CHANGES.md
@ -1,3 +1,21 @@
|
|||||||
|
# Synapse 1.133.0 (2025-07-01)
|
||||||
|
|
||||||
|
Pre-built wheels are now built using the [manylinux_2_28](https://github.com/pypa/manylinux#manylinux_2_28-almalinux-8-based) base, which is expected to be compatible with distros using glibc 2.28 or later, including:
|
||||||
|
|
||||||
|
- Debian 10+
|
||||||
|
- Ubuntu 18.10+
|
||||||
|
- Fedora 29+
|
||||||
|
- CentOS/RHEL 8+
|
||||||
|
|
||||||
|
Previously, wheels were built using the [manylinux2014](https://github.com/pypa/manylinux#manylinux2014-centos-7-based-glibc-217) base, which was expected to be compatible with distros using glibc 2.17 or later.
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Bump `cibuildwheel` to 3.0.0 to fix the `manylinux` wheel builds. ([\#18615](https://github.com/element-hq/synapse/issues/18615))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Synapse 1.133.0rc1 (2025-06-24)
|
# Synapse 1.133.0rc1 (2025-06-24)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
207
Cargo.lock
generated
207
Cargo.lock
generated
@ -62,15 +62,9 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"object",
|
"object",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "base64"
|
|
||||||
version = "0.21.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.22.1"
|
version = "0.22.1"
|
||||||
@ -331,7 +325,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.13.3+wasi-0.2.2",
|
"wasi 0.13.3+wasi-0.2.2",
|
||||||
"windows-targets 0.52.6",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -371,7 +365,7 @@ version = "0.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
|
checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"headers-core",
|
"headers-core",
|
||||||
"http",
|
"http",
|
||||||
@ -487,17 +481,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hyper-util"
|
name = "hyper-util"
|
||||||
version = "0.1.11"
|
version = "0.1.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
|
checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"ipnet",
|
||||||
"libc",
|
"libc",
|
||||||
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio",
|
"tokio",
|
||||||
@ -660,12 +658,33 @@ version = "2.0.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "io-uring"
|
||||||
|
version = "0.7.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnet"
|
name = "ipnet"
|
||||||
version = "2.11.0"
|
version = "2.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iri-string"
|
||||||
|
version = "0.7.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
@ -1041,11 +1060,11 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.15"
|
version = "0.12.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -1056,17 +1075,13 @@ dependencies = [
|
|||||||
"hyper",
|
"hyper",
|
||||||
"hyper-rustls",
|
"hyper-rustls",
|
||||||
"hyper-util",
|
"hyper-util",
|
||||||
"ipnet",
|
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
|
||||||
"once_cell",
|
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"quinn",
|
"quinn",
|
||||||
"rustls",
|
"rustls",
|
||||||
"rustls-native-certs",
|
"rustls-native-certs",
|
||||||
"rustls-pemfile",
|
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -1076,13 +1091,13 @@ dependencies = [
|
|||||||
"tokio-rustls",
|
"tokio-rustls",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tower",
|
"tower",
|
||||||
|
"tower-http",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"wasm-streams",
|
"wasm-streams",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"windows-registry",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1137,15 +1152,6 @@ dependencies = [
|
|||||||
"security-framework",
|
"security-framework",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustls-pemfile"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
|
|
||||||
dependencies = [
|
|
||||||
"rustls-pki-types",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pki-types"
|
name = "rustls-pki-types"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
@ -1332,7 +1338,7 @@ name = "synapse"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64 0.21.7",
|
"base64",
|
||||||
"blake2",
|
"blake2",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures",
|
"futures",
|
||||||
@ -1428,15 +1434,17 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.45.1"
|
version = "1.46.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779"
|
checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"io-uring",
|
||||||
"libc",
|
"libc",
|
||||||
"mio",
|
"mio",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"slab",
|
||||||
"socket2",
|
"socket2",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
@ -1479,6 +1487,24 @@ dependencies = [
|
|||||||
"tower-service",
|
"tower-service",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tower-http"
|
||||||
|
version = "0.6.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"bytes",
|
||||||
|
"futures-util",
|
||||||
|
"http",
|
||||||
|
"http-body",
|
||||||
|
"iri-string",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tower",
|
||||||
|
"tower-layer",
|
||||||
|
"tower-service",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-layer"
|
name = "tower-layer"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
@ -1707,48 +1733,13 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-link"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-registry"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
|
|
||||||
dependencies = [
|
|
||||||
"windows-result",
|
|
||||||
"windows-strings",
|
|
||||||
"windows-targets 0.53.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-result"
|
|
||||||
version = "0.3.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-strings"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
|
|
||||||
dependencies = [
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.52.6",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1757,7 +1748,7 @@ version = "0.59.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets 0.52.6",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1766,30 +1757,14 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm 0.52.6",
|
"windows_aarch64_gnullvm",
|
||||||
"windows_aarch64_msvc 0.52.6",
|
"windows_aarch64_msvc",
|
||||||
"windows_i686_gnu 0.52.6",
|
"windows_i686_gnu",
|
||||||
"windows_i686_gnullvm 0.52.6",
|
"windows_i686_gnullvm",
|
||||||
"windows_i686_msvc 0.52.6",
|
"windows_i686_msvc",
|
||||||
"windows_x86_64_gnu 0.52.6",
|
"windows_x86_64_gnu",
|
||||||
"windows_x86_64_gnullvm 0.52.6",
|
"windows_x86_64_gnullvm",
|
||||||
"windows_x86_64_msvc 0.52.6",
|
"windows_x86_64_msvc",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.53.0",
|
|
||||||
"windows_aarch64_msvc 0.53.0",
|
|
||||||
"windows_i686_gnu 0.53.0",
|
|
||||||
"windows_i686_gnullvm 0.53.0",
|
|
||||||
"windows_i686_msvc 0.53.0",
|
|
||||||
"windows_x86_64_gnu 0.53.0",
|
|
||||||
"windows_x86_64_gnullvm 0.53.0",
|
|
||||||
"windows_x86_64_msvc 0.53.0",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1798,96 +1773,48 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnullvm"
|
name = "windows_i686_gnullvm"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.53.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen-rt"
|
name = "wit-bindgen-rt"
|
||||||
version = "0.33.0"
|
version = "0.33.0"
|
||||||
|
1
changelog.d/18070.feature
Normal file
1
changelog.d/18070.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Support for [MSC4235](https://github.com/matrix-org/matrix-spec-proposals/pull/4235): via query param for hierarchy endpoint. Contributed by Krishan (@kfiven).
|
1
changelog.d/18196.feature
Normal file
1
changelog.d/18196.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add `forget_forced_upon_leave` capability as per [MSC4267](https://github.com/matrix-org/matrix-spec-proposals/pull/4267).
|
1
changelog.d/18241.feature
Normal file
1
changelog.d/18241.feature
Normal file
@ -0,0 +1 @@
|
|||||||
|
Add `federated_user_may_invite` spam checker callback which receives the entire invite event. Contributed by @tulir @ Beeper.
|
1
changelog.d/18418.removal
Normal file
1
changelog.d/18418.removal
Normal file
@ -0,0 +1 @@
|
|||||||
|
Stop adding the "origin" field to newly-created events (PDUs).
|
1
changelog.d/18509.bugfix
Normal file
1
changelog.d/18509.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Fix `KeyError` on background updates when using split main/state databases.
|
1
changelog.d/18519.doc
Normal file
1
changelog.d/18519.doc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Fix documentation of the Delete Room Admin API's status field.
|
1
changelog.d/18573.misc
Normal file
1
changelog.d/18573.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Improve docstring on `simple_upsert_many`.
|
1
changelog.d/18575.misc
Normal file
1
changelog.d/18575.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Raise poetry-core version cap to 2.1.3.
|
1
changelog.d/18582.bugfix
Normal file
1
changelog.d/18582.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Improve performance of device deletion by adding missing index.
|
1
changelog.d/18594.bugfix
Normal file
1
changelog.d/18594.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Respond with 401 & `M_USER_LOCKED` when a locked user calls `POST /login`, as per the spec.
|
1
changelog.d/18595.misc
Normal file
1
changelog.d/18595.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Better handling of ratelimited requests.
|
1
changelog.d/18600.misc
Normal file
1
changelog.d/18600.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Better handling of ratelimited requests.
|
1
changelog.d/18602.misc
Normal file
1
changelog.d/18602.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Speed up bulk device deletion.
|
1
changelog.d/18605.bugfix
Normal file
1
changelog.d/18605.bugfix
Normal file
@ -0,0 +1 @@
|
|||||||
|
Ensure policy servers are not asked to scan policy server change events, allowing rooms to disable the use of a policy server while the policy server is down.
|
1
changelog.d/18625.misc
Normal file
1
changelog.d/18625.misc
Normal file
@ -0,0 +1 @@
|
|||||||
|
Log the room ID we're purging state for.
|
@ -45,6 +45,10 @@ def make_graph(pdus: List[dict], filename_prefix: str) -> None:
|
|||||||
colors = {"red", "green", "blue", "yellow", "purple"}
|
colors = {"red", "green", "blue", "yellow", "purple"}
|
||||||
|
|
||||||
for pdu in pdus:
|
for pdu in pdus:
|
||||||
|
# TODO: The "origin" field has since been removed from events generated
|
||||||
|
# by Synapse. We should consider removing it here as well but since this
|
||||||
|
# is part of `contrib/`, it is left for the community to revise and ensure things
|
||||||
|
# still work correctly.
|
||||||
origins.add(pdu.get("origin"))
|
origins.add(pdu.get("origin"))
|
||||||
|
|
||||||
color_map = {color: color for color in colors if color in origins}
|
color_map = {color: color for color in colors if color in origins}
|
||||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
|||||||
|
matrix-synapse-py3 (1.133.0) stable; urgency=medium
|
||||||
|
|
||||||
|
* New synapse release 1.133.0.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Tue, 01 Jul 2025 13:13:24 +0000
|
||||||
|
|
||||||
matrix-synapse-py3 (1.133.0~rc1) stable; urgency=medium
|
matrix-synapse-py3 (1.133.0~rc1) stable; urgency=medium
|
||||||
|
|
||||||
* New Synapse release 1.133.0rc1.
|
* New Synapse release 1.133.0rc1.
|
||||||
|
@ -117,7 +117,6 @@ It returns a JSON body like the following:
|
|||||||
"hashes": {
|
"hashes": {
|
||||||
"sha256": "xK1//xnmvHJIOvbgXlkI8eEqdvoMmihVDJ9J4SNlsAw"
|
"sha256": "xK1//xnmvHJIOvbgXlkI8eEqdvoMmihVDJ9J4SNlsAw"
|
||||||
},
|
},
|
||||||
"origin": "matrix.org",
|
|
||||||
"origin_server_ts": 1592291711430,
|
"origin_server_ts": 1592291711430,
|
||||||
"prev_events": [
|
"prev_events": [
|
||||||
"$YK4arsKKcc0LRoe700pS8DSjOvUT4NDv0HfInlMFw2M"
|
"$YK4arsKKcc0LRoe700pS8DSjOvUT4NDv0HfInlMFw2M"
|
||||||
|
@ -806,7 +806,7 @@ A response body like the following is returned:
|
|||||||
}, {
|
}, {
|
||||||
"delete_id": "delete_id2",
|
"delete_id": "delete_id2",
|
||||||
"room_id": "!roomid:example.com",
|
"room_id": "!roomid:example.com",
|
||||||
"status": "purging",
|
"status": "active",
|
||||||
"shutdown_room": {
|
"shutdown_room": {
|
||||||
"kicked_users": [
|
"kicked_users": [
|
||||||
"@foobar:example.com"
|
"@foobar:example.com"
|
||||||
@ -843,7 +843,7 @@ A response body like the following is returned:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"status": "purging",
|
"status": "active",
|
||||||
"delete_id": "bHkCNQpHqOaFhPtK",
|
"delete_id": "bHkCNQpHqOaFhPtK",
|
||||||
"room_id": "!roomid:example.com",
|
"room_id": "!roomid:example.com",
|
||||||
"shutdown_room": {
|
"shutdown_room": {
|
||||||
@ -876,8 +876,8 @@ The following fields are returned in the JSON response body:
|
|||||||
- `delete_id` - The ID for this purge
|
- `delete_id` - The ID for this purge
|
||||||
- `room_id` - The ID of the room being deleted
|
- `room_id` - The ID of the room being deleted
|
||||||
- `status` - The status will be one of:
|
- `status` - The status will be one of:
|
||||||
- `shutting_down` - The process is removing users from the room.
|
- `scheduled` - The deletion is waiting to be started
|
||||||
- `purging` - The process is purging the room and event data from database.
|
- `active` - The process is purging the room and event data from database.
|
||||||
- `complete` - The process has completed successfully.
|
- `complete` - The process has completed successfully.
|
||||||
- `failed` - The process is aborted, an error has occurred.
|
- `failed` - The process is aborted, an error has occurred.
|
||||||
- `error` - A string that shows an error message if `status` is `failed`.
|
- `error` - A string that shows an error message if `status` is `failed`.
|
||||||
|
@ -80,6 +80,8 @@ Called when processing an invitation, both when one is created locally or when
|
|||||||
receiving an invite over federation. Both inviter and invitee are represented by
|
receiving an invite over federation. Both inviter and invitee are represented by
|
||||||
their Matrix user ID (e.g. `@alice:example.com`).
|
their Matrix user ID (e.g. `@alice:example.com`).
|
||||||
|
|
||||||
|
Note that federated invites will call `federated_user_may_invite` before this callback.
|
||||||
|
|
||||||
|
|
||||||
The callback must return one of:
|
The callback must return one of:
|
||||||
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
|
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
|
||||||
@ -97,6 +99,34 @@ be used. If this happens, Synapse will not call any of the subsequent implementa
|
|||||||
this callback.
|
this callback.
|
||||||
|
|
||||||
|
|
||||||
|
### `federated_user_may_invite`
|
||||||
|
|
||||||
|
_First introduced in Synapse v1.133.0_
|
||||||
|
|
||||||
|
```python
|
||||||
|
async def federated_user_may_invite(event: "synapse.events.EventBase") -> Union["synapse.module_api.NOT_SPAM", "synapse.module_api.errors.Codes", bool]
|
||||||
|
```
|
||||||
|
|
||||||
|
Called when processing an invitation received over federation. Unlike `user_may_invite`,
|
||||||
|
this callback receives the entire event, including any stripped state in the `unsigned`
|
||||||
|
section, not just the room and user IDs.
|
||||||
|
|
||||||
|
The callback must return one of:
|
||||||
|
- `synapse.module_api.NOT_SPAM`, to allow the operation. Other callbacks may still
|
||||||
|
decide to reject it.
|
||||||
|
- `synapse.module_api.errors.Codes` to reject the operation with an error code. In case
|
||||||
|
of doubt, `synapse.module_api.errors.Codes.FORBIDDEN` is a good error code.
|
||||||
|
|
||||||
|
If multiple modules implement this callback, they will be considered in order. If a
|
||||||
|
callback returns `synapse.module_api.NOT_SPAM`, Synapse falls through to the next one.
|
||||||
|
The value of the first callback that does not return `synapse.module_api.NOT_SPAM` will
|
||||||
|
be used. If this happens, Synapse will not call any of the subsequent implementations of
|
||||||
|
this callback.
|
||||||
|
|
||||||
|
If all of the callbacks return `synapse.module_api.NOT_SPAM`, Synapse will also fall
|
||||||
|
through to the `user_may_invite` callback before approving the invite.
|
||||||
|
|
||||||
|
|
||||||
### `user_may_send_3pid_invite`
|
### `user_may_send_3pid_invite`
|
||||||
|
|
||||||
_First introduced in Synapse v1.45.0_
|
_First introduced in Synapse v1.45.0_
|
||||||
|
291
poetry.lock
generated
291
poetry.lock
generated
@ -1,4 +1,4 @@
|
|||||||
# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "annotated-types"
|
name = "annotated-types"
|
||||||
@ -39,7 +39,7 @@ description = "The ultimate Python library in building OAuth and OpenID Connect
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"oidc\" or extra == \"jwt\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"jwt\" or extra == \"oidc\""
|
||||||
files = [
|
files = [
|
||||||
{file = "authlib-1.5.2-py2.py3-none-any.whl", hash = "sha256:8804dd4402ac5e4a0435ac49e0b6e19e395357cfa632a3f624dcb4f6df13b4b1"},
|
{file = "authlib-1.5.2-py2.py3-none-any.whl", hash = "sha256:8804dd4402ac5e4a0435ac49e0b6e19e395357cfa632a3f624dcb4f6df13b4b1"},
|
||||||
{file = "authlib-1.5.2.tar.gz", hash = "sha256:fe85ec7e50c5f86f1e2603518bb3b4f632985eb4a355e52256530790e326c512"},
|
{file = "authlib-1.5.2.tar.gz", hash = "sha256:fe85ec7e50c5f86f1e2603518bb3b4f632985eb4a355e52256530790e326c512"},
|
||||||
@ -450,7 +450,7 @@ description = "XML bomb protection for Python stdlib modules"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"saml2\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"saml2\""
|
||||||
files = [
|
files = [
|
||||||
{file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
|
{file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
|
||||||
{file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
|
{file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
|
||||||
@ -493,7 +493,7 @@ description = "XPath 1.0/2.0/3.0/3.1 parsers and selectors for ElementTree and l
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"saml2\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"saml2\""
|
||||||
files = [
|
files = [
|
||||||
{file = "elementpath-4.1.5-py3-none-any.whl", hash = "sha256:2ac1a2fb31eb22bbbf817f8cf6752f844513216263f0e3892c8e79782fe4bb55"},
|
{file = "elementpath-4.1.5-py3-none-any.whl", hash = "sha256:2ac1a2fb31eb22bbbf817f8cf6752f844513216263f0e3892c8e79782fe4bb55"},
|
||||||
{file = "elementpath-4.1.5.tar.gz", hash = "sha256:c2d6dc524b29ef751ecfc416b0627668119d8812441c555d7471da41d4bacb8d"},
|
{file = "elementpath-4.1.5.tar.gz", hash = "sha256:c2d6dc524b29ef751ecfc416b0627668119d8812441c555d7471da41d4bacb8d"},
|
||||||
@ -543,7 +543,7 @@ description = "Python wrapper for hiredis"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"redis\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"redis\""
|
||||||
files = [
|
files = [
|
||||||
{file = "hiredis-3.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:2892db9db21f0cf7cc298d09f85d3e1f6dc4c4c24463ab67f79bc7a006d51867"},
|
{file = "hiredis-3.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:2892db9db21f0cf7cc298d09f85d3e1f6dc4c4c24463ab67f79bc7a006d51867"},
|
||||||
{file = "hiredis-3.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:93cfa6cc25ee2ceb0be81dc61eca9995160b9e16bdb7cca4a00607d57e998918"},
|
{file = "hiredis-3.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:93cfa6cc25ee2ceb0be81dc61eca9995160b9e16bdb7cca4a00607d57e998918"},
|
||||||
@ -889,7 +889,7 @@ description = "Jaeger Python OpenTracing Tracer implementation"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||||
files = [
|
files = [
|
||||||
{file = "jaeger-client-4.8.0.tar.gz", hash = "sha256:3157836edab8e2c209bd2d6ae61113db36f7ee399e66b1dcbb715d87ab49bfe0"},
|
{file = "jaeger-client-4.8.0.tar.gz", hash = "sha256:3157836edab8e2c209bd2d6ae61113db36f7ee399e66b1dcbb715d87ab49bfe0"},
|
||||||
]
|
]
|
||||||
@ -1027,7 +1027,7 @@ description = "A strictly RFC 4510 conforming LDAP V3 pure Python client library
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"matrix-synapse-ldap3\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"matrix-synapse-ldap3\""
|
||||||
files = [
|
files = [
|
||||||
{file = "ldap3-2.9.1-py2.py3-none-any.whl", hash = "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70"},
|
{file = "ldap3-2.9.1-py2.py3-none-any.whl", hash = "sha256:5869596fc4948797020d3f03b7939da938778a0f9e2009f7a072ccf92b8e8d70"},
|
||||||
{file = "ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"},
|
{file = "ldap3-2.9.1.tar.gz", hash = "sha256:f3e7fc4718e3f09dda568b57100095e0ce58633bcabbed8667ce3f8fbaa4229f"},
|
||||||
@ -1043,7 +1043,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"url-preview\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"url-preview\""
|
||||||
files = [
|
files = [
|
||||||
{file = "lxml-5.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e7bc6df34d42322c5289e37e9971d6ed114e3776b45fa879f734bded9d1fea9c"},
|
{file = "lxml-5.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e7bc6df34d42322c5289e37e9971d6ed114e3776b45fa879f734bded9d1fea9c"},
|
||||||
{file = "lxml-5.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6854f8bd8a1536f8a1d9a3655e6354faa6406621cf857dc27b681b69860645c7"},
|
{file = "lxml-5.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6854f8bd8a1536f8a1d9a3655e6354faa6406621cf857dc27b681b69860645c7"},
|
||||||
@ -1323,7 +1323,7 @@ description = "An LDAP3 auth provider for Synapse"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"matrix-synapse-ldap3\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"matrix-synapse-ldap3\""
|
||||||
files = [
|
files = [
|
||||||
{file = "matrix-synapse-ldap3-0.3.0.tar.gz", hash = "sha256:8bb6517173164d4b9cc44f49de411d8cebdb2e705d5dd1ea1f38733c4a009e1d"},
|
{file = "matrix-synapse-ldap3-0.3.0.tar.gz", hash = "sha256:8bb6517173164d4b9cc44f49de411d8cebdb2e705d5dd1ea1f38733c4a009e1d"},
|
||||||
{file = "matrix_synapse_ldap3-0.3.0-py3-none-any.whl", hash = "sha256:8b4d701f8702551e98cc1d8c20dbed532de5613584c08d0df22de376ba99159d"},
|
{file = "matrix_synapse_ldap3-0.3.0-py3-none-any.whl", hash = "sha256:8b4d701f8702551e98cc1d8c20dbed532de5613584c08d0df22de376ba99159d"},
|
||||||
@ -1436,6 +1436,22 @@ files = [
|
|||||||
{file = "msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e"},
|
{file = "msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "multipart"
|
||||||
|
version = "1.2.1"
|
||||||
|
description = "Parser for multipart/form-data"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
groups = ["main"]
|
||||||
|
files = [
|
||||||
|
{file = "multipart-1.2.1-py3-none-any.whl", hash = "sha256:c03dc203bc2e67f6b46a599467ae0d87cf71d7530504b2c1ff4a9ea21d8b8c8c"},
|
||||||
|
{file = "multipart-1.2.1.tar.gz", hash = "sha256:829b909b67bc1ad1c6d4488fcdc6391c2847842b08323addf5200db88dbe9480"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["build", "pytest", "pytest-cov", "twine"]
|
||||||
|
docs = ["sphinx (>=8,<9)", "sphinx-autobuild"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
@ -1544,7 +1560,7 @@ description = "OpenTracing API for Python. See documentation at http://opentraci
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||||
files = [
|
files = [
|
||||||
{file = "opentracing-2.4.0.tar.gz", hash = "sha256:a173117e6ef580d55874734d1fa7ecb6f3655160b8b8974a2a1e98e5ec9c840d"},
|
{file = "opentracing-2.4.0.tar.gz", hash = "sha256:a173117e6ef580d55874734d1fa7ecb6f3655160b8b8974a2a1e98e5ec9c840d"},
|
||||||
]
|
]
|
||||||
@ -1593,114 +1609,119 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pillow"
|
name = "pillow"
|
||||||
version = "11.2.1"
|
version = "11.3.0"
|
||||||
description = "Python Imaging Library (Fork)"
|
description = "Python Imaging Library (Fork)"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pillow-11.2.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:d57a75d53922fc20c165016a20d9c44f73305e67c351bbc60d1adaf662e74047"},
|
{file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:127bf6ac4a5b58b3d32fc8289656f77f80567d65660bc46f72c0d77e6600cc95"},
|
{file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4ba4be812c7a40280629e55ae0b14a0aafa150dd6451297562e1764808bbe61"},
|
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8bd62331e5032bc396a93609982a9ab6b411c05078a52f5fe3cc59234a3abd1"},
|
{file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:562d11134c97a62fe3af29581f083033179f7ff435f78392565a1ad2d1c2c45c"},
|
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:c97209e85b5be259994eb5b69ff50c5d20cca0f458ef9abd835e262d9d88b39d"},
|
{file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0c3e6d0f59171dfa2e25d7116217543310908dfa2770aa64b8f87605f8cacc97"},
|
{file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cc1c3bc53befb6096b84165956e886b1729634a799e9d6329a0c512ab651e579"},
|
{file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-win32.whl", hash = "sha256:312c77b7f07ab2139924d2639860e084ec2a13e72af54d4f08ac843a5fc9c79d"},
|
{file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:9bc7ae48b8057a611e5fe9f853baa88093b9a76303937449397899385da06fad"},
|
{file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"},
|
||||||
{file = "pillow-11.2.1-cp310-cp310-win_arm64.whl", hash = "sha256:2728567e249cdd939f6cc3d1f049595c66e4187f3c34078cbc0a7d21c47482d2"},
|
{file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35ca289f712ccfc699508c4658a1d14652e8033e9b69839edf83cbdd0ba39e70"},
|
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0409af9f829f87a2dfb7e259f78f317a5351f2045158be321fd135973fff7bf"},
|
{file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4e5c5edee874dce4f653dbe59db7c73a600119fbea8d31f53423586ee2aafd7"},
|
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b93a07e76d13bff9444f1a029e0af2964e654bfc2e2c2d46bfd080df5ad5f3d8"},
|
{file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:e6def7eed9e7fa90fde255afaf08060dc4b343bbe524a8f69bdd2a2f0018f600"},
|
{file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8f4f3724c068be008c08257207210c138d5f3731af6c155a81c2b09a9eb3a788"},
|
{file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a0a6709b47019dff32e678bc12c63008311b82b9327613f534e496dacaefb71e"},
|
{file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f6b0c664ccb879109ee3ca702a9272d877f4fcd21e5eb63c26422fd6e415365e"},
|
{file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-win32.whl", hash = "sha256:cc5d875d56e49f112b6def6813c4e3d3036d269c008bf8aef72cd08d20ca6df6"},
|
{file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:0f5c7eda47bf8e3c8a283762cab94e496ba977a420868cb819159980b6709193"},
|
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"},
|
||||||
{file = "pillow-11.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:4d375eb838755f2528ac8cbc926c3e31cc49ca4ad0cf79cff48b20e30634a4a7"},
|
{file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:78afba22027b4accef10dbd5eed84425930ba41b3ea0a86fa8d20baaf19d807f"},
|
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:78092232a4ab376a35d68c4e6d5e00dfd73454bd12b230420025fbe178ee3b0b"},
|
{file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a5f306095c6780c52e6bbb6109624b95c5b18e40aab1c3041da3e9e0cd3e2d"},
|
{file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c7b29dbd4281923a2bfe562acb734cee96bbb129e96e6972d315ed9f232bef4"},
|
{file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:3e645b020f3209a0181a418bffe7b4a93171eef6c4ef6cc20980b30bebf17b7d"},
|
{file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:b2dbea1012ccb784a65349f57bbc93730b96e85b42e9bf7b01ef40443db720b4"},
|
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:da3104c57bbd72948d75f6a9389e6727d2ab6333c3617f0a89d72d4940aa0443"},
|
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:598174aef4589af795f66f9caab87ba4ff860ce08cd5bb447c6fc553ffee603c"},
|
{file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-win32.whl", hash = "sha256:1d535df14716e7f8776b9e7fee118576d65572b4aad3ed639be9e4fa88a1cad3"},
|
{file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:14e33b28bf17c7a38eede290f77db7c664e4eb01f7869e37fa98a5aa95978941"},
|
{file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"},
|
||||||
{file = "pillow-11.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:21e1470ac9e5739ff880c211fc3af01e3ae505859392bf65458c224d0bf283eb"},
|
{file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fdec757fea0b793056419bca3e9932eb2b0ceec90ef4813ea4c1e072c389eb28"},
|
{file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0e130705d568e2f43a17bcbe74d90958e8a16263868a12c3e0d9c8162690830"},
|
{file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdb5e09068332578214cadd9c05e3d64d99e0e87591be22a324bdbc18925be0"},
|
{file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d189ba1bebfbc0c0e529159631ec72bb9e9bc041f01ec6d3233d6d82eb823bc1"},
|
{file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:191955c55d8a712fab8934a42bfefbf99dd0b5875078240943f913bb66d46d9f"},
|
{file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ad275964d52e2243430472fc5d2c2334b4fc3ff9c16cb0a19254e25efa03a155"},
|
{file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:750f96efe0597382660d8b53e90dd1dd44568a8edb51cb7f9d5d918b80d4de14"},
|
{file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fe15238d3798788d00716637b3d4e7bb6bde18b26e5d08335a96e88564a36b6b"},
|
{file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-win32.whl", hash = "sha256:3fe735ced9a607fee4f481423a9c36701a39719252a9bb251679635f99d0f7d2"},
|
{file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:74ee3d7ecb3f3c05459ba95eed5efa28d6092d751ce9bf20e3e253a4e497e691"},
|
{file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:5119225c622403afb4b44bad4c1ca6c1f98eed79db8d3bc6e4e160fc6339d66c"},
|
{file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8ce2e8411c7aaef53e6bb29fe98f28cd4fbd9a1d9be2eeea434331aac0536b22"},
|
{file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9ee66787e095127116d91dea2143db65c7bb1e232f617aa5957c0d9d2a3f23a7"},
|
{file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9622e3b6c1d8b551b6e6f21873bdcc55762b4b2126633014cea1803368a9aa16"},
|
{file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63b5dff3a68f371ea06025a1a6966c9a1e1ee452fc8020c2cd0ea41b83e9037b"},
|
{file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:31df6e2d3d8fc99f993fd253e97fae451a8db2e7207acf97859732273e108406"},
|
{file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:062b7a42d672c45a70fa1f8b43d1d38ff76b63421cbbe7f88146b39e8a558d91"},
|
{file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4eb92eca2711ef8be42fd3f67533765d9fd043b8c80db204f16c8ea62ee1a751"},
|
{file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f91ebf30830a48c825590aede79376cb40f110b387c17ee9bd59932c961044f9"},
|
{file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-win32.whl", hash = "sha256:e0b55f27f584ed623221cfe995c912c61606be8513bfa0e07d2c674b4516d9dd"},
|
{file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:36d6b82164c39ce5482f649b437382c0fb2395eabc1e2b1702a6deb8ad647d6e"},
|
{file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"},
|
||||||
{file = "pillow-11.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:225c832a13326e34f212d2072982bb1adb210e0cc0b153e688743018c94a2681"},
|
{file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:7491cf8a79b8eb867d419648fff2f83cb0b3891c8b36da92cc7f1931d46108c8"},
|
{file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b02d8f9cb83c52578a0b4beadba92e37d83a4ef11570a8688bbf43f4ca50909"},
|
{file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:014ca0050c85003620526b0ac1ac53f56fc93af128f7546623cc8e31875ab928"},
|
{file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3692b68c87096ac6308296d96354eddd25f98740c9d2ab54e1549d6c8aea9d79"},
|
{file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:f781dcb0bc9929adc77bad571b8621ecb1e4cdef86e940fe2e5b5ee24fd33b35"},
|
{file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:2b490402c96f907a166615e9a5afacf2519e28295f157ec3a2bb9bd57de638cb"},
|
{file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dd6b20b93b3ccc9c1b597999209e4bc5cf2853f9ee66e3fc9a400a78733ffc9a"},
|
{file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:4b835d89c08a6c2ee7781b8dd0a30209a8012b5f09c0a665b65b0eb3560b6f36"},
|
{file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-win32.whl", hash = "sha256:b10428b3416d4f9c61f94b494681280be7686bda15898a3a9e08eb66a6d92d67"},
|
{file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:6ebce70c3f486acf7591a3d73431fa504a4e18a9b97ff27f5f47b7368e4b9dd1"},
|
{file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"},
|
||||||
{file = "pillow-11.2.1-cp39-cp39-win_arm64.whl", hash = "sha256:c27476257b2fdcd7872d54cfd119b3a9ce4610fb85c8e32b70b42e3680a29a1e"},
|
{file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"},
|
||||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9b7b0d4fd2635f54ad82785d56bc0d94f147096493a79985d0ab57aedd563156"},
|
{file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"},
|
||||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:aa442755e31c64037aa7c1cb186e0b369f8416c567381852c63444dd666fb772"},
|
{file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"},
|
||||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d3348c95b766f54b76116d53d4cb171b52992a1027e7ca50c81b43b9d9e363"},
|
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"},
|
||||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85d27ea4c889342f7e35f6d56e7e1cb345632ad592e8c51b693d7b7556043ce0"},
|
{file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"},
|
||||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bf2c33d6791c598142f00c9c4c7d47f6476731c31081331664eb26d6ab583e01"},
|
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"},
|
||||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e616e7154c37669fc1dfc14584f11e284e05d1c650e1c0f972f281c4ccc53193"},
|
{file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"},
|
||||||
{file = "pillow-11.2.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:39ad2e0f424394e3aebc40168845fee52df1394a4673a6ee512d840d14ab3013"},
|
{file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"},
|
||||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:80f1df8dbe9572b4b7abdfa17eb5d78dd620b1d55d9e25f834efdbee872d3aed"},
|
{file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"},
|
||||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ea926cfbc3957090becbcbbb65ad177161a2ff2ad578b5a6ec9bb1e1cd78753c"},
|
{file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"},
|
||||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:738db0e0941ca0376804d4de6a782c005245264edaa253ffce24e5a15cbdc7bd"},
|
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"},
|
||||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9db98ab6565c69082ec9b0d4e40dd9f6181dab0dd236d26f7a50b8b9bfbd5076"},
|
{file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"},
|
||||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:036e53f4170e270ddb8797d4c590e6dd14d28e15c7da375c18978045f7e6c37b"},
|
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"},
|
||||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14f73f7c291279bd65fda51ee87affd7c1e097709f7fdd0188957a16c264601f"},
|
{file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"},
|
||||||
{file = "pillow-11.2.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:208653868d5c9ecc2b327f9b9ef34e0e42a4cdd172c2988fd81d62d2bc9bc044"},
|
{file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"},
|
||||||
{file = "pillow-11.2.1.tar.gz", hash = "sha256:a64dd61998416367b7ef979b73d3a85853ba9bec4c2925f74e588879a58716b6"},
|
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"},
|
||||||
|
{file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"},
|
||||||
|
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"},
|
||||||
|
{file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"},
|
||||||
|
{file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"},
|
||||||
|
{file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
|
docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
|
||||||
fpx = ["olefile"]
|
fpx = ["olefile"]
|
||||||
mic = ["olefile"]
|
mic = ["olefile"]
|
||||||
test-arrow = ["pyarrow"]
|
test-arrow = ["pyarrow"]
|
||||||
tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "trove-classifiers (>=2024.10.12)"]
|
tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"]
|
||||||
typing = ["typing-extensions ; python_version < \"3.10\""]
|
typing = ["typing-extensions ; python_version < \"3.10\""]
|
||||||
xmp = ["defusedxml"]
|
xmp = ["defusedxml"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prometheus-client"
|
name = "prometheus-client"
|
||||||
version = "0.21.0"
|
version = "0.22.1"
|
||||||
description = "Python client for the Prometheus monitoring system."
|
description = "Python client for the Prometheus monitoring system."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.9"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "prometheus_client-0.21.0-py3-none-any.whl", hash = "sha256:4fa6b4dd0ac16d58bb587c04b1caae65b8c5043e85f778f42f5f632f6af2e166"},
|
{file = "prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094"},
|
||||||
{file = "prometheus_client-0.21.0.tar.gz", hash = "sha256:96c83c606b71ff2b0a433c98889d275f51ffec6c5e267de37c7a2b5c9aa9233e"},
|
{file = "prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -1713,7 +1734,7 @@ description = "psycopg2 - Python-PostgreSQL Database Adapter"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"postgres\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"postgres\""
|
||||||
files = [
|
files = [
|
||||||
{file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"},
|
{file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"},
|
||||||
{file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"},
|
{file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"},
|
||||||
@ -1721,6 +1742,7 @@ files = [
|
|||||||
{file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"},
|
{file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"},
|
||||||
{file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"},
|
{file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"},
|
||||||
{file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"},
|
{file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"},
|
||||||
|
{file = "psycopg2-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2"},
|
||||||
{file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"},
|
{file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"},
|
||||||
{file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"},
|
{file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"},
|
||||||
{file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"},
|
{file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"},
|
||||||
@ -1733,7 +1755,7 @@ description = ".. image:: https://travis-ci.org/chtd/psycopg2cffi.svg?branch=mas
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "platform_python_implementation == \"PyPy\" and (extra == \"postgres\" or extra == \"all\")"
|
markers = "platform_python_implementation == \"PyPy\" and (extra == \"all\" or extra == \"postgres\")"
|
||||||
files = [
|
files = [
|
||||||
{file = "psycopg2cffi-2.9.0.tar.gz", hash = "sha256:7e272edcd837de3a1d12b62185eb85c45a19feda9e62fa1b120c54f9e8d35c52"},
|
{file = "psycopg2cffi-2.9.0.tar.gz", hash = "sha256:7e272edcd837de3a1d12b62185eb85c45a19feda9e62fa1b120c54f9e8d35c52"},
|
||||||
]
|
]
|
||||||
@ -1749,7 +1771,7 @@ description = "A Simple library to enable psycopg2 compatability"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "platform_python_implementation == \"PyPy\" and (extra == \"postgres\" or extra == \"all\")"
|
markers = "platform_python_implementation == \"PyPy\" and (extra == \"all\" or extra == \"postgres\")"
|
||||||
files = [
|
files = [
|
||||||
{file = "psycopg2cffi-compat-1.1.tar.gz", hash = "sha256:d25e921748475522b33d13420aad5c2831c743227dc1f1f2585e0fdb5c914e05"},
|
{file = "psycopg2cffi-compat-1.1.tar.gz", hash = "sha256:d25e921748475522b33d13420aad5c2831c743227dc1f1f2585e0fdb5c914e05"},
|
||||||
]
|
]
|
||||||
@ -1771,18 +1793,18 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyasn1-modules"
|
name = "pyasn1-modules"
|
||||||
version = "0.4.1"
|
version = "0.4.2"
|
||||||
description = "A collection of ASN.1-based protocols modules"
|
description = "A collection of ASN.1-based protocols modules"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"},
|
{file = "pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a"},
|
||||||
{file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"},
|
{file = "pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pyasn1 = ">=0.4.6,<0.7.0"
|
pyasn1 = ">=0.6.1,<0.7.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycparser"
|
name = "pycparser"
|
||||||
@ -1972,7 +1994,7 @@ description = "Python extension wrapping the ICU C++ API"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"user-search\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"user-search\""
|
||||||
files = [
|
files = [
|
||||||
{file = "PyICU-2.14.tar.gz", hash = "sha256:acc7eb92bd5c554ed577249c6978450a4feda0aa6f01470152b3a7b382a02132"},
|
{file = "PyICU-2.14.tar.gz", hash = "sha256:acc7eb92bd5c554ed577249c6978450a4feda0aa6f01470152b3a7b382a02132"},
|
||||||
]
|
]
|
||||||
@ -2021,7 +2043,7 @@ description = "A development tool to measure, monitor and analyze the memory beh
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"cache-memory\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"cache-memory\""
|
||||||
files = [
|
files = [
|
||||||
{file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"},
|
{file = "Pympler-1.0.1-py3-none-any.whl", hash = "sha256:d260dda9ae781e1eab6ea15bacb84015849833ba5555f141d2d9b7b7473b307d"},
|
||||||
{file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"},
|
{file = "Pympler-1.0.1.tar.gz", hash = "sha256:993f1a3599ca3f4fcd7160c7545ad06310c9e12f70174ae7ae8d4e25f6c5d3fa"},
|
||||||
@ -2081,7 +2103,7 @@ description = "Python implementation of SAML Version 2 Standard"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.9,<4.0"
|
python-versions = ">=3.9,<4.0"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"saml2\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"saml2\""
|
||||||
files = [
|
files = [
|
||||||
{file = "pysaml2-7.5.0-py3-none-any.whl", hash = "sha256:bc6627cc344476a83c757f440a73fda1369f13b6fda1b4e16bca63ffbabb5318"},
|
{file = "pysaml2-7.5.0-py3-none-any.whl", hash = "sha256:bc6627cc344476a83c757f440a73fda1369f13b6fda1b4e16bca63ffbabb5318"},
|
||||||
{file = "pysaml2-7.5.0.tar.gz", hash = "sha256:f36871d4e5ee857c6b85532e942550d2cf90ea4ee943d75eb681044bbc4f54f7"},
|
{file = "pysaml2-7.5.0.tar.gz", hash = "sha256:f36871d4e5ee857c6b85532e942550d2cf90ea4ee943d75eb681044bbc4f54f7"},
|
||||||
@ -2106,7 +2128,7 @@ description = "Extensions to the standard Python datetime module"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"saml2\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"saml2\""
|
||||||
files = [
|
files = [
|
||||||
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
{file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
|
||||||
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
{file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
|
||||||
@ -2134,7 +2156,7 @@ description = "World timezone definitions, modern and historical"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"saml2\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"saml2\""
|
||||||
files = [
|
files = [
|
||||||
{file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
|
{file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
|
||||||
{file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
|
{file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
|
||||||
@ -2498,7 +2520,7 @@ description = "Python client for Sentry (https://sentry.io)"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"sentry\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"sentry\""
|
||||||
files = [
|
files = [
|
||||||
{file = "sentry_sdk-2.22.0-py2.py3-none-any.whl", hash = "sha256:3d791d631a6c97aad4da7074081a57073126c69487560c6f8bffcf586461de66"},
|
{file = "sentry_sdk-2.22.0-py2.py3-none-any.whl", hash = "sha256:3d791d631a6c97aad4da7074081a57073126c69487560c6f8bffcf586461de66"},
|
||||||
{file = "sentry_sdk-2.22.0.tar.gz", hash = "sha256:b4bf43bb38f547c84b2eadcefbe389b36ef75f3f38253d7a74d6b928c07ae944"},
|
{file = "sentry_sdk-2.22.0.tar.gz", hash = "sha256:b4bf43bb38f547c84b2eadcefbe389b36ef75f3f38253d7a74d6b928c07ae944"},
|
||||||
@ -2686,7 +2708,7 @@ description = "Tornado IOLoop Backed Concurrent Futures"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||||
files = [
|
files = [
|
||||||
{file = "threadloop-1.0.2-py2-none-any.whl", hash = "sha256:5c90dbefab6ffbdba26afb4829d2a9df8275d13ac7dc58dccb0e279992679599"},
|
{file = "threadloop-1.0.2-py2-none-any.whl", hash = "sha256:5c90dbefab6ffbdba26afb4829d2a9df8275d13ac7dc58dccb0e279992679599"},
|
||||||
{file = "threadloop-1.0.2.tar.gz", hash = "sha256:8b180aac31013de13c2ad5c834819771992d350267bddb854613ae77ef571944"},
|
{file = "threadloop-1.0.2.tar.gz", hash = "sha256:8b180aac31013de13c2ad5c834819771992d350267bddb854613ae77ef571944"},
|
||||||
@ -2702,7 +2724,7 @@ description = "Python bindings for the Apache Thrift RPC system"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||||
files = [
|
files = [
|
||||||
{file = "thrift-0.16.0.tar.gz", hash = "sha256:2b5b6488fcded21f9d312aa23c9ff6a0195d0f6ae26ddbd5ad9e3e25dfc14408"},
|
{file = "thrift-0.16.0.tar.gz", hash = "sha256:2b5b6488fcded21f9d312aa23c9ff6a0195d0f6ae26ddbd5ad9e3e25dfc14408"},
|
||||||
]
|
]
|
||||||
@ -2764,7 +2786,7 @@ description = "Tornado is a Python web framework and asynchronous networking lib
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"opentracing\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"opentracing\""
|
||||||
files = [
|
files = [
|
||||||
{file = "tornado-6.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:f81067dad2e4443b015368b24e802d0083fecada4f0a4572fdb72fc06e54a9a6"},
|
{file = "tornado-6.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:f81067dad2e4443b015368b24e802d0083fecada4f0a4572fdb72fc06e54a9a6"},
|
||||||
{file = "tornado-6.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9ac1cbe1db860b3cbb251e795c701c41d343f06a96049d6274e7c77559117e41"},
|
{file = "tornado-6.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9ac1cbe1db860b3cbb251e795c701c41d343f06a96049d6274e7c77559117e41"},
|
||||||
@ -2804,27 +2826,28 @@ dev = ["furo (>=2024.05.06)", "nox", "packaging", "sphinx (>=5)", "twisted"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "treq"
|
name = "treq"
|
||||||
version = "24.9.1"
|
version = "25.5.0"
|
||||||
description = "High-level Twisted HTTP Client API"
|
description = "High-level Twisted HTTP Client API"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8.0"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "treq-24.9.1-py3-none-any.whl", hash = "sha256:eee4756fd9a857c77f180fd5202b52c518f2d3e2826dce28b89066c03bfc45d0"},
|
{file = "treq-25.5.0-py3-none-any.whl", hash = "sha256:e99d4e66cacaa1f0da82bb60b317d104c29dbd8ac0a75d7f657b348178d830f4"},
|
||||||
{file = "treq-24.9.1.tar.gz", hash = "sha256:15da7fc404f3e4ed59d0abe5f8eef4966fabbe618039a2a23bc7c15305cefea8"},
|
{file = "treq-25.5.0.tar.gz", hash = "sha256:25dde3a55ae85ec2f2c56332c99aef255ab14f997d0d00552ebff13538a9804a"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
attrs = "*"
|
attrs = "*"
|
||||||
hyperlink = ">=21.0.0"
|
hyperlink = ">=21.0.0"
|
||||||
incremental = "*"
|
incremental = ">=24.7.2"
|
||||||
|
multipart = "*"
|
||||||
requests = ">=2.1.0"
|
requests = ">=2.1.0"
|
||||||
Twisted = {version = ">=22.10.0", extras = ["tls"]}
|
twisted = {version = ">=22.10.0", extras = ["tls"]}
|
||||||
typing-extensions = ">=3.10.0"
|
typing-extensions = ">=3.10.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
dev = ["httpbin (==0.7.0)", "pep8", "pyflakes", "werkzeug (==2.0.3)"]
|
dev = ["httpbin (==0.7.0)", "pep8", "pyflakes", "werkzeug (==2.0.3)"]
|
||||||
docs = ["sphinx (<7.0.0)"]
|
docs = ["sphinx", "sphinx-rtd-theme"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twine"
|
name = "twine"
|
||||||
@ -2900,7 +2923,7 @@ description = "non-blocking redis client for python"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"redis\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"redis\""
|
||||||
files = [
|
files = [
|
||||||
{file = "txredisapi-1.4.11-py3-none-any.whl", hash = "sha256:ac64d7a9342b58edca13ef267d4fa7637c1aa63f8595e066801c1e8b56b22d0b"},
|
{file = "txredisapi-1.4.11-py3-none-any.whl", hash = "sha256:ac64d7a9342b58edca13ef267d4fa7637c1aa63f8595e066801c1e8b56b22d0b"},
|
||||||
{file = "txredisapi-1.4.11.tar.gz", hash = "sha256:3eb1af99aefdefb59eb877b1dd08861efad60915e30ad5bf3d5bf6c5cedcdbc6"},
|
{file = "txredisapi-1.4.11.tar.gz", hash = "sha256:3eb1af99aefdefb59eb877b1dd08861efad60915e30ad5bf3d5bf6c5cedcdbc6"},
|
||||||
@ -2966,14 +2989,14 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-jsonschema"
|
name = "types-jsonschema"
|
||||||
version = "4.23.0.20250516"
|
version = "4.24.0.20250528"
|
||||||
description = "Typing stubs for jsonschema"
|
description = "Typing stubs for jsonschema"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "types_jsonschema-4.23.0.20250516-py3-none-any.whl", hash = "sha256:e7d0dd7db7e59e63c26e3230e26ffc64c4704cc5170dc21270b366a35ead1618"},
|
{file = "types_jsonschema-4.24.0.20250528-py3-none-any.whl", hash = "sha256:6a906b5ff73ac11c8d1e0b6c30a9693e1e4e1ab56c56c932b3a7e081b86d187b"},
|
||||||
{file = "types_jsonschema-4.23.0.20250516.tar.gz", hash = "sha256:9ace09d9d35c4390a7251ccd7d833b92ccc189d24d1b347f26212afce361117e"},
|
{file = "types_jsonschema-4.24.0.20250528.tar.gz", hash = "sha256:7e28c64e0ae7980eeb158105b20663fc6a6b8f81d5f86ea6614aa0014417bd1e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@ -2993,14 +3016,14 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-opentracing"
|
name = "types-opentracing"
|
||||||
version = "2.4.10.6"
|
version = "2.4.10.20250622"
|
||||||
description = "Typing stubs for opentracing"
|
description = "Typing stubs for opentracing"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = ">=3.9"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "types-opentracing-2.4.10.6.tar.gz", hash = "sha256:87a1bdfce9de5e555e30497663583b9b9c3bb494d029ef9806aa1f137c19e744"},
|
{file = "types_opentracing-2.4.10.20250622-py3-none-any.whl", hash = "sha256:26bc21f9e385d54898b47e9bd1fa13f200c2dada50394f6eafd063ed53813062"},
|
||||||
{file = "types_opentracing-2.4.10.6-py3-none-any.whl", hash = "sha256:25914c834db033a4a38fc322df0b5e5e14503b0ac97f78304ae180d721555e97"},
|
{file = "types_opentracing-2.4.10.20250622.tar.gz", hash = "sha256:00db48b7f57136c45ac3250218bd0f18b9792566dfcbd5ad1de9f7e180347e74"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3123,14 +3146,14 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "2.2.2"
|
version = "2.5.0"
|
||||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.9"
|
||||||
groups = ["main", "dev"]
|
groups = ["main", "dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"},
|
{file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"},
|
||||||
{file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"},
|
{file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -3243,7 +3266,7 @@ description = "An XML Schema validator and decoder"
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"saml2\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"saml2\""
|
||||||
files = [
|
files = [
|
||||||
{file = "xmlschema-2.4.0-py3-none-any.whl", hash = "sha256:dc87be0caaa61f42649899189aab2fd8e0d567f2cf548433ba7b79278d231a4a"},
|
{file = "xmlschema-2.4.0-py3-none-any.whl", hash = "sha256:dc87be0caaa61f42649899189aab2fd8e0d567f2cf548433ba7b79278d231a4a"},
|
||||||
{file = "xmlschema-2.4.0.tar.gz", hash = "sha256:d74cd0c10866ac609e1ef94a5a69b018ad16e39077bc6393408b40c6babee793"},
|
{file = "xmlschema-2.4.0.tar.gz", hash = "sha256:d74cd0c10866ac609e1ef94a5a69b018ad16e39077bc6393408b40c6babee793"},
|
||||||
|
@ -101,7 +101,7 @@ module-name = "synapse.synapse_rust"
|
|||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "matrix-synapse"
|
name = "matrix-synapse"
|
||||||
version = "1.133.0rc1"
|
version = "1.133.0"
|
||||||
description = "Homeserver for the Matrix decentralised comms protocol"
|
description = "Homeserver for the Matrix decentralised comms protocol"
|
||||||
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
|
authors = ["Matrix.org Team and Contributors <packages@matrix.org>"]
|
||||||
license = "AGPL-3.0-or-later"
|
license = "AGPL-3.0-or-later"
|
||||||
@ -374,7 +374,7 @@ tomli = ">=1.2.3"
|
|||||||
# runtime errors caused by build system changes.
|
# runtime errors caused by build system changes.
|
||||||
# We are happy to raise these upper bounds upon request,
|
# 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).
|
# provided we check that it's safe to do so (i.e. that CI passes).
|
||||||
requires = ["poetry-core>=1.1.0,<=1.9.1", "setuptools_rust>=1.3,<=1.10.2"]
|
requires = ["poetry-core>=1.1.0,<=2.1.3", "setuptools_rust>=1.3,<=1.10.2"]
|
||||||
build-backend = "poetry.core.masonry.api"
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ pub enum IdentifierError {
|
|||||||
|
|
||||||
impl fmt::Display for IdentifierError {
|
impl fmt::Display for IdentifierError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{:?}", self)
|
write!(f, "{self:?}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ from synapse.api.errors import (
|
|||||||
InvalidClientTokenError,
|
InvalidClientTokenError,
|
||||||
MissingClientTokenError,
|
MissingClientTokenError,
|
||||||
UnrecognizedRequestError,
|
UnrecognizedRequestError,
|
||||||
|
UserLockedError,
|
||||||
)
|
)
|
||||||
from synapse.http.site import SynapseRequest
|
from synapse.http.site import SynapseRequest
|
||||||
from synapse.logging.opentracing import active_span, force_tracing, start_active_span
|
from synapse.logging.opentracing import active_span, force_tracing, start_active_span
|
||||||
@ -162,12 +163,7 @@ class InternalAuth(BaseAuth):
|
|||||||
if not allow_locked and await self.store.get_user_locked_status(
|
if not allow_locked and await self.store.get_user_locked_status(
|
||||||
requester.user.to_string()
|
requester.user.to_string()
|
||||||
):
|
):
|
||||||
raise AuthError(
|
raise UserLockedError()
|
||||||
401,
|
|
||||||
"User account has been locked",
|
|
||||||
errcode=Codes.USER_LOCKED,
|
|
||||||
additional_fields={"soft_logout": True},
|
|
||||||
)
|
|
||||||
|
|
||||||
# Deny the request if the user account has expired.
|
# Deny the request if the user account has expired.
|
||||||
# This check is only done for regular users, not appservice ones.
|
# This check is only done for regular users, not appservice ones.
|
||||||
|
@ -306,6 +306,20 @@ class UserDeactivatedError(SynapseError):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UserLockedError(SynapseError):
|
||||||
|
"""The error returned to the client when the user attempted to access an
|
||||||
|
authenticated endpoint, but the account has been locked.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__(
|
||||||
|
code=HTTPStatus.UNAUTHORIZED,
|
||||||
|
msg="User account has been locked",
|
||||||
|
errcode=Codes.USER_LOCKED,
|
||||||
|
additional_fields={"soft_logout": True},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FederationDeniedError(SynapseError):
|
class FederationDeniedError(SynapseError):
|
||||||
"""An error raised when the server tries to federate with a server which
|
"""An error raised when the server tries to federate with a server which
|
||||||
is not on its federation whitelist.
|
is not on its federation whitelist.
|
||||||
@ -527,7 +541,11 @@ class InvalidCaptchaError(SynapseError):
|
|||||||
|
|
||||||
|
|
||||||
class LimitExceededError(SynapseError):
|
class LimitExceededError(SynapseError):
|
||||||
"""A client has sent too many requests and is being throttled."""
|
"""A client has sent too many requests and is being throttled.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
pause: Optional time in seconds to pause before responding to the client.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -535,6 +553,7 @@ class LimitExceededError(SynapseError):
|
|||||||
code: int = 429,
|
code: int = 429,
|
||||||
retry_after_ms: Optional[int] = None,
|
retry_after_ms: Optional[int] = None,
|
||||||
errcode: str = Codes.LIMIT_EXCEEDED,
|
errcode: str = Codes.LIMIT_EXCEEDED,
|
||||||
|
pause: Optional[float] = None,
|
||||||
):
|
):
|
||||||
# Use HTTP header Retry-After to enable library-assisted retry handling.
|
# Use HTTP header Retry-After to enable library-assisted retry handling.
|
||||||
headers = (
|
headers = (
|
||||||
@ -545,6 +564,7 @@ class LimitExceededError(SynapseError):
|
|||||||
super().__init__(code, "Too Many Requests", errcode, headers=headers)
|
super().__init__(code, "Too Many Requests", errcode, headers=headers)
|
||||||
self.retry_after_ms = retry_after_ms
|
self.retry_after_ms = retry_after_ms
|
||||||
self.limiter_name = limiter_name
|
self.limiter_name = limiter_name
|
||||||
|
self.pause = pause
|
||||||
|
|
||||||
def error_dict(self, config: Optional["HomeServerConfig"]) -> "JsonDict":
|
def error_dict(self, config: Optional["HomeServerConfig"]) -> "JsonDict":
|
||||||
return cs_error(self.msg, self.errcode, retry_after_ms=self.retry_after_ms)
|
return cs_error(self.msg, self.errcode, retry_after_ms=self.retry_after_ms)
|
||||||
|
@ -338,12 +338,10 @@ class Ratelimiter:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if not allowed:
|
if not allowed:
|
||||||
if pause:
|
|
||||||
await self.clock.sleep(pause)
|
|
||||||
|
|
||||||
raise LimitExceededError(
|
raise LimitExceededError(
|
||||||
limiter_name=self._limiter_name,
|
limiter_name=self._limiter_name,
|
||||||
retry_after_ms=int(1000 * (time_allowed - time_now_s)),
|
retry_after_ms=int(1000 * (time_allowed - time_now_s)),
|
||||||
|
pause=pause,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -561,11 +561,17 @@ class ExperimentalConfig(Config):
|
|||||||
# MSC4076: Add `disable_badge_count`` to pusher configuration
|
# MSC4076: Add `disable_badge_count`` to pusher configuration
|
||||||
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)
|
self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False)
|
||||||
|
|
||||||
|
# MSC4235: Add `via` param to hierarchy endpoint
|
||||||
|
self.msc4235_enabled: bool = experimental.get("msc4235_enabled", False)
|
||||||
|
|
||||||
# MSC4263: Preventing MXID enumeration via key queries
|
# MSC4263: Preventing MXID enumeration via key queries
|
||||||
self.msc4263_limit_key_queries_to_users_who_share_rooms = experimental.get(
|
self.msc4263_limit_key_queries_to_users_who_share_rooms = experimental.get(
|
||||||
"msc4263_limit_key_queries_to_users_who_share_rooms",
|
"msc4263_limit_key_queries_to_users_who_share_rooms",
|
||||||
False,
|
False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# MSC4267: Automatically forgetting rooms on leave
|
||||||
|
self.msc4267_enabled: bool = experimental.get("msc4267_enabled", False)
|
||||||
|
|
||||||
# MSC4155: Invite filtering
|
# MSC4155: Invite filtering
|
||||||
self.msc4155_enabled: bool = experimental.get("msc4155_enabled", False)
|
self.msc4155_enabled: bool = experimental.get("msc4155_enabled", False)
|
||||||
|
@ -85,4 +85,4 @@ class RoomConfig(Config):
|
|||||||
|
|
||||||
# When enabled, users will forget rooms when they leave them, either via a
|
# When enabled, users will forget rooms when they leave them, either via a
|
||||||
# leave, kick or ban.
|
# leave, kick or ban.
|
||||||
self.forget_on_leave = config.get("forget_rooms_on_leave", False)
|
self.forget_on_leave: bool = config.get("forget_rooms_on_leave", False)
|
||||||
|
@ -208,7 +208,6 @@ class EventBase(metaclass=abc.ABCMeta):
|
|||||||
depth: DictProperty[int] = DictProperty("depth")
|
depth: DictProperty[int] = DictProperty("depth")
|
||||||
content: DictProperty[JsonDict] = DictProperty("content")
|
content: DictProperty[JsonDict] = DictProperty("content")
|
||||||
hashes: DictProperty[Dict[str, str]] = DictProperty("hashes")
|
hashes: DictProperty[Dict[str, str]] = DictProperty("hashes")
|
||||||
origin: DictProperty[str] = DictProperty("origin")
|
|
||||||
origin_server_ts: DictProperty[int] = DictProperty("origin_server_ts")
|
origin_server_ts: DictProperty[int] = DictProperty("origin_server_ts")
|
||||||
room_id: DictProperty[str] = DictProperty("room_id")
|
room_id: DictProperty[str] = DictProperty("room_id")
|
||||||
sender: DictProperty[str] = DictProperty("sender")
|
sender: DictProperty[str] = DictProperty("sender")
|
||||||
|
@ -302,8 +302,8 @@ def create_local_event_from_event_dict(
|
|||||||
event_dict: JsonDict,
|
event_dict: JsonDict,
|
||||||
internal_metadata_dict: Optional[JsonDict] = None,
|
internal_metadata_dict: Optional[JsonDict] = None,
|
||||||
) -> EventBase:
|
) -> EventBase:
|
||||||
"""Takes a fully formed event dict, ensuring that fields like `origin`
|
"""Takes a fully formed event dict, ensuring that fields like
|
||||||
and `origin_server_ts` have correct values for a locally produced event,
|
`origin_server_ts` have correct values for a locally produced event,
|
||||||
then signs and hashes it.
|
then signs and hashes it.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -319,7 +319,6 @@ def create_local_event_from_event_dict(
|
|||||||
if format_version == EventFormatVersions.ROOM_V1_V2:
|
if format_version == EventFormatVersions.ROOM_V1_V2:
|
||||||
event_dict["event_id"] = _create_event_id(clock, hostname)
|
event_dict["event_id"] = _create_event_id(clock, hostname)
|
||||||
|
|
||||||
event_dict["origin"] = hostname
|
|
||||||
event_dict.setdefault("origin_server_ts", time_now)
|
event_dict.setdefault("origin_server_ts", time_now)
|
||||||
|
|
||||||
event_dict.setdefault("unsigned", {})
|
event_dict.setdefault("unsigned", {})
|
||||||
|
@ -67,7 +67,6 @@ class EventValidator:
|
|||||||
"auth_events",
|
"auth_events",
|
||||||
"content",
|
"content",
|
||||||
"hashes",
|
"hashes",
|
||||||
"origin",
|
|
||||||
"prev_events",
|
"prev_events",
|
||||||
"sender",
|
"sender",
|
||||||
"type",
|
"type",
|
||||||
@ -77,13 +76,6 @@ class EventValidator:
|
|||||||
if k not in event:
|
if k not in event:
|
||||||
raise SynapseError(400, "Event does not have key %s" % (k,))
|
raise SynapseError(400, "Event does not have key %s" % (k,))
|
||||||
|
|
||||||
# Check that the following keys have string values
|
|
||||||
event_strings = ["origin"]
|
|
||||||
|
|
||||||
for s in event_strings:
|
|
||||||
if not isinstance(getattr(event, s), str):
|
|
||||||
raise SynapseError(400, "'%s' not a string type" % (s,))
|
|
||||||
|
|
||||||
# Depending on the room version, ensure the data is spec compliant JSON.
|
# Depending on the room version, ensure the data is spec compliant JSON.
|
||||||
if event.room_version.strict_canonicaljson:
|
if event.room_version.strict_canonicaljson:
|
||||||
validate_canonicaljson(event.get_pdu_json())
|
validate_canonicaljson(event.get_pdu_json())
|
||||||
|
@ -322,8 +322,7 @@ def event_from_pdu_json(pdu_json: JsonDict, room_version: RoomVersion) -> EventB
|
|||||||
SynapseError: if the pdu is missing required fields or is otherwise
|
SynapseError: if the pdu is missing required fields or is otherwise
|
||||||
not a valid matrix event
|
not a valid matrix event
|
||||||
"""
|
"""
|
||||||
# we could probably enforce a bunch of other fields here (room_id, sender,
|
# we could probably enforce a bunch of other fields here (room_id, sender, etc.)
|
||||||
# origin, etc etc)
|
|
||||||
assert_params_in_dict(pdu_json, ("type", "depth"))
|
assert_params_in_dict(pdu_json, ("type", "depth"))
|
||||||
|
|
||||||
# Strip any unauthorized values from "unsigned" if they exist
|
# Strip any unauthorized values from "unsigned" if they exist
|
||||||
|
@ -76,7 +76,7 @@ from synapse.storage.databases.main.registration import (
|
|||||||
LoginTokenLookupResult,
|
LoginTokenLookupResult,
|
||||||
LoginTokenReused,
|
LoginTokenReused,
|
||||||
)
|
)
|
||||||
from synapse.types import JsonDict, Requester, UserID
|
from synapse.types import JsonDict, Requester, StrCollection, UserID
|
||||||
from synapse.util import stringutils as stringutils
|
from synapse.util import stringutils as stringutils
|
||||||
from synapse.util.async_helpers import delay_cancellation, maybe_awaitable
|
from synapse.util.async_helpers import delay_cancellation, maybe_awaitable
|
||||||
from synapse.util.msisdn import phone_number_to_msisdn
|
from synapse.util.msisdn import phone_number_to_msisdn
|
||||||
@ -1547,6 +1547,31 @@ class AuthHandler:
|
|||||||
user_id, (token_id for _, token_id, _ in tokens_and_devices)
|
user_id, (token_id for _, token_id, _ in tokens_and_devices)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def delete_access_tokens_for_devices(
|
||||||
|
self,
|
||||||
|
user_id: str,
|
||||||
|
device_ids: StrCollection,
|
||||||
|
) -> None:
|
||||||
|
"""Invalidate access tokens for the devices
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: ID of user the tokens belong to
|
||||||
|
device_ids: ID of device the tokens are associated with.
|
||||||
|
If None, tokens associated with any device (or no device) will
|
||||||
|
be deleted
|
||||||
|
"""
|
||||||
|
tokens_and_devices = await self.store.user_delete_access_tokens_for_devices(
|
||||||
|
user_id,
|
||||||
|
device_ids,
|
||||||
|
)
|
||||||
|
|
||||||
|
# see if any modules want to know about this
|
||||||
|
if self.password_auth_provider.on_logged_out_callbacks:
|
||||||
|
for token, _, device_id in tokens_and_devices:
|
||||||
|
await self.password_auth_provider.on_logged_out(
|
||||||
|
user_id=user_id, device_id=device_id, access_token=token
|
||||||
|
)
|
||||||
|
|
||||||
async def add_threepid(
|
async def add_threepid(
|
||||||
self, user_id: str, medium: str, address: str, validated_at: int
|
self, user_id: str, medium: str, address: str, validated_at: int
|
||||||
) -> None:
|
) -> None:
|
||||||
|
@ -671,12 +671,12 @@ class DeviceHandler(DeviceWorkerHandler):
|
|||||||
except_device_id: optional device id which should not be deleted
|
except_device_id: optional device id which should not be deleted
|
||||||
"""
|
"""
|
||||||
device_map = await self.store.get_devices_by_user(user_id)
|
device_map = await self.store.get_devices_by_user(user_id)
|
||||||
device_ids = list(device_map)
|
|
||||||
if except_device_id is not None:
|
if except_device_id is not None:
|
||||||
device_ids = [d for d in device_ids if d != except_device_id]
|
device_map.pop(except_device_id, None)
|
||||||
await self.delete_devices(user_id, device_ids)
|
user_device_ids = device_map.keys()
|
||||||
|
await self.delete_devices(user_id, user_device_ids)
|
||||||
|
|
||||||
async def delete_devices(self, user_id: str, device_ids: List[str]) -> None:
|
async def delete_devices(self, user_id: str, device_ids: StrCollection) -> None:
|
||||||
"""Delete several devices
|
"""Delete several devices
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -695,17 +695,10 @@ class DeviceHandler(DeviceWorkerHandler):
|
|||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# Delete data specific to each device. Not optimised as it is not
|
# Delete data specific to each device. Not optimised as its an
|
||||||
# considered as part of a critical path.
|
# experimental MSC.
|
||||||
for device_id in device_ids:
|
if self.hs.config.experimental.msc3890_enabled:
|
||||||
await self._auth_handler.delete_access_tokens_for_user(
|
for device_id in device_ids:
|
||||||
user_id, device_id=device_id
|
|
||||||
)
|
|
||||||
await self.store.delete_e2e_keys_by_device(
|
|
||||||
user_id=user_id, device_id=device_id
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.hs.config.experimental.msc3890_enabled:
|
|
||||||
# Remove any local notification settings for this device in accordance
|
# Remove any local notification settings for this device in accordance
|
||||||
# with MSC3890.
|
# with MSC3890.
|
||||||
await self._account_data_handler.remove_account_data_for_user(
|
await self._account_data_handler.remove_account_data_for_user(
|
||||||
@ -713,6 +706,13 @@ class DeviceHandler(DeviceWorkerHandler):
|
|||||||
f"org.matrix.msc3890.local_notification_settings.{device_id}",
|
f"org.matrix.msc3890.local_notification_settings.{device_id}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# If we're deleting a lot of devices, a bunch of them may not have any
|
||||||
|
# to-device messages queued up. We filter those out to avoid scheduling
|
||||||
|
# unnecessary tasks.
|
||||||
|
devices_with_messages = await self.store.get_devices_with_messages(
|
||||||
|
user_id, device_ids
|
||||||
|
)
|
||||||
|
for device_id in devices_with_messages:
|
||||||
# Delete device messages asynchronously and in batches using the task scheduler
|
# Delete device messages asynchronously and in batches using the task scheduler
|
||||||
# We specify an upper stream id to avoid deleting non delivered messages
|
# We specify an upper stream id to avoid deleting non delivered messages
|
||||||
# if an user re-uses a device ID.
|
# if an user re-uses a device ID.
|
||||||
@ -726,6 +726,10 @@ class DeviceHandler(DeviceWorkerHandler):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
await self._auth_handler.delete_access_tokens_for_devices(
|
||||||
|
user_id, device_ids=device_ids
|
||||||
|
)
|
||||||
|
|
||||||
# Pushers are deleted after `delete_access_tokens_for_user` is called so that
|
# Pushers are deleted after `delete_access_tokens_for_user` is called so that
|
||||||
# modules using `on_logged_out` hook can use them if needed.
|
# modules using `on_logged_out` hook can use them if needed.
|
||||||
await self.hs.get_pusherpool().remove_pushers_by_devices(user_id, device_ids)
|
await self.hs.get_pusherpool().remove_pushers_by_devices(user_id, device_ids)
|
||||||
@ -819,10 +823,11 @@ class DeviceHandler(DeviceWorkerHandler):
|
|||||||
# This should only happen if there are no updates, so we bail.
|
# This should only happen if there are no updates, so we bail.
|
||||||
return
|
return
|
||||||
|
|
||||||
for device_id in device_ids:
|
if logger.isEnabledFor(logging.DEBUG):
|
||||||
logger.debug(
|
for device_id in device_ids:
|
||||||
"Notifying about update %r/%r, ID: %r", user_id, device_id, position
|
logger.debug(
|
||||||
)
|
"Notifying about update %r/%r, ID: %r", user_id, device_id, position
|
||||||
|
)
|
||||||
|
|
||||||
# specify the user ID too since the user should always get their own device list
|
# specify the user ID too since the user should always get their own device list
|
||||||
# updates, even if they aren't in any rooms.
|
# updates, even if they aren't in any rooms.
|
||||||
@ -922,9 +927,6 @@ class DeviceHandler(DeviceWorkerHandler):
|
|||||||
# can't call self.delete_device because that will clobber the
|
# can't call self.delete_device because that will clobber the
|
||||||
# access token so call the storage layer directly
|
# access token so call the storage layer directly
|
||||||
await self.store.delete_devices(user_id, [old_device_id])
|
await self.store.delete_devices(user_id, [old_device_id])
|
||||||
await self.store.delete_e2e_keys_by_device(
|
|
||||||
user_id=user_id, device_id=old_device_id
|
|
||||||
)
|
|
||||||
|
|
||||||
# tell everyone that the old device is gone and that the dehydrated
|
# tell everyone that the old device is gone and that the dehydrated
|
||||||
# device has a new display name
|
# device has a new display name
|
||||||
@ -946,7 +948,6 @@ class DeviceHandler(DeviceWorkerHandler):
|
|||||||
raise errors.NotFoundError()
|
raise errors.NotFoundError()
|
||||||
|
|
||||||
await self.delete_devices(user_id, [device_id])
|
await self.delete_devices(user_id, [device_id])
|
||||||
await self.store.delete_e2e_keys_by_device(user_id=user_id, device_id=device_id)
|
|
||||||
|
|
||||||
@wrap_as_background_process("_handle_new_device_update_async")
|
@wrap_as_background_process("_handle_new_device_update_async")
|
||||||
async def _handle_new_device_update_async(self) -> None:
|
async def _handle_new_device_update_async(self) -> None:
|
||||||
|
@ -1062,8 +1062,8 @@ class FederationHandler:
|
|||||||
if self.hs.config.server.block_non_admin_invites:
|
if self.hs.config.server.block_non_admin_invites:
|
||||||
raise SynapseError(403, "This server does not accept room invites")
|
raise SynapseError(403, "This server does not accept room invites")
|
||||||
|
|
||||||
spam_check = await self._spam_checker_module_callbacks.user_may_invite(
|
spam_check = (
|
||||||
event.sender, event.state_key, event.room_id
|
await self._spam_checker_module_callbacks.federated_user_may_invite(event)
|
||||||
)
|
)
|
||||||
if spam_check != NOT_SPAM:
|
if spam_check != NOT_SPAM:
|
||||||
raise SynapseError(
|
raise SynapseError(
|
||||||
|
@ -54,6 +54,9 @@ class RoomPolicyHandler:
|
|||||||
Returns:
|
Returns:
|
||||||
bool: True if the event is allowed in the room, False otherwise.
|
bool: True if the event is allowed in the room, False otherwise.
|
||||||
"""
|
"""
|
||||||
|
if event.type == "org.matrix.msc4284.policy" and event.state_key is not None:
|
||||||
|
return True # always allow policy server change events
|
||||||
|
|
||||||
policy_event = await self._storage_controllers.state.get_current_state_event(
|
policy_event = await self._storage_controllers.state.get_current_state_event(
|
||||||
event.room_id, "org.matrix.msc4284.policy", ""
|
event.room_id, "org.matrix.msc4284.policy", ""
|
||||||
)
|
)
|
||||||
|
@ -111,7 +111,15 @@ class RoomSummaryHandler:
|
|||||||
# If a user tries to fetch the same page multiple times in quick succession,
|
# If a user tries to fetch the same page multiple times in quick succession,
|
||||||
# only process the first attempt and return its result to subsequent requests.
|
# only process the first attempt and return its result to subsequent requests.
|
||||||
self._pagination_response_cache: ResponseCache[
|
self._pagination_response_cache: ResponseCache[
|
||||||
Tuple[str, str, bool, Optional[int], Optional[int], Optional[str]]
|
Tuple[
|
||||||
|
str,
|
||||||
|
str,
|
||||||
|
bool,
|
||||||
|
Optional[int],
|
||||||
|
Optional[int],
|
||||||
|
Optional[str],
|
||||||
|
Optional[Tuple[str, ...]],
|
||||||
|
]
|
||||||
] = ResponseCache(
|
] = ResponseCache(
|
||||||
hs.get_clock(),
|
hs.get_clock(),
|
||||||
"get_room_hierarchy",
|
"get_room_hierarchy",
|
||||||
@ -126,6 +134,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth: Optional[int] = None,
|
max_depth: Optional[int] = None,
|
||||||
limit: Optional[int] = None,
|
limit: Optional[int] = None,
|
||||||
from_token: Optional[str] = None,
|
from_token: Optional[str] = None,
|
||||||
|
remote_room_hosts: Optional[Tuple[str, ...]] = None,
|
||||||
) -> JsonDict:
|
) -> JsonDict:
|
||||||
"""
|
"""
|
||||||
Implementation of the room hierarchy C-S API.
|
Implementation of the room hierarchy C-S API.
|
||||||
@ -143,6 +152,9 @@ class RoomSummaryHandler:
|
|||||||
limit: An optional limit on the number of rooms to return per
|
limit: An optional limit on the number of rooms to return per
|
||||||
page. Must be a positive integer.
|
page. Must be a positive integer.
|
||||||
from_token: An optional pagination token.
|
from_token: An optional pagination token.
|
||||||
|
remote_room_hosts: An optional list of remote homeserver server names. If defined,
|
||||||
|
each host will be used to try and fetch the room hierarchy. Must be a tuple so
|
||||||
|
that it can be hashed by the `RoomSummaryHandler._pagination_response_cache`.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The JSON hierarchy dictionary.
|
The JSON hierarchy dictionary.
|
||||||
@ -162,6 +174,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth,
|
max_depth,
|
||||||
limit,
|
limit,
|
||||||
from_token,
|
from_token,
|
||||||
|
remote_room_hosts,
|
||||||
),
|
),
|
||||||
self._get_room_hierarchy,
|
self._get_room_hierarchy,
|
||||||
requester.user.to_string(),
|
requester.user.to_string(),
|
||||||
@ -170,6 +183,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth,
|
max_depth,
|
||||||
limit,
|
limit,
|
||||||
from_token,
|
from_token,
|
||||||
|
remote_room_hosts,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def _get_room_hierarchy(
|
async def _get_room_hierarchy(
|
||||||
@ -180,6 +194,7 @@ class RoomSummaryHandler:
|
|||||||
max_depth: Optional[int] = None,
|
max_depth: Optional[int] = None,
|
||||||
limit: Optional[int] = None,
|
limit: Optional[int] = None,
|
||||||
from_token: Optional[str] = None,
|
from_token: Optional[str] = None,
|
||||||
|
remote_room_hosts: Optional[Tuple[str, ...]] = None,
|
||||||
) -> JsonDict:
|
) -> JsonDict:
|
||||||
"""See docstring for SpaceSummaryHandler.get_room_hierarchy."""
|
"""See docstring for SpaceSummaryHandler.get_room_hierarchy."""
|
||||||
|
|
||||||
@ -199,7 +214,7 @@ class RoomSummaryHandler:
|
|||||||
|
|
||||||
if not local_room:
|
if not local_room:
|
||||||
room_hierarchy = await self._summarize_remote_room_hierarchy(
|
room_hierarchy = await self._summarize_remote_room_hierarchy(
|
||||||
_RoomQueueEntry(requested_room_id, ()),
|
_RoomQueueEntry(requested_room_id, remote_room_hosts or ()),
|
||||||
False,
|
False,
|
||||||
)
|
)
|
||||||
root_room_entry = room_hierarchy[0]
|
root_room_entry = room_hierarchy[0]
|
||||||
@ -240,7 +255,7 @@ class RoomSummaryHandler:
|
|||||||
processed_rooms = set(pagination_session["processed_rooms"])
|
processed_rooms = set(pagination_session["processed_rooms"])
|
||||||
else:
|
else:
|
||||||
# The queue of rooms to process, the next room is last on the stack.
|
# The queue of rooms to process, the next room is last on the stack.
|
||||||
room_queue = [_RoomQueueEntry(requested_room_id, ())]
|
room_queue = [_RoomQueueEntry(requested_room_id, remote_room_hosts or ())]
|
||||||
|
|
||||||
# Rooms we have already processed.
|
# Rooms we have already processed.
|
||||||
processed_rooms = set()
|
processed_rooms = set()
|
||||||
|
@ -53,7 +53,7 @@ class AdditionalResource(DirectServeJsonResource):
|
|||||||
hs: homeserver
|
hs: homeserver
|
||||||
handler: function to be called to handle the request.
|
handler: function to be called to handle the request.
|
||||||
"""
|
"""
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._handler = handler
|
self._handler = handler
|
||||||
|
|
||||||
async def _async_render(self, request: Request) -> Optional[Tuple[int, Any]]:
|
async def _async_render(self, request: Request) -> Optional[Tuple[int, Any]]:
|
||||||
|
@ -106,7 +106,7 @@ class ProxyResource(_AsyncResource):
|
|||||||
isLeaf = True
|
isLeaf = True
|
||||||
|
|
||||||
def __init__(self, reactor: ISynapseReactor, hs: "HomeServer"):
|
def __init__(self, reactor: ISynapseReactor, hs: "HomeServer"):
|
||||||
super().__init__(True)
|
super().__init__(hs.get_clock(), True)
|
||||||
|
|
||||||
self.reactor = reactor
|
self.reactor = reactor
|
||||||
self.agent = hs.get_federation_http_client().agent
|
self.agent = hs.get_federation_http_client().agent
|
||||||
|
@ -42,6 +42,7 @@ from typing import (
|
|||||||
Protocol,
|
Protocol,
|
||||||
Tuple,
|
Tuple,
|
||||||
Union,
|
Union,
|
||||||
|
cast,
|
||||||
)
|
)
|
||||||
|
|
||||||
import attr
|
import attr
|
||||||
@ -49,8 +50,9 @@ import jinja2
|
|||||||
from canonicaljson import encode_canonical_json
|
from canonicaljson import encode_canonical_json
|
||||||
from zope.interface import implementer
|
from zope.interface import implementer
|
||||||
|
|
||||||
from twisted.internet import defer, interfaces
|
from twisted.internet import defer, interfaces, reactor
|
||||||
from twisted.internet.defer import CancelledError
|
from twisted.internet.defer import CancelledError
|
||||||
|
from twisted.internet.interfaces import IReactorTime
|
||||||
from twisted.python import failure
|
from twisted.python import failure
|
||||||
from twisted.web import resource
|
from twisted.web import resource
|
||||||
|
|
||||||
@ -67,6 +69,7 @@ from twisted.web.util import redirectTo
|
|||||||
from synapse.api.errors import (
|
from synapse.api.errors import (
|
||||||
CodeMessageException,
|
CodeMessageException,
|
||||||
Codes,
|
Codes,
|
||||||
|
LimitExceededError,
|
||||||
RedirectException,
|
RedirectException,
|
||||||
SynapseError,
|
SynapseError,
|
||||||
UnrecognizedRequestError,
|
UnrecognizedRequestError,
|
||||||
@ -74,7 +77,7 @@ from synapse.api.errors import (
|
|||||||
from synapse.config.homeserver import HomeServerConfig
|
from synapse.config.homeserver import HomeServerConfig
|
||||||
from synapse.logging.context import defer_to_thread, preserve_fn, run_in_background
|
from synapse.logging.context import defer_to_thread, preserve_fn, run_in_background
|
||||||
from synapse.logging.opentracing import active_span, start_active_span, trace_servlet
|
from synapse.logging.opentracing import active_span, start_active_span, trace_servlet
|
||||||
from synapse.util import json_encoder
|
from synapse.util import Clock, json_encoder
|
||||||
from synapse.util.caches import intern_dict
|
from synapse.util.caches import intern_dict
|
||||||
from synapse.util.cancellation import is_function_cancellable
|
from synapse.util.cancellation import is_function_cancellable
|
||||||
from synapse.util.iterutils import chunk_seq
|
from synapse.util.iterutils import chunk_seq
|
||||||
@ -308,9 +311,10 @@ class _AsyncResource(resource.Resource, metaclass=abc.ABCMeta):
|
|||||||
context from the request the servlet is handling.
|
context from the request the servlet is handling.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, extract_context: bool = False):
|
def __init__(self, clock: Clock, extract_context: bool = False):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
self._clock = clock
|
||||||
self._extract_context = extract_context
|
self._extract_context = extract_context
|
||||||
|
|
||||||
def render(self, request: "SynapseRequest") -> int:
|
def render(self, request: "SynapseRequest") -> int:
|
||||||
@ -329,7 +333,12 @@ class _AsyncResource(resource.Resource, metaclass=abc.ABCMeta):
|
|||||||
request.request_metrics.name = self.__class__.__name__
|
request.request_metrics.name = self.__class__.__name__
|
||||||
|
|
||||||
with trace_servlet(request, self._extract_context):
|
with trace_servlet(request, self._extract_context):
|
||||||
callback_return = await self._async_render(request)
|
try:
|
||||||
|
callback_return = await self._async_render(request)
|
||||||
|
except LimitExceededError as e:
|
||||||
|
if e.pause:
|
||||||
|
self._clock.sleep(e.pause)
|
||||||
|
raise
|
||||||
|
|
||||||
if callback_return is not None:
|
if callback_return is not None:
|
||||||
code, response = callback_return
|
code, response = callback_return
|
||||||
@ -393,8 +402,17 @@ class DirectServeJsonResource(_AsyncResource):
|
|||||||
formatting responses and errors as JSON.
|
formatting responses and errors as JSON.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, canonical_json: bool = False, extract_context: bool = False):
|
def __init__(
|
||||||
super().__init__(extract_context)
|
self,
|
||||||
|
canonical_json: bool = False,
|
||||||
|
extract_context: bool = False,
|
||||||
|
# Clock is optional as this class is exposed to the module API.
|
||||||
|
clock: Optional[Clock] = None,
|
||||||
|
):
|
||||||
|
if clock is None:
|
||||||
|
clock = Clock(cast(IReactorTime, reactor))
|
||||||
|
|
||||||
|
super().__init__(clock, extract_context)
|
||||||
self.canonical_json = canonical_json
|
self.canonical_json = canonical_json
|
||||||
|
|
||||||
def _send_response(
|
def _send_response(
|
||||||
@ -450,8 +468,8 @@ class JsonResource(DirectServeJsonResource):
|
|||||||
canonical_json: bool = True,
|
canonical_json: bool = True,
|
||||||
extract_context: bool = False,
|
extract_context: bool = False,
|
||||||
):
|
):
|
||||||
super().__init__(canonical_json, extract_context)
|
|
||||||
self.clock = hs.get_clock()
|
self.clock = hs.get_clock()
|
||||||
|
super().__init__(canonical_json, extract_context, clock=self.clock)
|
||||||
# Map of path regex -> method -> callback.
|
# Map of path regex -> method -> callback.
|
||||||
self._routes: Dict[Pattern[str], Dict[bytes, _PathEntry]] = {}
|
self._routes: Dict[Pattern[str], Dict[bytes, _PathEntry]] = {}
|
||||||
self.hs = hs
|
self.hs = hs
|
||||||
@ -564,6 +582,17 @@ class DirectServeHtmlResource(_AsyncResource):
|
|||||||
# The error template to use for this resource
|
# The error template to use for this resource
|
||||||
ERROR_TEMPLATE = HTML_ERROR_TEMPLATE
|
ERROR_TEMPLATE = HTML_ERROR_TEMPLATE
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
extract_context: bool = False,
|
||||||
|
# Clock is optional as this class is exposed to the module API.
|
||||||
|
clock: Optional[Clock] = None,
|
||||||
|
):
|
||||||
|
if clock is None:
|
||||||
|
clock = Clock(cast(IReactorTime, reactor))
|
||||||
|
|
||||||
|
super().__init__(clock, extract_context)
|
||||||
|
|
||||||
def _send_response(
|
def _send_response(
|
||||||
self,
|
self,
|
||||||
request: "SynapseRequest",
|
request: "SynapseRequest",
|
||||||
|
@ -104,6 +104,7 @@ from synapse.module_api.callbacks.spamchecker_callbacks import (
|
|||||||
CHECK_MEDIA_FILE_FOR_SPAM_CALLBACK,
|
CHECK_MEDIA_FILE_FOR_SPAM_CALLBACK,
|
||||||
CHECK_REGISTRATION_FOR_SPAM_CALLBACK,
|
CHECK_REGISTRATION_FOR_SPAM_CALLBACK,
|
||||||
CHECK_USERNAME_FOR_SPAM_CALLBACK,
|
CHECK_USERNAME_FOR_SPAM_CALLBACK,
|
||||||
|
FEDERATED_USER_MAY_INVITE_CALLBACK,
|
||||||
SHOULD_DROP_FEDERATED_EVENT_CALLBACK,
|
SHOULD_DROP_FEDERATED_EVENT_CALLBACK,
|
||||||
USER_MAY_CREATE_ROOM_ALIAS_CALLBACK,
|
USER_MAY_CREATE_ROOM_ALIAS_CALLBACK,
|
||||||
USER_MAY_CREATE_ROOM_CALLBACK,
|
USER_MAY_CREATE_ROOM_CALLBACK,
|
||||||
@ -315,6 +316,7 @@ class ModuleApi:
|
|||||||
] = None,
|
] = None,
|
||||||
user_may_join_room: Optional[USER_MAY_JOIN_ROOM_CALLBACK] = None,
|
user_may_join_room: Optional[USER_MAY_JOIN_ROOM_CALLBACK] = None,
|
||||||
user_may_invite: Optional[USER_MAY_INVITE_CALLBACK] = None,
|
user_may_invite: Optional[USER_MAY_INVITE_CALLBACK] = None,
|
||||||
|
federated_user_may_invite: Optional[FEDERATED_USER_MAY_INVITE_CALLBACK] = None,
|
||||||
user_may_send_3pid_invite: Optional[USER_MAY_SEND_3PID_INVITE_CALLBACK] = None,
|
user_may_send_3pid_invite: Optional[USER_MAY_SEND_3PID_INVITE_CALLBACK] = None,
|
||||||
user_may_create_room: Optional[USER_MAY_CREATE_ROOM_CALLBACK] = None,
|
user_may_create_room: Optional[USER_MAY_CREATE_ROOM_CALLBACK] = None,
|
||||||
user_may_create_room_alias: Optional[
|
user_may_create_room_alias: Optional[
|
||||||
@ -338,6 +340,7 @@ class ModuleApi:
|
|||||||
should_drop_federated_event=should_drop_federated_event,
|
should_drop_federated_event=should_drop_federated_event,
|
||||||
user_may_join_room=user_may_join_room,
|
user_may_join_room=user_may_join_room,
|
||||||
user_may_invite=user_may_invite,
|
user_may_invite=user_may_invite,
|
||||||
|
federated_user_may_invite=federated_user_may_invite,
|
||||||
user_may_send_3pid_invite=user_may_send_3pid_invite,
|
user_may_send_3pid_invite=user_may_send_3pid_invite,
|
||||||
user_may_create_room=user_may_create_room,
|
user_may_create_room=user_may_create_room,
|
||||||
user_may_create_room_alias=user_may_create_room_alias,
|
user_may_create_room_alias=user_may_create_room_alias,
|
||||||
|
@ -105,6 +105,22 @@ USER_MAY_INVITE_CALLBACK = Callable[
|
|||||||
]
|
]
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
FEDERATED_USER_MAY_INVITE_CALLBACK = Callable[
|
||||||
|
["synapse.events.EventBase"],
|
||||||
|
Awaitable[
|
||||||
|
Union[
|
||||||
|
Literal["NOT_SPAM"],
|
||||||
|
Codes,
|
||||||
|
# Highly experimental, not officially part of the spamchecker API, may
|
||||||
|
# disappear without warning depending on the results of ongoing
|
||||||
|
# experiments.
|
||||||
|
# Use this to return additional information as part of an error.
|
||||||
|
Tuple[Codes, JsonDict],
|
||||||
|
# Deprecated
|
||||||
|
bool,
|
||||||
|
]
|
||||||
|
],
|
||||||
|
]
|
||||||
USER_MAY_SEND_3PID_INVITE_CALLBACK = Callable[
|
USER_MAY_SEND_3PID_INVITE_CALLBACK = Callable[
|
||||||
[str, str, str, str],
|
[str, str, str, str],
|
||||||
Awaitable[
|
Awaitable[
|
||||||
@ -266,6 +282,7 @@ def load_legacy_spam_checkers(hs: "synapse.server.HomeServer") -> None:
|
|||||||
spam_checker_methods = {
|
spam_checker_methods = {
|
||||||
"check_event_for_spam",
|
"check_event_for_spam",
|
||||||
"user_may_invite",
|
"user_may_invite",
|
||||||
|
"federated_user_may_invite",
|
||||||
"user_may_create_room",
|
"user_may_create_room",
|
||||||
"user_may_create_room_alias",
|
"user_may_create_room_alias",
|
||||||
"user_may_publish_room",
|
"user_may_publish_room",
|
||||||
@ -347,6 +364,9 @@ class SpamCheckerModuleApiCallbacks:
|
|||||||
] = []
|
] = []
|
||||||
self._user_may_join_room_callbacks: List[USER_MAY_JOIN_ROOM_CALLBACK] = []
|
self._user_may_join_room_callbacks: List[USER_MAY_JOIN_ROOM_CALLBACK] = []
|
||||||
self._user_may_invite_callbacks: List[USER_MAY_INVITE_CALLBACK] = []
|
self._user_may_invite_callbacks: List[USER_MAY_INVITE_CALLBACK] = []
|
||||||
|
self._federated_user_may_invite_callbacks: List[
|
||||||
|
FEDERATED_USER_MAY_INVITE_CALLBACK
|
||||||
|
] = []
|
||||||
self._user_may_send_3pid_invite_callbacks: List[
|
self._user_may_send_3pid_invite_callbacks: List[
|
||||||
USER_MAY_SEND_3PID_INVITE_CALLBACK
|
USER_MAY_SEND_3PID_INVITE_CALLBACK
|
||||||
] = []
|
] = []
|
||||||
@ -377,6 +397,7 @@ class SpamCheckerModuleApiCallbacks:
|
|||||||
] = None,
|
] = None,
|
||||||
user_may_join_room: Optional[USER_MAY_JOIN_ROOM_CALLBACK] = None,
|
user_may_join_room: Optional[USER_MAY_JOIN_ROOM_CALLBACK] = None,
|
||||||
user_may_invite: Optional[USER_MAY_INVITE_CALLBACK] = None,
|
user_may_invite: Optional[USER_MAY_INVITE_CALLBACK] = None,
|
||||||
|
federated_user_may_invite: Optional[FEDERATED_USER_MAY_INVITE_CALLBACK] = None,
|
||||||
user_may_send_3pid_invite: Optional[USER_MAY_SEND_3PID_INVITE_CALLBACK] = None,
|
user_may_send_3pid_invite: Optional[USER_MAY_SEND_3PID_INVITE_CALLBACK] = None,
|
||||||
user_may_create_room: Optional[USER_MAY_CREATE_ROOM_CALLBACK] = None,
|
user_may_create_room: Optional[USER_MAY_CREATE_ROOM_CALLBACK] = None,
|
||||||
user_may_create_room_alias: Optional[
|
user_may_create_room_alias: Optional[
|
||||||
@ -406,6 +427,11 @@ class SpamCheckerModuleApiCallbacks:
|
|||||||
if user_may_invite is not None:
|
if user_may_invite is not None:
|
||||||
self._user_may_invite_callbacks.append(user_may_invite)
|
self._user_may_invite_callbacks.append(user_may_invite)
|
||||||
|
|
||||||
|
if federated_user_may_invite is not None:
|
||||||
|
self._federated_user_may_invite_callbacks.append(
|
||||||
|
federated_user_may_invite,
|
||||||
|
)
|
||||||
|
|
||||||
if user_may_send_3pid_invite is not None:
|
if user_may_send_3pid_invite is not None:
|
||||||
self._user_may_send_3pid_invite_callbacks.append(
|
self._user_may_send_3pid_invite_callbacks.append(
|
||||||
user_may_send_3pid_invite,
|
user_may_send_3pid_invite,
|
||||||
@ -605,6 +631,43 @@ class SpamCheckerModuleApiCallbacks:
|
|||||||
# No spam-checker has rejected the request, let it pass.
|
# No spam-checker has rejected the request, let it pass.
|
||||||
return self.NOT_SPAM
|
return self.NOT_SPAM
|
||||||
|
|
||||||
|
async def federated_user_may_invite(
|
||||||
|
self, event: "synapse.events.EventBase"
|
||||||
|
) -> Union[Tuple[Codes, dict], Literal["NOT_SPAM"]]:
|
||||||
|
"""Checks if a given user may send an invite
|
||||||
|
|
||||||
|
Args:
|
||||||
|
event: The event to be checked
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
NOT_SPAM if the operation is permitted, Codes otherwise.
|
||||||
|
"""
|
||||||
|
for callback in self._federated_user_may_invite_callbacks:
|
||||||
|
with Measure(self.clock, f"{callback.__module__}.{callback.__qualname__}"):
|
||||||
|
res = await delay_cancellation(callback(event))
|
||||||
|
# Normalize return values to `Codes` or `"NOT_SPAM"`.
|
||||||
|
if res is True or res is self.NOT_SPAM:
|
||||||
|
continue
|
||||||
|
elif res is False:
|
||||||
|
return synapse.api.errors.Codes.FORBIDDEN, {}
|
||||||
|
elif isinstance(res, synapse.api.errors.Codes):
|
||||||
|
return res, {}
|
||||||
|
elif (
|
||||||
|
isinstance(res, tuple)
|
||||||
|
and len(res) == 2
|
||||||
|
and isinstance(res[0], synapse.api.errors.Codes)
|
||||||
|
and isinstance(res[1], dict)
|
||||||
|
):
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
logger.warning(
|
||||||
|
"Module returned invalid value, rejecting invite as spam"
|
||||||
|
)
|
||||||
|
return synapse.api.errors.Codes.FORBIDDEN, {}
|
||||||
|
|
||||||
|
# Check the standard user_may_invite callback if no module has rejected the invite yet.
|
||||||
|
return await self.user_may_invite(event.sender, event.state_key, event.room_id)
|
||||||
|
|
||||||
async def user_may_send_3pid_invite(
|
async def user_may_send_3pid_invite(
|
||||||
self, inviter_userid: str, medium: str, address: str, room_id: str
|
self, inviter_userid: str, medium: str, address: str, room_id: str
|
||||||
) -> Union[Tuple[Codes, dict], Literal["NOT_SPAM"]]:
|
) -> Union[Tuple[Codes, dict], Literal["NOT_SPAM"]]:
|
||||||
|
@ -109,6 +109,11 @@ class CapabilitiesRestServlet(RestServlet):
|
|||||||
"disallowed"
|
"disallowed"
|
||||||
] = disallowed
|
] = disallowed
|
||||||
|
|
||||||
|
if self.config.experimental.msc4267_enabled:
|
||||||
|
response["capabilities"]["org.matrix.msc4267.forget_forced_upon_leave"] = {
|
||||||
|
"enabled": self.config.room.forget_on_leave,
|
||||||
|
}
|
||||||
|
|
||||||
return HTTPStatus.OK, response
|
return HTTPStatus.OK, response
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ from synapse.api.errors import (
|
|||||||
NotApprovedError,
|
NotApprovedError,
|
||||||
SynapseError,
|
SynapseError,
|
||||||
UserDeactivatedError,
|
UserDeactivatedError,
|
||||||
|
UserLockedError,
|
||||||
)
|
)
|
||||||
from synapse.api.ratelimiting import Ratelimiter
|
from synapse.api.ratelimiting import Ratelimiter
|
||||||
from synapse.api.urls import CLIENT_API_PREFIX
|
from synapse.api.urls import CLIENT_API_PREFIX
|
||||||
@ -313,7 +314,7 @@ class LoginRestServlet(RestServlet):
|
|||||||
should_issue_refresh_token=should_issue_refresh_token,
|
should_issue_refresh_token=should_issue_refresh_token,
|
||||||
# The user represented by an appservice's configured sender_localpart
|
# The user represented by an appservice's configured sender_localpart
|
||||||
# is not actually created in Synapse.
|
# is not actually created in Synapse.
|
||||||
should_check_deactivated=qualified_user_id != appservice.sender,
|
should_check_deactivated_or_locked=qualified_user_id != appservice.sender,
|
||||||
request_info=request_info,
|
request_info=request_info,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -367,7 +368,7 @@ class LoginRestServlet(RestServlet):
|
|||||||
auth_provider_id: Optional[str] = None,
|
auth_provider_id: Optional[str] = None,
|
||||||
should_issue_refresh_token: bool = False,
|
should_issue_refresh_token: bool = False,
|
||||||
auth_provider_session_id: Optional[str] = None,
|
auth_provider_session_id: Optional[str] = None,
|
||||||
should_check_deactivated: bool = True,
|
should_check_deactivated_or_locked: bool = True,
|
||||||
*,
|
*,
|
||||||
request_info: RequestInfo,
|
request_info: RequestInfo,
|
||||||
) -> LoginResponse:
|
) -> LoginResponse:
|
||||||
@ -389,8 +390,8 @@ class LoginRestServlet(RestServlet):
|
|||||||
should_issue_refresh_token: True if this login should issue
|
should_issue_refresh_token: True if this login should issue
|
||||||
a refresh token alongside the access token.
|
a refresh token alongside the access token.
|
||||||
auth_provider_session_id: The session ID got during login from the SSO IdP.
|
auth_provider_session_id: The session ID got during login from the SSO IdP.
|
||||||
should_check_deactivated: True if the user should be checked for
|
should_check_deactivated_or_locked: True if the user should be checked for
|
||||||
deactivation status before logging in.
|
deactivation or locked status before logging in.
|
||||||
|
|
||||||
This exists purely for appservice's configured sender_localpart
|
This exists purely for appservice's configured sender_localpart
|
||||||
which doesn't have an associated user in the database.
|
which doesn't have an associated user in the database.
|
||||||
@ -415,11 +416,14 @@ class LoginRestServlet(RestServlet):
|
|||||||
)
|
)
|
||||||
user_id = canonical_uid
|
user_id = canonical_uid
|
||||||
|
|
||||||
# If the account has been deactivated, do not proceed with the login.
|
# If the account has been deactivated or locked, do not proceed with the login.
|
||||||
if should_check_deactivated:
|
if should_check_deactivated_or_locked:
|
||||||
deactivated = await self._main_store.get_user_deactivated_status(user_id)
|
deactivated = await self._main_store.get_user_deactivated_status(user_id)
|
||||||
if deactivated:
|
if deactivated:
|
||||||
raise UserDeactivatedError("This account has been deactivated")
|
raise UserDeactivatedError("This account has been deactivated")
|
||||||
|
locked = await self._main_store.get_user_locked_status(user_id)
|
||||||
|
if locked:
|
||||||
|
raise UserLockedError()
|
||||||
|
|
||||||
device_id = login_submission.get("device_id")
|
device_id = login_submission.get("device_id")
|
||||||
|
|
||||||
|
@ -1538,6 +1538,7 @@ class RoomHierarchyRestServlet(RestServlet):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self._auth = hs.get_auth()
|
self._auth = hs.get_auth()
|
||||||
self._room_summary_handler = hs.get_room_summary_handler()
|
self._room_summary_handler = hs.get_room_summary_handler()
|
||||||
|
self.msc4235_enabled = hs.config.experimental.msc4235_enabled
|
||||||
|
|
||||||
async def on_GET(
|
async def on_GET(
|
||||||
self, request: SynapseRequest, room_id: str
|
self, request: SynapseRequest, room_id: str
|
||||||
@ -1547,6 +1548,15 @@ class RoomHierarchyRestServlet(RestServlet):
|
|||||||
max_depth = parse_integer(request, "max_depth")
|
max_depth = parse_integer(request, "max_depth")
|
||||||
limit = parse_integer(request, "limit")
|
limit = parse_integer(request, "limit")
|
||||||
|
|
||||||
|
# twisted.web.server.Request.args is incorrectly defined as Optional[Any]
|
||||||
|
remote_room_hosts = None
|
||||||
|
if self.msc4235_enabled:
|
||||||
|
args: Dict[bytes, List[bytes]] = request.args # type: ignore
|
||||||
|
via_param = parse_strings_from_args(
|
||||||
|
args, "org.matrix.msc4235.via", required=False
|
||||||
|
)
|
||||||
|
remote_room_hosts = tuple(via_param or [])
|
||||||
|
|
||||||
return 200, await self._room_summary_handler.get_room_hierarchy(
|
return 200, await self._room_summary_handler.get_room_hierarchy(
|
||||||
requester,
|
requester,
|
||||||
room_id,
|
room_id,
|
||||||
@ -1554,6 +1564,7 @@ class RoomHierarchyRestServlet(RestServlet):
|
|||||||
max_depth=max_depth,
|
max_depth=max_depth,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
from_token=parse_string(request, "from"),
|
from_token=parse_string(request, "from"),
|
||||||
|
remote_room_hosts=remote_room_hosts,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class ConsentResource(DirectServeHtmlResource):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
|
|
||||||
self.hs = hs
|
self.hs = hs
|
||||||
self.store = hs.get_datastores().main
|
self.store = hs.get_datastores().main
|
||||||
|
@ -44,7 +44,7 @@ class FederationWhitelistResource(DirectServeJsonResource):
|
|||||||
PATH = "/_synapse/client/v1/config/federation_whitelist"
|
PATH = "/_synapse/client/v1/config/federation_whitelist"
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
|
|
||||||
self._federation_whitelist = hs.config.federation.federation_domain_whitelist
|
self._federation_whitelist = hs.config.federation.federation_domain_whitelist
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
class JwksResource(DirectServeJsonResource):
|
class JwksResource(DirectServeJsonResource):
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__(extract_context=True)
|
super().__init__(clock=hs.get_clock(), extract_context=True)
|
||||||
|
|
||||||
# Parameters that are allowed to be exposed in the public key.
|
# Parameters that are allowed to be exposed in the public key.
|
||||||
# This is done manually, because authlib's private to public key conversion
|
# This is done manually, because authlib's private to public key conversion
|
||||||
|
@ -48,7 +48,7 @@ class NewUserConsentResource(DirectServeHtmlResource):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._sso_handler = hs.get_sso_handler()
|
self._sso_handler = hs.get_sso_handler()
|
||||||
self._server_name = hs.hostname
|
self._server_name = hs.hostname
|
||||||
self._consent_version = hs.config.consent.user_consent_version
|
self._consent_version = hs.config.consent.user_consent_version
|
||||||
|
@ -35,7 +35,7 @@ class OIDCBackchannelLogoutResource(DirectServeJsonResource):
|
|||||||
isLeaf = 1
|
isLeaf = 1
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._oidc_handler = hs.get_oidc_handler()
|
self._oidc_handler = hs.get_oidc_handler()
|
||||||
|
|
||||||
async def _async_render_POST(self, request: SynapseRequest) -> None:
|
async def _async_render_POST(self, request: SynapseRequest) -> None:
|
||||||
|
@ -35,7 +35,7 @@ class OIDCCallbackResource(DirectServeHtmlResource):
|
|||||||
isLeaf = 1
|
isLeaf = 1
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._oidc_handler = hs.get_oidc_handler()
|
self._oidc_handler = hs.get_oidc_handler()
|
||||||
|
|
||||||
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
||||||
|
@ -47,7 +47,7 @@ class PasswordResetSubmitTokenResource(DirectServeHtmlResource):
|
|||||||
Args:
|
Args:
|
||||||
hs: server
|
hs: server
|
||||||
"""
|
"""
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
|
|
||||||
self.clock = hs.get_clock()
|
self.clock = hs.get_clock()
|
||||||
self.store = hs.get_datastores().main
|
self.store = hs.get_datastores().main
|
||||||
|
@ -44,7 +44,7 @@ class PickIdpResource(DirectServeHtmlResource):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._sso_handler = hs.get_sso_handler()
|
self._sso_handler = hs.get_sso_handler()
|
||||||
self._sso_login_idp_picker_template = (
|
self._sso_login_idp_picker_template = (
|
||||||
hs.config.sso.sso_login_idp_picker_template
|
hs.config.sso.sso_login_idp_picker_template
|
||||||
|
@ -62,7 +62,7 @@ def pick_username_resource(hs: "HomeServer") -> Resource:
|
|||||||
|
|
||||||
class AvailabilityCheckResource(DirectServeJsonResource):
|
class AvailabilityCheckResource(DirectServeJsonResource):
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._sso_handler = hs.get_sso_handler()
|
self._sso_handler = hs.get_sso_handler()
|
||||||
|
|
||||||
async def _async_render_GET(self, request: Request) -> Tuple[int, JsonDict]:
|
async def _async_render_GET(self, request: Request) -> Tuple[int, JsonDict]:
|
||||||
@ -78,7 +78,7 @@ class AvailabilityCheckResource(DirectServeJsonResource):
|
|||||||
|
|
||||||
class AccountDetailsResource(DirectServeHtmlResource):
|
class AccountDetailsResource(DirectServeHtmlResource):
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._sso_handler = hs.get_sso_handler()
|
self._sso_handler = hs.get_sso_handler()
|
||||||
|
|
||||||
def template_search_dirs() -> Generator[str, None, None]:
|
def template_search_dirs() -> Generator[str, None, None]:
|
||||||
|
@ -30,7 +30,7 @@ class MSC4108RendezvousSessionResource(DirectServeJsonResource):
|
|||||||
isLeaf = True
|
isLeaf = True
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer") -> None:
|
def __init__(self, hs: "HomeServer") -> None:
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._handler = hs.get_rendezvous_handler()
|
self._handler = hs.get_rendezvous_handler()
|
||||||
|
|
||||||
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
async def _async_render_GET(self, request: SynapseRequest) -> None:
|
||||||
|
@ -35,7 +35,7 @@ class SAML2ResponseResource(DirectServeHtmlResource):
|
|||||||
isLeaf = 1
|
isLeaf = 1
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._saml_handler = hs.get_saml_handler()
|
self._saml_handler = hs.get_saml_handler()
|
||||||
self._sso_handler = hs.get_sso_handler()
|
self._sso_handler = hs.get_sso_handler()
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ class SsoRegisterResource(DirectServeHtmlResource):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._sso_handler = hs.get_sso_handler()
|
self._sso_handler = hs.get_sso_handler()
|
||||||
|
|
||||||
async def _async_render_GET(self, request: Request) -> None:
|
async def _async_render_GET(self, request: Request) -> None:
|
||||||
|
@ -38,7 +38,7 @@ class UnsubscribeResource(DirectServeHtmlResource):
|
|||||||
SUCCESS_HTML = b"<html><body>You have been unsubscribed</body><html>"
|
SUCCESS_HTML = b"<html><body>You have been unsubscribed</body><html>"
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self.notifier = hs.get_notifier()
|
self.notifier = hs.get_notifier()
|
||||||
self.auth = hs.get_auth()
|
self.auth = hs.get_auth()
|
||||||
self.pusher_pool = hs.get_pusherpool()
|
self.pusher_pool = hs.get_pusherpool()
|
||||||
|
@ -86,7 +86,7 @@ class ClientWellKnownResource(DirectServeJsonResource):
|
|||||||
isLeaf = 1
|
isLeaf = 1
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
super().__init__()
|
super().__init__(clock=hs.get_clock())
|
||||||
self._well_known_builder = WellKnownBuilder(hs)
|
self._well_known_builder = WellKnownBuilder(hs)
|
||||||
|
|
||||||
async def _async_render_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
async def _async_render_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
|
||||||
|
@ -34,6 +34,7 @@ from synapse.metrics.background_process_metrics import wrap_as_background_proces
|
|||||||
from synapse.storage.database import LoggingTransaction
|
from synapse.storage.database import LoggingTransaction
|
||||||
from synapse.storage.databases import Databases
|
from synapse.storage.databases import Databases
|
||||||
from synapse.types.storage import _BackgroundUpdates
|
from synapse.types.storage import _BackgroundUpdates
|
||||||
|
from synapse.util.stringutils import shortstr
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
@ -167,6 +168,12 @@ class PurgeEventsStorageController:
|
|||||||
break
|
break
|
||||||
|
|
||||||
(room_id, groups_to_sequences) = next_to_delete
|
(room_id, groups_to_sequences) = next_to_delete
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"[purge] deleting state groups for room %s: %s",
|
||||||
|
room_id,
|
||||||
|
shortstr(groups_to_sequences.keys(), maxitems=10),
|
||||||
|
)
|
||||||
made_progress = await self._delete_state_groups(
|
made_progress = await self._delete_state_groups(
|
||||||
room_id, groups_to_sequences
|
room_id, groups_to_sequences
|
||||||
)
|
)
|
||||||
|
@ -1478,13 +1478,49 @@ class DatabasePool:
|
|||||||
"""
|
"""
|
||||||
Upsert, many times.
|
Upsert, many times.
|
||||||
|
|
||||||
|
This executes a query equivalent to `INSERT INTO ... ON CONFLICT DO UPDATE`,
|
||||||
|
with multiple value rows.
|
||||||
|
The query may use emulated upserts if the database engine does not support upserts,
|
||||||
|
or if the table is currently unsafe to upsert.
|
||||||
|
|
||||||
|
If there are no value columns, this instead generates a `ON CONFLICT DO NOTHING`.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
table: The table to upsert into
|
table: The table to upsert into
|
||||||
key_names: The key column names.
|
key_names: The unique key column names. These are the columns used in the ON CONFLICT clause.
|
||||||
key_values: A list of each row's key column values.
|
key_values: A list of each row's key column values, in the same order as `key_names`.
|
||||||
value_names: The value column names
|
value_names: The non-unique value column names
|
||||||
value_values: A list of each row's value column values.
|
value_values: A list of each row's value column values, in the same order as `value_names`.
|
||||||
Ignored if value_names is empty.
|
Ignored if value_names is empty.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```python
|
||||||
|
simple_upsert_many(
|
||||||
|
"mytable",
|
||||||
|
key_names=("room_id", "user_id"),
|
||||||
|
key_values=[
|
||||||
|
("!room1:example.org", "@user1:example.org"),
|
||||||
|
("!room2:example.org", "@user2:example.org"),
|
||||||
|
],
|
||||||
|
value_names=("wombat_count", "is_updated"),
|
||||||
|
value_values=[
|
||||||
|
(42, True),
|
||||||
|
(7, False)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
gives something equivalent to:
|
||||||
|
|
||||||
|
```sql
|
||||||
|
INSERT INTO mytable (room_id, user_id, wombat_count, is_updated)
|
||||||
|
VALUES
|
||||||
|
('!room1:example.org', '@user1:example.org', 42, True),
|
||||||
|
('!room2:example.org', '@user2:example.org', 7, False)
|
||||||
|
ON CONFLICT DO UPDATE SET
|
||||||
|
wombat_count = EXCLUDED.wombat_count,
|
||||||
|
is_updated = EXCLUDED.is_updated
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# We can autocommit if it safe to upsert
|
# We can autocommit if it safe to upsert
|
||||||
@ -1513,6 +1549,8 @@ class DatabasePool:
|
|||||||
"""
|
"""
|
||||||
Upsert, many times.
|
Upsert, many times.
|
||||||
|
|
||||||
|
See the documentation for `simple_upsert_many` for examples.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
table: The table to upsert into
|
table: The table to upsert into
|
||||||
key_names: The key column names.
|
key_names: The key column names.
|
||||||
|
@ -52,10 +52,11 @@ from synapse.storage.database import (
|
|||||||
make_in_list_sql_clause,
|
make_in_list_sql_clause,
|
||||||
)
|
)
|
||||||
from synapse.storage.util.id_generators import MultiWriterIdGenerator
|
from synapse.storage.util.id_generators import MultiWriterIdGenerator
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict, StrCollection
|
||||||
from synapse.util import Duration, json_encoder
|
from synapse.util import Duration, json_encoder
|
||||||
from synapse.util.caches.expiringcache import ExpiringCache
|
from synapse.util.caches.expiringcache import ExpiringCache
|
||||||
from synapse.util.caches.stream_change_cache import StreamChangeCache
|
from synapse.util.caches.stream_change_cache import StreamChangeCache
|
||||||
|
from synapse.util.iterutils import batch_iter
|
||||||
from synapse.util.stringutils import parse_and_validate_server_name
|
from synapse.util.stringutils import parse_and_validate_server_name
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@ -1027,6 +1028,40 @@ class DeviceInboxWorkerStore(SQLBaseStore):
|
|||||||
# loop first time we run this.
|
# loop first time we run this.
|
||||||
self._clock.sleep(1)
|
self._clock.sleep(1)
|
||||||
|
|
||||||
|
async def get_devices_with_messages(
|
||||||
|
self, user_id: str, device_ids: StrCollection
|
||||||
|
) -> StrCollection:
|
||||||
|
"""Get the matching device IDs that have messages in the device inbox."""
|
||||||
|
|
||||||
|
def get_devices_with_messages_txn(
|
||||||
|
txn: LoggingTransaction,
|
||||||
|
batch_device_ids: StrCollection,
|
||||||
|
) -> StrCollection:
|
||||||
|
clause, args = make_in_list_sql_clause(
|
||||||
|
self.database_engine, "device_id", batch_device_ids
|
||||||
|
)
|
||||||
|
sql = f"""
|
||||||
|
SELECT DISTINCT device_id FROM device_inbox
|
||||||
|
WHERE {clause} AND user_id = ?
|
||||||
|
"""
|
||||||
|
args.append(user_id)
|
||||||
|
txn.execute(sql, args)
|
||||||
|
return {row[0] for row in txn}
|
||||||
|
|
||||||
|
results: Set[str] = set()
|
||||||
|
for batch_device_ids in batch_iter(device_ids, 1000):
|
||||||
|
batch_results = await self.db_pool.runInteraction(
|
||||||
|
"get_devices_with_messages",
|
||||||
|
get_devices_with_messages_txn,
|
||||||
|
batch_device_ids,
|
||||||
|
# We don't need to run in a transaction as it's a single query
|
||||||
|
db_autocommit=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
results.update(batch_results)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
class DeviceInboxBackgroundUpdateStore(SQLBaseStore):
|
class DeviceInboxBackgroundUpdateStore(SQLBaseStore):
|
||||||
DEVICE_INBOX_STREAM_ID = "device_inbox_stream_drop"
|
DEVICE_INBOX_STREAM_ID = "device_inbox_stream_drop"
|
||||||
|
@ -282,7 +282,7 @@ class DeviceWorkerStore(RoomMemberWorkerStore, EndToEndKeyWorkerStore):
|
|||||||
"count_devices_by_users", count_devices_by_users_txn, user_ids
|
"count_devices_by_users", count_devices_by_users_txn, user_ids
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached()
|
@cached(tree=True)
|
||||||
async def get_device(
|
async def get_device(
|
||||||
self, user_id: str, device_id: str
|
self, user_id: str, device_id: str
|
||||||
) -> Optional[Mapping[str, Any]]:
|
) -> Optional[Mapping[str, Any]]:
|
||||||
@ -1861,7 +1861,7 @@ class DeviceStore(DeviceWorkerStore, DeviceBackgroundUpdateStore):
|
|||||||
)
|
)
|
||||||
raise StoreError(500, "Problem storing device.")
|
raise StoreError(500, "Problem storing device.")
|
||||||
|
|
||||||
async def delete_devices(self, user_id: str, device_ids: List[str]) -> None:
|
async def delete_devices(self, user_id: str, device_ids: StrCollection) -> None:
|
||||||
"""Deletes several devices.
|
"""Deletes several devices.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -1885,11 +1885,49 @@ class DeviceStore(DeviceWorkerStore, DeviceBackgroundUpdateStore):
|
|||||||
values=device_ids,
|
values=device_ids,
|
||||||
keyvalues={"user_id": user_id},
|
keyvalues={"user_id": user_id},
|
||||||
)
|
)
|
||||||
self._invalidate_cache_and_stream_bulk(
|
|
||||||
txn, self.get_device, [(user_id, device_id) for device_id in device_ids]
|
# Also delete associated e2e keys.
|
||||||
|
self.db_pool.simple_delete_many_txn(
|
||||||
|
txn,
|
||||||
|
table="e2e_device_keys_json",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
column="device_id",
|
||||||
|
values=device_ids,
|
||||||
|
)
|
||||||
|
self.db_pool.simple_delete_many_txn(
|
||||||
|
txn,
|
||||||
|
table="e2e_one_time_keys_json",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
column="device_id",
|
||||||
|
values=device_ids,
|
||||||
|
)
|
||||||
|
self.db_pool.simple_delete_many_txn(
|
||||||
|
txn,
|
||||||
|
table="dehydrated_devices",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
column="device_id",
|
||||||
|
values=device_ids,
|
||||||
|
)
|
||||||
|
self.db_pool.simple_delete_many_txn(
|
||||||
|
txn,
|
||||||
|
table="e2e_fallback_keys_json",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
column="device_id",
|
||||||
|
values=device_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
for batch in batch_iter(device_ids, 100):
|
# We're bulk deleting potentially many devices at once, so
|
||||||
|
# let's not invalidate the cache for each device individually.
|
||||||
|
# Instead, we will invalidate the cache for the user as a whole.
|
||||||
|
self._invalidate_cache_and_stream(txn, self.get_device, (user_id,))
|
||||||
|
self._invalidate_cache_and_stream(
|
||||||
|
txn, self.count_e2e_one_time_keys, (user_id,)
|
||||||
|
)
|
||||||
|
self._invalidate_cache_and_stream(
|
||||||
|
txn, self.get_e2e_unused_fallback_key_types, (user_id,)
|
||||||
|
)
|
||||||
|
|
||||||
|
for batch in batch_iter(device_ids, 1000):
|
||||||
await self.db_pool.runInteraction(
|
await self.db_pool.runInteraction(
|
||||||
"delete_devices", _delete_devices_txn, batch
|
"delete_devices", _delete_devices_txn, batch
|
||||||
)
|
)
|
||||||
@ -2061,32 +2099,36 @@ class DeviceStore(DeviceWorkerStore, DeviceBackgroundUpdateStore):
|
|||||||
context = get_active_span_text_map()
|
context = get_active_span_text_map()
|
||||||
|
|
||||||
def add_device_changes_txn(
|
def add_device_changes_txn(
|
||||||
txn: LoggingTransaction, stream_ids: List[int]
|
txn: LoggingTransaction,
|
||||||
|
batch_device_ids: StrCollection,
|
||||||
|
stream_ids: List[int],
|
||||||
) -> None:
|
) -> None:
|
||||||
self._add_device_change_to_stream_txn(
|
self._add_device_change_to_stream_txn(
|
||||||
txn,
|
txn,
|
||||||
user_id,
|
user_id,
|
||||||
device_ids,
|
batch_device_ids,
|
||||||
stream_ids,
|
stream_ids,
|
||||||
)
|
)
|
||||||
|
|
||||||
self._add_device_outbound_room_poke_txn(
|
self._add_device_outbound_room_poke_txn(
|
||||||
txn,
|
txn,
|
||||||
user_id,
|
user_id,
|
||||||
device_ids,
|
batch_device_ids,
|
||||||
room_ids,
|
room_ids,
|
||||||
stream_ids,
|
stream_ids,
|
||||||
context,
|
context,
|
||||||
)
|
)
|
||||||
|
|
||||||
async with self._device_list_id_gen.get_next_mult(
|
for batch_device_ids in batch_iter(device_ids, 1000):
|
||||||
len(device_ids)
|
async with self._device_list_id_gen.get_next_mult(
|
||||||
) as stream_ids:
|
len(device_ids)
|
||||||
await self.db_pool.runInteraction(
|
) as stream_ids:
|
||||||
"add_device_change_to_stream",
|
await self.db_pool.runInteraction(
|
||||||
add_device_changes_txn,
|
"add_device_change_to_stream",
|
||||||
stream_ids,
|
add_device_changes_txn,
|
||||||
)
|
batch_device_ids,
|
||||||
|
stream_ids,
|
||||||
|
)
|
||||||
|
|
||||||
return stream_ids[-1]
|
return stream_ids[-1]
|
||||||
|
|
||||||
|
@ -593,7 +593,7 @@ class EndToEndKeyWorkerStore(EndToEndKeyBackgroundStore, CacheInvalidationWorker
|
|||||||
txn, self.count_e2e_one_time_keys, (user_id, device_id)
|
txn, self.count_e2e_one_time_keys, (user_id, device_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached(max_entries=10000)
|
@cached(max_entries=10000, tree=True)
|
||||||
async def count_e2e_one_time_keys(
|
async def count_e2e_one_time_keys(
|
||||||
self, user_id: str, device_id: str
|
self, user_id: str, device_id: str
|
||||||
) -> Mapping[str, int]:
|
) -> Mapping[str, int]:
|
||||||
@ -808,7 +808,7 @@ class EndToEndKeyWorkerStore(EndToEndKeyBackgroundStore, CacheInvalidationWorker
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@cached(max_entries=10000)
|
@cached(max_entries=10000, tree=True)
|
||||||
async def get_e2e_unused_fallback_key_types(
|
async def get_e2e_unused_fallback_key_types(
|
||||||
self, user_id: str, device_id: str
|
self, user_id: str, device_id: str
|
||||||
) -> Sequence[str]:
|
) -> Sequence[str]:
|
||||||
@ -1632,46 +1632,6 @@ class EndToEndKeyStore(EndToEndKeyWorkerStore, SQLBaseStore):
|
|||||||
log_kv({"message": "Device keys stored."})
|
log_kv({"message": "Device keys stored."})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
async def delete_e2e_keys_by_device(self, user_id: str, device_id: str) -> None:
|
|
||||||
def delete_e2e_keys_by_device_txn(txn: LoggingTransaction) -> None:
|
|
||||||
log_kv(
|
|
||||||
{
|
|
||||||
"message": "Deleting keys for device",
|
|
||||||
"device_id": device_id,
|
|
||||||
"user_id": user_id,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
self.db_pool.simple_delete_txn(
|
|
||||||
txn,
|
|
||||||
table="e2e_device_keys_json",
|
|
||||||
keyvalues={"user_id": user_id, "device_id": device_id},
|
|
||||||
)
|
|
||||||
self.db_pool.simple_delete_txn(
|
|
||||||
txn,
|
|
||||||
table="e2e_one_time_keys_json",
|
|
||||||
keyvalues={"user_id": user_id, "device_id": device_id},
|
|
||||||
)
|
|
||||||
self._invalidate_cache_and_stream(
|
|
||||||
txn, self.count_e2e_one_time_keys, (user_id, device_id)
|
|
||||||
)
|
|
||||||
self.db_pool.simple_delete_txn(
|
|
||||||
txn,
|
|
||||||
table="dehydrated_devices",
|
|
||||||
keyvalues={"user_id": user_id, "device_id": device_id},
|
|
||||||
)
|
|
||||||
self.db_pool.simple_delete_txn(
|
|
||||||
txn,
|
|
||||||
table="e2e_fallback_keys_json",
|
|
||||||
keyvalues={"user_id": user_id, "device_id": device_id},
|
|
||||||
)
|
|
||||||
self._invalidate_cache_and_stream(
|
|
||||||
txn, self.get_e2e_unused_fallback_key_types, (user_id, device_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
await self.db_pool.runInteraction(
|
|
||||||
"delete_e2e_keys_by_device", delete_e2e_keys_by_device_txn
|
|
||||||
)
|
|
||||||
|
|
||||||
def _set_e2e_cross_signing_key_txn(
|
def _set_e2e_cross_signing_key_txn(
|
||||||
self,
|
self,
|
||||||
txn: LoggingTransaction,
|
txn: LoggingTransaction,
|
||||||
|
@ -294,6 +294,27 @@ class EventsBackgroundUpdatesStore(StreamWorkerStore, StateDeltasStore, SQLBaseS
|
|||||||
where_clause="NOT outlier",
|
where_clause="NOT outlier",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# These indices are needed to validate the foreign key constraint
|
||||||
|
# when events are deleted.
|
||||||
|
self.db_pool.updates.register_background_index_update(
|
||||||
|
_BackgroundUpdates.CURRENT_STATE_EVENTS_STREAM_ORDERING_INDEX_UPDATE_NAME,
|
||||||
|
index_name="current_state_events_stream_ordering_idx",
|
||||||
|
table="current_state_events",
|
||||||
|
columns=["event_stream_ordering"],
|
||||||
|
)
|
||||||
|
self.db_pool.updates.register_background_index_update(
|
||||||
|
_BackgroundUpdates.ROOM_MEMBERSHIPS_STREAM_ORDERING_INDEX_UPDATE_NAME,
|
||||||
|
index_name="room_memberships_stream_ordering_idx",
|
||||||
|
table="room_memberships",
|
||||||
|
columns=["event_stream_ordering"],
|
||||||
|
)
|
||||||
|
self.db_pool.updates.register_background_index_update(
|
||||||
|
_BackgroundUpdates.LOCAL_CURRENT_MEMBERSHIP_STREAM_ORDERING_INDEX_UPDATE_NAME,
|
||||||
|
index_name="local_current_membership_stream_ordering_idx",
|
||||||
|
table="local_current_membership",
|
||||||
|
columns=["event_stream_ordering"],
|
||||||
|
)
|
||||||
|
|
||||||
# Handle background updates for Sliding Sync tables
|
# Handle background updates for Sliding Sync tables
|
||||||
#
|
#
|
||||||
self.db_pool.updates.register_background_update_handler(
|
self.db_pool.updates.register_background_update_handler(
|
||||||
|
@ -349,6 +349,19 @@ class EventsWorkerStore(SQLBaseStore):
|
|||||||
where_clause="type = 'm.room.member'",
|
where_clause="type = 'm.room.member'",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Added to support efficient reverse lookups on the foreign key
|
||||||
|
# (user_id, device_id) when deleting devices.
|
||||||
|
# We already had a UNIQUE index on these 4 columns but out-of-order
|
||||||
|
# so replace that one.
|
||||||
|
self.db_pool.updates.register_background_index_update(
|
||||||
|
update_name="event_txn_id_device_id_txn_id2",
|
||||||
|
index_name="event_txn_id_device_id_txn_id2",
|
||||||
|
table="event_txn_id_device_id",
|
||||||
|
columns=("user_id", "device_id", "room_id", "txn_id"),
|
||||||
|
unique=True,
|
||||||
|
replaces_index="event_txn_id_device_id_txn_id",
|
||||||
|
)
|
||||||
|
|
||||||
def get_un_partial_stated_events_token(self, instance_name: str) -> int:
|
def get_un_partial_stated_events_token(self, instance_name: str) -> int:
|
||||||
return (
|
return (
|
||||||
self._un_partial_stated_events_stream_id_gen.get_current_token_for_writer(
|
self._un_partial_stated_events_stream_id_gen.get_current_token_for_writer(
|
||||||
|
@ -40,14 +40,16 @@ from synapse.storage.database import (
|
|||||||
DatabasePool,
|
DatabasePool,
|
||||||
LoggingDatabaseConnection,
|
LoggingDatabaseConnection,
|
||||||
LoggingTransaction,
|
LoggingTransaction,
|
||||||
|
make_in_list_sql_clause,
|
||||||
)
|
)
|
||||||
from synapse.storage.databases.main.cache import CacheInvalidationWorkerStore
|
from synapse.storage.databases.main.cache import CacheInvalidationWorkerStore
|
||||||
from synapse.storage.databases.main.stats import StatsStore
|
from synapse.storage.databases.main.stats import StatsStore
|
||||||
from synapse.storage.types import Cursor
|
from synapse.storage.types import Cursor
|
||||||
from synapse.storage.util.id_generators import IdGenerator
|
from synapse.storage.util.id_generators import IdGenerator
|
||||||
from synapse.storage.util.sequence import build_sequence_generator
|
from synapse.storage.util.sequence import build_sequence_generator
|
||||||
from synapse.types import JsonDict, UserID, UserInfo
|
from synapse.types import JsonDict, StrCollection, UserID, UserInfo
|
||||||
from synapse.util.caches.descriptors import cached
|
from synapse.util.caches.descriptors import cached
|
||||||
|
from synapse.util.iterutils import batch_iter
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
@ -2801,6 +2803,81 @@ class RegistrationStore(StatsStore, RegistrationBackgroundUpdateStore):
|
|||||||
|
|
||||||
return await self.db_pool.runInteraction("user_delete_access_tokens", f)
|
return await self.db_pool.runInteraction("user_delete_access_tokens", f)
|
||||||
|
|
||||||
|
async def user_delete_access_tokens_for_devices(
|
||||||
|
self,
|
||||||
|
user_id: str,
|
||||||
|
device_ids: StrCollection,
|
||||||
|
) -> List[Tuple[str, int, Optional[str]]]:
|
||||||
|
"""
|
||||||
|
Invalidate access and refresh tokens belonging to a user
|
||||||
|
|
||||||
|
Args:
|
||||||
|
user_id: ID of user the tokens belong to
|
||||||
|
device_ids: The devices to delete tokens for.
|
||||||
|
Returns:
|
||||||
|
A tuple of (token, token id, device id) for each of the deleted tokens
|
||||||
|
"""
|
||||||
|
|
||||||
|
def user_delete_access_tokens_for_devices_txn(
|
||||||
|
txn: LoggingTransaction, batch_device_ids: StrCollection
|
||||||
|
) -> List[Tuple[str, int, Optional[str]]]:
|
||||||
|
self.db_pool.simple_delete_many_txn(
|
||||||
|
txn,
|
||||||
|
table="refresh_tokens",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
column="device_id",
|
||||||
|
values=batch_device_ids,
|
||||||
|
)
|
||||||
|
|
||||||
|
clause, args = make_in_list_sql_clause(
|
||||||
|
txn.database_engine, "device_id", batch_device_ids
|
||||||
|
)
|
||||||
|
args.append(user_id)
|
||||||
|
|
||||||
|
if self.database_engine.supports_returning:
|
||||||
|
sql = f"""
|
||||||
|
DELETE FROM access_tokens
|
||||||
|
WHERE {clause} AND user_id = ?
|
||||||
|
RETURNING token, id, device_id
|
||||||
|
"""
|
||||||
|
txn.execute(sql, args)
|
||||||
|
tokens_and_devices = txn.fetchall()
|
||||||
|
else:
|
||||||
|
tokens_and_devices = self.db_pool.simple_select_many_txn(
|
||||||
|
txn,
|
||||||
|
table="access_tokens",
|
||||||
|
column="device_id",
|
||||||
|
iterable=batch_device_ids,
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
retcols=("token", "id", "device_id"),
|
||||||
|
)
|
||||||
|
|
||||||
|
self.db_pool.simple_delete_many_txn(
|
||||||
|
txn,
|
||||||
|
table="access_tokens",
|
||||||
|
keyvalues={"user_id": user_id},
|
||||||
|
column="device_id",
|
||||||
|
values=batch_device_ids,
|
||||||
|
)
|
||||||
|
|
||||||
|
self._invalidate_cache_and_stream_bulk(
|
||||||
|
txn,
|
||||||
|
self.get_user_by_access_token,
|
||||||
|
[(t[0],) for t in tokens_and_devices],
|
||||||
|
)
|
||||||
|
return tokens_and_devices
|
||||||
|
|
||||||
|
results = []
|
||||||
|
for batch_device_ids in batch_iter(device_ids, 1000):
|
||||||
|
tokens_and_devices = await self.db_pool.runInteraction(
|
||||||
|
"user_delete_access_tokens_for_devices",
|
||||||
|
user_delete_access_tokens_for_devices_txn,
|
||||||
|
batch_device_ids,
|
||||||
|
)
|
||||||
|
results.extend(tokens_and_devices)
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
async def delete_access_token(self, access_token: str) -> None:
|
async def delete_access_token(self, access_token: str) -> None:
|
||||||
def f(txn: LoggingTransaction) -> None:
|
def f(txn: LoggingTransaction) -> None:
|
||||||
self.db_pool.simple_delete_one_txn(
|
self.db_pool.simple_delete_one_txn(
|
||||||
|
@ -290,16 +290,6 @@ class StateBackgroundUpdateStore(StateGroupBackgroundUpdateStore):
|
|||||||
STATE_GROUPS_ROOM_INDEX_UPDATE_NAME = "state_groups_room_id_idx"
|
STATE_GROUPS_ROOM_INDEX_UPDATE_NAME = "state_groups_room_id_idx"
|
||||||
STATE_GROUP_EDGES_UNIQUE_INDEX_UPDATE_NAME = "state_group_edges_unique_idx"
|
STATE_GROUP_EDGES_UNIQUE_INDEX_UPDATE_NAME = "state_group_edges_unique_idx"
|
||||||
|
|
||||||
CURRENT_STATE_EVENTS_STREAM_ORDERING_INDEX_UPDATE_NAME = (
|
|
||||||
"current_state_events_stream_ordering_idx"
|
|
||||||
)
|
|
||||||
ROOM_MEMBERSHIPS_STREAM_ORDERING_INDEX_UPDATE_NAME = (
|
|
||||||
"room_memberships_stream_ordering_idx"
|
|
||||||
)
|
|
||||||
LOCAL_CURRENT_MEMBERSHIP_STREAM_ORDERING_INDEX_UPDATE_NAME = (
|
|
||||||
"local_current_membership_stream_ordering_idx"
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
database: DatabasePool,
|
database: DatabasePool,
|
||||||
@ -336,27 +326,6 @@ class StateBackgroundUpdateStore(StateGroupBackgroundUpdateStore):
|
|||||||
replaces_index="state_group_edges_idx",
|
replaces_index="state_group_edges_idx",
|
||||||
)
|
)
|
||||||
|
|
||||||
# These indices are needed to validate the foreign key constraint
|
|
||||||
# when events are deleted.
|
|
||||||
self.db_pool.updates.register_background_index_update(
|
|
||||||
self.CURRENT_STATE_EVENTS_STREAM_ORDERING_INDEX_UPDATE_NAME,
|
|
||||||
index_name="current_state_events_stream_ordering_idx",
|
|
||||||
table="current_state_events",
|
|
||||||
columns=["event_stream_ordering"],
|
|
||||||
)
|
|
||||||
self.db_pool.updates.register_background_index_update(
|
|
||||||
self.ROOM_MEMBERSHIPS_STREAM_ORDERING_INDEX_UPDATE_NAME,
|
|
||||||
index_name="room_memberships_stream_ordering_idx",
|
|
||||||
table="room_memberships",
|
|
||||||
columns=["event_stream_ordering"],
|
|
||||||
)
|
|
||||||
self.db_pool.updates.register_background_index_update(
|
|
||||||
self.LOCAL_CURRENT_MEMBERSHIP_STREAM_ORDERING_INDEX_UPDATE_NAME,
|
|
||||||
index_name="local_current_membership_stream_ordering_idx",
|
|
||||||
table="local_current_membership",
|
|
||||||
columns=["event_stream_ordering"],
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _background_deduplicate_state(
|
async def _background_deduplicate_state(
|
||||||
self, progress: dict, batch_size: int
|
self, progress: dict, batch_size: int
|
||||||
) -> int:
|
) -> int:
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
--
|
||||||
|
-- This file is licensed under the Affero General Public License (AGPL) version 3.
|
||||||
|
--
|
||||||
|
-- Copyright (C) 2025 New Vector, Ltd
|
||||||
|
--
|
||||||
|
-- This program is free software: you can redistribute it and/or modify
|
||||||
|
-- it under the terms of the GNU Affero General Public License as
|
||||||
|
-- published by the Free Software Foundation, either version 3 of the
|
||||||
|
-- License, or (at your option) any later version.
|
||||||
|
--
|
||||||
|
-- See the GNU Affero General Public License for more details:
|
||||||
|
-- <https://www.gnu.org/licenses/agpl-3.0.html>.
|
||||||
|
|
||||||
|
INSERT INTO background_updates (ordering, update_name, progress_json) VALUES
|
||||||
|
(9207, 'event_txn_id_device_id_txn_id2', '{}');
|
@ -38,6 +38,16 @@ class _BackgroundUpdates:
|
|||||||
|
|
||||||
EVENTS_JUMP_TO_DATE_INDEX = "events_jump_to_date_index"
|
EVENTS_JUMP_TO_DATE_INDEX = "events_jump_to_date_index"
|
||||||
|
|
||||||
|
CURRENT_STATE_EVENTS_STREAM_ORDERING_INDEX_UPDATE_NAME = (
|
||||||
|
"current_state_events_stream_ordering_idx"
|
||||||
|
)
|
||||||
|
ROOM_MEMBERSHIPS_STREAM_ORDERING_INDEX_UPDATE_NAME = (
|
||||||
|
"room_memberships_stream_ordering_idx"
|
||||||
|
)
|
||||||
|
LOCAL_CURRENT_MEMBERSHIP_STREAM_ORDERING_INDEX_UPDATE_NAME = (
|
||||||
|
"local_current_membership_stream_ordering_idx"
|
||||||
|
)
|
||||||
|
|
||||||
SLIDING_SYNC_PREFILL_JOINED_ROOMS_TO_RECALCULATE_TABLE_BG_UPDATE = (
|
SLIDING_SYNC_PREFILL_JOINED_ROOMS_TO_RECALCULATE_TABLE_BG_UPDATE = (
|
||||||
"sliding_sync_prefill_joined_rooms_to_recalculate_table_bg_update"
|
"sliding_sync_prefill_joined_rooms_to_recalculate_table_bg_update"
|
||||||
)
|
)
|
||||||
|
@ -225,7 +225,7 @@ KNOWN_KEYS = {
|
|||||||
"depth",
|
"depth",
|
||||||
"event_id",
|
"event_id",
|
||||||
"hashes",
|
"hashes",
|
||||||
"origin",
|
"origin", # old events were created with an origin field.
|
||||||
"origin_server_ts",
|
"origin_server_ts",
|
||||||
"prev_events",
|
"prev_events",
|
||||||
"room_id",
|
"room_id",
|
||||||
|
@ -48,7 +48,6 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
def test_sign_minimal(self) -> None:
|
def test_sign_minimal(self) -> None:
|
||||||
event_dict = {
|
event_dict = {
|
||||||
"event_id": "$0:domain",
|
"event_id": "$0:domain",
|
||||||
"origin": "domain",
|
|
||||||
"origin_server_ts": 1000000,
|
"origin_server_ts": 1000000,
|
||||||
"signatures": {},
|
"signatures": {},
|
||||||
"type": "X",
|
"type": "X",
|
||||||
@ -64,7 +63,7 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertTrue(hasattr(event, "hashes"))
|
self.assertTrue(hasattr(event, "hashes"))
|
||||||
self.assertIn("sha256", event.hashes)
|
self.assertIn("sha256", event.hashes)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.hashes["sha256"], "6tJjLpXtggfke8UxFhAKg82QVkJzvKOVOOSjUDK4ZSI"
|
event.hashes["sha256"], "A6Nco6sqoy18PPfPDVdYvoowfc0PVBk9g9OiyT3ncRM"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(hasattr(event, "signatures"))
|
self.assertTrue(hasattr(event, "signatures"))
|
||||||
@ -72,15 +71,14 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertIn(KEY_NAME, event.signatures["domain"])
|
self.assertIn(KEY_NAME, event.signatures["domain"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.signatures[HOSTNAME][KEY_NAME],
|
event.signatures[HOSTNAME][KEY_NAME],
|
||||||
"2Wptgo4CwmLo/Y8B8qinxApKaCkBG2fjTWB7AbP5Uy+"
|
"PBc48yDVszWB9TRaB/+CZC1B+pDAC10F8zll006j+NN"
|
||||||
"aIbygsSdLOFzvdDjww8zUVKCmI02eP9xtyJxc/cLiBA",
|
"fe4PEMWcVuLaG63LFTK9e4rwJE8iLZMPtCKhDTXhpAQ",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_sign_message(self) -> None:
|
def test_sign_message(self) -> None:
|
||||||
event_dict = {
|
event_dict = {
|
||||||
"content": {"body": "Here is the message content"},
|
"content": {"body": "Here is the message content"},
|
||||||
"event_id": "$0:domain",
|
"event_id": "$0:domain",
|
||||||
"origin": "domain",
|
|
||||||
"origin_server_ts": 1000000,
|
"origin_server_ts": 1000000,
|
||||||
"type": "m.room.message",
|
"type": "m.room.message",
|
||||||
"room_id": "!r:domain",
|
"room_id": "!r:domain",
|
||||||
@ -98,7 +96,7 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertTrue(hasattr(event, "hashes"))
|
self.assertTrue(hasattr(event, "hashes"))
|
||||||
self.assertIn("sha256", event.hashes)
|
self.assertIn("sha256", event.hashes)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.hashes["sha256"], "onLKD1bGljeBWQhWZ1kaP9SorVmRQNdN5aM2JYU2n/g"
|
event.hashes["sha256"], "rDCeYBepPlI891h/RkI2/Lkf9bt7u0TxFku4tMs7WKk"
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertTrue(hasattr(event, "signatures"))
|
self.assertTrue(hasattr(event, "signatures"))
|
||||||
@ -106,6 +104,6 @@ class EventSigningTestCase(unittest.TestCase):
|
|||||||
self.assertIn(KEY_NAME, event.signatures["domain"])
|
self.assertIn(KEY_NAME, event.signatures["domain"])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
event.signatures[HOSTNAME][KEY_NAME],
|
event.signatures[HOSTNAME][KEY_NAME],
|
||||||
"Wm+VzmOUOz08Ds+0NTWb1d4CZrVsJSikkeRxh6aCcUw"
|
"Ay4aj2b5oJ1k8INYZ9n3KnszCflM0emwcmQQ7vxpbdc"
|
||||||
"u6pNC78FunoD7KNWzqFn241eYHYMGCA5McEiVPdhzBA",
|
"Sv9bkJxIZdWX1IJllcZLq89+D3sSabE+vqPtZs9akDw",
|
||||||
)
|
)
|
||||||
|
@ -122,7 +122,7 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
"prev_events": "prev_events",
|
"prev_events": "prev_events",
|
||||||
"prev_state": "prev_state",
|
"prev_state": "prev_state",
|
||||||
"auth_events": "auth_events",
|
"auth_events": "auth_events",
|
||||||
"origin": "domain",
|
"origin": "domain", # historical top-level field that still exists on old events
|
||||||
"origin_server_ts": 1234,
|
"origin_server_ts": 1234,
|
||||||
"membership": "join",
|
"membership": "join",
|
||||||
# Also include a key that should be removed.
|
# Also include a key that should be removed.
|
||||||
@ -139,7 +139,7 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
"prev_events": "prev_events",
|
"prev_events": "prev_events",
|
||||||
"prev_state": "prev_state",
|
"prev_state": "prev_state",
|
||||||
"auth_events": "auth_events",
|
"auth_events": "auth_events",
|
||||||
"origin": "domain",
|
"origin": "domain", # historical top-level field that still exists on old events
|
||||||
"origin_server_ts": 1234,
|
"origin_server_ts": 1234,
|
||||||
"membership": "join",
|
"membership": "join",
|
||||||
"content": {},
|
"content": {},
|
||||||
@ -148,13 +148,12 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
# As of room versions we now redact the membership, prev_states, and origin keys.
|
# As of room versions we now redact the membership and prev_states keys.
|
||||||
self.run_test(
|
self.run_test(
|
||||||
{
|
{
|
||||||
"type": "A",
|
"type": "A",
|
||||||
"prev_state": "prev_state",
|
"prev_state": "prev_state",
|
||||||
"membership": "join",
|
"membership": "join",
|
||||||
"origin": "example.com",
|
|
||||||
},
|
},
|
||||||
{"type": "A", "content": {}, "signatures": {}, "unsigned": {}},
|
{"type": "A", "content": {}, "signatures": {}, "unsigned": {}},
|
||||||
room_version=RoomVersions.V11,
|
room_version=RoomVersions.V11,
|
||||||
@ -238,7 +237,6 @@ class PruneEventTestCase(stdlib_unittest.TestCase):
|
|||||||
{
|
{
|
||||||
"type": "m.room.create",
|
"type": "m.room.create",
|
||||||
"content": {"not_a_real_key": True},
|
"content": {"not_a_real_key": True},
|
||||||
"origin": "some_homeserver",
|
|
||||||
"nonsense_field": "some_random_garbage",
|
"nonsense_field": "some_random_garbage",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -535,7 +535,6 @@ class StripUnsignedFromEventsTestCase(unittest.TestCase):
|
|||||||
"depth": 1000,
|
"depth": 1000,
|
||||||
"origin_server_ts": 1,
|
"origin_server_ts": 1,
|
||||||
"type": "m.room.member",
|
"type": "m.room.member",
|
||||||
"origin": "test.servx",
|
|
||||||
"content": {"membership": "join"},
|
"content": {"membership": "join"},
|
||||||
"auth_events": [],
|
"auth_events": [],
|
||||||
"unsigned": {"malicious garbage": "hackz", "more warez": "more hackz"},
|
"unsigned": {"malicious garbage": "hackz", "more warez": "more hackz"},
|
||||||
@ -552,7 +551,6 @@ class StripUnsignedFromEventsTestCase(unittest.TestCase):
|
|||||||
"depth": 1000,
|
"depth": 1000,
|
||||||
"origin_server_ts": 1,
|
"origin_server_ts": 1,
|
||||||
"type": "m.room.member",
|
"type": "m.room.member",
|
||||||
"origin": "test.servx",
|
|
||||||
"auth_events": [],
|
"auth_events": [],
|
||||||
"content": {"membership": "join"},
|
"content": {"membership": "join"},
|
||||||
"unsigned": {
|
"unsigned": {
|
||||||
@ -579,7 +577,6 @@ class StripUnsignedFromEventsTestCase(unittest.TestCase):
|
|||||||
"depth": 1000,
|
"depth": 1000,
|
||||||
"origin_server_ts": 1,
|
"origin_server_ts": 1,
|
||||||
"type": "m.room.power_levels",
|
"type": "m.room.power_levels",
|
||||||
"origin": "test.servx",
|
|
||||||
"content": {},
|
"content": {},
|
||||||
"auth_events": [],
|
"auth_events": [],
|
||||||
"unsigned": {
|
"unsigned": {
|
||||||
|
@ -1080,6 +1080,62 @@ class SpaceSummaryTestCase(unittest.HomeserverTestCase):
|
|||||||
self.assertEqual(federation_requests, 2)
|
self.assertEqual(federation_requests, 2)
|
||||||
self._assert_hierarchy(result, expected)
|
self._assert_hierarchy(result, expected)
|
||||||
|
|
||||||
|
def test_fed_remote_room_hosts(self) -> None:
|
||||||
|
"""
|
||||||
|
Test if requested room is available over federation using via's.
|
||||||
|
"""
|
||||||
|
fed_hostname = self.hs.hostname + "2"
|
||||||
|
fed_space = "#fed_space:" + fed_hostname
|
||||||
|
fed_subroom = "#fed_sub_room:" + fed_hostname
|
||||||
|
|
||||||
|
remote_room_hosts = tuple(fed_hostname)
|
||||||
|
|
||||||
|
requested_room_entry = _RoomEntry(
|
||||||
|
fed_space,
|
||||||
|
{
|
||||||
|
"room_id": fed_space,
|
||||||
|
"world_readable": True,
|
||||||
|
"join_rule": "public",
|
||||||
|
"room_type": RoomTypes.SPACE,
|
||||||
|
},
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": EventTypes.SpaceChild,
|
||||||
|
"room_id": fed_space,
|
||||||
|
"state_key": fed_subroom,
|
||||||
|
"content": {"via": [fed_hostname]},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
)
|
||||||
|
child_room = {
|
||||||
|
"room_id": fed_subroom,
|
||||||
|
"world_readable": True,
|
||||||
|
"join_rule": "public",
|
||||||
|
}
|
||||||
|
|
||||||
|
async def summarize_remote_room_hierarchy(
|
||||||
|
_self: Any, room: Any, suggested_only: bool
|
||||||
|
) -> Tuple[Optional[_RoomEntry], Dict[str, JsonDict], Set[str]]:
|
||||||
|
return requested_room_entry, {fed_subroom: child_room}, set()
|
||||||
|
|
||||||
|
expected = [
|
||||||
|
(fed_space, [fed_subroom]),
|
||||||
|
(fed_subroom, ()),
|
||||||
|
]
|
||||||
|
|
||||||
|
with mock.patch(
|
||||||
|
"synapse.handlers.room_summary.RoomSummaryHandler._summarize_remote_room_hierarchy",
|
||||||
|
new=summarize_remote_room_hierarchy,
|
||||||
|
):
|
||||||
|
result = self.get_success(
|
||||||
|
self.handler.get_room_hierarchy(
|
||||||
|
create_requester(self.user),
|
||||||
|
fed_space,
|
||||||
|
remote_room_hosts=remote_room_hosts,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self._assert_hierarchy(result, expected)
|
||||||
|
|
||||||
|
|
||||||
class RoomSummaryTestCase(unittest.HomeserverTestCase):
|
class RoomSummaryTestCase(unittest.HomeserverTestCase):
|
||||||
servlets = [
|
servlets = [
|
||||||
|
@ -2846,6 +2846,16 @@ class UserRestTestCase(unittest.HomeserverTestCase):
|
|||||||
self.assertEqual(Codes.USER_LOCKED, channel.json_body["errcode"])
|
self.assertEqual(Codes.USER_LOCKED, channel.json_body["errcode"])
|
||||||
self.assertTrue(channel.json_body["soft_logout"])
|
self.assertTrue(channel.json_body["soft_logout"])
|
||||||
|
|
||||||
|
# User is not authorized to log in anymore
|
||||||
|
channel = self.make_request(
|
||||||
|
"POST",
|
||||||
|
"/_matrix/client/r0/login",
|
||||||
|
{"type": "m.login.password", "user": "user", "password": "pass"},
|
||||||
|
)
|
||||||
|
self.assertEqual(401, channel.code, msg=channel.json_body)
|
||||||
|
self.assertEqual(Codes.USER_LOCKED, channel.json_body["errcode"])
|
||||||
|
self.assertTrue(channel.json_body["soft_logout"])
|
||||||
|
|
||||||
@override_config({"user_directory": {"enabled": True, "search_all_users": True}})
|
@override_config({"user_directory": {"enabled": True, "search_all_users": True}})
|
||||||
def test_locked_user_not_in_user_dir(self) -> None:
|
def test_locked_user_not_in_user_dir(self) -> None:
|
||||||
# User is available in the user dir
|
# User is available in the user dir
|
||||||
|
@ -264,3 +264,43 @@ class CapabilitiesTestCase(unittest.HomeserverTestCase):
|
|||||||
|
|
||||||
self.assertEqual(channel.code, HTTPStatus.OK)
|
self.assertEqual(channel.code, HTTPStatus.OK)
|
||||||
self.assertTrue(capabilities["m.get_login_token"]["enabled"])
|
self.assertTrue(capabilities["m.get_login_token"]["enabled"])
|
||||||
|
|
||||||
|
@override_config(
|
||||||
|
{
|
||||||
|
"experimental_features": {"msc4267_enabled": True},
|
||||||
|
"forget_rooms_on_leave": True,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_get_forget_forced_upon_leave_with_auto_forget(self) -> None:
|
||||||
|
# Server auto-forgets on /leave, expect enabled client capability
|
||||||
|
access_token = self.get_success(
|
||||||
|
self.auth_handler.create_access_token_for_user_id(
|
||||||
|
self.user, device_id=None, valid_until_ms=None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
channel = self.make_request("GET", self.url, access_token=access_token)
|
||||||
|
capabilities = channel.json_body["capabilities"]
|
||||||
|
self.assertEqual(channel.code, HTTPStatus.OK)
|
||||||
|
self.assertTrue(
|
||||||
|
capabilities["org.matrix.msc4267.forget_forced_upon_leave"]["enabled"]
|
||||||
|
)
|
||||||
|
|
||||||
|
@override_config(
|
||||||
|
{
|
||||||
|
"experimental_features": {"msc4267_enabled": True},
|
||||||
|
"forget_rooms_on_leave": False,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
def test_get_forget_forced_upon_leave_without_auto_forget(self) -> None:
|
||||||
|
# Server doesn't auto-forget on /leave, expect disabled client capability
|
||||||
|
access_token = self.get_success(
|
||||||
|
self.auth_handler.create_access_token_for_user_id(
|
||||||
|
self.user, device_id=None, valid_until_ms=None
|
||||||
|
)
|
||||||
|
)
|
||||||
|
channel = self.make_request("GET", self.url, access_token=access_token)
|
||||||
|
capabilities = channel.json_body["capabilities"]
|
||||||
|
self.assertEqual(channel.code, HTTPStatus.OK)
|
||||||
|
self.assertFalse(
|
||||||
|
capabilities["org.matrix.msc4267.forget_forced_upon_leave"]["enabled"]
|
||||||
|
)
|
||||||
|
@ -316,15 +316,16 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
|||||||
await self.callback(request)
|
await self.callback(request)
|
||||||
|
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
reactor, _ = get_clock()
|
reactor, clock = get_clock()
|
||||||
self.reactor = reactor
|
self.reactor = reactor
|
||||||
|
self.clock = clock
|
||||||
|
|
||||||
def test_good_response(self) -> None:
|
def test_good_response(self) -> None:
|
||||||
async def callback(request: SynapseRequest) -> None:
|
async def callback(request: SynapseRequest) -> None:
|
||||||
request.write(b"response")
|
request.write(b"response")
|
||||||
request.finish()
|
request.finish()
|
||||||
|
|
||||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
|
||||||
res.callback = callback
|
res.callback = callback
|
||||||
|
|
||||||
channel = make_request(
|
channel = make_request(
|
||||||
@ -344,7 +345,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
|||||||
async def callback(request: SynapseRequest, **kwargs: object) -> None:
|
async def callback(request: SynapseRequest, **kwargs: object) -> None:
|
||||||
raise RedirectException(b"/look/an/eagle", 301)
|
raise RedirectException(b"/look/an/eagle", 301)
|
||||||
|
|
||||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
|
||||||
res.callback = callback
|
res.callback = callback
|
||||||
|
|
||||||
channel = make_request(
|
channel = make_request(
|
||||||
@ -366,7 +367,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
|||||||
e.cookies.append(b"session=yespls")
|
e.cookies.append(b"session=yespls")
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
|
||||||
res.callback = callback
|
res.callback = callback
|
||||||
|
|
||||||
channel = make_request(
|
channel = make_request(
|
||||||
@ -387,7 +388,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
|||||||
request.write(b"response")
|
request.write(b"response")
|
||||||
request.finish()
|
request.finish()
|
||||||
|
|
||||||
res = WrapHtmlRequestHandlerTests.TestResource()
|
res = WrapHtmlRequestHandlerTests.TestResource(clock=self.clock)
|
||||||
res.callback = callback
|
res.callback = callback
|
||||||
|
|
||||||
channel = make_request(
|
channel = make_request(
|
||||||
@ -400,7 +401,7 @@ class WrapHtmlRequestHandlerTests(unittest.TestCase):
|
|||||||
|
|
||||||
class CancellableDirectServeJsonResource(DirectServeJsonResource):
|
class CancellableDirectServeJsonResource(DirectServeJsonResource):
|
||||||
def __init__(self, clock: Clock):
|
def __init__(self, clock: Clock):
|
||||||
super().__init__()
|
super().__init__(clock=clock)
|
||||||
self.clock = clock
|
self.clock = clock
|
||||||
|
|
||||||
@cancellable
|
@cancellable
|
||||||
@ -417,7 +418,7 @@ class CancellableDirectServeHtmlResource(DirectServeHtmlResource):
|
|||||||
ERROR_TEMPLATE = "{code} {msg}"
|
ERROR_TEMPLATE = "{code} {msg}"
|
||||||
|
|
||||||
def __init__(self, clock: Clock):
|
def __init__(self, clock: Clock):
|
||||||
super().__init__()
|
super().__init__(clock=clock)
|
||||||
self.clock = clock
|
self.clock = clock
|
||||||
|
|
||||||
@cancellable
|
@cancellable
|
||||||
|
Loading…
x
Reference in New Issue
Block a user