mirror of
https://github.com/element-hq/synapse.git
synced 2025-12-07 01:20:16 +00:00
Compare commits
144 Commits
madlittlem
...
quenting/l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
724a48ecdd | ||
|
|
4cee8c7b99 | ||
|
|
4ac656073d | ||
|
|
3212526673 | ||
|
|
c0878ac9e6 | ||
|
|
76c9f09e09 | ||
|
|
5c20a60f0b | ||
|
|
3671bdbc51 | ||
|
|
7e60ca70c8 | ||
|
|
9135d78b88 | ||
|
|
3e10b3392f | ||
|
|
40e4e379da | ||
|
|
87ba085cdf | ||
|
|
7e3e9a6d60 | ||
|
|
874c6b38f7 | ||
|
|
09aa3fc270 | ||
|
|
14e93d8043 | ||
|
|
6d39e3a411 | ||
|
|
f7aa36926e | ||
|
|
283ade8e33 | ||
|
|
1f155c9650 | ||
|
|
6679c719e3 | ||
|
|
073ce74464 | ||
|
|
a93ec56cec | ||
|
|
e8c6cb3d9e | ||
|
|
3bb95d4a9d | ||
|
|
526b875e03 | ||
|
|
d27438bc25 | ||
|
|
8f375ea6c1 | ||
|
|
3db9fa3eeb | ||
|
|
0c0a9fafde | ||
|
|
4054d956f7 | ||
|
|
04932c76f5 | ||
|
|
9244948750 | ||
|
|
fdd63882b1 | ||
|
|
1e45f35eb6 | ||
|
|
9301baa5f8 | ||
|
|
576022912b | ||
|
|
848949a727 | ||
|
|
3f37bd6277 | ||
|
|
a89afc733b | ||
|
|
f0656a3b06 | ||
|
|
2c434e5187 | ||
|
|
9f579b36c8 | ||
|
|
a407357eec | ||
|
|
92b0077b27 | ||
|
|
7e8782f47f | ||
|
|
8fe3c73f95 | ||
|
|
81f815ee33 | ||
|
|
3108fa32d3 | ||
|
|
a1a40523ae | ||
|
|
e65a6fc58a | ||
|
|
bd8f12f9c6 | ||
|
|
0eb7252a23 | ||
|
|
15146c2259 | ||
|
|
340e4de5af | ||
|
|
88a24bdd13 | ||
|
|
7aac7db652 | ||
|
|
a8886d3351 | ||
|
|
da23e8acde | ||
|
|
2f3a075514 | ||
|
|
87d80b0f9a | ||
|
|
731e81c9a3 | ||
|
|
6dd6bb4714 | ||
|
|
7ed4f65561 | ||
|
|
3a01e9d3d2 | ||
|
|
e587b8c2ee | ||
|
|
2cee540022 | ||
|
|
ff03a51cb0 | ||
|
|
6514381b02 | ||
|
|
8306cee06a | ||
|
|
d49185972d | ||
|
|
aefd3949ab | ||
|
|
1bb3084e34 | ||
|
|
076db0ab49 | ||
|
|
ae7883d1f4 | ||
|
|
43f0c6fd62 | ||
|
|
c7762cd55e | ||
|
|
357b749bf3 | ||
|
|
20615115fb | ||
|
|
ddbcd859aa | ||
|
|
7ed55666b5 | ||
|
|
8c71875195 | ||
|
|
bbe78c253c | ||
|
|
72cd5cccf7 | ||
|
|
e16fbdcdcc | ||
|
|
e43a1cec84 | ||
|
|
510924a2f6 | ||
|
|
3b5b6f6152 | ||
|
|
edac7a471f | ||
|
|
c15001d765 | ||
|
|
a6e326582f | ||
|
|
cd339d52b6 | ||
|
|
e7348406a3 | ||
|
|
4a01e2df47 | ||
|
|
2465659942 | ||
|
|
501b96134c | ||
|
|
f8887a64e4 | ||
|
|
8551e0f0af | ||
|
|
25289b6444 | ||
|
|
86370979d9 | ||
|
|
664f0e8938 | ||
|
|
ea87853188 | ||
|
|
caf5f0110e | ||
|
|
a31d53b28f | ||
|
|
16a639e0fe | ||
|
|
a2ba909ded | ||
|
|
c823d2e98a | ||
|
|
7ae7468159 | ||
|
|
d4af2970f3 | ||
|
|
31a38f57f5 | ||
|
|
5b8b45a16d | ||
|
|
3d683350e9 | ||
|
|
106afe4984 | ||
|
|
5106818bd0 | ||
|
|
f13a136396 | ||
|
|
2c236be058 | ||
|
|
458e6410e8 | ||
|
|
1dd5f68251 | ||
|
|
8344c944b1 | ||
|
|
b34342eedf | ||
|
|
61e79a4cdf | ||
|
|
b7e7f537f1 | ||
|
|
8fb9c105c9 | ||
|
|
a82b8a966a | ||
|
|
f5f2c9587e | ||
|
|
0be7fe926d | ||
|
|
98f84256e9 | ||
|
|
15b927ffab | ||
|
|
7fa88d6d07 | ||
|
|
9ecf192089 | ||
|
|
6838a1020b | ||
|
|
a77befcc29 | ||
|
|
cedb8cd045 | ||
|
|
bb84121553 | ||
|
|
7de4fdf61a | ||
|
|
8fc9aa70a5 | ||
|
|
3db73b974f | ||
|
|
c51bd89c3b | ||
|
|
7de9ac01a0 | ||
|
|
4e118aecd0 | ||
|
|
11a11414c5 | ||
|
|
8a4e2e826d | ||
|
|
875269eb53 |
@@ -61,7 +61,7 @@ poetry run update_synapse_database --database-config .ci/postgres-config-unporte
|
|||||||
echo "+++ Comparing ported schema with unported schema"
|
echo "+++ Comparing ported schema with unported schema"
|
||||||
# Ignore the tables that portdb creates. (Should it tidy them up when the porting is completed?)
|
# Ignore the tables that portdb creates. (Should it tidy them up when the porting is completed?)
|
||||||
psql synapse -c "DROP TABLE port_from_sqlite3;"
|
psql synapse -c "DROP TABLE port_from_sqlite3;"
|
||||||
pg_dump --format=plain --schema-only --no-tablespaces --no-acl --no-owner synapse_unported > unported.sql
|
pg_dump --format=plain --schema-only --no-tablespaces --no-acl --no-owner --restrict-key=TESTING synapse_unported > unported.sql
|
||||||
pg_dump --format=plain --schema-only --no-tablespaces --no-acl --no-owner synapse > ported.sql
|
pg_dump --format=plain --schema-only --no-tablespaces --no-acl --no-owner --restrict-key=TESTING synapse > ported.sql
|
||||||
# By default, `diff` returns zero if there are no changes and nonzero otherwise
|
# By default, `diff` returns zero if there are no changes and nonzero otherwise
|
||||||
diff -u unported.sql ported.sql | tee schema_diff
|
diff -u unported.sql ported.sql | tee schema_diff
|
||||||
|
|||||||
8
.github/workflows/docker.yml
vendored
8
.github/workflows/docker.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Extract version from pyproject.toml
|
- name: Extract version from pyproject.toml
|
||||||
# Note: explicitly requesting bash will mean bash is invoked with `-eo pipefail`, see
|
# Note: explicitly requesting bash will mean bash is invoked with `-eo pipefail`, see
|
||||||
@@ -95,7 +95,7 @@ jobs:
|
|||||||
- build
|
- build
|
||||||
steps:
|
steps:
|
||||||
- name: Download digests
|
- name: Download digests
|
||||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||||
with:
|
with:
|
||||||
path: ${{ runner.temp }}/digests
|
path: ${{ runner.temp }}/digests
|
||||||
pattern: digests-*
|
pattern: digests-*
|
||||||
@@ -120,10 +120,10 @@ jobs:
|
|||||||
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1
|
||||||
|
|
||||||
- name: Install Cosign
|
- name: Install Cosign
|
||||||
uses: sigstore/cosign-installer@398d4b0eeef1380460a10c8013a76f728fb906ac # v3.9.1
|
uses: sigstore/cosign-installer@d58896d6a1865668819e1d91763c7751a165e159 # v3.9.2
|
||||||
|
|
||||||
- name: Calculate docker image tag
|
- name: Calculate docker image tag
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||||
with:
|
with:
|
||||||
images: ${{ matrix.repository }}
|
images: ${{ matrix.repository }}
|
||||||
flavor: |
|
flavor: |
|
||||||
|
|||||||
4
.github/workflows/docs-pr.yaml
vendored
4
.github/workflows/docs-pr.yaml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
name: GitHub Pages
|
name: GitHub Pages
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
# Fetch all history so that the schema_versions script works.
|
# Fetch all history so that the schema_versions script works.
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -50,7 +50,7 @@ jobs:
|
|||||||
name: Check links in documentation
|
name: Check links in documentation
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Setup mdbook
|
- name: Setup mdbook
|
||||||
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0
|
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2.0.0
|
||||||
|
|||||||
2
.github/workflows/docs.yaml
vendored
2
.github/workflows/docs.yaml
vendored
@@ -50,7 +50,7 @@ jobs:
|
|||||||
needs:
|
needs:
|
||||||
- pre
|
- pre
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
# Fetch all history so that the schema_versions script works.
|
# Fetch all history so that the schema_versions script works.
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|||||||
2
.github/workflows/fix_lint.yaml
vendored
2
.github/workflows/fix_lint.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
|
|||||||
10
.github/workflows/latest_deps.yml
vendored
10
.github/workflows/latest_deps.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
|||||||
if: needs.check_repo.outputs.should_run_workflow == 'true'
|
if: needs.check_repo.outputs.should_run_workflow == 'true'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
@@ -77,7 +77,7 @@ jobs:
|
|||||||
postgres-version: "14"
|
postgres-version: "14"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -152,7 +152,7 @@ jobs:
|
|||||||
BLACKLIST: ${{ matrix.workers && 'synapse-blacklist-with-workers' }}
|
BLACKLIST: ${{ matrix.workers && 'synapse-blacklist-with-workers' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -202,7 +202,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out synapse codebase
|
- name: Check out synapse codebase
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: synapse
|
path: synapse
|
||||||
|
|
||||||
@@ -234,7 +234,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
|
- uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
2
.github/workflows/poetry_lockfile.yaml
vendored
2
.github/workflows/poetry_lockfile.yaml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
name: "Check locked dependencies have sdists"
|
name: "Check locked dependencies have sdists"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: '3.x'
|
python-version: '3.x'
|
||||||
|
|||||||
8
.github/workflows/push_complement_image.yml
vendored
8
.github/workflows/push_complement_image.yml
vendored
@@ -33,17 +33,17 @@ jobs:
|
|||||||
packages: write
|
packages: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout specific branch (debug build)
|
- name: Checkout specific branch (debug build)
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
if: github.event_name == 'workflow_dispatch'
|
if: github.event_name == 'workflow_dispatch'
|
||||||
with:
|
with:
|
||||||
ref: ${{ inputs.branch }}
|
ref: ${{ inputs.branch }}
|
||||||
- name: Checkout clean copy of develop (scheduled build)
|
- name: Checkout clean copy of develop (scheduled build)
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
if: github.event_name == 'schedule'
|
if: github.event_name == 'schedule'
|
||||||
with:
|
with:
|
||||||
ref: develop
|
ref: develop
|
||||||
- name: Checkout clean copy of master (on-push)
|
- name: Checkout clean copy of master (on-push)
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
if: github.event_name == 'push'
|
if: github.event_name == 'push'
|
||||||
with:
|
with:
|
||||||
ref: master
|
ref: master
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Work out labels for complement image
|
- name: Work out labels for complement image
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@902fa8ec7d6ecbf8d84d538b9b233a880e428804 # v5.7.0
|
uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v5.8.0
|
||||||
with:
|
with:
|
||||||
images: ghcr.io/${{ github.repository }}/complement-synapse
|
images: ghcr.io/${{ github.repository }}/complement-synapse
|
||||||
tags: |
|
tags: |
|
||||||
|
|||||||
12
.github/workflows/release-artifacts.yml
vendored
12
.github/workflows/release-artifacts.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
name: "Calculate list of debian distros"
|
name: "Calculate list of debian distros"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@@ -55,7 +55,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: src
|
path: src
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ jobs:
|
|||||||
install: true
|
install: true
|
||||||
|
|
||||||
- name: Set up docker layer caching
|
- name: Set up docker layer caching
|
||||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||||
with:
|
with:
|
||||||
path: /tmp/.buildx-cache
|
path: /tmp/.buildx-cache
|
||||||
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
key: ${{ runner.os }}-buildx-${{ github.sha }}
|
||||||
@@ -132,7 +132,7 @@ jobs:
|
|||||||
os: "ubuntu-24.04-arm"
|
os: "ubuntu-24.04-arm"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
@@ -165,7 +165,7 @@ jobs:
|
|||||||
if: ${{ !startsWith(github.ref, 'refs/pull/') }}
|
if: ${{ !startsWith(github.ref, 'refs/pull/') }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.10"
|
python-version: "3.10"
|
||||||
@@ -191,7 +191,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Download all workflow run artifacts
|
- name: Download all workflow run artifacts
|
||||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
|
||||||
- name: Build a tarball for the debs
|
- name: Build a tarball for the debs
|
||||||
# We need to merge all the debs uploads into one folder, then compress
|
# We need to merge all the debs uploads into one folder, then compress
|
||||||
# that.
|
# that.
|
||||||
|
|||||||
4
.github/workflows/schema.yaml
vendored
4
.github/workflows/schema.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
|||||||
name: Ensure Synapse config schema is valid
|
name: Ensure Synapse config schema is valid
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@@ -40,7 +40,7 @@ jobs:
|
|||||||
name: Ensure generated documentation is up-to-date
|
name: Ensure generated documentation is up-to-date
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
|
|||||||
48
.github/workflows/tests.yml
vendored
48
.github/workflows/tests.yml
vendored
@@ -86,7 +86,7 @@ jobs:
|
|||||||
if: ${{ needs.changes.outputs.linting == 'true' }}
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
with:
|
with:
|
||||||
@@ -106,7 +106,7 @@ jobs:
|
|||||||
if: ${{ needs.changes.outputs.linting == 'true' }}
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@@ -116,7 +116,7 @@ jobs:
|
|||||||
check-lockfile:
|
check-lockfile:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@@ -129,7 +129,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.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
|
||||||
@@ -151,7 +151,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -174,7 +174,7 @@ jobs:
|
|||||||
# Cribbed from
|
# Cribbed from
|
||||||
# https://github.com/AustinScola/mypy-cache-github-action/blob/85ea4f2972abed39b33bd02c36e341b28ca59213/src/restore.ts#L10-L17
|
# https://github.com/AustinScola/mypy-cache-github-action/blob/85ea4f2972abed39b33bd02c36e341b28ca59213/src/restore.ts#L10-L17
|
||||||
- name: Restore/persist mypy's cache
|
- name: Restore/persist mypy's cache
|
||||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
.mypy_cache
|
.mypy_cache
|
||||||
@@ -187,7 +187,7 @@ jobs:
|
|||||||
lint-crlf:
|
lint-crlf:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- name: Check line endings
|
- name: Check line endings
|
||||||
run: scripts-dev/check_line_terminators.sh
|
run: scripts-dev/check_line_terminators.sh
|
||||||
|
|
||||||
@@ -195,7 +195,7 @@ jobs:
|
|||||||
if: ${{ (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.actor != 'dependabot[bot]' }}
|
if: ${{ (github.base_ref == 'develop' || contains(github.base_ref, 'release-')) && github.actor != 'dependabot[bot]' }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
@@ -213,7 +213,7 @@ jobs:
|
|||||||
if: ${{ needs.changes.outputs.linting == 'true' }}
|
if: ${{ needs.changes.outputs.linting == 'true' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
@@ -233,7 +233,7 @@ jobs:
|
|||||||
if: ${{ needs.changes.outputs.rust == 'true' }}
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -252,7 +252,7 @@ jobs:
|
|||||||
if: ${{ needs.changes.outputs.rust == 'true' }}
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -270,7 +270,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -306,7 +306,7 @@ jobs:
|
|||||||
if: ${{ needs.changes.outputs.rust == 'true' }}
|
if: ${{ needs.changes.outputs.rust == 'true' }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -326,7 +326,7 @@ jobs:
|
|||||||
needs: changes
|
needs: changes
|
||||||
if: ${{ needs.changes.outputs.linting_readme == 'true' }}
|
if: ${{ needs.changes.outputs.linting_readme == 'true' }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@@ -376,7 +376,7 @@ jobs:
|
|||||||
needs: linting-done
|
needs: linting-done
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.x"
|
python-version: "3.x"
|
||||||
@@ -397,7 +397,7 @@ jobs:
|
|||||||
job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
|
job: ${{ fromJson(needs.calculate-test-jobs.outputs.trial_test_matrix) }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- run: sudo apt-get -qq install xmlsec1
|
- run: sudo apt-get -qq install xmlsec1
|
||||||
- name: Set up PostgreSQL ${{ matrix.job.postgres-version }}
|
- name: Set up PostgreSQL ${{ matrix.job.postgres-version }}
|
||||||
if: ${{ matrix.job.postgres-version }}
|
if: ${{ matrix.job.postgres-version }}
|
||||||
@@ -453,7 +453,7 @@ jobs:
|
|||||||
- changes
|
- changes
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -518,7 +518,7 @@ jobs:
|
|||||||
extras: ["all"]
|
extras: ["all"]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
# Install libs necessary for PyPy to build binary wheels for dependencies
|
# Install libs necessary for PyPy to build binary wheels for dependencies
|
||||||
- run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev
|
- run: sudo apt-get -qq install xmlsec1 libxml2-dev libxslt-dev
|
||||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
@@ -568,7 +568,7 @@ jobs:
|
|||||||
job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }}
|
job: ${{ fromJson(needs.calculate-test-jobs.outputs.sytest_test_matrix) }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- name: Prepare test blacklist
|
- name: Prepare test blacklist
|
||||||
run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
|
run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
|
||||||
|
|
||||||
@@ -615,7 +615,7 @@ jobs:
|
|||||||
--health-retries 5
|
--health-retries 5
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- run: sudo apt-get -qq install xmlsec1 postgresql-client
|
- run: sudo apt-get -qq install xmlsec1 postgresql-client
|
||||||
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
- uses: matrix-org/setup-python-poetry@5bbf6603c5c930615ec8a29f1b5d7d258d905aa4 # v2.0.0
|
||||||
with:
|
with:
|
||||||
@@ -659,7 +659,7 @@ jobs:
|
|||||||
--health-retries 5
|
--health-retries 5
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- name: Add PostgreSQL apt repository
|
- name: Add PostgreSQL apt repository
|
||||||
# We need a version of pg_dump that can handle the version of
|
# We need a version of pg_dump that can handle the version of
|
||||||
# PostgreSQL being tested against. The Ubuntu package repository lags
|
# PostgreSQL being tested against. The Ubuntu package repository lags
|
||||||
@@ -714,7 +714,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout synapse codebase
|
- name: Checkout synapse codebase
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: synapse
|
path: synapse
|
||||||
|
|
||||||
@@ -750,7 +750,7 @@ jobs:
|
|||||||
- changes
|
- changes
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -770,7 +770,7 @@ jobs:
|
|||||||
- changes
|
- changes
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
|
|||||||
6
.github/workflows/triage_labelled.yml
vendored
6
.github/workflows/triage_labelled.yml
vendored
@@ -11,11 +11,15 @@ jobs:
|
|||||||
if: >
|
if: >
|
||||||
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/add-to-project@5b1a254a3546aef88e0a7724a77a623fa2e47c36 # main (v1.0.2 + 10 commits)
|
- uses: actions/add-to-project@c0c5949b017d0d4a39f7ba888255881bdac2a823 # v1.0.2
|
||||||
id: add_project
|
id: add_project
|
||||||
with:
|
with:
|
||||||
project-url: "https://github.com/orgs/matrix-org/projects/67"
|
project-url: "https://github.com/orgs/matrix-org/projects/67"
|
||||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||||
|
# This action will error if the issue already exists on the project. Which is
|
||||||
|
# common as `X-Needs-Info` will often be added to issues that are already in
|
||||||
|
# the triage queue. Prevent the whole job from failing in this case.
|
||||||
|
continue-on-error: true
|
||||||
- name: Set status
|
- name: Set status
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||||
|
|||||||
10
.github/workflows/twisted_trunk.yml
vendored
10
.github/workflows/twisted_trunk.yml
vendored
@@ -43,7 +43,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -70,7 +70,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- run: sudo apt-get -qq install xmlsec1
|
- run: sudo apt-get -qq install xmlsec1
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
@@ -117,7 +117,7 @@ jobs:
|
|||||||
- ${{ github.workspace }}:/src
|
- ${{ github.workspace }}:/src
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
|
|
||||||
- name: Install Rust
|
- name: Install Rust
|
||||||
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
uses: dtolnay/rust-toolchain@b3b07ba8b418998c39fb20f53e8b695cdcc8de1b # master
|
||||||
@@ -175,7 +175,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Run actions/checkout@v4 for synapse
|
- name: Run actions/checkout@v4 for synapse
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
with:
|
with:
|
||||||
path: synapse
|
path: synapse
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
|
||||||
- uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
|
- uses: JasonEtco/create-an-issue@1b14a70e4d8dc185e5cc76d3bec9eab20257b2c5 # v2.9.2
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
190
CHANGES.md
190
CHANGES.md
@@ -1,3 +1,193 @@
|
|||||||
|
# Synapse 1.136.0 (2025-08-12)
|
||||||
|
|
||||||
|
Note: This release includes the security fixes from `1.135.2` and `1.136.0rc2`, detailed below.
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Fix bug introduced in 1.135.2 and 1.136.0rc2 where the [Make Room Admin API](https://element-hq.github.io/synapse/latest/admin_api/rooms.html#make-room-admin-api) would not treat a room v12's creator power level as the highest in room. ([\#18805](https://github.com/element-hq/synapse/issues/18805))
|
||||||
|
|
||||||
|
|
||||||
|
# Synapse 1.135.2 (2025-08-11)
|
||||||
|
|
||||||
|
This is the Synapse portion of the [Matrix coordinated security release](https://matrix.org/blog/2025/07/security-predisclosure/). This release includes support for [room version](https://spec.matrix.org/v1.15/rooms/) 12 which fixes a number of security vulnerabilities, including [CVE-2025-49090](https://www.cve.org/CVERecord?id=CVE-2025-49090).
|
||||||
|
|
||||||
|
The default room version is not changed. Not all clients will support room version 12 immediately, and not all users will be using the latest version of their clients. Large, public rooms are advised to wait a few weeks before upgrading to room version 12 to allow users throughout the Matrix ecosystem to update their clients.
|
||||||
|
|
||||||
|
Note: release 1.135.1 was skipped due to issues discovered during the release process.
|
||||||
|
|
||||||
|
Two patched Synapse releases are now available:
|
||||||
|
|
||||||
|
* `1.135.2`: stable release comprised of `1.135.0` + security patches
|
||||||
|
* Upgrade to this release **if you are currently running 1.135.0 or below**.
|
||||||
|
* `1.136.0rc2`: unstable release candidate comprised of `1.136.0rc1` + security patches.
|
||||||
|
* Upgrade to this release **only if you are on 1.136.0rc1**.
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Fix invalidation of storage cache that was broken in 1.135.0. ([\#18786](https://github.com/element-hq/synapse/issues/18786))
|
||||||
|
|
||||||
|
### Internal Changes
|
||||||
|
|
||||||
|
- Add a parameter to `upgrade_rooms(..)` to allow auto join local users. ([\#82](https://github.com/element-hq/synapse/issues/82))
|
||||||
|
- Speed up upgrading a room with large numbers of banned users. ([\#18574](https://github.com/element-hq/synapse/issues/18574))
|
||||||
|
|
||||||
|
|
||||||
|
# Synapse 1.136.0rc2 (2025-08-11)
|
||||||
|
|
||||||
|
- Update MSC4293 redaction logic for room v12. ([\#80](https://github.com/element-hq/synapse/issues/80))
|
||||||
|
|
||||||
|
### Internal Changes
|
||||||
|
|
||||||
|
- Add a parameter to `upgrade_rooms(..)` to allow auto join local users. ([\#83](https://github.com/element-hq/synapse/issues/83))
|
||||||
|
|
||||||
|
|
||||||
|
# Synapse 1.136.0rc1 (2025-08-05)
|
||||||
|
|
||||||
|
Please check [the relevant section in the upgrade notes](https://github.com/element-hq/synapse/blob/develop/docs/upgrade.md#upgrading-to-v11360) as this release contains changes to MAS support, metrics labels and the module API which may require your attention when upgrading.
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Add configurable rate limiting for the creation of rooms. ([\#18514](https://github.com/element-hq/synapse/issues/18514))
|
||||||
|
- Add support for [MSC4293](https://github.com/matrix-org/matrix-spec-proposals/pull/4293) - Redact on Kick/Ban. ([\#18540](https://github.com/element-hq/synapse/issues/18540))
|
||||||
|
- When admins enable themselves to see soft-failed events, they will also see if the cause is due to the policy server flagging them as spam via `unsigned`. ([\#18585](https://github.com/element-hq/synapse/issues/18585))
|
||||||
|
- Add ability to configure forward/outbound proxy via homeserver config instead of environment variables. See `http_proxy`, `https_proxy`, `no_proxy_hosts`. ([\#18686](https://github.com/element-hq/synapse/issues/18686))
|
||||||
|
- Advertise experimental support for [MSC4306](https://github.com/matrix-org/matrix-spec-proposals/pull/4306) (Thread Subscriptions) through `/_matrix/clients/versions` if enabled. ([\#18722](https://github.com/element-hq/synapse/issues/18722))
|
||||||
|
- Stabilise support for delegating authentication to [Matrix Authentication Service](https://github.com/element-hq/matrix-authentication-service/). ([\#18759](https://github.com/element-hq/synapse/issues/18759))
|
||||||
|
- Implement the push rules for experimental [MSC4306: Thread Subscriptions](https://github.com/matrix-org/matrix-doc/issues/4306). ([\#18762](https://github.com/element-hq/synapse/issues/18762))
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Allow return code 403 (allowed by C2S Spec since v1.2) when fetching profiles via federation. ([\#18696](https://github.com/element-hq/synapse/issues/18696))
|
||||||
|
- Register the MSC4306 (Thread Subscriptions) endpoints in the CS API when the experimental feature is enabled. ([\#18726](https://github.com/element-hq/synapse/issues/18726))
|
||||||
|
- Fix a long-standing bug where suspended users could not have server notices sent to them (a 403 was returned to the admin). ([\#18750](https://github.com/element-hq/synapse/issues/18750))
|
||||||
|
- Fix an issue that could cause logcontexts to be lost on rate-limited requests. Found by @realtyem. ([\#18763](https://github.com/element-hq/synapse/issues/18763))
|
||||||
|
- Fix invalidation of storage cache that was broken in 1.135.0. ([\#18786](https://github.com/element-hq/synapse/issues/18786))
|
||||||
|
|
||||||
|
### Improved Documentation
|
||||||
|
|
||||||
|
- Minor improvements to README. ([\#18700](https://github.com/element-hq/synapse/issues/18700))
|
||||||
|
- Document that there can be multiple workers handling the `receipts` stream. ([\#18760](https://github.com/element-hq/synapse/issues/18760))
|
||||||
|
- Improve worker documentation for some device paths. ([\#18761](https://github.com/element-hq/synapse/issues/18761))
|
||||||
|
|
||||||
|
### Deprecations and Removals
|
||||||
|
|
||||||
|
- Deprecate `run_as_background_process` exported as part of the module API interface in favor of `ModuleApi.run_as_background_process`. See [the relevant section in the upgrade notes](https://github.com/element-hq/synapse/blob/develop/docs/upgrade.md#upgrading-to-v11360) for more information. ([\#18737](https://github.com/element-hq/synapse/issues/18737))
|
||||||
|
|
||||||
|
### Internal Changes
|
||||||
|
|
||||||
|
- Add debug logging for HMAC digest verification failures when using the admin API to register users. ([\#18474](https://github.com/element-hq/synapse/issues/18474))
|
||||||
|
- Speed up upgrading a room with large numbers of banned users. ([\#18574](https://github.com/element-hq/synapse/issues/18574))
|
||||||
|
- Fix config documentation generation script on Windows by enforcing UTF-8. ([\#18580](https://github.com/element-hq/synapse/issues/18580))
|
||||||
|
- Refactor cache, background process, `Counter`, `LaterGauge`, `GaugeBucketCollector`, `Histogram`, and `Gauge` metrics to be homeserver-scoped. ([\#18656](https://github.com/element-hq/synapse/issues/18656), [\#18714](https://github.com/element-hq/synapse/issues/18714), [\#18715](https://github.com/element-hq/synapse/issues/18715), [\#18724](https://github.com/element-hq/synapse/issues/18724), [\#18753](https://github.com/element-hq/synapse/issues/18753), [\#18725](https://github.com/element-hq/synapse/issues/18725), [\#18670](https://github.com/element-hq/synapse/issues/18670), [\#18748](https://github.com/element-hq/synapse/issues/18748), [\#18751](https://github.com/element-hq/synapse/issues/18751))
|
||||||
|
- Reduce database usage in Sliding Sync by not querying for background update completion after the update is known to be complete. ([\#18718](https://github.com/element-hq/synapse/issues/18718))
|
||||||
|
- Improve order of validation and ratelimiting in room creation. ([\#18723](https://github.com/element-hq/synapse/issues/18723))
|
||||||
|
- Bump minimum version bound on Twisted to 21.2.0. ([\#18727](https://github.com/element-hq/synapse/issues/18727), [\#18729](https://github.com/element-hq/synapse/issues/18729))
|
||||||
|
- Use `twisted.internet.testing` module in tests instead of deprecated `twisted.test.proto_helpers`. ([\#18728](https://github.com/element-hq/synapse/issues/18728))
|
||||||
|
- Remove obsolete `/send_event` replication endpoint. ([\#18730](https://github.com/element-hq/synapse/issues/18730))
|
||||||
|
- Update metrics linting to be able to handle custom metrics. ([\#18733](https://github.com/element-hq/synapse/issues/18733))
|
||||||
|
- Work around `twisted.protocols.amp.TooLong` error by reducing logging in some tests. ([\#18736](https://github.com/element-hq/synapse/issues/18736))
|
||||||
|
- Prevent "Move labelled issues to correct projects" GitHub Actions workflow from failing when an issue is already on the project board. ([\#18755](https://github.com/element-hq/synapse/issues/18755))
|
||||||
|
- Bump minimum supported Rust version (MSRV) to 1.82.0. Missed in [#18553](https://github.com/element-hq/synapse/pull/18553) (released in Synapse 1.134.0). ([\#18757](https://github.com/element-hq/synapse/issues/18757))
|
||||||
|
- Make `Clock.sleep(...)` return a coroutine, so that mypy can catch places where we don't await on it. ([\#18772](https://github.com/element-hq/synapse/issues/18772))
|
||||||
|
- Update implementation of [MSC4306: Thread Subscriptions](https://github.com/matrix-org/matrix-doc/issues/4306) to include automatic subscription conflict prevention as introduced in later drafts. ([\#18756](https://github.com/element-hq/synapse/issues/18756))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Updates to locked dependencies
|
||||||
|
|
||||||
|
* Bump gitpython from 3.1.44 to 3.1.45. ([\#18743](https://github.com/element-hq/synapse/issues/18743))
|
||||||
|
* Bump mypy-zope from 1.0.12 to 1.0.13. ([\#18744](https://github.com/element-hq/synapse/issues/18744))
|
||||||
|
* Bump phonenumbers from 9.0.9 to 9.0.10. ([\#18741](https://github.com/element-hq/synapse/issues/18741))
|
||||||
|
* Bump ruff from 0.12.4 to 0.12.5. ([\#18742](https://github.com/element-hq/synapse/issues/18742))
|
||||||
|
* Bump sentry-sdk from 2.32.0 to 2.33.2. ([\#18745](https://github.com/element-hq/synapse/issues/18745))
|
||||||
|
* Bump tokio from 1.46.1 to 1.47.0. ([\#18740](https://github.com/element-hq/synapse/issues/18740))
|
||||||
|
* Bump types-jsonschema from 4.24.0.20250708 to 4.25.0.20250720. ([\#18703](https://github.com/element-hq/synapse/issues/18703))
|
||||||
|
* Bump types-psycopg2 from 2.9.21.20250516 to 2.9.21.20250718. ([\#18706](https://github.com/element-hq/synapse/issues/18706))
|
||||||
|
|
||||||
|
# Synapse 1.135.0 (2025-08-01)
|
||||||
|
|
||||||
|
No significant changes since 1.135.0rc2.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Synapse 1.135.0rc2 (2025-07-30)
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Fix user failing to deactivate with MAS when `/_synapse/mas` is handled by a worker. ([\#18716](https://github.com/element-hq/synapse/issues/18716))
|
||||||
|
|
||||||
|
### Internal Changes
|
||||||
|
|
||||||
|
- Fix performance regression introduced in [#18238](https://github.com/element-hq/synapse/issues/18238) by adding a cache to `is_server_admin`. ([\#18747](https://github.com/element-hq/synapse/issues/18747))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Synapse 1.135.0rc1 (2025-07-22)
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- Add `recaptcha_private_key_path` and `recaptcha_public_key_path` config option. ([\#17984](https://github.com/element-hq/synapse/issues/17984), [\#18684](https://github.com/element-hq/synapse/issues/18684))
|
||||||
|
- Add plain-text handling for rich-text topics as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765). ([\#18195](https://github.com/element-hq/synapse/issues/18195))
|
||||||
|
- If enabled by the user, server admins will see [soft failed](https://spec.matrix.org/v1.13/server-server-api/#soft-failure) events over the Client-Server API. ([\#18238](https://github.com/element-hq/synapse/issues/18238))
|
||||||
|
- Add experimental support for [MSC4277: Harmonizing the reporting endpoints](https://github.com/matrix-org/matrix-spec-proposals/pull/4277). ([\#18263](https://github.com/element-hq/synapse/issues/18263))
|
||||||
|
- Add ability to limit amount of media uploaded by a user in a given time period. ([\#18527](https://github.com/element-hq/synapse/issues/18527))
|
||||||
|
- Enable workers to write directly to the device lists stream and handle device list updates, reducing load on the main process. ([\#18581](https://github.com/element-hq/synapse/issues/18581))
|
||||||
|
- Support arbitrary profile fields. Contributed by @clokep. ([\#18635](https://github.com/element-hq/synapse/issues/18635))
|
||||||
|
- Advertise support for Matrix v1.12. ([\#18647](https://github.com/element-hq/synapse/issues/18647))
|
||||||
|
- Add an option to issue redactions as an admin user via the [admin redaction endpoint](https://element-hq.github.io/synapse/latest/admin_api/user_admin_api.html#redact-all-the-events-of-a-user). ([\#18671](https://github.com/element-hq/synapse/issues/18671))
|
||||||
|
- Add experimental and incomplete support for [MSC4306: Thread Subscriptions](https://github.com/matrix-org/matrix-spec-proposals/blob/rei/msc_thread_subscriptions/proposals/4306-thread-subscriptions.md). ([\#18674](https://github.com/element-hq/synapse/issues/18674))
|
||||||
|
- Include `event_id` when getting state with `?format=event`. Contributed by @tulir @ Beeper. ([\#18675](https://github.com/element-hq/synapse/issues/18675))
|
||||||
|
|
||||||
|
### Bugfixes
|
||||||
|
|
||||||
|
- Fix CPU and database spinning when retrying sending events to servers whilst at the same time purging those events. ([\#18499](https://github.com/element-hq/synapse/issues/18499))
|
||||||
|
- Don't allow creation of tags with names longer than 255 bytes, [as per the spec](https://spec.matrix.org/v1.15/client-server-api/#events-14). ([\#18660](https://github.com/element-hq/synapse/issues/18660))
|
||||||
|
- Fix `sliding_sync_connections`-related errors when porting from SQLite to Postgres. ([\#18677](https://github.com/element-hq/synapse/issues/18677))
|
||||||
|
- Fix the MAS integration not working when Synapse is started with `--daemonize` or using `synctl`. ([\#18691](https://github.com/element-hq/synapse/issues/18691))
|
||||||
|
|
||||||
|
### Improved Documentation
|
||||||
|
|
||||||
|
- Document that some config options for the user directory are in violation of the Matrix spec. ([\#18548](https://github.com/element-hq/synapse/issues/18548))
|
||||||
|
- Update `rc_delayed_event_mgmt` docs to the actual nesting level. Contributed by @HarHarLinks. ([\#18692](https://github.com/element-hq/synapse/issues/18692))
|
||||||
|
|
||||||
|
### Internal Changes
|
||||||
|
|
||||||
|
- Add a dedicated internal API for Matrix Authentication Service to Synapse communication. ([\#18520](https://github.com/element-hq/synapse/issues/18520))
|
||||||
|
- Allow user registrations to be done on workers. ([\#18552](https://github.com/element-hq/synapse/issues/18552))
|
||||||
|
- Remove unnecessary HTTP replication calls. ([\#18564](https://github.com/element-hq/synapse/issues/18564))
|
||||||
|
- Refactor `Measure` block metrics to be homeserver-scoped. ([\#18601](https://github.com/element-hq/synapse/issues/18601))
|
||||||
|
- Refactor cache metrics to be homeserver-scoped. ([\#18604](https://github.com/element-hq/synapse/issues/18604))
|
||||||
|
- Unbreak "Latest dependencies" workflow by using the `--without dev` poetry option instead of removed `--no-dev`. ([\#18617](https://github.com/element-hq/synapse/issues/18617))
|
||||||
|
- Update URL Preview code to work with `lxml` 6.0.0+. ([\#18622](https://github.com/element-hq/synapse/issues/18622))
|
||||||
|
- Use `markdown-it-py` instead of `commonmark` in the release script. ([\#18637](https://github.com/element-hq/synapse/issues/18637))
|
||||||
|
- Fix typing errors with upgraded mypy version. ([\#18653](https://github.com/element-hq/synapse/issues/18653))
|
||||||
|
- Add doc comment explaining that config files are shallowly merged. ([\#18664](https://github.com/element-hq/synapse/issues/18664))
|
||||||
|
- Minor speed up of insertion into `stream_positions` table. ([\#18672](https://github.com/element-hq/synapse/issues/18672))
|
||||||
|
- Remove unused `allow_no_prev_events` option when creating an event. ([\#18676](https://github.com/element-hq/synapse/issues/18676))
|
||||||
|
- Clean up `MetricsResource` and Prometheus hacks. ([\#18687](https://github.com/element-hq/synapse/issues/18687))
|
||||||
|
- Fix dirty `Cargo.lock` changes appearing after install (`base64`). ([\#18689](https://github.com/element-hq/synapse/issues/18689))
|
||||||
|
- Prevent dirty `Cargo.lock` changes from install. ([\#18693](https://github.com/element-hq/synapse/issues/18693))
|
||||||
|
- Correct spelling of 'Admin token used' log line. ([\#18697](https://github.com/element-hq/synapse/issues/18697))
|
||||||
|
- Reduce log spam when client stops downloading media while it is being streamed to them. ([\#18699](https://github.com/element-hq/synapse/issues/18699))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Updates to locked dependencies
|
||||||
|
|
||||||
|
* Bump authlib from 1.6.0 to 1.6.1. ([\#18704](https://github.com/element-hq/synapse/issues/18704))
|
||||||
|
* Bump base64 from 0.21.7 to 0.22.1. ([\#18666](https://github.com/element-hq/synapse/issues/18666))
|
||||||
|
* Bump jsonschema from 4.24.0 to 4.25.0. ([\#18707](https://github.com/element-hq/synapse/issues/18707))
|
||||||
|
* Bump lxml from 5.4.0 to 6.0.0. ([\#18631](https://github.com/element-hq/synapse/issues/18631))
|
||||||
|
* Bump mypy from 1.13.0 to 1.16.1. ([\#18653](https://github.com/element-hq/synapse/issues/18653))
|
||||||
|
* Bump once_cell from 1.19.0 to 1.21.3. ([\#18710](https://github.com/element-hq/synapse/issues/18710))
|
||||||
|
* Bump phonenumbers from 9.0.8 to 9.0.9. ([\#18681](https://github.com/element-hq/synapse/issues/18681))
|
||||||
|
* Bump ruff from 0.12.2 to 0.12.5. ([\#18683](https://github.com/element-hq/synapse/issues/18683), [\#18705](https://github.com/element-hq/synapse/issues/18705))
|
||||||
|
* Bump serde_json from 1.0.140 to 1.0.141. ([\#18709](https://github.com/element-hq/synapse/issues/18709))
|
||||||
|
* Bump sigstore/cosign-installer from 3.9.1 to 3.9.2. ([\#18708](https://github.com/element-hq/synapse/issues/18708))
|
||||||
|
* Bump types-jsonschema from 4.24.0.20250528 to 4.24.0.20250708. ([\#18682](https://github.com/element-hq/synapse/issues/18682))
|
||||||
|
|
||||||
# Synapse 1.134.0 (2025-07-15)
|
# Synapse 1.134.0 (2025-07-15)
|
||||||
|
|
||||||
No significant changes since 1.134.0rc1.
|
No significant changes since 1.134.0rc1.
|
||||||
|
|||||||
574
Cargo.lock
generated
574
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
29
README.rst
29
README.rst
@@ -8,7 +8,7 @@
|
|||||||
Synapse is an open source `Matrix <https://matrix.org>`__ homeserver
|
Synapse is an open source `Matrix <https://matrix.org>`__ homeserver
|
||||||
implementation, written and maintained by `Element <https://element.io>`_.
|
implementation, written and maintained by `Element <https://element.io>`_.
|
||||||
`Matrix <https://github.com/matrix-org>`__ is the open standard for
|
`Matrix <https://github.com/matrix-org>`__ is the open standard for
|
||||||
secure and interoperable real time communications. You can directly run
|
secure and interoperable real-time communications. You can directly run
|
||||||
and manage the source code in this repository, available under an AGPL
|
and manage the source code in this repository, available under an AGPL
|
||||||
license (or alternatively under a commercial license from Element).
|
license (or alternatively under a commercial license from Element).
|
||||||
There is no support provided by Element unless you have a
|
There is no support provided by Element unless you have a
|
||||||
@@ -23,13 +23,13 @@ ESS builds on Synapse to offer a complete Matrix-based backend including the ful
|
|||||||
`Admin Console product <https://element.io/enterprise-functionality/admin-console>`_,
|
`Admin Console product <https://element.io/enterprise-functionality/admin-console>`_,
|
||||||
giving admins the power to easily manage an organization-wide
|
giving admins the power to easily manage an organization-wide
|
||||||
deployment. It includes advanced identity management, auditing,
|
deployment. It includes advanced identity management, auditing,
|
||||||
moderation and data retention options as well as Long Term Support and
|
moderation and data retention options as well as Long-Term Support and
|
||||||
SLAs. ESS can be used to support any Matrix-based frontend client.
|
SLAs. ESS supports any Matrix-compatible client.
|
||||||
|
|
||||||
.. contents::
|
.. contents::
|
||||||
|
|
||||||
🛠️ Installing and configuration
|
🛠️ Installation and configuration
|
||||||
===============================
|
==================================
|
||||||
|
|
||||||
The Synapse documentation describes `how to install Synapse <https://element-hq.github.io/synapse/latest/setup/installation.html>`_. We recommend using
|
The Synapse documentation describes `how to install Synapse <https://element-hq.github.io/synapse/latest/setup/installation.html>`_. We recommend using
|
||||||
`Docker images <https://element-hq.github.io/synapse/latest/setup/installation.html#docker-images-and-ansible-playbooks>`_ or `Debian packages from Matrix.org
|
`Docker images <https://element-hq.github.io/synapse/latest/setup/installation.html#docker-images-and-ansible-playbooks>`_ or `Debian packages from Matrix.org
|
||||||
@@ -133,7 +133,7 @@ connect from a client: see
|
|||||||
An easy way to get started is to login or register via Element at
|
An easy way to get started is to login or register via Element at
|
||||||
https://app.element.io/#/login or https://app.element.io/#/register respectively.
|
https://app.element.io/#/login or https://app.element.io/#/register respectively.
|
||||||
You will need to change the server you are logging into from ``matrix.org``
|
You will need to change the server you are logging into from ``matrix.org``
|
||||||
and instead specify a Homeserver URL of ``https://<server_name>:8448``
|
and instead specify a homeserver URL of ``https://<server_name>:8448``
|
||||||
(or just ``https://<server_name>`` if you are using a reverse proxy).
|
(or just ``https://<server_name>`` if you are using a reverse proxy).
|
||||||
If you prefer to use another client, refer to our
|
If you prefer to use another client, refer to our
|
||||||
`client breakdown <https://matrix.org/ecosystem/clients/>`_.
|
`client breakdown <https://matrix.org/ecosystem/clients/>`_.
|
||||||
@@ -162,16 +162,15 @@ the public internet. Without it, anyone can freely register accounts on your hom
|
|||||||
This can be exploited by attackers to create spambots targeting the rest of the Matrix
|
This can be exploited by attackers to create spambots targeting the rest of the Matrix
|
||||||
federation.
|
federation.
|
||||||
|
|
||||||
Your new user name will be formed partly from the ``server_name``, and partly
|
Your new Matrix ID will be formed partly from the ``server_name``, and partly
|
||||||
from a localpart you specify when you create the account. Your name will take
|
from a localpart you specify when you create the account in the form of::
|
||||||
the form of::
|
|
||||||
|
|
||||||
@localpart:my.domain.name
|
@localpart:my.domain.name
|
||||||
|
|
||||||
(pronounced "at localpart on my dot domain dot name").
|
(pronounced "at localpart on my dot domain dot name").
|
||||||
|
|
||||||
As when logging in, you will need to specify a "Custom server". Specify your
|
As when logging in, you will need to specify a "Custom server". Specify your
|
||||||
desired ``localpart`` in the 'User name' box.
|
desired ``localpart`` in the 'Username' box.
|
||||||
|
|
||||||
🎯 Troubleshooting and support
|
🎯 Troubleshooting and support
|
||||||
==============================
|
==============================
|
||||||
@@ -209,10 +208,10 @@ Identity servers have the job of mapping email addresses and other 3rd Party
|
|||||||
IDs (3PIDs) to Matrix user IDs, as well as verifying the ownership of 3PIDs
|
IDs (3PIDs) to Matrix user IDs, as well as verifying the ownership of 3PIDs
|
||||||
before creating that mapping.
|
before creating that mapping.
|
||||||
|
|
||||||
**They are not where accounts or credentials are stored - these live on home
|
**Identity servers do not store accounts or credentials - these are stored and managed on homeservers.
|
||||||
servers. Identity Servers are just for mapping 3rd party IDs to matrix IDs.**
|
Identity Servers are just for mapping 3rd Party IDs to Matrix IDs.**
|
||||||
|
|
||||||
This process is very security-sensitive, as there is obvious risk of spam if it
|
This process is highly security-sensitive, as there is an obvious risk of spam if it
|
||||||
is too easy to sign up for Matrix accounts or harvest 3PID data. In the longer
|
is too easy to sign up for Matrix accounts or harvest 3PID data. In the longer
|
||||||
term, we hope to create a decentralised system to manage it (`matrix-doc #712
|
term, we hope to create a decentralised system to manage it (`matrix-doc #712
|
||||||
<https://github.com/matrix-org/matrix-doc/issues/712>`_), but in the meantime,
|
<https://github.com/matrix-org/matrix-doc/issues/712>`_), but in the meantime,
|
||||||
@@ -238,9 +237,9 @@ email address.
|
|||||||
We welcome contributions to Synapse from the community!
|
We welcome contributions to Synapse from the community!
|
||||||
The best place to get started is our
|
The best place to get started is our
|
||||||
`guide for contributors <https://element-hq.github.io/synapse/latest/development/contributing_guide.html>`_.
|
`guide for contributors <https://element-hq.github.io/synapse/latest/development/contributing_guide.html>`_.
|
||||||
This is part of our larger `documentation <https://element-hq.github.io/synapse/latest>`_, which includes
|
This is part of our broader `documentation <https://element-hq.github.io/synapse/latest>`_, which includes
|
||||||
|
|
||||||
information for Synapse developers as well as Synapse administrators.
|
information for Synapse developers as well as Synapse administrators.
|
||||||
|
|
||||||
Developers might be particularly interested in:
|
Developers might be particularly interested in:
|
||||||
|
|
||||||
* `Synapse's database schema <https://element-hq.github.io/synapse/latest/development/database_schema.html>`_,
|
* `Synapse's database schema <https://element-hq.github.io/synapse/latest/development/database_schema.html>`_,
|
||||||
|
|||||||
@@ -19,17 +19,17 @@ def build(setup_kwargs: Dict[str, Any]) -> None:
|
|||||||
# This flag is a no-op in the latest versions. Instead, we need to
|
# This flag is a no-op in the latest versions. Instead, we need to
|
||||||
# specify this in the `bdist_wheel` config below.
|
# specify this in the `bdist_wheel` config below.
|
||||||
py_limited_api=True,
|
py_limited_api=True,
|
||||||
# We force always building in release mode, as we can't tell the
|
# We always build in release mode, as we can't distinguish
|
||||||
# difference between using `poetry` in development vs production.
|
# between using `poetry` in development vs production.
|
||||||
debug=False,
|
debug=False,
|
||||||
)
|
)
|
||||||
setup_kwargs.setdefault("rust_extensions", []).append(extension)
|
setup_kwargs.setdefault("rust_extensions", []).append(extension)
|
||||||
setup_kwargs["zip_safe"] = False
|
setup_kwargs["zip_safe"] = False
|
||||||
|
|
||||||
# We lookup the minimum supported python version by looking at
|
# We look up the minimum supported Python version with
|
||||||
# `python_requires` (e.g. ">=3.9.0,<4.0.0") and finding the first python
|
# `python_requires` (e.g. ">=3.9.0,<4.0.0") and finding the first Python
|
||||||
# version that matches. We then convert that into the `py_limited_api` form,
|
# version that matches. We then convert that into the `py_limited_api` form,
|
||||||
# e.g. cp39 for python 3.9.
|
# e.g. cp39 for Python 3.9.
|
||||||
py_limited_api: str
|
py_limited_api: str
|
||||||
python_bounds = SpecifierSet(setup_kwargs["python_requires"])
|
python_bounds = SpecifierSet(setup_kwargs["python_requires"])
|
||||||
for minor_version in itertools.count(start=8):
|
for minor_version in itertools.count(start=8):
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Add `recaptcha_private_key_path` and `recaptcha_public_key_path` config option.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Add plain-text handling for rich-text topics as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765).
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
If enabled by the user, server admins will see [soft failed](https://spec.matrix.org/v1.13/server-server-api/#soft-failure) events over the Client-Server API.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Add experimental support for [MSC4277](https://github.com/matrix-org/matrix-spec-proposals/pull/4277).
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Fix CPU and database spinning when retrying sending events to servers whilst at the same time purging those events.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Add ability to limit amount uploaded by a user in a given time period.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Document that some config options for the user directory are in violation of the Matrix spec.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Allow user registrations to be done on workers.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Remove unnecessary HTTP replication calls.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Enable workers to write directly to the device lists stream and handle device list updates, reducing load on the main process.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Refactor `Measure` block metrics to be homeserver-scoped.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Refactor cache metrics to be homeserver-scoped.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Unbreak "Latest dependencies" workflow by using the `--without dev` poetry option instead of removed `--no-dev`.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Update URL Preview code to work with `lxml` 6.0.0+.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Support arbitrary profile fields.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Use `markdown-it-py` instead of `commonmark` in the release script.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Advertise support for Matrix v1.12.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Fix typing errors with upgraded mypy version.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Don't allow creation of tags with names longer than 255 bytes, as per the spec.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Add doc comment explaining that config files are shallowly merged.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Minor speed up of insertion into `stream_positions` table.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Include `event_id` when getting state with `?format=event`. Contributed by @tulir @ Beeper.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Remove unused `allow_no_prev_events` option when creating an event.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Fix sliding_sync_connections related errors when porting from SQLite to Postgres.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Add `recaptcha_private_key_path` and `recaptcha_public_key_path` config option.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Add ability to configure forward/outbound proxy via homeserver config instead of environment variables. See `http_proxy`, `https_proxy`, `no_proxy_hosts`.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Clean up `MetricsResource` and Prometheus hacks.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Fix dirty `Cargo.lock` changes appearing after install (`base64`).
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Fix the MAS integration not working when Synapse is started with `--daemonize` or using `synctl`.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Update `rc_delayed_event_mgmt` docs to the actual nesting level. Contributed by @HarHarLinks.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Prevent dirty `Cargo.lock` changes from install.
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Correct spelling of 'Admin token used' log line.
|
|
||||||
1
changelog.d/18746.bugfix
Normal file
1
changelog.d/18746.bugfix
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Fix a bug which could corrupt auth chains making it impossible to perform state resolution.
|
||||||
1
changelog.d/18780.bugfix
Normal file
1
changelog.d/18780.bugfix
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Fix error message in `register_new_matrix_user` utility script for empty `registration_shared_secret`.
|
||||||
1
changelog.d/18781.doc
Normal file
1
changelog.d/18781.doc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Include IPv6 networks in denied-peer-ips of coturn setup. Contributed by @litetex.
|
||||||
1
changelog.d/18794.misc
Normal file
1
changelog.d/18794.misc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Update tests to ensure all database tables are emptied when purging a room.
|
||||||
1
changelog.d/18815.misc
Normal file
1
changelog.d/18815.misc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Instrument the `encode_response` part of Sliding Sync requests for more complete traces in Jaeger.
|
||||||
1
changelog.d/18816.misc
Normal file
1
changelog.d/18816.misc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Tag Sliding Sync traces when we `wait_for_events`.
|
||||||
1
changelog.d/18824.misc
Normal file
1
changelog.d/18824.misc
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Fix portdb CI by hardcoding the new pg_dump restrict key that was added due to CVE-2025-8714.
|
||||||
1
changelog.d/18832.bugfix
Normal file
1
changelog.d/18832.bugfix
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Allow enabling MSC4108 when the stable Matrix Authentication Service integration is enabled.
|
||||||
@@ -4396,7 +4396,7 @@
|
|||||||
"exemplar": false,
|
"exemplar": false,
|
||||||
"expr": "(time() - max without (job, index, host) (avg_over_time(synapse_federation_last_received_pdu_time[10m]))) / 60",
|
"expr": "(time() - max without (job, index, host) (avg_over_time(synapse_federation_last_received_pdu_time[10m]))) / 60",
|
||||||
"instant": false,
|
"instant": false,
|
||||||
"legendFormat": "{{server_name}} ",
|
"legendFormat": "{{origin_server_name}} ",
|
||||||
"range": true,
|
"range": true,
|
||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
@@ -4518,7 +4518,7 @@
|
|||||||
"exemplar": false,
|
"exemplar": false,
|
||||||
"expr": "(time() - max without (job, index, host) (avg_over_time(synapse_federation_last_sent_pdu_time[10m]))) / 60",
|
"expr": "(time() - max without (job, index, host) (avg_over_time(synapse_federation_last_sent_pdu_time[10m]))) / 60",
|
||||||
"instant": false,
|
"instant": false,
|
||||||
"legendFormat": "{{server_name}}",
|
"legendFormat": "{{destination_server_name}}",
|
||||||
"range": true,
|
"range": true,
|
||||||
"refId": "A"
|
"refId": "A"
|
||||||
}
|
}
|
||||||
|
|||||||
48
debian/changelog
vendored
48
debian/changelog
vendored
@@ -1,3 +1,51 @@
|
|||||||
|
matrix-synapse-py3 (1.136.0) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.136.0.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Tue, 12 Aug 2025 13:18:03 +0100
|
||||||
|
|
||||||
|
matrix-synapse-py3 (1.136.0~rc2) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.136.0rc2.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Mon, 11 Aug 2025 12:18:52 -0600
|
||||||
|
|
||||||
|
matrix-synapse-py3 (1.136.0~rc1) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.136.0rc1.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Tue, 05 Aug 2025 08:13:30 -0600
|
||||||
|
|
||||||
|
matrix-synapse-py3 (1.135.2) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.135.2.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Mon, 11 Aug 2025 11:52:01 -0600
|
||||||
|
|
||||||
|
matrix-synapse-py3 (1.135.1) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.135.1.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Mon, 11 Aug 2025 11:13:15 -0600
|
||||||
|
|
||||||
|
matrix-synapse-py3 (1.135.0) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.135.0.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Fri, 01 Aug 2025 13:12:28 +0100
|
||||||
|
|
||||||
|
matrix-synapse-py3 (1.135.0~rc2) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.135.0rc2.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Wed, 30 Jul 2025 12:19:14 +0100
|
||||||
|
|
||||||
|
matrix-synapse-py3 (1.135.0~rc1) stable; urgency=medium
|
||||||
|
|
||||||
|
* New Synapse release 1.135.0rc1.
|
||||||
|
|
||||||
|
-- Synapse Packaging team <packages@matrix.org> Tue, 22 Jul 2025 12:08:37 +0100
|
||||||
|
|
||||||
matrix-synapse-py3 (1.134.0) stable; urgency=medium
|
matrix-synapse-py3 (1.134.0) stable; urgency=medium
|
||||||
|
|
||||||
* New Synapse release 1.134.0.
|
* New Synapse release 1.134.0.
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ rc_delayed_event_mgmt:
|
|||||||
per_second: 9999
|
per_second: 9999
|
||||||
burst_count: 9999
|
burst_count: 9999
|
||||||
|
|
||||||
|
rc_room_creation:
|
||||||
|
per_second: 9999
|
||||||
|
burst_count: 9999
|
||||||
|
|
||||||
federation_rr_transactions_per_room_per_second: 9999
|
federation_rr_transactions_per_room_per_second: 9999
|
||||||
|
|
||||||
allow_device_name_lookup_over_federation: true
|
allow_device_name_lookup_over_federation: true
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ WORKERS_CONFIG: Dict[str, Dict[str, Any]] = {
|
|||||||
"^/_matrix/client/(api/v1|r0|v3|unstable)/login$",
|
"^/_matrix/client/(api/v1|r0|v3|unstable)/login$",
|
||||||
"^/_matrix/client/(api/v1|r0|v3|unstable)/account/3pid$",
|
"^/_matrix/client/(api/v1|r0|v3|unstable)/account/3pid$",
|
||||||
"^/_matrix/client/(api/v1|r0|v3|unstable)/account/whoami$",
|
"^/_matrix/client/(api/v1|r0|v3|unstable)/account/whoami$",
|
||||||
|
"^/_matrix/client/(api/v1|r0|v3|unstable)/account/deactivate$",
|
||||||
"^/_matrix/client/(api/v1|r0|v3|unstable)/devices(/|$)",
|
"^/_matrix/client/(api/v1|r0|v3|unstable)/devices(/|$)",
|
||||||
"^/_matrix/client/(r0|v3)/delete_devices$",
|
"^/_matrix/client/(r0|v3)/delete_devices$",
|
||||||
"^/_matrix/client/versions$",
|
"^/_matrix/client/versions$",
|
||||||
@@ -327,6 +328,15 @@ WORKERS_CONFIG: Dict[str, Dict[str, Any]] = {
|
|||||||
"shared_extra_conf": {},
|
"shared_extra_conf": {},
|
||||||
"worker_extra_conf": "",
|
"worker_extra_conf": "",
|
||||||
},
|
},
|
||||||
|
"thread_subscriptions": {
|
||||||
|
"app": "synapse.app.generic_worker",
|
||||||
|
"listener_resources": ["client", "replication"],
|
||||||
|
"endpoint_patterns": [
|
||||||
|
"^/_matrix/client/unstable/io.element.msc4306/.*",
|
||||||
|
],
|
||||||
|
"shared_extra_conf": {},
|
||||||
|
"worker_extra_conf": "",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Templates for sections that may be inserted multiple times in config files
|
# Templates for sections that may be inserted multiple times in config files
|
||||||
@@ -427,6 +437,7 @@ def add_worker_roles_to_shared_config(
|
|||||||
"to_device",
|
"to_device",
|
||||||
"typing",
|
"typing",
|
||||||
"push_rules",
|
"push_rules",
|
||||||
|
"thread_subscriptions",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Worker-type specific sharding config. Now a single worker can fulfill multiple
|
# Worker-type specific sharding config. Now a single worker can fulfill multiple
|
||||||
|
|||||||
@@ -22,4 +22,46 @@ To receive soft failed events in APIs like `/sync` and `/messages`, set `return_
|
|||||||
to `true` in the admin client config. When `false`, the normal behaviour of these endpoints is to
|
to `true` in the admin client config. When `false`, the normal behaviour of these endpoints is to
|
||||||
exclude soft failed events.
|
exclude soft failed events.
|
||||||
|
|
||||||
|
**Note**: If the policy server flagged the event as spam and that caused soft failure, that will be indicated
|
||||||
|
in the event's `unsigned` content like so:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "m.room.message",
|
||||||
|
"other": "event_fields_go_here",
|
||||||
|
"unsigned": {
|
||||||
|
"io.element.synapse.soft_failed": true,
|
||||||
|
"io.element.synapse.policy_server_spammy": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Default: `false`
|
Default: `false`
|
||||||
|
|
||||||
|
## See events marked spammy by policy servers
|
||||||
|
|
||||||
|
Learn more about policy servers from [MSC4284](https://github.com/matrix-org/matrix-spec-proposals/pull/4284).
|
||||||
|
|
||||||
|
Similar to `return_soft_failed_events`, clients logged in with admin accounts can see events which were
|
||||||
|
flagged by the policy server as spammy (and thus soft failed) by setting `return_policy_server_spammy_events`
|
||||||
|
to `true`.
|
||||||
|
|
||||||
|
`return_policy_server_spammy_events` may be `true` while `return_soft_failed_events` is `false` to only see
|
||||||
|
policy server-flagged events. When `return_soft_failed_events` is `true` however, `return_policy_server_spammy_events`
|
||||||
|
is always `true`.
|
||||||
|
|
||||||
|
Events which were flagged by the policy will be flagged as `io.element.synapse.policy_server_spammy` in the
|
||||||
|
event's `unsigned` content, like so:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"type": "m.room.message",
|
||||||
|
"other": "event_fields_go_here",
|
||||||
|
"unsigned": {
|
||||||
|
"io.element.synapse.soft_failed": true,
|
||||||
|
"io.element.synapse.policy_server_spammy": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Default: `true` if `return_soft_failed_events` is `true`, otherwise `false`
|
||||||
|
|||||||
@@ -1227,7 +1227,7 @@ See also the
|
|||||||
|
|
||||||
## Controlling whether a user is shadow-banned
|
## Controlling whether a user is shadow-banned
|
||||||
|
|
||||||
Shadow-banning is a useful tool for moderating malicious or egregiously abusive users.
|
Shadow-banning is a useful tool for moderating malicious or egregiously abusive users.
|
||||||
A shadow-banned users receives successful responses to their client-server API requests,
|
A shadow-banned users receives successful responses to their client-server API requests,
|
||||||
but the events are not propagated into rooms. This can be an effective tool as it
|
but the events are not propagated into rooms. This can be an effective tool as it
|
||||||
(hopefully) takes longer for the user to realise they are being moderated before
|
(hopefully) takes longer for the user to realise they are being moderated before
|
||||||
@@ -1464,8 +1464,11 @@ _Added in Synapse 1.72.0._
|
|||||||
|
|
||||||
## Redact all the events of a user
|
## Redact all the events of a user
|
||||||
|
|
||||||
This endpoint allows an admin to redact the events of a given user. There are no restrictions on redactions for a
|
This endpoint allows an admin to redact the events of a given user. There are no restrictions on
|
||||||
local user. By default, we puppet the user who sent the message to redact it themselves. Redactions for non-local users are issued using the admin user, and will fail in rooms where the admin user is not admin/does not have the specified power level to issue redactions.
|
redactions for a local user. By default, we puppet the user who sent the message to redact it themselves.
|
||||||
|
Redactions for non-local users are issued using the admin user, and will fail in rooms where the
|
||||||
|
admin user is not admin/does not have the specified power level to issue redactions. An option
|
||||||
|
is provided to override the default and allow the admin to issue the redactions in all cases.
|
||||||
|
|
||||||
The API is
|
The API is
|
||||||
```
|
```
|
||||||
@@ -1475,7 +1478,7 @@ POST /_synapse/admin/v1/user/$user_id/redact
|
|||||||
"rooms": ["!roomid1", "!roomid2"]
|
"rooms": ["!roomid1", "!roomid2"]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
If an empty list is provided as the key for `rooms`, all events in all the rooms the user is member of will be redacted,
|
If an empty list is provided as the key for `rooms`, all events in all the rooms the user is member of will be redacted,
|
||||||
otherwise all the events in the rooms provided in the request will be redacted.
|
otherwise all the events in the rooms provided in the request will be redacted.
|
||||||
|
|
||||||
The API starts redaction process running, and returns immediately with a JSON body with
|
The API starts redaction process running, and returns immediately with a JSON body with
|
||||||
@@ -1501,7 +1504,10 @@ The following JSON body parameter must be provided:
|
|||||||
The following JSON body parameters are optional:
|
The following JSON body parameters are optional:
|
||||||
|
|
||||||
- `reason` - Reason the redaction is being requested, ie "spam", "abuse", etc. This will be included in each redaction event, and be visible to users.
|
- `reason` - Reason the redaction is being requested, ie "spam", "abuse", etc. This will be included in each redaction event, and be visible to users.
|
||||||
- `limit` - a limit on the number of the user's events to search for ones that can be redacted (events are redacted newest to oldest) in each room, defaults to 1000 if not provided
|
- `limit` - a limit on the number of the user's events to search for ones that can be redacted (events are redacted newest to oldest) in each room, defaults to 1000 if not provided.
|
||||||
|
- `use_admin` - If set to `true`, the admin user is used to issue the redactions, rather than puppeting the user. Useful
|
||||||
|
when the admin is also the moderator of the rooms that require redactions. Note that the redactions will fail in rooms
|
||||||
|
where the admin does not have the sufficient power level to issue the redactions.
|
||||||
|
|
||||||
_Added in Synapse 1.116.0._
|
_Added in Synapse 1.116.0._
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ This will install and start a systemd service called `coturn`.
|
|||||||
denied-peer-ip=172.16.0.0-172.31.255.255
|
denied-peer-ip=172.16.0.0-172.31.255.255
|
||||||
|
|
||||||
# recommended additional local peers to block, to mitigate external access to internal services.
|
# recommended additional local peers to block, to mitigate external access to internal services.
|
||||||
# https://www.rtcsec.com/article/slack-webrtc-turn-compromise-and-bug-bounty/#how-to-fix-an-open-turn-relay-to-address-this-vulnerability
|
# https://www.enablesecurity.com/blog/slack-webrtc-turn-compromise-and-bug-bounty/#how-to-fix-an-open-turn-relay-to-address-this-vulnerability
|
||||||
|
# https://www.enablesecurity.com/blog/cve-2020-26262-bypass-of-coturns-access-control-protection/#further-concerns-what-else
|
||||||
no-multicast-peers
|
no-multicast-peers
|
||||||
denied-peer-ip=0.0.0.0-0.255.255.255
|
denied-peer-ip=0.0.0.0-0.255.255.255
|
||||||
denied-peer-ip=100.64.0.0-100.127.255.255
|
denied-peer-ip=100.64.0.0-100.127.255.255
|
||||||
@@ -101,6 +102,14 @@ This will install and start a systemd service called `coturn`.
|
|||||||
denied-peer-ip=198.51.100.0-198.51.100.255
|
denied-peer-ip=198.51.100.0-198.51.100.255
|
||||||
denied-peer-ip=203.0.113.0-203.0.113.255
|
denied-peer-ip=203.0.113.0-203.0.113.255
|
||||||
denied-peer-ip=240.0.0.0-255.255.255.255
|
denied-peer-ip=240.0.0.0-255.255.255.255
|
||||||
|
denied-peer-ip=::1
|
||||||
|
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
|
||||||
|
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
|
||||||
|
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
|
||||||
|
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||||
|
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||||
|
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||||
|
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
|
||||||
|
|
||||||
# special case the turn server itself so that client->TURN->TURN->client flows work
|
# special case the turn server itself so that client->TURN->TURN->client flows work
|
||||||
# this should be one of the turn server's listening IPs
|
# this should be one of the turn server's listening IPs
|
||||||
|
|||||||
@@ -117,6 +117,77 @@ each upgrade are complete before moving on to the next upgrade, to avoid
|
|||||||
stacking them up. You can monitor the currently running background updates with
|
stacking them up. You can monitor the currently running background updates with
|
||||||
[the Admin API](usage/administration/admin_api/background_updates.html#status).
|
[the Admin API](usage/administration/admin_api/background_updates.html#status).
|
||||||
|
|
||||||
|
# Upgrading to v1.136.0
|
||||||
|
|
||||||
|
## Deprecate `run_as_background_process` exported as part of the module API interface in favor of `ModuleApi.run_as_background_process`
|
||||||
|
|
||||||
|
The `run_as_background_process` function is now a method of the `ModuleApi` class. If
|
||||||
|
you were using the function directly from the module API, it will continue to work fine
|
||||||
|
but the background process metrics will not include an accurate `server_name` label.
|
||||||
|
This kind of metric labeling isn't relevant for many use cases and is used to
|
||||||
|
differentiate Synapse instances running in the same Python process (relevant to Synapse
|
||||||
|
Pro: Small Hosts). We recommend updating your usage to use the new
|
||||||
|
`ModuleApi.run_as_background_process` method to stay on top of future changes.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Example <code>run_as_background_process</code> upgrade</summary>
|
||||||
|
|
||||||
|
Before:
|
||||||
|
```python
|
||||||
|
class MyModule:
|
||||||
|
def __init__(self, module_api: ModuleApi) -> None:
|
||||||
|
run_as_background_process(__name__ + ":setup_database", self.setup_database)
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
```python
|
||||||
|
class MyModule:
|
||||||
|
def __init__(self, module_api: ModuleApi) -> None:
|
||||||
|
module_api.run_as_background_process(__name__ + ":setup_database", self.setup_database)
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Metric labels have changed on `synapse_federation_last_received_pdu_time` and `synapse_federation_last_sent_pdu_time`
|
||||||
|
|
||||||
|
Previously, the `synapse_federation_last_received_pdu_time` and
|
||||||
|
`synapse_federation_last_sent_pdu_time` metrics both used the `server_name` label to
|
||||||
|
differentiate between different servers that we send and receive events from.
|
||||||
|
|
||||||
|
Since we're now using the `server_name` label to differentiate between different Synapse
|
||||||
|
homeserver instances running in the same process, these metrics have been changed as follows:
|
||||||
|
|
||||||
|
- `synapse_federation_last_received_pdu_time` now uses the `origin_server_name` label
|
||||||
|
- `synapse_federation_last_sent_pdu_time` now uses the `destination_server_name` label
|
||||||
|
|
||||||
|
The Grafana dashboard JSON in `contrib/grafana/synapse.json` has been updated to reflect
|
||||||
|
this change but you will need to manually update your own existing Grafana dashboards
|
||||||
|
using these metrics.
|
||||||
|
|
||||||
|
## Stable integration with Matrix Authentication Service
|
||||||
|
|
||||||
|
Support for [Matrix Authentication Service (MAS)](https://github.com/element-hq/matrix-authentication-service) is now stable, with a simplified configuration.
|
||||||
|
This stable integration requires MAS 0.20.0 or later.
|
||||||
|
|
||||||
|
The existing `experimental_features.msc3861` configuration option is now deprecated and will be removed in Synapse v1.137.0.
|
||||||
|
|
||||||
|
Synapse deployments already using MAS should now use the new configuration options:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_authentication_service:
|
||||||
|
# Enable the MAS integration
|
||||||
|
enabled: true
|
||||||
|
# The base URL where Synapse will contact MAS
|
||||||
|
endpoint: http://localhost:8080
|
||||||
|
# The shared secret used to authenticate MAS requests, must be the same as `matrix.secret` in the MAS configuration
|
||||||
|
# See https://element-hq.github.io/matrix-authentication-service/reference/configuration.html#matrix
|
||||||
|
secret: "asecurerandomsecretstring"
|
||||||
|
```
|
||||||
|
|
||||||
|
They must remove the `experimental_features.msc3861` configuration option from their configuration.
|
||||||
|
|
||||||
|
They can also remove the client previously used by Synapse [in the MAS configuration](https://element-hq.github.io/matrix-authentication-service/reference/configuration.html#clients) as it is no longer in use.
|
||||||
|
|
||||||
# Upgrading to v1.135.0
|
# Upgrading to v1.135.0
|
||||||
|
|
||||||
## `on_user_registration` module API callback may now run on any worker
|
## `on_user_registration` module API callback may now run on any worker
|
||||||
@@ -137,10 +208,10 @@ native ICU library on your system is no longer required.
|
|||||||
## Documented endpoint which can be delegated to a federation worker
|
## Documented endpoint which can be delegated to a federation worker
|
||||||
|
|
||||||
The endpoint `^/_matrix/federation/v1/version$` can be delegated to a federation
|
The endpoint `^/_matrix/federation/v1/version$` can be delegated to a federation
|
||||||
worker. This is not new behaviour, but had not been documented yet. The
|
worker. This is not new behaviour, but had not been documented yet. The
|
||||||
[list of delegatable endpoints](workers.md#synapseappgeneric_worker) has
|
[list of delegatable endpoints](workers.md#synapseappgeneric_worker) has
|
||||||
been updated to include it. Make sure to check your reverse proxy rules if you
|
been updated to include it. Make sure to check your reverse proxy rules if you
|
||||||
are using workers.
|
are using workers.
|
||||||
|
|
||||||
# Upgrading to v1.126.0
|
# Upgrading to v1.126.0
|
||||||
|
|
||||||
|
|||||||
@@ -643,6 +643,28 @@ no_proxy_hosts:
|
|||||||
- 172.30.0.0/16
|
- 172.30.0.0/16
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
### `matrix_authentication_service`
|
||||||
|
|
||||||
|
*(object)* The `matrix_authentication_service` setting configures integration with [Matrix Authentication Service (MAS)](https://github.com/element-hq/matrix-authentication-service).
|
||||||
|
|
||||||
|
This setting has the following sub-options:
|
||||||
|
|
||||||
|
* `enabled` (boolean): Whether or not to enable the MAS integration. If this is set to `false`, Synapse will use its legacy internal authentication API. Defaults to `false`.
|
||||||
|
|
||||||
|
* `endpoint` (string): The URL where Synapse can reach MAS. This *must* have the `discovery` and `oauth` resources mounted. Defaults to `"http://localhost:8080"`.
|
||||||
|
|
||||||
|
* `secret` (string|null): A shared secret that will be used to authenticate requests from and to MAS.
|
||||||
|
|
||||||
|
* `secret_path` (string|null): Alternative to `secret`, reading the shared secret from a file. The file should be a plain text file, containing only the secret. Synapse reads the secret from the given file once at startup.
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
```yaml
|
||||||
|
matrix_authentication_service:
|
||||||
|
enabled: true
|
||||||
|
secret: someverysecuresecret
|
||||||
|
endpoint: http://localhost:8080
|
||||||
|
```
|
||||||
|
---
|
||||||
### `dummy_events_threshold`
|
### `dummy_events_threshold`
|
||||||
|
|
||||||
*(integer)* Forward extremities can build up in a room due to networking delays between homeservers. Once this happens in a large room, calculation of the state of that room can become quite expensive. To mitigate this, once the number of forward extremities reaches a given threshold, Synapse will send an `org.matrix.dummy_event` event, which will reduce the forward extremities in the room.
|
*(integer)* Forward extremities can build up in a room due to networking delays between homeservers. Once this happens in a large room, calculation of the state of that room can become quite expensive. To mitigate this, once the number of forward extremities reaches a given threshold, Synapse will send an `org.matrix.dummy_event` event, which will reduce the forward extremities in the room.
|
||||||
@@ -1996,6 +2018,31 @@ rc_reports:
|
|||||||
burst_count: 20.0
|
burst_count: 20.0
|
||||||
```
|
```
|
||||||
---
|
---
|
||||||
|
### `rc_room_creation`
|
||||||
|
|
||||||
|
*(object)* Sets rate limits for how often users are able to create rooms.
|
||||||
|
|
||||||
|
This setting has the following sub-options:
|
||||||
|
|
||||||
|
* `per_second` (number): Maximum number of requests a client can send per second.
|
||||||
|
|
||||||
|
* `burst_count` (number): Maximum number of requests a client can send before being throttled.
|
||||||
|
|
||||||
|
Default configuration:
|
||||||
|
```yaml
|
||||||
|
rc_room_creation:
|
||||||
|
per_user:
|
||||||
|
per_second: 0.016
|
||||||
|
burst_count: 10.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Example configuration:
|
||||||
|
```yaml
|
||||||
|
rc_room_creation:
|
||||||
|
per_second: 1.0
|
||||||
|
burst_count: 5.0
|
||||||
|
```
|
||||||
|
---
|
||||||
### `federation_rr_transactions_per_room_per_second`
|
### `federation_rr_transactions_per_room_per_second`
|
||||||
|
|
||||||
*(integer)* Sets outgoing federation transaction frequency for sending read-receipts, per-room.
|
*(integer)* Sets outgoing federation transaction frequency for sending read-receipts, per-room.
|
||||||
@@ -4127,7 +4174,7 @@ The default power levels for each preset are:
|
|||||||
"m.room.history_visibility": 100
|
"m.room.history_visibility": 100
|
||||||
"m.room.canonical_alias": 50
|
"m.room.canonical_alias": 50
|
||||||
"m.room.avatar": 50
|
"m.room.avatar": 50
|
||||||
"m.room.tombstone": 100
|
"m.room.tombstone": 100 (150 if MSC4289 is used)
|
||||||
"m.room.server_acl": 100
|
"m.room.server_acl": 100
|
||||||
"m.room.encryption": 100
|
"m.room.encryption": 100
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -238,6 +238,7 @@ information.
|
|||||||
^/_matrix/client/unstable/im.nheko.summary/summary/.*$
|
^/_matrix/client/unstable/im.nheko.summary/summary/.*$
|
||||||
^/_matrix/client/(r0|v3|unstable)/account/3pid$
|
^/_matrix/client/(r0|v3|unstable)/account/3pid$
|
||||||
^/_matrix/client/(r0|v3|unstable)/account/whoami$
|
^/_matrix/client/(r0|v3|unstable)/account/whoami$
|
||||||
|
^/_matrix/client/(r0|v3|unstable)/account/deactivate$
|
||||||
^/_matrix/client/(r0|v3)/delete_devices$
|
^/_matrix/client/(r0|v3)/delete_devices$
|
||||||
^/_matrix/client/(api/v1|r0|v3|unstable)/devices(/|$)
|
^/_matrix/client/(api/v1|r0|v3|unstable)/devices(/|$)
|
||||||
^/_matrix/client/versions$
|
^/_matrix/client/versions$
|
||||||
@@ -259,7 +260,7 @@ information.
|
|||||||
^/_matrix/client/(r0|v3|unstable)/keys/claim$
|
^/_matrix/client/(r0|v3|unstable)/keys/claim$
|
||||||
^/_matrix/client/(r0|v3|unstable)/room_keys/
|
^/_matrix/client/(r0|v3|unstable)/room_keys/
|
||||||
^/_matrix/client/(r0|v3|unstable)/keys/upload
|
^/_matrix/client/(r0|v3|unstable)/keys/upload
|
||||||
^/_matrix/client/(api/v1|r0|v3|unstable/keys/device_signing/upload$
|
^/_matrix/client/(api/v1|r0|v3|unstable)/keys/device_signing/upload$
|
||||||
^/_matrix/client/(api/v1|r0|v3|unstable)/keys/signatures/upload$
|
^/_matrix/client/(api/v1|r0|v3|unstable)/keys/signatures/upload$
|
||||||
|
|
||||||
# Registration/login requests
|
# Registration/login requests
|
||||||
@@ -531,8 +532,9 @@ the stream writer for the `account_data` stream:
|
|||||||
|
|
||||||
##### The `receipts` stream
|
##### The `receipts` stream
|
||||||
|
|
||||||
The following endpoints should be routed directly to the worker configured as
|
The `receipts` stream supports multiple writers. The following endpoints
|
||||||
the stream writer for the `receipts` stream:
|
can be handled by any worker, but should be routed directly to one of the workers
|
||||||
|
configured as stream writer for the `receipts` stream:
|
||||||
|
|
||||||
^/_matrix/client/(r0|v3|unstable)/rooms/.*/receipt
|
^/_matrix/client/(r0|v3|unstable)/rooms/.*/receipt
|
||||||
^/_matrix/client/(r0|v3|unstable)/rooms/.*/read_markers
|
^/_matrix/client/(r0|v3|unstable)/rooms/.*/read_markers
|
||||||
@@ -554,13 +556,13 @@ the stream writer for the `push_rules` stream:
|
|||||||
##### The `device_lists` stream
|
##### The `device_lists` stream
|
||||||
|
|
||||||
The `device_lists` stream supports multiple writers. The following endpoints
|
The `device_lists` stream supports multiple writers. The following endpoints
|
||||||
can be handled by any worker, but should be routed directly one of the workers
|
can be handled by any worker, but should be routed directly to one of the workers
|
||||||
configured as stream writer for the `device_lists` stream:
|
configured as stream writer for the `device_lists` stream:
|
||||||
|
|
||||||
^/_matrix/client/(r0|v3)/delete_devices$
|
^/_matrix/client/(r0|v3)/delete_devices$
|
||||||
^/_matrix/client/(api/v1|r0|v3|unstable)/devices/
|
^/_matrix/client/(api/v1|r0|v3|unstable)/devices(/|$)
|
||||||
^/_matrix/client/(r0|v3|unstable)/keys/upload
|
^/_matrix/client/(r0|v3|unstable)/keys/upload
|
||||||
^/_matrix/client/(api/v1|r0|v3|unstable/keys/device_signing/upload$
|
^/_matrix/client/(api/v1|r0|v3|unstable)/keys/device_signing/upload$
|
||||||
^/_matrix/client/(api/v1|r0|v3|unstable)/keys/signatures/upload$
|
^/_matrix/client/(api/v1|r0|v3|unstable)/keys/signatures/upload$
|
||||||
|
|
||||||
#### Restrict outbound federation traffic to a specific set of workers
|
#### Restrict outbound federation traffic to a specific set of workers
|
||||||
|
|||||||
16
mypy.ini
16
mypy.ini
@@ -1,6 +1,17 @@
|
|||||||
[mypy]
|
[mypy]
|
||||||
namespace_packages = True
|
namespace_packages = True
|
||||||
plugins = pydantic.mypy, mypy_zope:plugin, scripts-dev/mypy_synapse_plugin.py
|
# Our custom mypy plugin should remain first in this list.
|
||||||
|
#
|
||||||
|
# mypy has a limitation where it only chooses the first plugin that returns a non-None
|
||||||
|
# value for each hook (known-limitation, c.f.
|
||||||
|
# https://github.com/python/mypy/issues/19524). We workaround this by putting our custom
|
||||||
|
# plugin first in the plugin order and then manually calling any other conflicting
|
||||||
|
# plugin hooks in our own plugin followed by our own checks.
|
||||||
|
#
|
||||||
|
# If you add a new plugin, make sure to check whether the hooks being used conflict with
|
||||||
|
# our custom plugin hooks and if so, manually call the other plugin's hooks in our
|
||||||
|
# custom plugin. (also applies to if the plugin is updated in the future)
|
||||||
|
plugins = scripts-dev/mypy_synapse_plugin.py, pydantic.mypy, mypy_zope:plugin
|
||||||
follow_imports = normal
|
follow_imports = normal
|
||||||
show_error_codes = True
|
show_error_codes = True
|
||||||
show_traceback = True
|
show_traceback = True
|
||||||
@@ -99,3 +110,6 @@ ignore_missing_imports = True
|
|||||||
|
|
||||||
[mypy-multipart.*]
|
[mypy-multipart.*]
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
|
|
||||||
|
[mypy-mypy_zope.*]
|
||||||
|
ignore_missing_imports = True
|
||||||
|
|||||||
335
poetry.lock
generated
335
poetry.lock
generated
@@ -1,4 +1,4 @@
|
|||||||
# This file is automatically @generated by Poetry 2.1.2 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"
|
||||||
@@ -34,15 +34,15 @@ tests-mypy = ["mypy (>=1.11.1) ; platform_python_implementation == \"CPython\" a
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "authlib"
|
name = "authlib"
|
||||||
version = "1.6.0"
|
version = "1.6.1"
|
||||||
description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients."
|
description = "The ultimate Python library in building OAuth and OpenID Connect servers and clients."
|
||||||
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.6.0-py2.py3-none-any.whl", hash = "sha256:91685589498f79e8655e8a8947431ad6288831d643f11c55c2143ffcc738048d"},
|
{file = "authlib-1.6.1-py2.py3-none-any.whl", hash = "sha256:e9d2031c34c6309373ab845afc24168fe9e93dc52d252631f52642f21f5ed06e"},
|
||||||
{file = "authlib-1.6.0.tar.gz", hash = "sha256:4367d32031b7af175ad3a323d571dc7257b7099d55978087ceae4a0d88cd3210"},
|
{file = "authlib-1.6.1.tar.gz", hash = "sha256:4dffdbb1460ba6ec8c17981a4c67af7d8af131231b5a36a88a1e8c80c111cdfd"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -435,30 +435,12 @@ 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"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "deprecated"
|
|
||||||
version = "1.2.13"
|
|
||||||
description = "Python @deprecated decorator to deprecate old python classes, functions or methods."
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
|
||||||
groups = ["dev"]
|
|
||||||
files = [
|
|
||||||
{file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"},
|
|
||||||
{file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
wrapt = ">=1.10,<2"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
dev = ["PyTest (<5) ; python_version < \"3.6\"", "PyTest ; python_version >= \"3.6\"", "PyTest-Cov (<2.6) ; python_version < \"3.6\"", "PyTest-Cov ; python_version >= \"3.6\"", "bump2version (<1)", "configparser (<5) ; python_version < \"3\"", "importlib-metadata (<3) ; python_version < \"3\"", "importlib-resources (<4) ; python_version < \"3\"", "sphinx (<2)", "sphinxcontrib-websupport (<2) ; python_version < \"3\"", "tox", "zipp (<2) ; python_version < \"3\""]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "docutils"
|
name = "docutils"
|
||||||
version = "0.19"
|
version = "0.19"
|
||||||
@@ -478,7 +460,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"},
|
||||||
@@ -504,18 +486,19 @@ smmap = ">=3.0.1,<6"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gitpython"
|
name = "gitpython"
|
||||||
version = "3.1.44"
|
version = "3.1.45"
|
||||||
description = "GitPython is a Python library used to interact with Git repositories"
|
description = "GitPython is a Python library used to interact with Git repositories"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110"},
|
{file = "gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77"},
|
||||||
{file = "gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269"},
|
{file = "gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
gitdb = ">=4.0.1,<5"
|
gitdb = ">=4.0.1,<5"
|
||||||
|
typing-extensions = {version = ">=3.10.0.2", markers = "python_version < \"3.10\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"]
|
doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"]
|
||||||
@@ -528,7 +511,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.2.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:add17efcbae46c5a6a13b244ff0b4a8fa079602ceb62290095c941b42e9d5dec"},
|
{file = "hiredis-3.2.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:add17efcbae46c5a6a13b244ff0b4a8fa079602ceb62290095c941b42e9d5dec"},
|
||||||
{file = "hiredis-3.2.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:5fe955cc4f66c57df1ae8e5caf4de2925d43b5efab4e40859662311d1bcc5f54"},
|
{file = "hiredis-3.2.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:5fe955cc4f66c57df1ae8e5caf4de2925d43b5efab4e40859662311d1bcc5f54"},
|
||||||
@@ -865,7 +848,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"},
|
||||||
]
|
]
|
||||||
@@ -936,14 +919,14 @@ i18n = ["Babel (>=2.7)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonschema"
|
name = "jsonschema"
|
||||||
version = "4.24.0"
|
version = "4.25.0"
|
||||||
description = "An implementation of JSON Schema validation for Python"
|
description = "An implementation of JSON Schema validation for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "jsonschema-4.24.0-py3-none-any.whl", hash = "sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d"},
|
{file = "jsonschema-4.25.0-py3-none-any.whl", hash = "sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716"},
|
||||||
{file = "jsonschema-4.24.0.tar.gz", hash = "sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196"},
|
{file = "jsonschema-4.25.0.tar.gz", hash = "sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -954,7 +937,7 @@ rpds-py = ">=0.7.1"
|
|||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
|
format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
|
||||||
format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=24.6.0)"]
|
format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "rfc3987-syntax (>=1.1.0)", "uri-template", "webcolors (>=24.6.0)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonschema-specifications"
|
name = "jsonschema-specifications"
|
||||||
@@ -1003,7 +986,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"},
|
||||||
@@ -1019,7 +1002,7 @@ description = "Powerful and Pythonic XML processing library combining libxml2/li
|
|||||||
optional = true
|
optional = true
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
markers = "extra == \"url-preview\" or extra == \"all\""
|
markers = "extra == \"all\" or extra == \"url-preview\""
|
||||||
files = [
|
files = [
|
||||||
{file = "lxml-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35bc626eec405f745199200ccb5c6b36f202675d204aa29bb52e27ba2b71dea8"},
|
{file = "lxml-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:35bc626eec405f745199200ccb5c6b36f202675d204aa29bb52e27ba2b71dea8"},
|
||||||
{file = "lxml-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:246b40f8a4aec341cbbf52617cad8ab7c888d944bfe12a6abd2b1f6cfb6f6082"},
|
{file = "lxml-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:246b40f8a4aec341cbbf52617cad8ab7c888d944bfe12a6abd2b1f6cfb6f6082"},
|
||||||
@@ -1260,7 +1243,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"},
|
||||||
@@ -1386,44 +1369,50 @@ docs = ["sphinx (>=8,<9)", "sphinx-autobuild"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy"
|
name = "mypy"
|
||||||
version = "1.16.1"
|
version = "1.17.1"
|
||||||
description = "Optional static typing for Python"
|
description = "Optional static typing for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy-1.16.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4f0fed1022a63c6fec38f28b7fc77fca47fd490445c69d0a66266c59dd0b88a"},
|
{file = "mypy-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3fbe6d5555bf608c47203baa3e72dbc6ec9965b3d7c318aa9a4ca76f465bd972"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86042bbf9f5a05ea000d3203cf87aa9d0ccf9a01f73f71c58979eb9249f46d72"},
|
{file = "mypy-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80ef5c058b7bce08c83cac668158cb7edea692e458d21098c7d3bce35a5d43e7"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ea7469ee5902c95542bea7ee545f7006508c65c8c54b06dc2c92676ce526f3ea"},
|
{file = "mypy-1.17.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4a580f8a70c69e4a75587bd925d298434057fe2a428faaf927ffe6e4b9a98df"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:352025753ef6a83cb9e7f2427319bb7875d1fdda8439d1e23de12ab164179574"},
|
{file = "mypy-1.17.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dd86bb649299f09d987a2eebb4d52d10603224500792e1bee18303bbcc1ce390"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff9fa5b16e4c1364eb89a4d16bcda9987f05d39604e1e6c35378a2987c1aac2d"},
|
{file = "mypy-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a76906f26bd8d51ea9504966a9c25419f2e668f012e0bdf3da4ea1526c534d94"},
|
||||||
{file = "mypy-1.16.1-cp310-cp310-win_amd64.whl", hash = "sha256:1256688e284632382f8f3b9e2123df7d279f603c561f099758e66dd6ed4e8bd6"},
|
{file = "mypy-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:e79311f2d904ccb59787477b7bd5d26f3347789c06fcd7656fa500875290264b"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:472e4e4c100062488ec643f6162dd0d5208e33e2f34544e1fc931372e806c0cc"},
|
{file = "mypy-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ad37544be07c5d7fba814eb370e006df58fed8ad1ef33ed1649cb1889ba6ff58"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea16e2a7d2714277e349e24d19a782a663a34ed60864006e8585db08f8ad1782"},
|
{file = "mypy-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:064e2ff508e5464b4bd807a7c1625bc5047c5022b85c70f030680e18f37273a5"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:08e850ea22adc4d8a4014651575567b0318ede51e8e9fe7a68f25391af699507"},
|
{file = "mypy-1.17.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70401bbabd2fa1aa7c43bb358f54037baf0586f41e83b0ae67dd0534fc64edfd"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:22d76a63a42619bfb90122889b903519149879ddbf2ba4251834727944c8baca"},
|
{file = "mypy-1.17.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e92bdc656b7757c438660f775f872a669b8ff374edc4d18277d86b63edba6b8b"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2c7ce0662b6b9dc8f4ed86eb7a5d505ee3298c04b40ec13b30e572c0e5ae17c4"},
|
{file = "mypy-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c1fdf4abb29ed1cb091cf432979e162c208a5ac676ce35010373ff29247bcad5"},
|
||||||
{file = "mypy-1.16.1-cp311-cp311-win_amd64.whl", hash = "sha256:211287e98e05352a2e1d4e8759c5490925a7c784ddc84207f4714822f8cf99b6"},
|
{file = "mypy-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:ff2933428516ab63f961644bc49bc4cbe42bbffb2cd3b71cc7277c07d16b1a8b"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:af4792433f09575d9eeca5c63d7d90ca4aeceda9d8355e136f80f8967639183d"},
|
{file = "mypy-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:69e83ea6553a3ba79c08c6e15dbd9bfa912ec1e493bf75489ef93beb65209aeb"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:66df38405fd8466ce3517eda1f6640611a0b8e70895e2a9462d1d4323c5eb4b9"},
|
{file = "mypy-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1b16708a66d38abb1e6b5702f5c2c87e133289da36f6a1d15f6a5221085c6403"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44e7acddb3c48bd2713994d098729494117803616e116032af192871aed80b79"},
|
{file = "mypy-1.17.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89e972c0035e9e05823907ad5398c5a73b9f47a002b22359b177d40bdaee7056"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ab5eca37b50188163fa7c1b73c685ac66c4e9bdee4a85c9adac0e91d8895e15"},
|
{file = "mypy-1.17.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03b6d0ed2b188e35ee6d5c36b5580cffd6da23319991c49ab5556c023ccf1341"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb6229b2c9086247e21a83c309754b9058b438704ad2f6807f0d8227f6ebdd"},
|
{file = "mypy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c837b896b37cd103570d776bda106eabb8737aa6dd4f248451aecf53030cdbeb"},
|
||||||
{file = "mypy-1.16.1-cp312-cp312-win_amd64.whl", hash = "sha256:1f0435cf920e287ff68af3d10a118a73f212deb2ce087619eb4e648116d1fe9b"},
|
{file = "mypy-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:665afab0963a4b39dff7c1fa563cc8b11ecff7910206db4b2e64dd1ba25aed19"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ddc91eb318c8751c69ddb200a5937f1232ee8efb4e64e9f4bc475a33719de438"},
|
{file = "mypy-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93378d3203a5c0800c6b6d850ad2f19f7a3cdf1a3701d3416dbf128805c6a6a7"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:87ff2c13d58bdc4bbe7dc0dedfe622c0f04e2cb2a492269f3b418df2de05c536"},
|
{file = "mypy-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15d54056f7fe7a826d897789f53dd6377ec2ea8ba6f776dc83c2902b899fee81"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a7cfb0fe29fe5a9841b7c8ee6dffb52382c45acdf68f032145b75620acfbd6f"},
|
{file = "mypy-1.17.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:209a58fed9987eccc20f2ca94afe7257a8f46eb5df1fb69958650973230f91e6"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:051e1677689c9d9578b9c7f4d206d763f9bbd95723cd1416fad50db49d52f359"},
|
{file = "mypy-1.17.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:099b9a5da47de9e2cb5165e581f158e854d9e19d2e96b6698c0d64de911dd849"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d5d2309511cc56c021b4b4e462907c2b12f669b2dbeb68300110ec27723971be"},
|
{file = "mypy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ffadfbe6994d724c5a1bb6123a7d27dd68fc9c059561cd33b664a79578e14"},
|
||||||
{file = "mypy-1.16.1-cp313-cp313-win_amd64.whl", hash = "sha256:4f58ac32771341e38a853c5d0ec0dfe27e18e27da9cdb8bbc882d2249c71a3ee"},
|
{file = "mypy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:9a2b7d9180aed171f033c9f2fc6c204c1245cf60b0cb61cf2e7acc24eea78e0a"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7fc688329af6a287567f45cc1cefb9db662defeb14625213a5b7da6e692e2069"},
|
{file = "mypy-1.17.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:15a83369400454c41ed3a118e0cc58bd8123921a602f385cb6d6ea5df050c733"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e198ab3f55924c03ead626ff424cad1732d0d391478dfbf7bb97b34602395da"},
|
{file = "mypy-1.17.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:55b918670f692fc9fba55c3298d8a3beae295c5cded0a55dccdc5bbead814acd"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09aa4f91ada245f0a45dbc47e548fd94e0dd5a8433e0114917dc3b526912a30c"},
|
{file = "mypy-1.17.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:62761474061feef6f720149d7ba876122007ddc64adff5ba6f374fda35a018a0"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13c7cd5b1cb2909aa318a90fd1b7e31f17c50b242953e7dd58345b2a814f6383"},
|
{file = "mypy-1.17.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c49562d3d908fd49ed0938e5423daed8d407774a479b595b143a3d7f87cdae6a"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:58e07fb958bc5d752a280da0e890c538f1515b79a65757bbdc54252ba82e0b40"},
|
{file = "mypy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:397fba5d7616a5bc60b45c7ed204717eaddc38f826e3645402c426057ead9a91"},
|
||||||
{file = "mypy-1.16.1-cp39-cp39-win_amd64.whl", hash = "sha256:f895078594d918f93337a505f8add9bd654d1a24962b4c6ed9390e12531eb31b"},
|
{file = "mypy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:9d6b20b97d373f41617bd0708fd46aa656059af57f2ef72aa8c7d6a2b73b74ed"},
|
||||||
{file = "mypy-1.16.1-py3-none-any.whl", hash = "sha256:5fc2ac4027d0ef28d6ba69a0343737a23c4d1b83672bf38d1fe237bdc0643b37"},
|
{file = "mypy-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5d1092694f166a7e56c805caaf794e0585cabdbf1df36911c414e4e9abb62ae9"},
|
||||||
{file = "mypy-1.16.1.tar.gz", hash = "sha256:6bd00a0a2094841c5e47e7374bb42b83d64c527a502e3334e1173a0c24437bab"},
|
{file = "mypy-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79d44f9bfb004941ebb0abe8eff6504223a9c1ac51ef967d1263c6572bbebc99"},
|
||||||
|
{file = "mypy-1.17.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b01586eed696ec905e61bd2568f48740f7ac4a45b3a468e6423a03d3788a51a8"},
|
||||||
|
{file = "mypy-1.17.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43808d9476c36b927fbcd0b0255ce75efe1b68a080154a38ae68a7e62de8f0f8"},
|
||||||
|
{file = "mypy-1.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:feb8cc32d319edd5859da2cc084493b3e2ce5e49a946377663cc90f6c15fb259"},
|
||||||
|
{file = "mypy-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d7598cf74c3e16539d4e2f0b8d8c318e00041553d83d4861f87c7a72e95ac24d"},
|
||||||
|
{file = "mypy-1.17.1-py3-none-any.whl", hash = "sha256:a9f52c0351c21fe24c21d8c0eb1f62967b262d6729393397b6f443c3b773c3b9"},
|
||||||
|
{file = "mypy-1.17.1.tar.gz", hash = "sha256:25e01ec741ab5bb3eec8ba9cdb0f769230368a22c959c4937360efb89b7e9f01"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -1453,18 +1442,18 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy-zope"
|
name = "mypy-zope"
|
||||||
version = "1.0.12"
|
version = "1.0.13"
|
||||||
description = "Plugin for mypy to support zope interfaces"
|
description = "Plugin for mypy to support zope interfaces"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "mypy_zope-1.0.12-py3-none-any.whl", hash = "sha256:f2ecf169f886fbc266e9339db0c2f3818528a7536b9bb4f5ece1d5854dc2f27c"},
|
{file = "mypy_zope-1.0.13-py3-none-any.whl", hash = "sha256:13740c4cbc910cca2c143c6709e1c483c991abeeeb7b629ad6f73d8ac1edad15"},
|
||||||
{file = "mypy_zope-1.0.12.tar.gz", hash = "sha256:d6f8f99eb5644885553b4ec7afc8d68f5daf412c9bf238ec3c36b65d97df6cbe"},
|
{file = "mypy_zope-1.0.13.tar.gz", hash = "sha256:63fb4d035ea874baf280dc69e714dcde4bd2a4a4837a0fd8d90ce91bea510f99"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
mypy = ">=1.0.0,<1.17.0"
|
mypy = ">=1.0.0,<1.18.0"
|
||||||
"zope.interface" = "*"
|
"zope.interface" = "*"
|
||||||
"zope.schema" = "*"
|
"zope.schema" = "*"
|
||||||
|
|
||||||
@@ -1493,7 +1482,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"},
|
||||||
]
|
]
|
||||||
@@ -1542,14 +1531,14 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "phonenumbers"
|
name = "phonenumbers"
|
||||||
version = "9.0.9"
|
version = "9.0.11"
|
||||||
description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
|
description = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
groups = ["main"]
|
groups = ["main"]
|
||||||
files = [
|
files = [
|
||||||
{file = "phonenumbers-9.0.9-py2.py3-none-any.whl", hash = "sha256:13b91aa153f87675902829b38a556bad54824f9c121b89588bbb5fa8550d97ef"},
|
{file = "phonenumbers-9.0.11-py2.py3-none-any.whl", hash = "sha256:a8ebb2136f1f14dfdbadb98be01cb71b96f880dea011eb5e0921967fe3a23abf"},
|
||||||
{file = "phonenumbers-9.0.9.tar.gz", hash = "sha256:c640545019a07e68b0bea57a5fede6eef45c7391165d28935f45615f9a567a5b"},
|
{file = "phonenumbers-9.0.11.tar.gz", hash = "sha256:6573858dcf0a7a2753a071375e154d9fc11791546c699b575af95d2ba7d84a1d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1699,7 +1688,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"},
|
||||||
@@ -1720,7 +1709,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"},
|
||||||
]
|
]
|
||||||
@@ -1736,7 +1725,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"},
|
||||||
]
|
]
|
||||||
@@ -1919,22 +1908,21 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pygithub"
|
name = "pygithub"
|
||||||
version = "2.6.1"
|
version = "2.7.0"
|
||||||
description = "Use the full Github API v3"
|
description = "Use the full Github API v3"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "PyGithub-2.6.1-py3-none-any.whl", hash = "sha256:6f2fa6d076ccae475f9fc392cc6cdbd54db985d4f69b8833a28397de75ed6ca3"},
|
{file = "pygithub-2.7.0-py3-none-any.whl", hash = "sha256:40ecbfe26dc55cc34ab4b0ffa1d455e6f816ef9a2bc8d6f5ad18ce572f163700"},
|
||||||
{file = "pygithub-2.6.1.tar.gz", hash = "sha256:b5c035392991cca63959e9453286b41b54d83bf2de2daa7d7ff7e4312cebf3bf"},
|
{file = "pygithub-2.7.0.tar.gz", hash = "sha256:7cd6eafabb09b5369afba3586d86b1f1ad6f1326d2ff01bc47bb26615dce4cbb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
Deprecated = "*"
|
|
||||||
pyjwt = {version = ">=2.4.0", extras = ["crypto"]}
|
pyjwt = {version = ">=2.4.0", extras = ["crypto"]}
|
||||||
pynacl = ">=1.4.0"
|
pynacl = ">=1.4.0"
|
||||||
requests = ">=2.14.0"
|
requests = ">=2.14.0"
|
||||||
typing-extensions = ">=4.0.0"
|
typing-extensions = ">=4.5.0"
|
||||||
urllib3 = ">=1.26.0"
|
urllib3 = ">=1.26.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1996,7 +1984,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"},
|
||||||
@@ -2056,7 +2044,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"},
|
||||||
@@ -2081,7 +2069,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"},
|
||||||
@@ -2109,7 +2097,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"},
|
||||||
@@ -2408,30 +2396,30 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.12.3"
|
version = "0.12.7"
|
||||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "ruff-0.12.3-py3-none-linux_armv6l.whl", hash = "sha256:47552138f7206454eaf0c4fe827e546e9ddac62c2a3d2585ca54d29a890137a2"},
|
{file = "ruff-0.12.7-py3-none-linux_armv6l.whl", hash = "sha256:76e4f31529899b8c434c3c1dede98c4483b89590e15fb49f2d46183801565303"},
|
||||||
{file = "ruff-0.12.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0a9153b000c6fe169bb307f5bd1b691221c4286c133407b8827c406a55282041"},
|
{file = "ruff-0.12.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:789b7a03e72507c54fb3ba6209e4bb36517b90f1a3569ea17084e3fd295500fb"},
|
||||||
{file = "ruff-0.12.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fa6b24600cf3b750e48ddb6057e901dd5b9aa426e316addb2a1af185a7509882"},
|
{file = "ruff-0.12.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2e1c2a3b8626339bb6369116e7030a4cf194ea48f49b64bb505732a7fce4f4e3"},
|
||||||
{file = "ruff-0.12.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2506961bf6ead54887ba3562604d69cb430f59b42133d36976421bc8bd45901"},
|
{file = "ruff-0.12.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32dec41817623d388e645612ec70d5757a6d9c035f3744a52c7b195a57e03860"},
|
||||||
{file = "ruff-0.12.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c4faaff1f90cea9d3033cbbcdf1acf5d7fb11d8180758feb31337391691f3df0"},
|
{file = "ruff-0.12.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47ef751f722053a5df5fa48d412dbb54d41ab9b17875c6840a58ec63ff0c247c"},
|
||||||
{file = "ruff-0.12.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40dced4a79d7c264389de1c59467d5d5cefd79e7e06d1dfa2c75497b5269a5a6"},
|
{file = "ruff-0.12.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a828a5fc25a3efd3e1ff7b241fd392686c9386f20e5ac90aa9234a5faa12c423"},
|
||||||
{file = "ruff-0.12.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:0262d50ba2767ed0fe212aa7e62112a1dcbfd46b858c5bf7bbd11f326998bafc"},
|
{file = "ruff-0.12.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5726f59b171111fa6a69d82aef48f00b56598b03a22f0f4170664ff4d8298efb"},
|
||||||
{file = "ruff-0.12.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12371aec33e1a3758597c5c631bae9a5286f3c963bdfb4d17acdd2d395406687"},
|
{file = "ruff-0.12.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74e6f5c04c4dd4aba223f4fe6e7104f79e0eebf7d307e4f9b18c18362124bccd"},
|
||||||
{file = "ruff-0.12.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:560f13b6baa49785665276c963edc363f8ad4b4fc910a883e2625bdb14a83a9e"},
|
{file = "ruff-0.12.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d0bfe4e77fba61bf2ccadf8cf005d6133e3ce08793bbe870dd1c734f2699a3e"},
|
||||||
{file = "ruff-0.12.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:023040a3499f6f974ae9091bcdd0385dd9e9eb4942f231c23c57708147b06311"},
|
{file = "ruff-0.12.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06bfb01e1623bf7f59ea749a841da56f8f653d641bfd046edee32ede7ff6c606"},
|
||||||
{file = "ruff-0.12.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:883d844967bffff5ab28bba1a4d246c1a1b2933f48cb9840f3fdc5111c603b07"},
|
{file = "ruff-0.12.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e41df94a957d50083fd09b916d6e89e497246698c3f3d5c681c8b3e7b9bb4ac8"},
|
||||||
{file = "ruff-0.12.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:2120d3aa855ff385e0e562fdee14d564c9675edbe41625c87eeab744a7830d12"},
|
{file = "ruff-0.12.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4000623300563c709458d0ce170c3d0d788c23a058912f28bbadc6f905d67afa"},
|
||||||
{file = "ruff-0.12.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6b16647cbb470eaf4750d27dddc6ebf7758b918887b56d39e9c22cce2049082b"},
|
{file = "ruff-0.12.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:69ffe0e5f9b2cf2b8e289a3f8945b402a1b19eff24ec389f45f23c42a3dd6fb5"},
|
||||||
{file = "ruff-0.12.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e1417051edb436230023575b149e8ff843a324557fe0a265863b7602df86722f"},
|
{file = "ruff-0.12.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a07a5c8ffa2611a52732bdc67bf88e243abd84fe2d7f6daef3826b59abbfeda4"},
|
||||||
{file = "ruff-0.12.3-py3-none-win32.whl", hash = "sha256:dfd45e6e926deb6409d0616078a666ebce93e55e07f0fb0228d4b2608b2c248d"},
|
{file = "ruff-0.12.7-py3-none-win32.whl", hash = "sha256:c928f1b2ec59fb77dfdf70e0419408898b63998789cc98197e15f560b9e77f77"},
|
||||||
{file = "ruff-0.12.3-py3-none-win_amd64.whl", hash = "sha256:a946cf1e7ba3209bdef039eb97647f1c77f6f540e5845ec9c114d3af8df873e7"},
|
{file = "ruff-0.12.7-py3-none-win_amd64.whl", hash = "sha256:9c18f3d707ee9edf89da76131956aba1270c6348bfee8f6c647de841eac7194f"},
|
||||||
{file = "ruff-0.12.3-py3-none-win_arm64.whl", hash = "sha256:5f9c7c9c8f84c2d7f27e93674d27136fbf489720251544c4da7fb3d742e011b1"},
|
{file = "ruff-0.12.7-py3-none-win_arm64.whl", hash = "sha256:dfce05101dbd11833a0776716d5d1578641b7fddb537fe7fa956ab85d1769b69"},
|
||||||
{file = "ruff-0.12.3.tar.gz", hash = "sha256:f1b5a4b6668fd7b7ea3697d8d98857390b40c1320a63a178eee6be0899ea2d77"},
|
{file = "ruff-0.12.7.tar.gz", hash = "sha256:1fc3193f238bc2d7968772c82831a4ff69252f673be371fb49663f0068b7ec71"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2469,15 +2457,15 @@ doc = ["Sphinx", "sphinx-rtd-theme"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sentry-sdk"
|
name = "sentry-sdk"
|
||||||
version = "2.32.0"
|
version = "2.34.1"
|
||||||
description = "Python client for Sentry (https://sentry.io)"
|
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.32.0-py2.py3-none-any.whl", hash = "sha256:6cf51521b099562d7ce3606da928c473643abe99b00ce4cb5626ea735f4ec345"},
|
{file = "sentry_sdk-2.34.1-py2.py3-none-any.whl", hash = "sha256:b7a072e1cdc5abc48101d5146e1ae680fa81fe886d8d95aaa25a0b450c818d32"},
|
||||||
{file = "sentry_sdk-2.32.0.tar.gz", hash = "sha256:9016c75d9316b0f6921ac14c8cd4fb938f26002430ac5be9945ab280f78bec6b"},
|
{file = "sentry_sdk-2.34.1.tar.gz", hash = "sha256:69274eb8c5c38562a544c3e9f68b5be0a43be4b697f5fd385bf98e4fbe672687"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2662,7 +2650,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"},
|
||||||
@@ -2678,7 +2666,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"},
|
||||||
]
|
]
|
||||||
@@ -2740,7 +2728,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"},
|
||||||
@@ -2877,7 +2865,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"},
|
||||||
@@ -2931,14 +2919,14 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-jsonschema"
|
name = "types-jsonschema"
|
||||||
version = "4.24.0.20250708"
|
version = "4.25.0.20250720"
|
||||||
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.24.0.20250708-py3-none-any.whl", hash = "sha256:d574aa3421d178a8435cc898cf4cf5e5e8c8f37b949c8e3ceeff06da433a18bf"},
|
{file = "types_jsonschema-4.25.0.20250720-py3-none-any.whl", hash = "sha256:7d7897c715310d8bf9ae27a2cedba78bbb09e4cad83ce06d2aa79b73a88941df"},
|
||||||
{file = "types_jsonschema-4.24.0.20250708.tar.gz", hash = "sha256:a910e4944681cbb1b18a93ffb502e09910db788314312fc763df08d8ac2aadb7"},
|
{file = "types_jsonschema-4.25.0.20250720.tar.gz", hash = "sha256:765a3b6144798fe3161fd8cbe570a756ed3e8c0e5adb7c09693eb49faad39dbd"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
@@ -2982,14 +2970,14 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-psycopg2"
|
name = "types-psycopg2"
|
||||||
version = "2.9.21.20250516"
|
version = "2.9.21.20250718"
|
||||||
description = "Typing stubs for psycopg2"
|
description = "Typing stubs for psycopg2"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "types_psycopg2-2.9.21.20250516-py3-none-any.whl", hash = "sha256:2a9212d1e5e507017b31486ce8147634d06b85d652769d7a2d91d53cb4edbd41"},
|
{file = "types_psycopg2-2.9.21.20250718-py3-none-any.whl", hash = "sha256:bcf085d4293bda48f5943a46dadf0389b2f98f7e8007722f7e1c12ee0f541858"},
|
||||||
{file = "types_psycopg2-2.9.21.20250516.tar.gz", hash = "sha256:6721018279175cce10b9582202e2a2b4a0da667857ccf82a97691bdb5ecd610f"},
|
{file = "types_psycopg2-2.9.21.20250718.tar.gz", hash = "sha256:dc09a97272ef67e739e57b9f4740b761208f4514257e311c0b05c8c7a37d04b4"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3010,14 +2998,14 @@ types-cffi = "*"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-pyyaml"
|
name = "types-pyyaml"
|
||||||
version = "6.0.12.20250516"
|
version = "6.0.12.20250809"
|
||||||
description = "Typing stubs for PyYAML"
|
description = "Typing stubs for PyYAML"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "types_pyyaml-6.0.12.20250516-py3-none-any.whl", hash = "sha256:8478208feaeb53a34cb5d970c56a7cd76b72659442e733e268a94dc72b2d0530"},
|
{file = "types_pyyaml-6.0.12.20250809-py3-none-any.whl", hash = "sha256:032b6003b798e7de1a1ddfeefee32fac6486bdfe4845e0ae0e7fb3ee4512b52f"},
|
||||||
{file = "types_pyyaml-6.0.12.20250516.tar.gz", hash = "sha256:9f21a70216fc0fa1b216a8176db5f9e0af6eb35d2f2932acb87689d03a5bf6ba"},
|
{file = "types_pyyaml-6.0.12.20250809.tar.gz", hash = "sha256:af4a1aca028f18e75297da2ee0da465f799627370d74073e96fee876524f61b5"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3037,14 +3025,14 @@ urllib3 = ">=2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-setuptools"
|
name = "types-setuptools"
|
||||||
version = "80.9.0.20250529"
|
version = "80.9.0.20250809"
|
||||||
description = "Typing stubs for setuptools"
|
description = "Typing stubs for setuptools"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.9"
|
python-versions = ">=3.9"
|
||||||
groups = ["dev"]
|
groups = ["dev"]
|
||||||
files = [
|
files = [
|
||||||
{file = "types_setuptools-80.9.0.20250529-py3-none-any.whl", hash = "sha256:00dfcedd73e333a430e10db096e4d46af93faf9314f832f13b6bbe3d6757e95f"},
|
{file = "types_setuptools-80.9.0.20250809-py3-none-any.whl", hash = "sha256:7c6539b4c7ac7b4ab4db2be66d8a58fb1e28affa3ee3834be48acafd94f5976a"},
|
||||||
{file = "types_setuptools-80.9.0.20250529.tar.gz", hash = "sha256:79e088ba0cba2186c8d6499cbd3e143abb142d28a44b042c28d3148b1e353c91"},
|
{file = "types_setuptools-80.9.0.20250809.tar.gz", hash = "sha256:e986ba37ffde364073d76189e1d79d9928fb6f5278c7d07589cde353d0218864"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3116,91 +3104,6 @@ files = [
|
|||||||
{file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
|
{file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "wrapt"
|
|
||||||
version = "1.15.0"
|
|
||||||
description = "Module for decorators, wrappers and monkey patching."
|
|
||||||
optional = false
|
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
|
||||||
groups = ["dev"]
|
|
||||||
files = [
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"},
|
|
||||||
{file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"},
|
|
||||||
{file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"},
|
|
||||||
{file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"},
|
|
||||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"},
|
|
||||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"},
|
|
||||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"},
|
|
||||||
{file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"},
|
|
||||||
{file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"},
|
|
||||||
{file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"},
|
|
||||||
{file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"},
|
|
||||||
{file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"},
|
|
||||||
{file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"},
|
|
||||||
{file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"},
|
|
||||||
{file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"},
|
|
||||||
{file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xmlschema"
|
name = "xmlschema"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
@@ -3208,7 +3111,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"},
|
||||||
@@ -3352,4 +3255,4 @@ url-preview = ["lxml"]
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = "^3.9.0"
|
python-versions = "^3.9.0"
|
||||||
content-hash = "a6965a294ca751ec2b5b0b92a050acc9afd4efb3e58550845dd32c60b74a70d1"
|
content-hash = "600a349d08dde732df251583094a121b5385eb43ae0c6ceff10dcf9749359446"
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ module-name = "synapse.synapse_rust"
|
|||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "matrix-synapse"
|
name = "matrix-synapse"
|
||||||
version = "1.134.0"
|
version = "1.136.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"
|
||||||
@@ -178,8 +178,13 @@ signedjson = "^1.1.0"
|
|||||||
service-identity = ">=18.1.0"
|
service-identity = ">=18.1.0"
|
||||||
# Twisted 18.9 introduces some logger improvements that the structured
|
# Twisted 18.9 introduces some logger improvements that the structured
|
||||||
# logger utilises
|
# logger utilises
|
||||||
Twisted = {extras = ["tls"], version = ">=18.9.0"}
|
# Twisted 19.7.0 moves test helpers to a new module and deprecates the old location.
|
||||||
treq = ">=15.1"
|
# Twisted 21.2.0 introduces contextvar support.
|
||||||
|
# We could likely bump this to 22.1 without making distro packagers'
|
||||||
|
# lives hard (as of 2025-07, distro support is Ubuntu LTS: 22.1, Debian stable: 22.4,
|
||||||
|
# RHEL 9: 22.10)
|
||||||
|
Twisted = {extras = ["tls"], version = ">=21.2.0"}
|
||||||
|
treq = ">=21.5.0"
|
||||||
# Twisted has required pyopenssl 16.0 since about Twisted 16.6.
|
# Twisted has required pyopenssl 16.0 since about Twisted 16.6.
|
||||||
pyOpenSSL = ">=16.0.0"
|
pyOpenSSL = ">=16.0.0"
|
||||||
PyYAML = ">=5.3"
|
PyYAML = ">=5.3"
|
||||||
@@ -319,7 +324,7 @@ all = [
|
|||||||
# failing on new releases. Keeping lower bounds loose here means that dependabot
|
# failing on new releases. Keeping lower bounds loose here means that dependabot
|
||||||
# can bump versions without having to update the content-hash in the lockfile.
|
# can bump versions without having to update the content-hash in the lockfile.
|
||||||
# This helps prevents merge conflicts when running a batch of dependabot updates.
|
# This helps prevents merge conflicts when running a batch of dependabot updates.
|
||||||
ruff = "0.12.3"
|
ruff = "0.12.7"
|
||||||
# Type checking only works with the pydantic.v1 compat module from pydantic v2
|
# Type checking only works with the pydantic.v1 compat module from pydantic v2
|
||||||
pydantic = "^2"
|
pydantic = "^2"
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ name = "synapse"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.81.0"
|
rust-version = "1.82.0"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "synapse"
|
name = "synapse"
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ fn bench_match_exact(b: &mut Bencher) {
|
|||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -71,10 +72,10 @@ fn bench_match_exact(b: &mut Bencher) {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
let matched = eval.match_condition(&condition, None, None).unwrap();
|
let matched = eval.match_condition(&condition, None, None, None).unwrap();
|
||||||
assert!(matched, "Didn't match");
|
assert!(matched, "Didn't match");
|
||||||
|
|
||||||
b.iter(|| eval.match_condition(&condition, None, None).unwrap());
|
b.iter(|| eval.match_condition(&condition, None, None, None).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -107,6 +108,7 @@ fn bench_match_word(b: &mut Bencher) {
|
|||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -117,10 +119,10 @@ fn bench_match_word(b: &mut Bencher) {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
let matched = eval.match_condition(&condition, None, None).unwrap();
|
let matched = eval.match_condition(&condition, None, None, None).unwrap();
|
||||||
assert!(matched, "Didn't match");
|
assert!(matched, "Didn't match");
|
||||||
|
|
||||||
b.iter(|| eval.match_condition(&condition, None, None).unwrap());
|
b.iter(|| eval.match_condition(&condition, None, None, None).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -153,6 +155,7 @@ fn bench_match_word_miss(b: &mut Bencher) {
|
|||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -163,10 +166,10 @@ fn bench_match_word_miss(b: &mut Bencher) {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
let matched = eval.match_condition(&condition, None, None).unwrap();
|
let matched = eval.match_condition(&condition, None, None, None).unwrap();
|
||||||
assert!(!matched, "Didn't match");
|
assert!(!matched, "Didn't match");
|
||||||
|
|
||||||
b.iter(|| eval.match_condition(&condition, None, None).unwrap());
|
b.iter(|| eval.match_condition(&condition, None, None, None).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
@@ -199,6 +202,7 @@ fn bench_eval_message(b: &mut Bencher) {
|
|||||||
vec![],
|
vec![],
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -210,7 +214,8 @@ fn bench_eval_message(b: &mut Bencher) {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
b.iter(|| eval.run(&rules, Some("bob"), Some("person")));
|
b.iter(|| eval.run(&rules, Some("bob"), Some("person"), None));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ enum EventInternalMetadataData {
|
|||||||
RecheckRedaction(bool),
|
RecheckRedaction(bool),
|
||||||
SoftFailed(bool),
|
SoftFailed(bool),
|
||||||
ProactivelySend(bool),
|
ProactivelySend(bool),
|
||||||
|
PolicyServerSpammy(bool),
|
||||||
Redacted(bool),
|
Redacted(bool),
|
||||||
TxnId(Box<str>),
|
TxnId(Box<str>),
|
||||||
TokenId(i64),
|
TokenId(i64),
|
||||||
@@ -96,6 +97,13 @@ impl EventInternalMetadataData {
|
|||||||
.to_owned()
|
.to_owned()
|
||||||
.into_any(),
|
.into_any(),
|
||||||
),
|
),
|
||||||
|
EventInternalMetadataData::PolicyServerSpammy(o) => (
|
||||||
|
pyo3::intern!(py, "policy_server_spammy"),
|
||||||
|
o.into_pyobject(py)
|
||||||
|
.unwrap_infallible()
|
||||||
|
.to_owned()
|
||||||
|
.into_any(),
|
||||||
|
),
|
||||||
EventInternalMetadataData::Redacted(o) => (
|
EventInternalMetadataData::Redacted(o) => (
|
||||||
pyo3::intern!(py, "redacted"),
|
pyo3::intern!(py, "redacted"),
|
||||||
o.into_pyobject(py)
|
o.into_pyobject(py)
|
||||||
@@ -155,6 +163,11 @@ impl EventInternalMetadataData {
|
|||||||
.extract()
|
.extract()
|
||||||
.with_context(|| format!("'{key_str}' has invalid type"))?,
|
.with_context(|| format!("'{key_str}' has invalid type"))?,
|
||||||
),
|
),
|
||||||
|
"policy_server_spammy" => EventInternalMetadataData::PolicyServerSpammy(
|
||||||
|
value
|
||||||
|
.extract()
|
||||||
|
.with_context(|| format!("'{key_str}' has invalid type"))?,
|
||||||
|
),
|
||||||
"redacted" => EventInternalMetadataData::Redacted(
|
"redacted" => EventInternalMetadataData::Redacted(
|
||||||
value
|
value
|
||||||
.extract()
|
.extract()
|
||||||
@@ -427,6 +440,17 @@ impl EventInternalMetadata {
|
|||||||
set_property!(self, ProactivelySend, obj);
|
set_property!(self, ProactivelySend, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn get_policy_server_spammy(&self) -> PyResult<bool> {
|
||||||
|
Ok(get_property_opt!(self, PolicyServerSpammy)
|
||||||
|
.copied()
|
||||||
|
.unwrap_or(false))
|
||||||
|
}
|
||||||
|
#[setter]
|
||||||
|
fn set_policy_server_spammy(&mut self, obj: bool) {
|
||||||
|
set_property!(self, PolicyServerSpammy, obj);
|
||||||
|
}
|
||||||
|
|
||||||
#[getter]
|
#[getter]
|
||||||
fn get_redacted(&self) -> PyResult<bool> {
|
fn get_redacted(&self) -> PyResult<bool> {
|
||||||
let bool = get_property!(self, Redacted)?;
|
let bool = get_property!(self, Redacted)?;
|
||||||
|
|||||||
@@ -290,6 +290,26 @@ pub const BASE_APPEND_CONTENT_RULES: &[PushRule] = &[PushRule {
|
|||||||
}];
|
}];
|
||||||
|
|
||||||
pub const BASE_APPEND_UNDERRIDE_RULES: &[PushRule] = &[
|
pub const BASE_APPEND_UNDERRIDE_RULES: &[PushRule] = &[
|
||||||
|
PushRule {
|
||||||
|
rule_id: Cow::Borrowed("global/content/.io.element.msc4306.rule.unsubscribed_thread"),
|
||||||
|
priority_class: 1,
|
||||||
|
conditions: Cow::Borrowed(&[Condition::Known(
|
||||||
|
KnownCondition::Msc4306ThreadSubscription { subscribed: false },
|
||||||
|
)]),
|
||||||
|
actions: Cow::Borrowed(&[]),
|
||||||
|
default: true,
|
||||||
|
default_enabled: true,
|
||||||
|
},
|
||||||
|
PushRule {
|
||||||
|
rule_id: Cow::Borrowed("global/content/.io.element.msc4306.rule.subscribed_thread"),
|
||||||
|
priority_class: 1,
|
||||||
|
conditions: Cow::Borrowed(&[Condition::Known(
|
||||||
|
KnownCondition::Msc4306ThreadSubscription { subscribed: true },
|
||||||
|
)]),
|
||||||
|
actions: Cow::Borrowed(&[Action::Notify, SOUND_ACTION]),
|
||||||
|
default: true,
|
||||||
|
default_enabled: true,
|
||||||
|
},
|
||||||
PushRule {
|
PushRule {
|
||||||
rule_id: Cow::Borrowed("global/underride/.m.rule.call"),
|
rule_id: Cow::Borrowed("global/underride/.m.rule.call"),
|
||||||
priority_class: 1,
|
priority_class: 1,
|
||||||
|
|||||||
@@ -106,8 +106,11 @@ pub struct PushRuleEvaluator {
|
|||||||
/// flag as MSC1767 (extensible events core).
|
/// flag as MSC1767 (extensible events core).
|
||||||
msc3931_enabled: bool,
|
msc3931_enabled: bool,
|
||||||
|
|
||||||
// If MSC4210 (remove legacy mentions) is enabled.
|
/// If MSC4210 (remove legacy mentions) is enabled.
|
||||||
msc4210_enabled: bool,
|
msc4210_enabled: bool,
|
||||||
|
|
||||||
|
/// If MSC4306 (thread subscriptions) is enabled.
|
||||||
|
msc4306_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
@@ -126,6 +129,7 @@ impl PushRuleEvaluator {
|
|||||||
room_version_feature_flags,
|
room_version_feature_flags,
|
||||||
msc3931_enabled,
|
msc3931_enabled,
|
||||||
msc4210_enabled,
|
msc4210_enabled,
|
||||||
|
msc4306_enabled,
|
||||||
))]
|
))]
|
||||||
pub fn py_new(
|
pub fn py_new(
|
||||||
flattened_keys: BTreeMap<String, JsonValue>,
|
flattened_keys: BTreeMap<String, JsonValue>,
|
||||||
@@ -138,6 +142,7 @@ impl PushRuleEvaluator {
|
|||||||
room_version_feature_flags: Vec<String>,
|
room_version_feature_flags: Vec<String>,
|
||||||
msc3931_enabled: bool,
|
msc3931_enabled: bool,
|
||||||
msc4210_enabled: bool,
|
msc4210_enabled: bool,
|
||||||
|
msc4306_enabled: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let body = match flattened_keys.get("content.body") {
|
let body = match flattened_keys.get("content.body") {
|
||||||
Some(JsonValue::Value(SimpleJsonValue::Str(s))) => s.clone().into_owned(),
|
Some(JsonValue::Value(SimpleJsonValue::Str(s))) => s.clone().into_owned(),
|
||||||
@@ -156,6 +161,7 @@ impl PushRuleEvaluator {
|
|||||||
room_version_feature_flags,
|
room_version_feature_flags,
|
||||||
msc3931_enabled,
|
msc3931_enabled,
|
||||||
msc4210_enabled,
|
msc4210_enabled,
|
||||||
|
msc4306_enabled,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,12 +173,19 @@ impl PushRuleEvaluator {
|
|||||||
///
|
///
|
||||||
/// Returns the set of actions, if any, that match (filtering out any
|
/// Returns the set of actions, if any, that match (filtering out any
|
||||||
/// `dont_notify` and `coalesce` actions).
|
/// `dont_notify` and `coalesce` actions).
|
||||||
#[pyo3(signature = (push_rules, user_id=None, display_name=None))]
|
///
|
||||||
|
/// msc4306_thread_subscription_state: (Only populated if MSC4306 is enabled)
|
||||||
|
/// The thread subscription state corresponding to the thread containing this event.
|
||||||
|
/// - `None` if the event is not in a thread, or if MSC4306 is disabled.
|
||||||
|
/// - `Some(true)` if the event is in a thread and the user has a subscription for that thread
|
||||||
|
/// - `Some(false)` if the event is in a thread and the user does NOT have a subscription for that thread
|
||||||
|
#[pyo3(signature = (push_rules, user_id=None, display_name=None, msc4306_thread_subscription_state=None))]
|
||||||
pub fn run(
|
pub fn run(
|
||||||
&self,
|
&self,
|
||||||
push_rules: &FilteredPushRules,
|
push_rules: &FilteredPushRules,
|
||||||
user_id: Option<&str>,
|
user_id: Option<&str>,
|
||||||
display_name: Option<&str>,
|
display_name: Option<&str>,
|
||||||
|
msc4306_thread_subscription_state: Option<bool>,
|
||||||
) -> Vec<Action> {
|
) -> Vec<Action> {
|
||||||
'outer: for (push_rule, enabled) in push_rules.iter() {
|
'outer: for (push_rule, enabled) in push_rules.iter() {
|
||||||
if !enabled {
|
if !enabled {
|
||||||
@@ -204,7 +217,12 @@ impl PushRuleEvaluator {
|
|||||||
Condition::Known(KnownCondition::RoomVersionSupports { feature: _ }),
|
Condition::Known(KnownCondition::RoomVersionSupports { feature: _ }),
|
||||||
);
|
);
|
||||||
|
|
||||||
match self.match_condition(condition, user_id, display_name) {
|
match self.match_condition(
|
||||||
|
condition,
|
||||||
|
user_id,
|
||||||
|
display_name,
|
||||||
|
msc4306_thread_subscription_state,
|
||||||
|
) {
|
||||||
Ok(true) => {}
|
Ok(true) => {}
|
||||||
Ok(false) => continue 'outer,
|
Ok(false) => continue 'outer,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -237,14 +255,20 @@ impl PushRuleEvaluator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the given condition matches.
|
/// Check if the given condition matches.
|
||||||
#[pyo3(signature = (condition, user_id=None, display_name=None))]
|
#[pyo3(signature = (condition, user_id=None, display_name=None, msc4306_thread_subscription_state=None))]
|
||||||
fn matches(
|
fn matches(
|
||||||
&self,
|
&self,
|
||||||
condition: Condition,
|
condition: Condition,
|
||||||
user_id: Option<&str>,
|
user_id: Option<&str>,
|
||||||
display_name: Option<&str>,
|
display_name: Option<&str>,
|
||||||
|
msc4306_thread_subscription_state: Option<bool>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match self.match_condition(&condition, user_id, display_name) {
|
match self.match_condition(
|
||||||
|
&condition,
|
||||||
|
user_id,
|
||||||
|
display_name,
|
||||||
|
msc4306_thread_subscription_state,
|
||||||
|
) {
|
||||||
Ok(true) => true,
|
Ok(true) => true,
|
||||||
Ok(false) => false,
|
Ok(false) => false,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -262,6 +286,7 @@ impl PushRuleEvaluator {
|
|||||||
condition: &Condition,
|
condition: &Condition,
|
||||||
user_id: Option<&str>,
|
user_id: Option<&str>,
|
||||||
display_name: Option<&str>,
|
display_name: Option<&str>,
|
||||||
|
msc4306_thread_subscription_state: Option<bool>,
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
let known_condition = match condition {
|
let known_condition = match condition {
|
||||||
Condition::Known(known) => known,
|
Condition::Known(known) => known,
|
||||||
@@ -393,6 +418,13 @@ impl PushRuleEvaluator {
|
|||||||
&& self.room_version_feature_flags.contains(&flag)
|
&& self.room_version_feature_flags.contains(&flag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
KnownCondition::Msc4306ThreadSubscription { subscribed } => {
|
||||||
|
if !self.msc4306_enabled {
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
msc4306_thread_subscription_state == Some(*subscribed)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
@@ -536,10 +568,11 @@ fn push_rule_evaluator() {
|
|||||||
vec![],
|
vec![],
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let result = evaluator.run(&FilteredPushRules::default(), None, Some("bob"));
|
let result = evaluator.run(&FilteredPushRules::default(), None, Some("bob"), None);
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,6 +599,7 @@ fn test_requires_room_version_supports_condition() {
|
|||||||
flags,
|
flags,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -575,6 +609,7 @@ fn test_requires_room_version_supports_condition() {
|
|||||||
&FilteredPushRules::default(),
|
&FilteredPushRules::default(),
|
||||||
Some("@bob:example.org"),
|
Some("@bob:example.org"),
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
assert_eq!(result.len(), 3);
|
assert_eq!(result.len(), 3);
|
||||||
|
|
||||||
@@ -593,7 +628,17 @@ fn test_requires_room_version_supports_condition() {
|
|||||||
};
|
};
|
||||||
let rules = PushRules::new(vec![custom_rule]);
|
let rules = PushRules::new(vec![custom_rule]);
|
||||||
result = evaluator.run(
|
result = evaluator.run(
|
||||||
&FilteredPushRules::py_new(rules, BTreeMap::new(), true, false, true, false, false),
|
&FilteredPushRules::py_new(
|
||||||
|
rules,
|
||||||
|
BTreeMap::new(),
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -369,6 +369,10 @@ pub enum KnownCondition {
|
|||||||
RoomVersionSupports {
|
RoomVersionSupports {
|
||||||
feature: Cow<'static, str>,
|
feature: Cow<'static, str>,
|
||||||
},
|
},
|
||||||
|
#[serde(rename = "io.element.msc4306.thread_subscription")]
|
||||||
|
Msc4306ThreadSubscription {
|
||||||
|
subscribed: bool,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'source> IntoPyObject<'source> for Condition {
|
impl<'source> IntoPyObject<'source> for Condition {
|
||||||
@@ -547,11 +551,13 @@ pub struct FilteredPushRules {
|
|||||||
msc3664_enabled: bool,
|
msc3664_enabled: bool,
|
||||||
msc4028_push_encrypted_events: bool,
|
msc4028_push_encrypted_events: bool,
|
||||||
msc4210_enabled: bool,
|
msc4210_enabled: bool,
|
||||||
|
msc4306_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl FilteredPushRules {
|
impl FilteredPushRules {
|
||||||
#[new]
|
#[new]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn py_new(
|
pub fn py_new(
|
||||||
push_rules: PushRules,
|
push_rules: PushRules,
|
||||||
enabled_map: BTreeMap<String, bool>,
|
enabled_map: BTreeMap<String, bool>,
|
||||||
@@ -560,6 +566,7 @@ impl FilteredPushRules {
|
|||||||
msc3664_enabled: bool,
|
msc3664_enabled: bool,
|
||||||
msc4028_push_encrypted_events: bool,
|
msc4028_push_encrypted_events: bool,
|
||||||
msc4210_enabled: bool,
|
msc4210_enabled: bool,
|
||||||
|
msc4306_enabled: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
push_rules,
|
push_rules,
|
||||||
@@ -569,6 +576,7 @@ impl FilteredPushRules {
|
|||||||
msc3664_enabled,
|
msc3664_enabled,
|
||||||
msc4028_push_encrypted_events,
|
msc4028_push_encrypted_events,
|
||||||
msc4210_enabled,
|
msc4210_enabled,
|
||||||
|
msc4306_enabled,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,6 +627,10 @@ impl FilteredPushRules {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.msc4306_enabled && rule.rule_id.contains("/.io.element.msc4306.rule.") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
})
|
})
|
||||||
.map(|r| {
|
.map(|r| {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
$schema: https://element-hq.github.io/synapse/latest/schema/v1/meta.schema.json
|
$schema: https://element-hq.github.io/synapse/latest/schema/v1/meta.schema.json
|
||||||
$id: https://element-hq.github.io/synapse/schema/synapse/v1.134/synapse-config.schema.json
|
$id: https://element-hq.github.io/synapse/schema/synapse/v1.136/synapse-config.schema.json
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
modules:
|
modules:
|
||||||
@@ -656,6 +656,43 @@ properties:
|
|||||||
- - master.hostname.example.com
|
- - master.hostname.example.com
|
||||||
- 10.1.0.0/16
|
- 10.1.0.0/16
|
||||||
- 172.30.0.0/16
|
- 172.30.0.0/16
|
||||||
|
matrix_authentication_service:
|
||||||
|
type: object
|
||||||
|
description: >-
|
||||||
|
The `matrix_authentication_service` setting configures integration with
|
||||||
|
[Matrix Authentication Service (MAS)](https://github.com/element-hq/matrix-authentication-service).
|
||||||
|
properties:
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
description: >-
|
||||||
|
Whether or not to enable the MAS integration. If this is set to
|
||||||
|
`false`, Synapse will use its legacy internal authentication API.
|
||||||
|
default: false
|
||||||
|
|
||||||
|
endpoint:
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
description: >-
|
||||||
|
The URL where Synapse can reach MAS. This *must* have the `discovery`
|
||||||
|
and `oauth` resources mounted.
|
||||||
|
default: http://localhost:8080
|
||||||
|
|
||||||
|
secret:
|
||||||
|
type: ["string", "null"]
|
||||||
|
description: >-
|
||||||
|
A shared secret that will be used to authenticate requests from and to MAS.
|
||||||
|
|
||||||
|
secret_path:
|
||||||
|
type: ["string", "null"]
|
||||||
|
description: >-
|
||||||
|
Alternative to `secret`, reading the shared secret from a file.
|
||||||
|
The file should be a plain text file, containing only the secret.
|
||||||
|
Synapse reads the secret from the given file once at startup.
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- enabled: true
|
||||||
|
secret: someverysecuresecret
|
||||||
|
endpoint: http://localhost:8080
|
||||||
dummy_events_threshold:
|
dummy_events_threshold:
|
||||||
type: integer
|
type: integer
|
||||||
description: >-
|
description: >-
|
||||||
@@ -2228,6 +2265,17 @@ properties:
|
|||||||
examples:
|
examples:
|
||||||
- per_second: 2.0
|
- per_second: 2.0
|
||||||
burst_count: 20.0
|
burst_count: 20.0
|
||||||
|
rc_room_creation:
|
||||||
|
$ref: "#/$defs/rc"
|
||||||
|
description: >-
|
||||||
|
Sets rate limits for how often users are able to create rooms.
|
||||||
|
default:
|
||||||
|
per_user:
|
||||||
|
per_second: 0.016
|
||||||
|
burst_count: 10.0
|
||||||
|
examples:
|
||||||
|
- per_second: 1.0
|
||||||
|
burst_count: 5.0
|
||||||
federation_rr_transactions_per_room_per_second:
|
federation_rr_transactions_per_room_per_second:
|
||||||
type: integer
|
type: integer
|
||||||
description: >-
|
description: >-
|
||||||
@@ -5136,7 +5184,7 @@ properties:
|
|||||||
|
|
||||||
"m.room.avatar": 50
|
"m.room.avatar": 50
|
||||||
|
|
||||||
"m.room.tombstone": 100
|
"m.room.tombstone": 100 (150 if MSC4289 is used)
|
||||||
|
|
||||||
"m.room.server_acl": 100
|
"m.room.server_acl": 100
|
||||||
|
|
||||||
|
|||||||
@@ -473,6 +473,10 @@ def section(prop: str, values: dict) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
# For Windows: reconfigure the terminal to be UTF-8 for `print()` calls.
|
||||||
|
if sys.platform == "win32":
|
||||||
|
sys.stdout.reconfigure(encoding="utf-8")
|
||||||
|
|
||||||
def usage(err_msg: str) -> int:
|
def usage(err_msg: str) -> int:
|
||||||
script_name = (sys.argv[:1] or ["__main__.py"])[0]
|
script_name = (sys.argv[:1] or ["__main__.py"])[0]
|
||||||
print(err_msg, file=sys.stderr)
|
print(err_msg, file=sys.stderr)
|
||||||
@@ -485,7 +489,10 @@ def main() -> None:
|
|||||||
exit(usage("Too many arguments."))
|
exit(usage("Too many arguments."))
|
||||||
if not (filepath := (sys.argv[1:] or [""])[0]):
|
if not (filepath := (sys.argv[1:] or [""])[0]):
|
||||||
exit(usage("No schema file provided."))
|
exit(usage("No schema file provided."))
|
||||||
with open(filepath) as f:
|
with open(filepath, "r", encoding="utf-8") as f:
|
||||||
|
# Note: Windows requires that we specify the encoding otherwise it uses
|
||||||
|
# things like CP-1251, which can cause explosions.
|
||||||
|
# See https://github.com/yaml/pyyaml/issues/123 for more info.
|
||||||
return yaml.safe_load(f)
|
return yaml.safe_load(f)
|
||||||
|
|
||||||
schema = read_json_file_arg()
|
schema = read_json_file_arg()
|
||||||
|
|||||||
@@ -23,28 +23,195 @@
|
|||||||
can crop up, e.g the cache descriptors.
|
can crop up, e.g the cache descriptors.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Callable, Optional, Tuple, Type, Union
|
import enum
|
||||||
|
from typing import Callable, Mapping, Optional, Tuple, Type, Union
|
||||||
|
|
||||||
|
import attr
|
||||||
import mypy.types
|
import mypy.types
|
||||||
from mypy.erasetype import remove_instance_last_known_values
|
from mypy.erasetype import remove_instance_last_known_values
|
||||||
from mypy.errorcodes import ErrorCode
|
from mypy.errorcodes import ErrorCode
|
||||||
from mypy.nodes import ARG_NAMED_OPT, TempNode, Var
|
from mypy.nodes import ARG_NAMED_OPT, ListExpr, NameExpr, TempNode, TupleExpr, Var
|
||||||
from mypy.plugin import FunctionSigContext, MethodSigContext, Plugin
|
from mypy.plugin import (
|
||||||
|
ClassDefContext,
|
||||||
|
Context,
|
||||||
|
FunctionLike,
|
||||||
|
FunctionSigContext,
|
||||||
|
MethodSigContext,
|
||||||
|
MypyFile,
|
||||||
|
Plugin,
|
||||||
|
)
|
||||||
from mypy.typeops import bind_self
|
from mypy.typeops import bind_self
|
||||||
from mypy.types import (
|
from mypy.types import (
|
||||||
AnyType,
|
AnyType,
|
||||||
CallableType,
|
CallableType,
|
||||||
Instance,
|
Instance,
|
||||||
NoneType,
|
NoneType,
|
||||||
|
Options,
|
||||||
TupleType,
|
TupleType,
|
||||||
TypeAliasType,
|
TypeAliasType,
|
||||||
TypeVarType,
|
TypeVarType,
|
||||||
UninhabitedType,
|
UninhabitedType,
|
||||||
UnionType,
|
UnionType,
|
||||||
)
|
)
|
||||||
|
from mypy_zope import plugin as mypy_zope_plugin
|
||||||
|
from pydantic.mypy import plugin as mypy_pydantic_plugin
|
||||||
|
|
||||||
|
PROMETHEUS_METRIC_MISSING_SERVER_NAME_LABEL = ErrorCode(
|
||||||
|
"missing-server-name-label",
|
||||||
|
"`SERVER_NAME_LABEL` required in metric",
|
||||||
|
category="per-homeserver-tenant-metrics",
|
||||||
|
)
|
||||||
|
|
||||||
|
PROMETHEUS_METRIC_MISSING_FROM_LIST_TO_CHECK = ErrorCode(
|
||||||
|
"metric-type-missing-from-list",
|
||||||
|
"Every Prometheus metric type must be included in the `prometheus_metric_fullname_to_label_arg_map`.",
|
||||||
|
category="per-homeserver-tenant-metrics",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Sentinel(enum.Enum):
|
||||||
|
# defining a sentinel in this way allows mypy to correctly handle the
|
||||||
|
# type of a dictionary lookup and subsequent type narrowing.
|
||||||
|
UNSET_SENTINEL = object()
|
||||||
|
|
||||||
|
|
||||||
|
@attr.s(auto_attribs=True)
|
||||||
|
class ArgLocation:
|
||||||
|
keyword_name: str
|
||||||
|
"""
|
||||||
|
The keyword argument name for this argument
|
||||||
|
"""
|
||||||
|
position: int
|
||||||
|
"""
|
||||||
|
The 0-based positional index of this argument
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
prometheus_metric_fullname_to_label_arg_map: Mapping[str, Optional[ArgLocation]] = {
|
||||||
|
# `Collector` subclasses:
|
||||||
|
"prometheus_client.metrics.MetricWrapperBase": ArgLocation("labelnames", 2),
|
||||||
|
"prometheus_client.metrics.Counter": ArgLocation("labelnames", 2),
|
||||||
|
"prometheus_client.metrics.Histogram": ArgLocation("labelnames", 2),
|
||||||
|
"prometheus_client.metrics.Gauge": ArgLocation("labelnames", 2),
|
||||||
|
"prometheus_client.metrics.Summary": ArgLocation("labelnames", 2),
|
||||||
|
"prometheus_client.metrics.Info": ArgLocation("labelnames", 2),
|
||||||
|
"prometheus_client.metrics.Enum": ArgLocation("labelnames", 2),
|
||||||
|
"synapse.metrics.LaterGauge": ArgLocation("labelnames", 2),
|
||||||
|
"synapse.metrics.InFlightGauge": ArgLocation("labels", 2),
|
||||||
|
"synapse.metrics.GaugeBucketCollector": ArgLocation("labelnames", 2),
|
||||||
|
"prometheus_client.registry.Collector": None,
|
||||||
|
"prometheus_client.registry._EmptyCollector": None,
|
||||||
|
"prometheus_client.registry.CollectorRegistry": None,
|
||||||
|
"prometheus_client.process_collector.ProcessCollector": None,
|
||||||
|
"prometheus_client.platform_collector.PlatformCollector": None,
|
||||||
|
"prometheus_client.gc_collector.GCCollector": None,
|
||||||
|
"synapse.metrics._gc.GCCounts": None,
|
||||||
|
"synapse.metrics._gc.PyPyGCStats": None,
|
||||||
|
"synapse.metrics._reactor_metrics.ReactorLastSeenMetric": None,
|
||||||
|
"synapse.metrics.CPUMetrics": None,
|
||||||
|
"synapse.metrics.jemalloc.JemallocCollector": None,
|
||||||
|
"synapse.util.metrics.DynamicCollectorRegistry": None,
|
||||||
|
"synapse.metrics.background_process_metrics._Collector": None,
|
||||||
|
#
|
||||||
|
# `Metric` subclasses:
|
||||||
|
"prometheus_client.metrics_core.Metric": None,
|
||||||
|
"prometheus_client.metrics_core.UnknownMetricFamily": ArgLocation("labels", 3),
|
||||||
|
"prometheus_client.metrics_core.CounterMetricFamily": ArgLocation("labels", 3),
|
||||||
|
"prometheus_client.metrics_core.GaugeMetricFamily": ArgLocation("labels", 3),
|
||||||
|
"prometheus_client.metrics_core.SummaryMetricFamily": ArgLocation("labels", 3),
|
||||||
|
"prometheus_client.metrics_core.InfoMetricFamily": ArgLocation("labels", 3),
|
||||||
|
"prometheus_client.metrics_core.HistogramMetricFamily": ArgLocation("labels", 3),
|
||||||
|
"prometheus_client.metrics_core.GaugeHistogramMetricFamily": ArgLocation(
|
||||||
|
"labels", 4
|
||||||
|
),
|
||||||
|
"prometheus_client.metrics_core.StateSetMetricFamily": ArgLocation("labels", 3),
|
||||||
|
"synapse.metrics.GaugeHistogramMetricFamilyWithLabels": ArgLocation(
|
||||||
|
"labelnames", 4
|
||||||
|
),
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
Map from the fullname of the Prometheus `Metric`/`Collector` classes to the keyword
|
||||||
|
argument name and positional index of the label names. This map is useful because
|
||||||
|
different metrics have different signatures for passing in label names and we just need
|
||||||
|
to know where to look.
|
||||||
|
|
||||||
|
This map should include any metrics that we collect with Prometheus. Which corresponds
|
||||||
|
to anything that inherits from `prometheus_client.registry.Collector`
|
||||||
|
(`synapse.metrics._types.Collector`) or `prometheus_client.metrics_core.Metric`. The
|
||||||
|
exhaustiveness of this list is enforced by `analyze_prometheus_metric_classes`.
|
||||||
|
|
||||||
|
The entries with `None` always fail the lint because they don't have a `labelnames`
|
||||||
|
argument (therefore, no `SERVER_NAME_LABEL`), but we include them here so that people
|
||||||
|
can notice and manually allow via a type ignore comment as the source of truth
|
||||||
|
should be in the source code.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Unbound at this point because we don't know the mypy version yet.
|
||||||
|
# This is set in the `plugin(...)` function below.
|
||||||
|
MypyPydanticPluginClass: Type[Plugin]
|
||||||
|
MypyZopePluginClass: Type[Plugin]
|
||||||
|
|
||||||
|
|
||||||
class SynapsePlugin(Plugin):
|
class SynapsePlugin(Plugin):
|
||||||
|
def __init__(self, options: Options):
|
||||||
|
super().__init__(options)
|
||||||
|
self.mypy_pydantic_plugin = MypyPydanticPluginClass(options)
|
||||||
|
self.mypy_zope_plugin = MypyZopePluginClass(options)
|
||||||
|
|
||||||
|
def set_modules(self, modules: dict[str, MypyFile]) -> None:
|
||||||
|
"""
|
||||||
|
This is called by mypy internals. We have to override this to ensure it's also
|
||||||
|
called for any other plugins that we're manually handling.
|
||||||
|
|
||||||
|
Here is how mypy describes it:
|
||||||
|
|
||||||
|
> [`self._modules`] can't be set in `__init__` because it is executed too soon
|
||||||
|
> in `build.py`. Therefore, `build.py` *must* set it later before graph processing
|
||||||
|
> starts by calling `set_modules()`.
|
||||||
|
"""
|
||||||
|
super().set_modules(modules)
|
||||||
|
self.mypy_pydantic_plugin.set_modules(modules)
|
||||||
|
self.mypy_zope_plugin.set_modules(modules)
|
||||||
|
|
||||||
|
def get_base_class_hook(
|
||||||
|
self, fullname: str
|
||||||
|
) -> Optional[Callable[[ClassDefContext], None]]:
|
||||||
|
def _get_base_class_hook(ctx: ClassDefContext) -> None:
|
||||||
|
# Run any `get_base_class_hook` checks from other plugins first.
|
||||||
|
#
|
||||||
|
# Unfortunately, because mypy only chooses the first plugin that returns a
|
||||||
|
# non-None value (known-limitation, c.f.
|
||||||
|
# https://github.com/python/mypy/issues/19524), we workaround this by
|
||||||
|
# putting our custom plugin first in the plugin order and then calling the
|
||||||
|
# other plugin's hook manually followed by our own checks.
|
||||||
|
if callback := self.mypy_pydantic_plugin.get_base_class_hook(fullname):
|
||||||
|
callback(ctx)
|
||||||
|
if callback := self.mypy_zope_plugin.get_base_class_hook(fullname):
|
||||||
|
callback(ctx)
|
||||||
|
|
||||||
|
# Now run our own checks
|
||||||
|
analyze_prometheus_metric_classes(ctx)
|
||||||
|
|
||||||
|
return _get_base_class_hook
|
||||||
|
|
||||||
|
def get_function_signature_hook(
|
||||||
|
self, fullname: str
|
||||||
|
) -> Optional[Callable[[FunctionSigContext], FunctionLike]]:
|
||||||
|
# Strip off the unique identifier for classes that are dynamically created inside
|
||||||
|
# functions. ex. `synapse.metrics.jemalloc.JemallocCollector@185` (this is the line
|
||||||
|
# number)
|
||||||
|
if "@" in fullname:
|
||||||
|
fullname = fullname.split("@", 1)[0]
|
||||||
|
|
||||||
|
# Look for any Prometheus metrics to make sure they have the `SERVER_NAME_LABEL`
|
||||||
|
# label.
|
||||||
|
if fullname in prometheus_metric_fullname_to_label_arg_map.keys():
|
||||||
|
# Because it's difficult to determine the `fullname` of the function in the
|
||||||
|
# callback, let's just pass it in while we have it.
|
||||||
|
return lambda ctx: check_prometheus_metric_instantiation(ctx, fullname)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def get_method_signature_hook(
|
def get_method_signature_hook(
|
||||||
self, fullname: str
|
self, fullname: str
|
||||||
) -> Optional[Callable[[MethodSigContext], CallableType]]:
|
) -> Optional[Callable[[MethodSigContext], CallableType]]:
|
||||||
@@ -65,6 +232,157 @@ class SynapsePlugin(Plugin):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def analyze_prometheus_metric_classes(ctx: ClassDefContext) -> None:
|
||||||
|
"""
|
||||||
|
Cross-check the list of Prometheus metric classes against the
|
||||||
|
`prometheus_metric_fullname_to_label_arg_map` to ensure the list is exhaustive and
|
||||||
|
up-to-date.
|
||||||
|
"""
|
||||||
|
|
||||||
|
fullname = ctx.cls.fullname
|
||||||
|
# Strip off the unique identifier for classes that are dynamically created inside
|
||||||
|
# functions. ex. `synapse.metrics.jemalloc.JemallocCollector@185` (this is the line
|
||||||
|
# number)
|
||||||
|
if "@" in fullname:
|
||||||
|
fullname = fullname.split("@", 1)[0]
|
||||||
|
|
||||||
|
if any(
|
||||||
|
ancestor_type.fullname
|
||||||
|
in (
|
||||||
|
# All of the Prometheus metric classes inherit from the `Collector`.
|
||||||
|
"prometheus_client.registry.Collector",
|
||||||
|
"synapse.metrics._types.Collector",
|
||||||
|
# And custom metrics that inherit from `Metric`.
|
||||||
|
"prometheus_client.metrics_core.Metric",
|
||||||
|
)
|
||||||
|
for ancestor_type in ctx.cls.info.mro
|
||||||
|
):
|
||||||
|
if fullname not in prometheus_metric_fullname_to_label_arg_map:
|
||||||
|
ctx.api.fail(
|
||||||
|
f"Expected {fullname} to be in `prometheus_metric_fullname_to_label_arg_map`, "
|
||||||
|
f"but it was not found. This is a problem with our custom mypy plugin. "
|
||||||
|
f"Please add it to the map.",
|
||||||
|
Context(),
|
||||||
|
code=PROMETHEUS_METRIC_MISSING_FROM_LIST_TO_CHECK,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_prometheus_metric_instantiation(
|
||||||
|
ctx: FunctionSigContext, fullname: str
|
||||||
|
) -> CallableType:
|
||||||
|
"""
|
||||||
|
Ensure that the `prometheus_client` metrics include the `SERVER_NAME_LABEL` label
|
||||||
|
when instantiated.
|
||||||
|
|
||||||
|
This is important because we support multiple Synapse instances running in the same
|
||||||
|
process, where all metrics share a single global `REGISTRY`. The `server_name` label
|
||||||
|
ensures metrics are correctly separated by homeserver.
|
||||||
|
|
||||||
|
There are also some metrics that apply at the process level, such as CPU usage,
|
||||||
|
Python garbage collection, and Twisted reactor tick time, which shouldn't have the
|
||||||
|
`SERVER_NAME_LABEL`. In those cases, use a type ignore comment to disable the
|
||||||
|
check, e.g. `# type: ignore[missing-server-name-label]`.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
ctx: The `FunctionSigContext` from mypy.
|
||||||
|
fullname: The fully qualified name of the function being called,
|
||||||
|
e.g. `"prometheus_client.metrics.Counter"`
|
||||||
|
"""
|
||||||
|
# The true signature, this isn't being modified so this is what will be returned.
|
||||||
|
signature = ctx.default_signature
|
||||||
|
|
||||||
|
# Find where the label names argument is in the function signature.
|
||||||
|
arg_location = prometheus_metric_fullname_to_label_arg_map.get(
|
||||||
|
fullname, Sentinel.UNSET_SENTINEL
|
||||||
|
)
|
||||||
|
assert arg_location is not Sentinel.UNSET_SENTINEL, (
|
||||||
|
f"Expected to find {fullname} in `prometheus_metric_fullname_to_label_arg_map`, "
|
||||||
|
f"but it was not found. This is a problem with our custom mypy plugin. "
|
||||||
|
f"Please add it to the map. Context: {ctx.context}"
|
||||||
|
)
|
||||||
|
# People should be using `# type: ignore[missing-server-name-label]` for
|
||||||
|
# process-level metrics that should not have the `SERVER_NAME_LABEL`.
|
||||||
|
if arg_location is None:
|
||||||
|
ctx.api.fail(
|
||||||
|
f"{signature.name} does not have a `labelnames`/`labels` argument "
|
||||||
|
"(if this is untrue, update `prometheus_metric_fullname_to_label_arg_map` "
|
||||||
|
"in our custom mypy plugin) and should probably have a type ignore comment, "
|
||||||
|
"e.g. `# type: ignore[missing-server-name-label]`. The reason we don't "
|
||||||
|
"automatically ignore this is the source of truth should be in the source code.",
|
||||||
|
ctx.context,
|
||||||
|
code=PROMETHEUS_METRIC_MISSING_SERVER_NAME_LABEL,
|
||||||
|
)
|
||||||
|
return signature
|
||||||
|
|
||||||
|
# Sanity check the arguments are still as expected in this version of
|
||||||
|
# `prometheus_client`. ex. `Counter(name, documentation, labelnames, ...)`
|
||||||
|
#
|
||||||
|
# `signature.arg_names` should be: ["name", "documentation", "labelnames", ...]
|
||||||
|
if (
|
||||||
|
len(signature.arg_names) < (arg_location.position + 1)
|
||||||
|
or signature.arg_names[arg_location.position] != arg_location.keyword_name
|
||||||
|
):
|
||||||
|
ctx.api.fail(
|
||||||
|
f"Expected argument number {arg_location.position + 1} of {signature.name} to be `labelnames`/`labels`, "
|
||||||
|
f"but got {signature.arg_names[arg_location.position]}",
|
||||||
|
ctx.context,
|
||||||
|
)
|
||||||
|
return signature
|
||||||
|
|
||||||
|
# Ensure mypy is passing the correct number of arguments because we are doing some
|
||||||
|
# dirty indexing into `ctx.args` later on.
|
||||||
|
assert len(ctx.args) == len(signature.arg_names), (
|
||||||
|
f"Expected the list of arguments in the {signature.name} signature ({len(signature.arg_names)})"
|
||||||
|
f"to match the number of arguments from the function signature context ({len(ctx.args)})"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check if the `labelnames` argument includes `SERVER_NAME_LABEL`
|
||||||
|
#
|
||||||
|
# `ctx.args` should look like this:
|
||||||
|
# ```
|
||||||
|
# [
|
||||||
|
# [StrExpr("name")],
|
||||||
|
# [StrExpr("documentation")],
|
||||||
|
# [ListExpr([StrExpr("label1"), StrExpr("label2")])]
|
||||||
|
# ...
|
||||||
|
# ]
|
||||||
|
# ```
|
||||||
|
labelnames_arg_expression = (
|
||||||
|
ctx.args[arg_location.position][0]
|
||||||
|
if len(ctx.args[arg_location.position]) > 0
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
if isinstance(labelnames_arg_expression, (ListExpr, TupleExpr)):
|
||||||
|
# Check if the `labelnames` argument includes the `server_name` label (`SERVER_NAME_LABEL`).
|
||||||
|
for labelname_expression in labelnames_arg_expression.items:
|
||||||
|
if (
|
||||||
|
isinstance(labelname_expression, NameExpr)
|
||||||
|
and labelname_expression.fullname == "synapse.metrics.SERVER_NAME_LABEL"
|
||||||
|
):
|
||||||
|
# Found the `SERVER_NAME_LABEL`, all good!
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
ctx.api.fail(
|
||||||
|
f"Expected {signature.name} to include `SERVER_NAME_LABEL` in the list of labels. "
|
||||||
|
"If this is a process-level metric (vs homeserver-level), use a type ignore comment "
|
||||||
|
"to disable this check.",
|
||||||
|
ctx.context,
|
||||||
|
code=PROMETHEUS_METRIC_MISSING_SERVER_NAME_LABEL,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
ctx.api.fail(
|
||||||
|
f"Expected the `labelnames` argument of {signature.name} to be a list of label names "
|
||||||
|
f"(including `SERVER_NAME_LABEL`), but got {labelnames_arg_expression}. "
|
||||||
|
"If this is a process-level metric (vs homeserver-level), use a type ignore comment "
|
||||||
|
"to disable this check.",
|
||||||
|
ctx.context,
|
||||||
|
code=PROMETHEUS_METRIC_MISSING_SERVER_NAME_LABEL,
|
||||||
|
)
|
||||||
|
return signature
|
||||||
|
|
||||||
|
return signature
|
||||||
|
|
||||||
|
|
||||||
def _get_true_return_type(signature: CallableType) -> mypy.types.Type:
|
def _get_true_return_type(signature: CallableType) -> mypy.types.Type:
|
||||||
"""
|
"""
|
||||||
Get the "final" return type of a callable which might return an Awaitable/Deferred.
|
Get the "final" return type of a callable which might return an Awaitable/Deferred.
|
||||||
@@ -372,10 +690,13 @@ def is_cacheable(
|
|||||||
|
|
||||||
|
|
||||||
def plugin(version: str) -> Type[SynapsePlugin]:
|
def plugin(version: str) -> Type[SynapsePlugin]:
|
||||||
|
global MypyPydanticPluginClass, MypyZopePluginClass
|
||||||
# This is the entry point of the plugin, and lets us deal with the fact
|
# This is the entry point of the plugin, and lets us deal with the fact
|
||||||
# that the mypy plugin interface is *not* stable by looking at the version
|
# that the mypy plugin interface is *not* stable by looking at the version
|
||||||
# string.
|
# string.
|
||||||
#
|
#
|
||||||
# However, since we pin the version of mypy Synapse uses in CI, we don't
|
# However, since we pin the version of mypy Synapse uses in CI, we don't
|
||||||
# really care.
|
# really care.
|
||||||
|
MypyPydanticPluginClass = mypy_pydantic_plugin(version)
|
||||||
|
MypyZopePluginClass = mypy_zope_plugin(version)
|
||||||
return SynapsePlugin
|
return SynapsePlugin
|
||||||
|
|||||||
@@ -45,16 +45,6 @@ if py_version < (3, 9):
|
|||||||
|
|
||||||
# Allow using the asyncio reactor via env var.
|
# Allow using the asyncio reactor via env var.
|
||||||
if strtobool(os.environ.get("SYNAPSE_ASYNC_IO_REACTOR", "0")):
|
if strtobool(os.environ.get("SYNAPSE_ASYNC_IO_REACTOR", "0")):
|
||||||
from incremental import Version
|
|
||||||
|
|
||||||
import twisted
|
|
||||||
|
|
||||||
# We need a bugfix that is included in Twisted 21.2.0:
|
|
||||||
# https://twistedmatrix.com/trac/ticket/9787
|
|
||||||
if twisted.version < Version("Twisted", 21, 2, 0):
|
|
||||||
print("Using asyncio reactor requires Twisted>=21.2.0")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
from twisted.internet import asyncioreactor
|
from twisted.internet import asyncioreactor
|
||||||
|
|||||||
@@ -34,9 +34,11 @@ HAS_PYDANTIC_V2: bool = Version(pydantic_version).major == 2
|
|||||||
|
|
||||||
if TYPE_CHECKING or HAS_PYDANTIC_V2:
|
if TYPE_CHECKING or HAS_PYDANTIC_V2:
|
||||||
from pydantic.v1 import (
|
from pydantic.v1 import (
|
||||||
|
AnyHttpUrl,
|
||||||
BaseModel,
|
BaseModel,
|
||||||
Extra,
|
Extra,
|
||||||
Field,
|
Field,
|
||||||
|
FilePath,
|
||||||
MissingError,
|
MissingError,
|
||||||
PydanticValueError,
|
PydanticValueError,
|
||||||
StrictBool,
|
StrictBool,
|
||||||
@@ -48,15 +50,18 @@ if TYPE_CHECKING or HAS_PYDANTIC_V2:
|
|||||||
conint,
|
conint,
|
||||||
constr,
|
constr,
|
||||||
parse_obj_as,
|
parse_obj_as,
|
||||||
|
root_validator,
|
||||||
validator,
|
validator,
|
||||||
)
|
)
|
||||||
from pydantic.v1.error_wrappers import ErrorWrapper
|
from pydantic.v1.error_wrappers import ErrorWrapper
|
||||||
from pydantic.v1.typing import get_args
|
from pydantic.v1.typing import get_args
|
||||||
else:
|
else:
|
||||||
from pydantic import (
|
from pydantic import (
|
||||||
|
AnyHttpUrl,
|
||||||
BaseModel,
|
BaseModel,
|
||||||
Extra,
|
Extra,
|
||||||
Field,
|
Field,
|
||||||
|
FilePath,
|
||||||
MissingError,
|
MissingError,
|
||||||
PydanticValueError,
|
PydanticValueError,
|
||||||
StrictBool,
|
StrictBool,
|
||||||
@@ -68,6 +73,7 @@ else:
|
|||||||
conint,
|
conint,
|
||||||
constr,
|
constr,
|
||||||
parse_obj_as,
|
parse_obj_as,
|
||||||
|
root_validator,
|
||||||
validator,
|
validator,
|
||||||
)
|
)
|
||||||
from pydantic.error_wrappers import ErrorWrapper
|
from pydantic.error_wrappers import ErrorWrapper
|
||||||
@@ -75,6 +81,7 @@ else:
|
|||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
"HAS_PYDANTIC_V2",
|
"HAS_PYDANTIC_V2",
|
||||||
|
"AnyHttpUrl",
|
||||||
"BaseModel",
|
"BaseModel",
|
||||||
"constr",
|
"constr",
|
||||||
"conbytes",
|
"conbytes",
|
||||||
@@ -83,6 +90,7 @@ __all__ = (
|
|||||||
"ErrorWrapper",
|
"ErrorWrapper",
|
||||||
"Extra",
|
"Extra",
|
||||||
"Field",
|
"Field",
|
||||||
|
"FilePath",
|
||||||
"get_args",
|
"get_args",
|
||||||
"MissingError",
|
"MissingError",
|
||||||
"parse_obj_as",
|
"parse_obj_as",
|
||||||
@@ -92,4 +100,5 @@ __all__ = (
|
|||||||
"StrictStr",
|
"StrictStr",
|
||||||
"ValidationError",
|
"ValidationError",
|
||||||
"validator",
|
"validator",
|
||||||
|
"root_validator",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from typing import Any, Callable, Dict, Optional
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
import yaml
|
import yaml
|
||||||
|
from typing_extensions import Never
|
||||||
|
|
||||||
_CONFLICTING_SHARED_SECRET_OPTS_ERROR = """\
|
_CONFLICTING_SHARED_SECRET_OPTS_ERROR = """\
|
||||||
Conflicting options 'registration_shared_secret' and 'registration_shared_secret_path'
|
Conflicting options 'registration_shared_secret' and 'registration_shared_secret_path'
|
||||||
@@ -40,6 +41,10 @@ _NO_SHARED_SECRET_OPTS_ERROR = """\
|
|||||||
No 'registration_shared_secret' or 'registration_shared_secret_path' defined in config.
|
No 'registration_shared_secret' or 'registration_shared_secret_path' defined in config.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
_EMPTY_SHARED_SECRET_PATH_OPTS_ERROR = """\
|
||||||
|
The secret given via `registration_shared_secret_path` must not be empty.
|
||||||
|
"""
|
||||||
|
|
||||||
_DEFAULT_SERVER_URL = "http://localhost:8008"
|
_DEFAULT_SERVER_URL = "http://localhost:8008"
|
||||||
|
|
||||||
|
|
||||||
@@ -170,6 +175,12 @@ def register_new_user(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def bail(err_msg: str) -> Never:
|
||||||
|
"""Prints the given message to stderr and exits."""
|
||||||
|
print(err_msg, file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
logging.captureWarnings(True)
|
logging.captureWarnings(True)
|
||||||
|
|
||||||
@@ -262,15 +273,20 @@ def main() -> None:
|
|||||||
assert config is not None
|
assert config is not None
|
||||||
|
|
||||||
secret = config.get("registration_shared_secret")
|
secret = config.get("registration_shared_secret")
|
||||||
|
if not isinstance(secret, (str, type(None))):
|
||||||
|
bail("registration_shared_secret is not a string.")
|
||||||
secret_file = config.get("registration_shared_secret_path")
|
secret_file = config.get("registration_shared_secret_path")
|
||||||
if secret_file:
|
if not isinstance(secret_file, (str, type(None))):
|
||||||
if secret:
|
bail("registration_shared_secret_path is not a string.")
|
||||||
print(_CONFLICTING_SHARED_SECRET_OPTS_ERROR, file=sys.stderr)
|
|
||||||
sys.exit(1)
|
if not secret and not secret_file:
|
||||||
|
bail(_NO_SHARED_SECRET_OPTS_ERROR)
|
||||||
|
elif secret and secret_file:
|
||||||
|
bail(_CONFLICTING_SHARED_SECRET_OPTS_ERROR)
|
||||||
|
elif not secret and secret_file:
|
||||||
secret = _read_file(secret_file, "registration_shared_secret_path").strip()
|
secret = _read_file(secret_file, "registration_shared_secret_path").strip()
|
||||||
if not secret:
|
if not secret:
|
||||||
print(_NO_SHARED_SECRET_OPTS_ERROR, file=sys.stderr)
|
bail(_EMPTY_SHARED_SECRET_PATH_OPTS_ERROR)
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if args.password_file:
|
if args.password_file:
|
||||||
password = _read_file(args.password_file, "password-file").strip()
|
password = _read_file(args.password_file, "password-file").strip()
|
||||||
|
|||||||
@@ -29,19 +29,21 @@ import attr
|
|||||||
|
|
||||||
from synapse.config._base import (
|
from synapse.config._base import (
|
||||||
Config,
|
Config,
|
||||||
|
ConfigError,
|
||||||
RootConfig,
|
RootConfig,
|
||||||
find_config_files,
|
find_config_files,
|
||||||
read_config_files,
|
read_config_files,
|
||||||
)
|
)
|
||||||
from synapse.config.database import DatabaseConfig
|
from synapse.config.database import DatabaseConfig
|
||||||
|
from synapse.config.server import ServerConfig
|
||||||
from synapse.storage.database import DatabasePool, LoggingTransaction, make_conn
|
from synapse.storage.database import DatabasePool, LoggingTransaction, make_conn
|
||||||
from synapse.storage.engines import create_engine
|
from synapse.storage.engines import create_engine
|
||||||
|
|
||||||
|
|
||||||
class ReviewConfig(RootConfig):
|
class ReviewConfig(RootConfig):
|
||||||
"A config class that just pulls out the database config"
|
"A config class that just pulls out the server and database config"
|
||||||
|
|
||||||
config_classes = [DatabaseConfig]
|
config_classes = [ServerConfig, DatabaseConfig]
|
||||||
|
|
||||||
|
|
||||||
@attr.s(auto_attribs=True)
|
@attr.s(auto_attribs=True)
|
||||||
@@ -148,6 +150,10 @@ def main() -> None:
|
|||||||
config_dict = read_config_files(config_files)
|
config_dict = read_config_files(config_files)
|
||||||
config.parse_config_dict(config_dict, "", "")
|
config.parse_config_dict(config_dict, "", "")
|
||||||
|
|
||||||
|
server_name = config.server.server_name
|
||||||
|
if not isinstance(server_name, str):
|
||||||
|
raise ConfigError("Must be a string", ("server_name",))
|
||||||
|
|
||||||
since_ms = time.time() * 1000 - Config.parse_duration(config_args.since)
|
since_ms = time.time() * 1000 - Config.parse_duration(config_args.since)
|
||||||
exclude_users_with_email = config_args.exclude_emails
|
exclude_users_with_email = config_args.exclude_emails
|
||||||
exclude_users_with_appservice = config_args.exclude_app_service
|
exclude_users_with_appservice = config_args.exclude_app_service
|
||||||
@@ -159,7 +165,12 @@ def main() -> None:
|
|||||||
|
|
||||||
engine = create_engine(database_config.config)
|
engine = create_engine(database_config.config)
|
||||||
|
|
||||||
with make_conn(database_config, engine, "review_recent_signups") as db_conn:
|
with make_conn(
|
||||||
|
db_config=database_config,
|
||||||
|
engine=engine,
|
||||||
|
default_txn_name="review_recent_signups",
|
||||||
|
server_name=server_name,
|
||||||
|
) as db_conn:
|
||||||
# This generates a type of Cursor, not LoggingTransaction.
|
# This generates a type of Cursor, not LoggingTransaction.
|
||||||
user_infos = get_recent_users(
|
user_infos = get_recent_users(
|
||||||
db_conn.cursor(),
|
db_conn.cursor(),
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ BOOLEAN_COLUMNS = {
|
|||||||
"has_known_state",
|
"has_known_state",
|
||||||
"is_encrypted",
|
"is_encrypted",
|
||||||
],
|
],
|
||||||
|
"thread_subscriptions": ["subscribed", "automatic"],
|
||||||
"users": ["shadow_banned", "approved", "locked", "suspended"],
|
"users": ["shadow_banned", "approved", "locked", "suspended"],
|
||||||
"un_partial_stated_event_stream": ["rejection_status_changed"],
|
"un_partial_stated_event_stream": ["rejection_status_changed"],
|
||||||
"users_who_share_rooms": ["share_private"],
|
"users_who_share_rooms": ["share_private"],
|
||||||
@@ -671,8 +672,14 @@ class Porter:
|
|||||||
engine = create_engine(db_config.config)
|
engine = create_engine(db_config.config)
|
||||||
|
|
||||||
hs = MockHomeserver(self.hs_config)
|
hs = MockHomeserver(self.hs_config)
|
||||||
|
server_name = hs.hostname
|
||||||
|
|
||||||
with make_conn(db_config, engine, "portdb") as db_conn:
|
with make_conn(
|
||||||
|
db_config=db_config,
|
||||||
|
engine=engine,
|
||||||
|
default_txn_name="portdb",
|
||||||
|
server_name=server_name,
|
||||||
|
) as db_conn:
|
||||||
engine.check_database(
|
engine.check_database(
|
||||||
db_conn, allow_outdated_version=allow_outdated_version
|
db_conn, allow_outdated_version=allow_outdated_version
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class MockHomeserver(HomeServer):
|
|||||||
|
|
||||||
|
|
||||||
def run_background_updates(hs: HomeServer) -> None:
|
def run_background_updates(hs: HomeServer) -> None:
|
||||||
|
server_name = hs.hostname
|
||||||
main = hs.get_datastores().main
|
main = hs.get_datastores().main
|
||||||
state = hs.get_datastores().state
|
state = hs.get_datastores().state
|
||||||
|
|
||||||
@@ -66,7 +67,11 @@ def run_background_updates(hs: HomeServer) -> None:
|
|||||||
def run() -> None:
|
def run() -> None:
|
||||||
# Apply all background updates on the database.
|
# Apply all background updates on the database.
|
||||||
defer.ensureDeferred(
|
defer.ensureDeferred(
|
||||||
run_as_background_process("background_updates", run_background_updates)
|
run_as_background_process(
|
||||||
|
"background_updates",
|
||||||
|
server_name,
|
||||||
|
run_background_updates,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
reactor.callWhenRunning(run)
|
reactor.callWhenRunning(run)
|
||||||
|
|||||||
@@ -20,10 +20,13 @@
|
|||||||
#
|
#
|
||||||
from typing import TYPE_CHECKING, Optional, Protocol, Tuple
|
from typing import TYPE_CHECKING, Optional, Protocol, Tuple
|
||||||
|
|
||||||
|
from prometheus_client import Histogram
|
||||||
|
|
||||||
from twisted.web.server import Request
|
from twisted.web.server import Request
|
||||||
|
|
||||||
from synapse.appservice import ApplicationService
|
from synapse.appservice import ApplicationService
|
||||||
from synapse.http.site import SynapseRequest
|
from synapse.http.site import SynapseRequest
|
||||||
|
from synapse.metrics import SERVER_NAME_LABEL
|
||||||
from synapse.types import Requester
|
from synapse.types import Requester
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -33,6 +36,13 @@ if TYPE_CHECKING:
|
|||||||
GUEST_DEVICE_ID = "guest_device"
|
GUEST_DEVICE_ID = "guest_device"
|
||||||
|
|
||||||
|
|
||||||
|
introspection_response_timer = Histogram(
|
||||||
|
"synapse_api_auth_delegated_introspection_response",
|
||||||
|
"Time taken to get a response for an introspection request",
|
||||||
|
labelnames=["code", SERVER_NAME_LABEL],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Auth(Protocol):
|
class Auth(Protocol):
|
||||||
"""The interface that an auth provider must implement."""
|
"""The interface that an auth provider must implement."""
|
||||||
|
|
||||||
|
|||||||
@@ -296,4 +296,4 @@ class InternalAuth(BaseAuth):
|
|||||||
Returns:
|
Returns:
|
||||||
True if the user is an admin
|
True if the user is an admin
|
||||||
"""
|
"""
|
||||||
return await self.store.is_server_admin(requester.user)
|
return await self.store.is_server_admin(requester.user.to_string())
|
||||||
|
|||||||
432
synapse/api/auth/mas.py
Normal file
432
synapse/api/auth/mas.py
Normal file
@@ -0,0 +1,432 @@
|
|||||||
|
#
|
||||||
|
# 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>.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
import logging
|
||||||
|
from typing import TYPE_CHECKING, Optional
|
||||||
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
|
from synapse._pydantic_compat import (
|
||||||
|
BaseModel,
|
||||||
|
Extra,
|
||||||
|
StrictBool,
|
||||||
|
StrictInt,
|
||||||
|
StrictStr,
|
||||||
|
ValidationError,
|
||||||
|
)
|
||||||
|
from synapse.api.auth.base import BaseAuth
|
||||||
|
from synapse.api.errors import (
|
||||||
|
AuthError,
|
||||||
|
HttpResponseException,
|
||||||
|
InvalidClientTokenError,
|
||||||
|
SynapseError,
|
||||||
|
UnrecognizedRequestError,
|
||||||
|
)
|
||||||
|
from synapse.http.site import SynapseRequest
|
||||||
|
from synapse.logging.context import PreserveLoggingContext
|
||||||
|
from synapse.logging.opentracing import (
|
||||||
|
active_span,
|
||||||
|
force_tracing,
|
||||||
|
inject_request_headers,
|
||||||
|
start_active_span,
|
||||||
|
)
|
||||||
|
from synapse.metrics import SERVER_NAME_LABEL
|
||||||
|
from synapse.synapse_rust.http_client import HttpClient
|
||||||
|
from synapse.types import JsonDict, Requester, UserID, create_requester
|
||||||
|
from synapse.util import json_decoder
|
||||||
|
from synapse.util.caches.cached_call import RetryOnExceptionCachedCall
|
||||||
|
from synapse.util.caches.response_cache import ResponseCache, ResponseCacheContext
|
||||||
|
|
||||||
|
from . import introspection_response_timer
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from synapse.rest.admin.experimental_features import ExperimentalFeature
|
||||||
|
from synapse.server import HomeServer
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Scope as defined by MSC2967
|
||||||
|
# https://github.com/matrix-org/matrix-spec-proposals/pull/2967
|
||||||
|
SCOPE_MATRIX_API = "urn:matrix:org.matrix.msc2967.client:api:*"
|
||||||
|
SCOPE_MATRIX_DEVICE_PREFIX = "urn:matrix:org.matrix.msc2967.client:device:"
|
||||||
|
|
||||||
|
|
||||||
|
class ServerMetadata(BaseModel):
|
||||||
|
class Config:
|
||||||
|
extra = Extra.allow
|
||||||
|
|
||||||
|
issuer: StrictStr
|
||||||
|
account_management_uri: StrictStr
|
||||||
|
|
||||||
|
|
||||||
|
class IntrospectionResponse(BaseModel):
|
||||||
|
retrieved_at_ms: StrictInt
|
||||||
|
active: StrictBool
|
||||||
|
scope: Optional[StrictStr]
|
||||||
|
username: Optional[StrictStr]
|
||||||
|
sub: Optional[StrictStr]
|
||||||
|
device_id: Optional[StrictStr]
|
||||||
|
expires_in: Optional[StrictInt]
|
||||||
|
|
||||||
|
class Config:
|
||||||
|
extra = Extra.allow
|
||||||
|
|
||||||
|
def get_scope_set(self) -> set[str]:
|
||||||
|
if not self.scope:
|
||||||
|
return set()
|
||||||
|
|
||||||
|
return {token for token in self.scope.split(" ") if token}
|
||||||
|
|
||||||
|
def is_active(self, now_ms: int) -> bool:
|
||||||
|
if not self.active:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Compatibility tokens don't expire and don't have an 'expires_in' field
|
||||||
|
if self.expires_in is None:
|
||||||
|
return True
|
||||||
|
|
||||||
|
absolute_expiry_ms = self.expires_in * 1000 + self.retrieved_at_ms
|
||||||
|
return now_ms < absolute_expiry_ms
|
||||||
|
|
||||||
|
|
||||||
|
class MasDelegatedAuth(BaseAuth):
|
||||||
|
def __init__(self, hs: "HomeServer"):
|
||||||
|
super().__init__(hs)
|
||||||
|
|
||||||
|
self.server_name = hs.hostname
|
||||||
|
self._clock = hs.get_clock()
|
||||||
|
self._config = hs.config.mas
|
||||||
|
|
||||||
|
self._http_client = hs.get_proxied_http_client()
|
||||||
|
self._rust_http_client = HttpClient(
|
||||||
|
reactor=hs.get_reactor(),
|
||||||
|
user_agent=self._http_client.user_agent.decode("utf8"),
|
||||||
|
)
|
||||||
|
self._server_metadata = RetryOnExceptionCachedCall[ServerMetadata](
|
||||||
|
self._load_metadata
|
||||||
|
)
|
||||||
|
self._force_tracing_for_users = hs.config.tracing.force_tracing_for_users
|
||||||
|
|
||||||
|
# # Token Introspection Cache
|
||||||
|
# This remembers what users/devices are represented by which access tokens,
|
||||||
|
# in order to reduce overall system load:
|
||||||
|
# - on Synapse (as requests are relatively expensive)
|
||||||
|
# - on the network
|
||||||
|
# - on MAS
|
||||||
|
#
|
||||||
|
# Since there is no invalidation mechanism currently,
|
||||||
|
# the entries expire after 2 minutes.
|
||||||
|
# This does mean tokens can be treated as valid by Synapse
|
||||||
|
# for longer than reality.
|
||||||
|
#
|
||||||
|
# Ideally, tokens should logically be invalidated in the following circumstances:
|
||||||
|
# - If a session logout happens.
|
||||||
|
# In this case, MAS will delete the device within Synapse
|
||||||
|
# anyway and this is good enough as an invalidation.
|
||||||
|
# - If the client refreshes their token in MAS.
|
||||||
|
# In this case, the device still exists and it's not the end of the world for
|
||||||
|
# the old access token to continue working for a short time.
|
||||||
|
self._introspection_cache: ResponseCache[str] = ResponseCache(
|
||||||
|
clock=self._clock,
|
||||||
|
name="mas_token_introspection",
|
||||||
|
server_name=self.server_name,
|
||||||
|
timeout_ms=120_000,
|
||||||
|
# don't log because the keys are access tokens
|
||||||
|
enable_logging=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _metadata_url(self) -> str:
|
||||||
|
return f"{self._config.endpoint.rstrip('/')}/.well-known/openid-configuration"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def _introspection_endpoint(self) -> str:
|
||||||
|
return f"{self._config.endpoint.rstrip('/')}/oauth2/introspect"
|
||||||
|
|
||||||
|
async def _load_metadata(self) -> ServerMetadata:
|
||||||
|
response = await self._http_client.get_json(self._metadata_url)
|
||||||
|
metadata = ServerMetadata(**response)
|
||||||
|
return metadata
|
||||||
|
|
||||||
|
async def issuer(self) -> str:
|
||||||
|
metadata = await self._server_metadata.get()
|
||||||
|
return metadata.issuer
|
||||||
|
|
||||||
|
async def account_management_url(self) -> str:
|
||||||
|
metadata = await self._server_metadata.get()
|
||||||
|
return metadata.account_management_uri
|
||||||
|
|
||||||
|
async def auth_metadata(self) -> JsonDict:
|
||||||
|
metadata = await self._server_metadata.get()
|
||||||
|
return metadata.dict()
|
||||||
|
|
||||||
|
def is_request_using_the_shared_secret(self, request: SynapseRequest) -> bool:
|
||||||
|
"""
|
||||||
|
Check if the request is using the shared secret.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request: The request to check.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if the request is using the shared secret, False otherwise.
|
||||||
|
"""
|
||||||
|
access_token = self.get_access_token_from_request(request)
|
||||||
|
shared_secret = self._config.secret()
|
||||||
|
if not shared_secret:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return access_token == shared_secret
|
||||||
|
|
||||||
|
async def _introspect_token(
|
||||||
|
self, token: str, cache_context: ResponseCacheContext[str]
|
||||||
|
) -> IntrospectionResponse:
|
||||||
|
"""
|
||||||
|
Send a token to the introspection endpoint and returns the introspection response
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
token: The token to introspect
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
HttpResponseException: If the introspection endpoint returns a non-2xx response
|
||||||
|
ValueError: If the introspection endpoint returns an invalid JSON response
|
||||||
|
JSONDecodeError: If the introspection endpoint returns a non-JSON response
|
||||||
|
Exception: If the HTTP request fails
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The introspection response
|
||||||
|
"""
|
||||||
|
|
||||||
|
# By default, we shouldn't cache the result unless we know it's valid
|
||||||
|
cache_context.should_cache = False
|
||||||
|
raw_headers: dict[str, str] = {
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
"Accept": "application/json",
|
||||||
|
"Authorization": f"Bearer {self._config.secret()}",
|
||||||
|
# Tell MAS that we support reading the device ID as an explicit
|
||||||
|
# value, not encoded in the scope. This is supported by MAS 0.15+
|
||||||
|
"X-MAS-Supports-Device-Id": "1",
|
||||||
|
}
|
||||||
|
|
||||||
|
args = {"token": token, "token_type_hint": "access_token"}
|
||||||
|
body = urlencode(args, True)
|
||||||
|
|
||||||
|
# Do the actual request
|
||||||
|
|
||||||
|
logger.debug("Fetching token from MAS")
|
||||||
|
start_time = self._clock.time()
|
||||||
|
try:
|
||||||
|
with start_active_span("mas-introspect-token"):
|
||||||
|
inject_request_headers(raw_headers)
|
||||||
|
with PreserveLoggingContext():
|
||||||
|
resp_body = await self._rust_http_client.post(
|
||||||
|
url=self._introspection_endpoint,
|
||||||
|
response_limit=1 * 1024 * 1024,
|
||||||
|
headers=raw_headers,
|
||||||
|
request_body=body,
|
||||||
|
)
|
||||||
|
except HttpResponseException as e:
|
||||||
|
end_time = self._clock.time()
|
||||||
|
introspection_response_timer.labels(
|
||||||
|
code=e.code, **{SERVER_NAME_LABEL: self.server_name}
|
||||||
|
).observe(end_time - start_time)
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
end_time = self._clock.time()
|
||||||
|
introspection_response_timer.labels(
|
||||||
|
code="ERR", **{SERVER_NAME_LABEL: self.server_name}
|
||||||
|
).observe(end_time - start_time)
|
||||||
|
raise
|
||||||
|
|
||||||
|
logger.debug("Fetched token from MAS")
|
||||||
|
|
||||||
|
end_time = self._clock.time()
|
||||||
|
introspection_response_timer.labels(
|
||||||
|
code=200, **{SERVER_NAME_LABEL: self.server_name}
|
||||||
|
).observe(end_time - start_time)
|
||||||
|
|
||||||
|
raw_response = json_decoder.decode(resp_body.decode("utf-8"))
|
||||||
|
try:
|
||||||
|
response = IntrospectionResponse(
|
||||||
|
retrieved_at_ms=self._clock.time_msec(),
|
||||||
|
**raw_response,
|
||||||
|
)
|
||||||
|
except ValidationError as e:
|
||||||
|
raise ValueError(
|
||||||
|
"The introspection endpoint returned an invalid JSON response"
|
||||||
|
) from e
|
||||||
|
|
||||||
|
# We had a valid response, so we can cache it
|
||||||
|
cache_context.should_cache = True
|
||||||
|
return response
|
||||||
|
|
||||||
|
async def is_server_admin(self, requester: Requester) -> bool:
|
||||||
|
return "urn:synapse:admin:*" in requester.scope
|
||||||
|
|
||||||
|
async def get_user_by_req(
|
||||||
|
self,
|
||||||
|
request: SynapseRequest,
|
||||||
|
allow_guest: bool = False,
|
||||||
|
allow_expired: bool = False,
|
||||||
|
allow_locked: bool = False,
|
||||||
|
) -> Requester:
|
||||||
|
parent_span = active_span()
|
||||||
|
with start_active_span("get_user_by_req"):
|
||||||
|
access_token = self.get_access_token_from_request(request)
|
||||||
|
|
||||||
|
requester = await self.get_appservice_user(request, access_token)
|
||||||
|
if not requester:
|
||||||
|
requester = await self.get_user_by_access_token(
|
||||||
|
token=access_token,
|
||||||
|
allow_expired=allow_expired,
|
||||||
|
)
|
||||||
|
|
||||||
|
await self._record_request(request, requester)
|
||||||
|
|
||||||
|
request.requester = requester
|
||||||
|
|
||||||
|
if parent_span:
|
||||||
|
if requester.authenticated_entity in self._force_tracing_for_users:
|
||||||
|
# request tracing is enabled for this user, so we need to force it
|
||||||
|
# tracing on for the parent span (which will be the servlet span).
|
||||||
|
#
|
||||||
|
# It's too late for the get_user_by_req span to inherit the setting,
|
||||||
|
# so we also force it on for that.
|
||||||
|
force_tracing()
|
||||||
|
force_tracing(parent_span)
|
||||||
|
parent_span.set_tag(
|
||||||
|
"authenticated_entity", requester.authenticated_entity
|
||||||
|
)
|
||||||
|
parent_span.set_tag("user_id", requester.user.to_string())
|
||||||
|
if requester.device_id is not None:
|
||||||
|
parent_span.set_tag("device_id", requester.device_id)
|
||||||
|
if requester.app_service is not None:
|
||||||
|
parent_span.set_tag("appservice_id", requester.app_service.id)
|
||||||
|
return requester
|
||||||
|
|
||||||
|
async def get_user_by_access_token(
|
||||||
|
self,
|
||||||
|
token: str,
|
||||||
|
allow_expired: bool = False,
|
||||||
|
) -> Requester:
|
||||||
|
try:
|
||||||
|
introspection_result = await self._introspection_cache.wrap(
|
||||||
|
token, self._introspect_token, token, cache_context=True
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
logger.exception("Failed to introspect token")
|
||||||
|
raise SynapseError(503, "Unable to introspect the access token")
|
||||||
|
|
||||||
|
logger.debug("Introspection result: %r", introspection_result)
|
||||||
|
if not introspection_result.is_active(self._clock.time_msec()):
|
||||||
|
raise InvalidClientTokenError("Token is not active")
|
||||||
|
|
||||||
|
# Let's look at the scope
|
||||||
|
scope = introspection_result.get_scope_set()
|
||||||
|
|
||||||
|
# Determine type of user based on presence of particular scopes
|
||||||
|
if SCOPE_MATRIX_API not in scope:
|
||||||
|
raise InvalidClientTokenError(
|
||||||
|
"Token doesn't grant access to the Matrix C-S API"
|
||||||
|
)
|
||||||
|
|
||||||
|
if introspection_result.username is None:
|
||||||
|
raise AuthError(
|
||||||
|
500,
|
||||||
|
"Invalid username claim in the introspection result",
|
||||||
|
)
|
||||||
|
|
||||||
|
user_id = UserID(
|
||||||
|
localpart=introspection_result.username,
|
||||||
|
domain=self.server_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Try to find a user from the username claim
|
||||||
|
user_info = await self.store.get_user_by_id(user_id=user_id.to_string())
|
||||||
|
if user_info is None:
|
||||||
|
raise AuthError(
|
||||||
|
500,
|
||||||
|
"User not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
# MAS will give us the device ID as an explicit value for *compatibility* sessions
|
||||||
|
# If present, we get it from here, if not we get it in the scope for next-gen sessions
|
||||||
|
device_id = introspection_result.device_id
|
||||||
|
if device_id is None:
|
||||||
|
# Find device_ids in scope
|
||||||
|
# We only allow a single device_id in the scope, so we find them all in the
|
||||||
|
# scope list, and raise if there are more than one. The OIDC server should be
|
||||||
|
# the one enforcing valid scopes, so we raise a 500 if we find an invalid scope.
|
||||||
|
device_ids = [
|
||||||
|
tok[len(SCOPE_MATRIX_DEVICE_PREFIX) :]
|
||||||
|
for tok in scope
|
||||||
|
if tok.startswith(SCOPE_MATRIX_DEVICE_PREFIX)
|
||||||
|
]
|
||||||
|
|
||||||
|
if len(device_ids) > 1:
|
||||||
|
raise AuthError(
|
||||||
|
500,
|
||||||
|
"Multiple device IDs in scope",
|
||||||
|
)
|
||||||
|
|
||||||
|
device_id = device_ids[0] if device_ids else None
|
||||||
|
|
||||||
|
if device_id is not None:
|
||||||
|
# Sanity check the device_id
|
||||||
|
if len(device_id) > 255 or len(device_id) < 1:
|
||||||
|
raise AuthError(
|
||||||
|
500,
|
||||||
|
"Invalid device ID in introspection result",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Make sure the device exists. This helps with introspection cache
|
||||||
|
# invalidation: if we log out, the device gets deleted by MAS
|
||||||
|
device = await self.store.get_device(
|
||||||
|
user_id=user_id.to_string(),
|
||||||
|
device_id=device_id,
|
||||||
|
)
|
||||||
|
if device is None:
|
||||||
|
# Invalidate the introspection cache, the device was deleted
|
||||||
|
self._introspection_cache.unset(token)
|
||||||
|
raise InvalidClientTokenError("Token is not active")
|
||||||
|
|
||||||
|
return create_requester(
|
||||||
|
user_id=user_id,
|
||||||
|
device_id=device_id,
|
||||||
|
scope=scope,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def get_user_by_req_experimental_feature(
|
||||||
|
self,
|
||||||
|
request: SynapseRequest,
|
||||||
|
feature: "ExperimentalFeature",
|
||||||
|
allow_guest: bool = False,
|
||||||
|
allow_expired: bool = False,
|
||||||
|
allow_locked: bool = False,
|
||||||
|
) -> Requester:
|
||||||
|
try:
|
||||||
|
requester = await self.get_user_by_req(
|
||||||
|
request,
|
||||||
|
allow_guest=allow_guest,
|
||||||
|
allow_expired=allow_expired,
|
||||||
|
allow_locked=allow_locked,
|
||||||
|
)
|
||||||
|
if await self.store.is_feature_enabled(requester.user.to_string(), feature):
|
||||||
|
return requester
|
||||||
|
|
||||||
|
raise UnrecognizedRequestError(code=404)
|
||||||
|
except (AuthError, InvalidClientTokenError):
|
||||||
|
if feature.is_globally_enabled(self.hs.config):
|
||||||
|
# If its globally enabled then return the auth error
|
||||||
|
raise
|
||||||
|
|
||||||
|
raise UnrecognizedRequestError(code=404)
|
||||||
@@ -28,7 +28,6 @@ from authlib.oauth2.auth import encode_client_secret_basic, encode_client_secret
|
|||||||
from authlib.oauth2.rfc7523 import ClientSecretJWT, PrivateKeyJWT, private_key_jwt_sign
|
from authlib.oauth2.rfc7523 import ClientSecretJWT, PrivateKeyJWT, private_key_jwt_sign
|
||||||
from authlib.oauth2.rfc7662 import IntrospectionToken
|
from authlib.oauth2.rfc7662 import IntrospectionToken
|
||||||
from authlib.oidc.discovery import OpenIDProviderMetadata, get_well_known_url
|
from authlib.oidc.discovery import OpenIDProviderMetadata, get_well_known_url
|
||||||
from prometheus_client import Histogram
|
|
||||||
|
|
||||||
from synapse.api.auth.base import BaseAuth
|
from synapse.api.auth.base import BaseAuth
|
||||||
from synapse.api.errors import (
|
from synapse.api.errors import (
|
||||||
@@ -47,25 +46,21 @@ from synapse.logging.opentracing import (
|
|||||||
inject_request_headers,
|
inject_request_headers,
|
||||||
start_active_span,
|
start_active_span,
|
||||||
)
|
)
|
||||||
|
from synapse.metrics import SERVER_NAME_LABEL
|
||||||
from synapse.synapse_rust.http_client import HttpClient
|
from synapse.synapse_rust.http_client import HttpClient
|
||||||
from synapse.types import Requester, UserID, create_requester
|
from synapse.types import Requester, UserID, create_requester
|
||||||
from synapse.util import json_decoder
|
from synapse.util import json_decoder
|
||||||
from synapse.util.caches.cached_call import RetryOnExceptionCachedCall
|
from synapse.util.caches.cached_call import RetryOnExceptionCachedCall
|
||||||
from synapse.util.caches.response_cache import ResponseCache, ResponseCacheContext
|
from synapse.util.caches.response_cache import ResponseCache, ResponseCacheContext
|
||||||
|
|
||||||
|
from . import introspection_response_timer
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from synapse.rest.admin.experimental_features import ExperimentalFeature
|
from synapse.rest.admin.experimental_features import ExperimentalFeature
|
||||||
from synapse.server import HomeServer
|
from synapse.server import HomeServer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
introspection_response_timer = Histogram(
|
|
||||||
"synapse_api_auth_delegated_introspection_response",
|
|
||||||
"Time taken to get a response for an introspection request",
|
|
||||||
["code"],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Scope as defined by MSC2967
|
# Scope as defined by MSC2967
|
||||||
# https://github.com/matrix-org/matrix-spec-proposals/pull/2967
|
# https://github.com/matrix-org/matrix-spec-proposals/pull/2967
|
||||||
SCOPE_MATRIX_API = "urn:matrix:org.matrix.msc2967.client:api:*"
|
SCOPE_MATRIX_API = "urn:matrix:org.matrix.msc2967.client:api:*"
|
||||||
@@ -341,17 +336,23 @@ class MSC3861DelegatedAuth(BaseAuth):
|
|||||||
)
|
)
|
||||||
except HttpResponseException as e:
|
except HttpResponseException as e:
|
||||||
end_time = self._clock.time()
|
end_time = self._clock.time()
|
||||||
introspection_response_timer.labels(e.code).observe(end_time - start_time)
|
introspection_response_timer.labels(
|
||||||
|
code=e.code, **{SERVER_NAME_LABEL: self.server_name}
|
||||||
|
).observe(end_time - start_time)
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
end_time = self._clock.time()
|
end_time = self._clock.time()
|
||||||
introspection_response_timer.labels("ERR").observe(end_time - start_time)
|
introspection_response_timer.labels(
|
||||||
|
code="ERR", **{SERVER_NAME_LABEL: self.server_name}
|
||||||
|
).observe(end_time - start_time)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
logger.debug("Fetched token from MAS")
|
logger.debug("Fetched token from MAS")
|
||||||
|
|
||||||
end_time = self._clock.time()
|
end_time = self._clock.time()
|
||||||
introspection_response_timer.labels(200).observe(end_time - start_time)
|
introspection_response_timer.labels(
|
||||||
|
code=200, **{SERVER_NAME_LABEL: self.server_name}
|
||||||
|
).observe(end_time - start_time)
|
||||||
|
|
||||||
resp = json_decoder.decode(resp_body.decode("utf-8"))
|
resp = json_decoder.decode(resp_body.decode("utf-8"))
|
||||||
|
|
||||||
@@ -369,6 +370,12 @@ class MSC3861DelegatedAuth(BaseAuth):
|
|||||||
async def is_server_admin(self, requester: Requester) -> bool:
|
async def is_server_admin(self, requester: Requester) -> bool:
|
||||||
return "urn:synapse:admin:*" in requester.scope
|
return "urn:synapse:admin:*" in requester.scope
|
||||||
|
|
||||||
|
def _is_access_token_the_admin_token(self, token: str) -> bool:
|
||||||
|
admin_token = self._admin_token()
|
||||||
|
if admin_token is None:
|
||||||
|
return False
|
||||||
|
return token == admin_token
|
||||||
|
|
||||||
async def get_user_by_req(
|
async def get_user_by_req(
|
||||||
self,
|
self,
|
||||||
request: SynapseRequest,
|
request: SynapseRequest,
|
||||||
@@ -434,7 +441,7 @@ class MSC3861DelegatedAuth(BaseAuth):
|
|||||||
requester = await self.get_user_by_access_token(access_token, allow_expired)
|
requester = await self.get_user_by_access_token(access_token, allow_expired)
|
||||||
|
|
||||||
# Do not record requests from MAS using the virtual `__oidc_admin` user.
|
# Do not record requests from MAS using the virtual `__oidc_admin` user.
|
||||||
if access_token != self._admin_token():
|
if not self._is_access_token_the_admin_token(access_token):
|
||||||
await self._record_request(request, requester)
|
await self._record_request(request, requester)
|
||||||
|
|
||||||
if not allow_guest and requester.is_guest:
|
if not allow_guest and requester.is_guest:
|
||||||
@@ -470,13 +477,25 @@ class MSC3861DelegatedAuth(BaseAuth):
|
|||||||
|
|
||||||
raise UnrecognizedRequestError(code=404)
|
raise UnrecognizedRequestError(code=404)
|
||||||
|
|
||||||
|
def is_request_using_the_admin_token(self, request: SynapseRequest) -> bool:
|
||||||
|
"""
|
||||||
|
Check if the request is using the admin token.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
request: The request to check.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if the request is using the admin token, False otherwise.
|
||||||
|
"""
|
||||||
|
access_token = self.get_access_token_from_request(request)
|
||||||
|
return self._is_access_token_the_admin_token(access_token)
|
||||||
|
|
||||||
async def get_user_by_access_token(
|
async def get_user_by_access_token(
|
||||||
self,
|
self,
|
||||||
token: str,
|
token: str,
|
||||||
allow_expired: bool = False,
|
allow_expired: bool = False,
|
||||||
) -> Requester:
|
) -> Requester:
|
||||||
admin_token = self._admin_token()
|
if self._is_access_token_the_admin_token(token):
|
||||||
if admin_token is not None and token == admin_token:
|
|
||||||
# XXX: This is a temporary solution so that the admin API can be called by
|
# XXX: This is a temporary solution so that the admin API can be called by
|
||||||
# the OIDC provider. This will be removed once we have OIDC client
|
# the OIDC provider. This will be removed once we have OIDC client
|
||||||
# credentials grant support in matrix-authentication-service.
|
# credentials grant support in matrix-authentication-service.
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ MAX_USERID_LENGTH = 255
|
|||||||
# Constant value used for the pseudo-thread which is the main timeline.
|
# Constant value used for the pseudo-thread which is the main timeline.
|
||||||
MAIN_TIMELINE: Final = "main"
|
MAIN_TIMELINE: Final = "main"
|
||||||
|
|
||||||
|
# MAX_INT + 1, so it always trumps any PL in canonical JSON.
|
||||||
|
CREATOR_POWER_LEVEL = 2**53
|
||||||
|
|
||||||
|
|
||||||
class Membership:
|
class Membership:
|
||||||
"""Represents the membership states of a user in a room."""
|
"""Represents the membership states of a user in a room."""
|
||||||
@@ -235,6 +238,8 @@ class EventContentFields:
|
|||||||
#
|
#
|
||||||
# This is deprecated in MSC2175.
|
# This is deprecated in MSC2175.
|
||||||
ROOM_CREATOR: Final = "creator"
|
ROOM_CREATOR: Final = "creator"
|
||||||
|
# MSC4289
|
||||||
|
ADDITIONAL_CREATORS: Final = "additional_creators"
|
||||||
|
|
||||||
# The version of the room for `m.room.create` events.
|
# The version of the room for `m.room.create` events.
|
||||||
ROOM_VERSION: Final = "room_version"
|
ROOM_VERSION: Final = "room_version"
|
||||||
|
|||||||
@@ -140,6 +140,12 @@ class Codes(str, Enum):
|
|||||||
# Part of MSC4155
|
# Part of MSC4155
|
||||||
INVITE_BLOCKED = "ORG.MATRIX.MSC4155.M_INVITE_BLOCKED"
|
INVITE_BLOCKED = "ORG.MATRIX.MSC4155.M_INVITE_BLOCKED"
|
||||||
|
|
||||||
|
# Part of MSC4306: Thread Subscriptions
|
||||||
|
MSC4306_CONFLICTING_UNSUBSCRIPTION = (
|
||||||
|
"IO.ELEMENT.MSC4306.M_CONFLICTING_UNSUBSCRIPTION"
|
||||||
|
)
|
||||||
|
MSC4306_NOT_IN_THREAD = "IO.ELEMENT.MSC4306.M_NOT_IN_THREAD"
|
||||||
|
|
||||||
|
|
||||||
class CodeMessageException(RuntimeError):
|
class CodeMessageException(RuntimeError):
|
||||||
"""An exception with integer code, a message string attributes and optional headers.
|
"""An exception with integer code, a message string attributes and optional headers.
|
||||||
|
|||||||
@@ -36,12 +36,14 @@ class EventFormatVersions:
|
|||||||
ROOM_V1_V2 = 1 # $id:server event id format: used for room v1 and v2
|
ROOM_V1_V2 = 1 # $id:server event id format: used for room v1 and v2
|
||||||
ROOM_V3 = 2 # MSC1659-style $hash event id format: used for room v3
|
ROOM_V3 = 2 # MSC1659-style $hash event id format: used for room v3
|
||||||
ROOM_V4_PLUS = 3 # MSC1884-style $hash format: introduced for room v4
|
ROOM_V4_PLUS = 3 # MSC1884-style $hash format: introduced for room v4
|
||||||
|
ROOM_V11_HYDRA_PLUS = 4 # MSC4291 room IDs as hashes: introduced for room HydraV11
|
||||||
|
|
||||||
|
|
||||||
KNOWN_EVENT_FORMAT_VERSIONS = {
|
KNOWN_EVENT_FORMAT_VERSIONS = {
|
||||||
EventFormatVersions.ROOM_V1_V2,
|
EventFormatVersions.ROOM_V1_V2,
|
||||||
EventFormatVersions.ROOM_V3,
|
EventFormatVersions.ROOM_V3,
|
||||||
EventFormatVersions.ROOM_V4_PLUS,
|
EventFormatVersions.ROOM_V4_PLUS,
|
||||||
|
EventFormatVersions.ROOM_V11_HYDRA_PLUS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -50,6 +52,7 @@ class StateResolutionVersions:
|
|||||||
|
|
||||||
V1 = 1 # room v1 state res
|
V1 = 1 # room v1 state res
|
||||||
V2 = 2 # MSC1442 state res: room v2 and later
|
V2 = 2 # MSC1442 state res: room v2 and later
|
||||||
|
V2_1 = 3 # MSC4297 state res
|
||||||
|
|
||||||
|
|
||||||
class RoomDisposition:
|
class RoomDisposition:
|
||||||
@@ -109,6 +112,10 @@ class RoomVersion:
|
|||||||
msc3931_push_features: Tuple[str, ...] # values from PushRuleRoomFlag
|
msc3931_push_features: Tuple[str, ...] # values from PushRuleRoomFlag
|
||||||
# MSC3757: Restricting who can overwrite a state event
|
# MSC3757: Restricting who can overwrite a state event
|
||||||
msc3757_enabled: bool
|
msc3757_enabled: bool
|
||||||
|
# MSC4289: Creator power enabled
|
||||||
|
msc4289_creator_power_enabled: bool
|
||||||
|
# MSC4291: Room IDs as hashes of the create event
|
||||||
|
msc4291_room_ids_as_hashes: bool
|
||||||
|
|
||||||
|
|
||||||
class RoomVersions:
|
class RoomVersions:
|
||||||
@@ -131,6 +138,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V2 = RoomVersion(
|
V2 = RoomVersion(
|
||||||
"2",
|
"2",
|
||||||
@@ -151,6 +160,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V3 = RoomVersion(
|
V3 = RoomVersion(
|
||||||
"3",
|
"3",
|
||||||
@@ -171,6 +182,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V4 = RoomVersion(
|
V4 = RoomVersion(
|
||||||
"4",
|
"4",
|
||||||
@@ -191,6 +204,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V5 = RoomVersion(
|
V5 = RoomVersion(
|
||||||
"5",
|
"5",
|
||||||
@@ -211,6 +226,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V6 = RoomVersion(
|
V6 = RoomVersion(
|
||||||
"6",
|
"6",
|
||||||
@@ -231,6 +248,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V7 = RoomVersion(
|
V7 = RoomVersion(
|
||||||
"7",
|
"7",
|
||||||
@@ -251,6 +270,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V8 = RoomVersion(
|
V8 = RoomVersion(
|
||||||
"8",
|
"8",
|
||||||
@@ -271,6 +292,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V9 = RoomVersion(
|
V9 = RoomVersion(
|
||||||
"9",
|
"9",
|
||||||
@@ -291,6 +314,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=False,
|
enforce_int_power_levels=False,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V10 = RoomVersion(
|
V10 = RoomVersion(
|
||||||
"10",
|
"10",
|
||||||
@@ -311,6 +336,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=True,
|
enforce_int_power_levels=True,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
MSC1767v10 = RoomVersion(
|
MSC1767v10 = RoomVersion(
|
||||||
# MSC1767 (Extensible Events) based on room version "10"
|
# MSC1767 (Extensible Events) based on room version "10"
|
||||||
@@ -332,6 +359,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=True,
|
enforce_int_power_levels=True,
|
||||||
msc3931_push_features=(PushRuleRoomFlag.EXTENSIBLE_EVENTS,),
|
msc3931_push_features=(PushRuleRoomFlag.EXTENSIBLE_EVENTS,),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
MSC3757v10 = RoomVersion(
|
MSC3757v10 = RoomVersion(
|
||||||
# MSC3757 (Restricting who can overwrite a state event) based on room version "10"
|
# MSC3757 (Restricting who can overwrite a state event) based on room version "10"
|
||||||
@@ -353,6 +382,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=True,
|
enforce_int_power_levels=True,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=True,
|
msc3757_enabled=True,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
V11 = RoomVersion(
|
V11 = RoomVersion(
|
||||||
"11",
|
"11",
|
||||||
@@ -373,6 +404,8 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=True,
|
enforce_int_power_levels=True,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=False,
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
)
|
)
|
||||||
MSC3757v11 = RoomVersion(
|
MSC3757v11 = RoomVersion(
|
||||||
# MSC3757 (Restricting who can overwrite a state event) based on room version "11"
|
# MSC3757 (Restricting who can overwrite a state event) based on room version "11"
|
||||||
@@ -394,6 +427,52 @@ class RoomVersions:
|
|||||||
enforce_int_power_levels=True,
|
enforce_int_power_levels=True,
|
||||||
msc3931_push_features=(),
|
msc3931_push_features=(),
|
||||||
msc3757_enabled=True,
|
msc3757_enabled=True,
|
||||||
|
msc4289_creator_power_enabled=False,
|
||||||
|
msc4291_room_ids_as_hashes=False,
|
||||||
|
)
|
||||||
|
HydraV11 = RoomVersion(
|
||||||
|
"org.matrix.hydra.11",
|
||||||
|
RoomDisposition.UNSTABLE,
|
||||||
|
EventFormatVersions.ROOM_V11_HYDRA_PLUS,
|
||||||
|
StateResolutionVersions.V2_1, # Changed from v11
|
||||||
|
enforce_key_validity=True,
|
||||||
|
special_case_aliases_auth=False,
|
||||||
|
strict_canonicaljson=True,
|
||||||
|
limit_notifications_power_levels=True,
|
||||||
|
implicit_room_creator=True, # Used by MSC3820
|
||||||
|
updated_redaction_rules=True, # Used by MSC3820
|
||||||
|
restricted_join_rule=True,
|
||||||
|
restricted_join_rule_fix=True,
|
||||||
|
knock_join_rule=True,
|
||||||
|
msc3389_relation_redactions=False,
|
||||||
|
knock_restricted_join_rule=True,
|
||||||
|
enforce_int_power_levels=True,
|
||||||
|
msc3931_push_features=(),
|
||||||
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=True, # Changed from v11
|
||||||
|
msc4291_room_ids_as_hashes=True, # Changed from v11
|
||||||
|
)
|
||||||
|
V12 = RoomVersion(
|
||||||
|
"12",
|
||||||
|
RoomDisposition.STABLE,
|
||||||
|
EventFormatVersions.ROOM_V11_HYDRA_PLUS,
|
||||||
|
StateResolutionVersions.V2_1, # Changed from v11
|
||||||
|
enforce_key_validity=True,
|
||||||
|
special_case_aliases_auth=False,
|
||||||
|
strict_canonicaljson=True,
|
||||||
|
limit_notifications_power_levels=True,
|
||||||
|
implicit_room_creator=True, # Used by MSC3820
|
||||||
|
updated_redaction_rules=True, # Used by MSC3820
|
||||||
|
restricted_join_rule=True,
|
||||||
|
restricted_join_rule_fix=True,
|
||||||
|
knock_join_rule=True,
|
||||||
|
msc3389_relation_redactions=False,
|
||||||
|
knock_restricted_join_rule=True,
|
||||||
|
enforce_int_power_levels=True,
|
||||||
|
msc3931_push_features=(),
|
||||||
|
msc3757_enabled=False,
|
||||||
|
msc4289_creator_power_enabled=True, # Changed from v11
|
||||||
|
msc4291_room_ids_as_hashes=True, # Changed from v11
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -411,8 +490,10 @@ KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {
|
|||||||
RoomVersions.V9,
|
RoomVersions.V9,
|
||||||
RoomVersions.V10,
|
RoomVersions.V10,
|
||||||
RoomVersions.V11,
|
RoomVersions.V11,
|
||||||
|
RoomVersions.V12,
|
||||||
RoomVersions.MSC3757v10,
|
RoomVersions.MSC3757v10,
|
||||||
RoomVersions.MSC3757v11,
|
RoomVersions.MSC3757v11,
|
||||||
|
RoomVersions.HydraV11,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ from synapse.http.site import SynapseSite
|
|||||||
from synapse.logging.context import PreserveLoggingContext
|
from synapse.logging.context import PreserveLoggingContext
|
||||||
from synapse.logging.opentracing import init_tracer
|
from synapse.logging.opentracing import init_tracer
|
||||||
from synapse.metrics import install_gc_manager, register_threadpool
|
from synapse.metrics import install_gc_manager, register_threadpool
|
||||||
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
from synapse.metrics.background_process_metrics import run_as_background_process
|
||||||
from synapse.metrics.jemalloc import setup_jemalloc_stats
|
from synapse.metrics.jemalloc import setup_jemalloc_stats
|
||||||
from synapse.module_api.callbacks.spamchecker_callbacks import load_legacy_spam_checkers
|
from synapse.module_api.callbacks.spamchecker_callbacks import load_legacy_spam_checkers
|
||||||
from synapse.module_api.callbacks.third_party_event_rules_callbacks import (
|
from synapse.module_api.callbacks.third_party_event_rules_callbacks import (
|
||||||
@@ -512,6 +512,7 @@ async def start(hs: "HomeServer") -> None:
|
|||||||
Args:
|
Args:
|
||||||
hs: homeserver instance
|
hs: homeserver instance
|
||||||
"""
|
"""
|
||||||
|
server_name = hs.hostname
|
||||||
reactor = hs.get_reactor()
|
reactor = hs.get_reactor()
|
||||||
|
|
||||||
# We want to use a separate thread pool for the resolver so that large
|
# We want to use a separate thread pool for the resolver so that large
|
||||||
@@ -524,22 +525,34 @@ async def start(hs: "HomeServer") -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Register the threadpools with our metrics.
|
# Register the threadpools with our metrics.
|
||||||
register_threadpool("default", reactor.getThreadPool())
|
register_threadpool(
|
||||||
register_threadpool("gai_resolver", resolver_threadpool)
|
name="default", server_name=server_name, threadpool=reactor.getThreadPool()
|
||||||
|
)
|
||||||
|
register_threadpool(
|
||||||
|
name="gai_resolver", server_name=server_name, threadpool=resolver_threadpool
|
||||||
|
)
|
||||||
|
|
||||||
# Set up the SIGHUP machinery.
|
# Set up the SIGHUP machinery.
|
||||||
if hasattr(signal, "SIGHUP"):
|
if hasattr(signal, "SIGHUP"):
|
||||||
|
|
||||||
@wrap_as_background_process("sighup")
|
def handle_sighup(*args: Any, **kwargs: Any) -> "defer.Deferred[None]":
|
||||||
async def handle_sighup(*args: Any, **kwargs: Any) -> None:
|
async def _handle_sighup(*args: Any, **kwargs: Any) -> None:
|
||||||
# Tell systemd our state, if we're using it. This will silently fail if
|
# Tell systemd our state, if we're using it. This will silently fail if
|
||||||
# we're not using systemd.
|
# we're not using systemd.
|
||||||
sdnotify(b"RELOADING=1")
|
sdnotify(b"RELOADING=1")
|
||||||
|
|
||||||
for i, args, kwargs in _sighup_callbacks:
|
for i, args, kwargs in _sighup_callbacks:
|
||||||
i(*args, **kwargs)
|
i(*args, **kwargs)
|
||||||
|
|
||||||
sdnotify(b"READY=1")
|
sdnotify(b"READY=1")
|
||||||
|
|
||||||
|
return run_as_background_process(
|
||||||
|
"sighup",
|
||||||
|
server_name,
|
||||||
|
_handle_sighup,
|
||||||
|
*args,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
|
||||||
# We defer running the sighup handlers until next reactor tick. This
|
# We defer running the sighup handlers until next reactor tick. This
|
||||||
# is so that we're in a sane state, e.g. flushing the logs may fail
|
# is so that we're in a sane state, e.g. flushing the logs may fail
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ from synapse.storage.databases.main.stats import StatsStore
|
|||||||
from synapse.storage.databases.main.stream import StreamWorkerStore
|
from synapse.storage.databases.main.stream import StreamWorkerStore
|
||||||
from synapse.storage.databases.main.tags import TagsWorkerStore
|
from synapse.storage.databases.main.tags import TagsWorkerStore
|
||||||
from synapse.storage.databases.main.task_scheduler import TaskSchedulerWorkerStore
|
from synapse.storage.databases.main.task_scheduler import TaskSchedulerWorkerStore
|
||||||
|
from synapse.storage.databases.main.thread_subscriptions import (
|
||||||
|
ThreadSubscriptionsWorkerStore,
|
||||||
|
)
|
||||||
from synapse.storage.databases.main.transactions import TransactionWorkerStore
|
from synapse.storage.databases.main.transactions import TransactionWorkerStore
|
||||||
from synapse.storage.databases.main.ui_auth import UIAuthWorkerStore
|
from synapse.storage.databases.main.ui_auth import UIAuthWorkerStore
|
||||||
from synapse.storage.databases.main.user_directory import UserDirectoryStore
|
from synapse.storage.databases.main.user_directory import UserDirectoryStore
|
||||||
@@ -132,6 +135,7 @@ class GenericWorkerStore(
|
|||||||
KeyStore,
|
KeyStore,
|
||||||
RoomWorkerStore,
|
RoomWorkerStore,
|
||||||
DirectoryWorkerStore,
|
DirectoryWorkerStore,
|
||||||
|
ThreadSubscriptionsWorkerStore,
|
||||||
PushRulesWorkerStore,
|
PushRulesWorkerStore,
|
||||||
ApplicationServiceTransactionWorkerStore,
|
ApplicationServiceTransactionWorkerStore,
|
||||||
ApplicationServiceWorkerStore,
|
ApplicationServiceWorkerStore,
|
||||||
|
|||||||
@@ -26,7 +26,12 @@ from typing import TYPE_CHECKING, List, Mapping, Sized, Tuple
|
|||||||
|
|
||||||
from prometheus_client import Gauge
|
from prometheus_client import Gauge
|
||||||
|
|
||||||
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
from twisted.internet import defer
|
||||||
|
|
||||||
|
from synapse.metrics import SERVER_NAME_LABEL
|
||||||
|
from synapse.metrics.background_process_metrics import (
|
||||||
|
run_as_background_process,
|
||||||
|
)
|
||||||
from synapse.types import JsonDict
|
from synapse.types import JsonDict
|
||||||
from synapse.util.constants import ONE_HOUR_SECONDS, ONE_MINUTE_SECONDS
|
from synapse.util.constants import ONE_HOUR_SECONDS, ONE_MINUTE_SECONDS
|
||||||
|
|
||||||
@@ -53,138 +58,158 @@ Phone home stats are sent every 3 hours
|
|||||||
_stats_process: List[Tuple[int, "resource.struct_rusage"]] = []
|
_stats_process: List[Tuple[int, "resource.struct_rusage"]] = []
|
||||||
|
|
||||||
# Gauges to expose monthly active user control metrics
|
# Gauges to expose monthly active user control metrics
|
||||||
current_mau_gauge = Gauge("synapse_admin_mau_current", "Current MAU")
|
current_mau_gauge = Gauge(
|
||||||
|
"synapse_admin_mau_current",
|
||||||
|
"Current MAU",
|
||||||
|
labelnames=[SERVER_NAME_LABEL],
|
||||||
|
)
|
||||||
current_mau_by_service_gauge = Gauge(
|
current_mau_by_service_gauge = Gauge(
|
||||||
"synapse_admin_mau_current_mau_by_service",
|
"synapse_admin_mau_current_mau_by_service",
|
||||||
"Current MAU by service",
|
"Current MAU by service",
|
||||||
["app_service"],
|
labelnames=["app_service", SERVER_NAME_LABEL],
|
||||||
|
)
|
||||||
|
max_mau_gauge = Gauge(
|
||||||
|
"synapse_admin_mau_max",
|
||||||
|
"MAU Limit",
|
||||||
|
labelnames=[SERVER_NAME_LABEL],
|
||||||
)
|
)
|
||||||
max_mau_gauge = Gauge("synapse_admin_mau_max", "MAU Limit")
|
|
||||||
registered_reserved_users_mau_gauge = Gauge(
|
registered_reserved_users_mau_gauge = Gauge(
|
||||||
"synapse_admin_mau_registered_reserved_users",
|
"synapse_admin_mau_registered_reserved_users",
|
||||||
"Registered users with reserved threepids",
|
"Registered users with reserved threepids",
|
||||||
|
labelnames=[SERVER_NAME_LABEL],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@wrap_as_background_process("phone_stats_home")
|
def phone_stats_home(
|
||||||
async def phone_stats_home(
|
|
||||||
hs: "HomeServer",
|
hs: "HomeServer",
|
||||||
stats: JsonDict,
|
stats: JsonDict,
|
||||||
stats_process: List[Tuple[int, "resource.struct_rusage"]] = _stats_process,
|
stats_process: List[Tuple[int, "resource.struct_rusage"]] = _stats_process,
|
||||||
) -> None:
|
) -> "defer.Deferred[None]":
|
||||||
"""Collect usage statistics and send them to the configured endpoint.
|
server_name = hs.hostname
|
||||||
|
|
||||||
Args:
|
async def _phone_stats_home(
|
||||||
hs: the HomeServer object to use for gathering usage data.
|
hs: "HomeServer",
|
||||||
stats: the dict in which to store the statistics sent to the configured
|
stats: JsonDict,
|
||||||
endpoint. Mostly used in tests to figure out the data that is supposed to
|
stats_process: List[Tuple[int, "resource.struct_rusage"]] = _stats_process,
|
||||||
be sent.
|
) -> None:
|
||||||
stats_process: statistics about resource usage of the process.
|
"""Collect usage statistics and send them to the configured endpoint.
|
||||||
"""
|
|
||||||
|
|
||||||
logger.info("Gathering stats for reporting")
|
Args:
|
||||||
now = int(hs.get_clock().time())
|
hs: the HomeServer object to use for gathering usage data.
|
||||||
# Ensure the homeserver has started.
|
stats: the dict in which to store the statistics sent to the configured
|
||||||
assert hs.start_time is not None
|
endpoint. Mostly used in tests to figure out the data that is supposed to
|
||||||
uptime = int(now - hs.start_time)
|
be sent.
|
||||||
if uptime < 0:
|
stats_process: statistics about resource usage of the process.
|
||||||
uptime = 0
|
"""
|
||||||
|
|
||||||
#
|
logger.info("Gathering stats for reporting")
|
||||||
# Performance statistics. Keep this early in the function to maintain reliability of `test_performance_100` test.
|
now = int(hs.get_clock().time())
|
||||||
#
|
# Ensure the homeserver has started.
|
||||||
old = stats_process[0]
|
assert hs.start_time is not None
|
||||||
new = (now, resource.getrusage(resource.RUSAGE_SELF))
|
uptime = int(now - hs.start_time)
|
||||||
stats_process[0] = new
|
if uptime < 0:
|
||||||
|
uptime = 0
|
||||||
|
|
||||||
# Get RSS in bytes
|
#
|
||||||
stats["memory_rss"] = new[1].ru_maxrss
|
# Performance statistics. Keep this early in the function to maintain reliability of `test_performance_100` test.
|
||||||
|
#
|
||||||
|
old = stats_process[0]
|
||||||
|
new = (now, resource.getrusage(resource.RUSAGE_SELF))
|
||||||
|
stats_process[0] = new
|
||||||
|
|
||||||
# Get CPU time in % of a single core, not % of all cores
|
# Get RSS in bytes
|
||||||
used_cpu_time = (new[1].ru_utime + new[1].ru_stime) - (
|
stats["memory_rss"] = new[1].ru_maxrss
|
||||||
old[1].ru_utime + old[1].ru_stime
|
|
||||||
)
|
|
||||||
if used_cpu_time == 0 or new[0] == old[0]:
|
|
||||||
stats["cpu_average"] = 0
|
|
||||||
else:
|
|
||||||
stats["cpu_average"] = math.floor(used_cpu_time / (new[0] - old[0]) * 100)
|
|
||||||
|
|
||||||
#
|
# Get CPU time in % of a single core, not % of all cores
|
||||||
# General statistics
|
used_cpu_time = (new[1].ru_utime + new[1].ru_stime) - (
|
||||||
#
|
old[1].ru_utime + old[1].ru_stime
|
||||||
|
|
||||||
store = hs.get_datastores().main
|
|
||||||
common_metrics = await hs.get_common_usage_metrics_manager().get_metrics()
|
|
||||||
|
|
||||||
stats["homeserver"] = hs.config.server.server_name
|
|
||||||
stats["server_context"] = hs.config.server.server_context
|
|
||||||
stats["timestamp"] = now
|
|
||||||
stats["uptime_seconds"] = uptime
|
|
||||||
version = sys.version_info
|
|
||||||
stats["python_version"] = "{}.{}.{}".format(
|
|
||||||
version.major, version.minor, version.micro
|
|
||||||
)
|
|
||||||
stats["total_users"] = await store.count_all_users()
|
|
||||||
|
|
||||||
total_nonbridged_users = await store.count_nonbridged_users()
|
|
||||||
stats["total_nonbridged_users"] = total_nonbridged_users
|
|
||||||
|
|
||||||
daily_user_type_results = await store.count_daily_user_type()
|
|
||||||
for name, count in daily_user_type_results.items():
|
|
||||||
stats["daily_user_type_" + name] = count
|
|
||||||
|
|
||||||
room_count = await store.get_room_count()
|
|
||||||
stats["total_room_count"] = room_count
|
|
||||||
|
|
||||||
stats["daily_active_users"] = common_metrics.daily_active_users
|
|
||||||
stats["monthly_active_users"] = await store.count_monthly_users()
|
|
||||||
daily_active_e2ee_rooms = await store.count_daily_active_e2ee_rooms()
|
|
||||||
stats["daily_active_e2ee_rooms"] = daily_active_e2ee_rooms
|
|
||||||
stats["daily_e2ee_messages"] = await store.count_daily_e2ee_messages()
|
|
||||||
daily_sent_e2ee_messages = await store.count_daily_sent_e2ee_messages()
|
|
||||||
stats["daily_sent_e2ee_messages"] = daily_sent_e2ee_messages
|
|
||||||
stats["daily_active_rooms"] = await store.count_daily_active_rooms()
|
|
||||||
stats["daily_messages"] = await store.count_daily_messages()
|
|
||||||
daily_sent_messages = await store.count_daily_sent_messages()
|
|
||||||
stats["daily_sent_messages"] = daily_sent_messages
|
|
||||||
|
|
||||||
r30v2_results = await store.count_r30v2_users()
|
|
||||||
for name, count in r30v2_results.items():
|
|
||||||
stats["r30v2_users_" + name] = count
|
|
||||||
|
|
||||||
stats["cache_factor"] = hs.config.caches.global_factor
|
|
||||||
stats["event_cache_size"] = hs.config.caches.event_cache_size
|
|
||||||
|
|
||||||
#
|
|
||||||
# Database version
|
|
||||||
#
|
|
||||||
|
|
||||||
# This only reports info about the *main* database.
|
|
||||||
stats["database_engine"] = store.db_pool.engine.module.__name__
|
|
||||||
stats["database_server_version"] = store.db_pool.engine.server_version
|
|
||||||
|
|
||||||
#
|
|
||||||
# Logging configuration
|
|
||||||
#
|
|
||||||
synapse_logger = logging.getLogger("synapse")
|
|
||||||
log_level = synapse_logger.getEffectiveLevel()
|
|
||||||
stats["log_level"] = logging.getLevelName(log_level)
|
|
||||||
|
|
||||||
logger.info(
|
|
||||||
"Reporting stats to %s: %s", hs.config.metrics.report_stats_endpoint, stats
|
|
||||||
)
|
|
||||||
try:
|
|
||||||
await hs.get_proxied_http_client().put_json(
|
|
||||||
hs.config.metrics.report_stats_endpoint, stats
|
|
||||||
)
|
)
|
||||||
except Exception as e:
|
if used_cpu_time == 0 or new[0] == old[0]:
|
||||||
logger.warning("Error reporting stats: %s", e)
|
stats["cpu_average"] = 0
|
||||||
|
else:
|
||||||
|
stats["cpu_average"] = math.floor(used_cpu_time / (new[0] - old[0]) * 100)
|
||||||
|
|
||||||
|
#
|
||||||
|
# General statistics
|
||||||
|
#
|
||||||
|
|
||||||
|
store = hs.get_datastores().main
|
||||||
|
common_metrics = await hs.get_common_usage_metrics_manager().get_metrics()
|
||||||
|
|
||||||
|
stats["homeserver"] = hs.config.server.server_name
|
||||||
|
stats["server_context"] = hs.config.server.server_context
|
||||||
|
stats["timestamp"] = now
|
||||||
|
stats["uptime_seconds"] = uptime
|
||||||
|
version = sys.version_info
|
||||||
|
stats["python_version"] = "{}.{}.{}".format(
|
||||||
|
version.major, version.minor, version.micro
|
||||||
|
)
|
||||||
|
stats["total_users"] = await store.count_all_users()
|
||||||
|
|
||||||
|
total_nonbridged_users = await store.count_nonbridged_users()
|
||||||
|
stats["total_nonbridged_users"] = total_nonbridged_users
|
||||||
|
|
||||||
|
daily_user_type_results = await store.count_daily_user_type()
|
||||||
|
for name, count in daily_user_type_results.items():
|
||||||
|
stats["daily_user_type_" + name] = count
|
||||||
|
|
||||||
|
room_count = await store.get_room_count()
|
||||||
|
stats["total_room_count"] = room_count
|
||||||
|
|
||||||
|
stats["daily_active_users"] = common_metrics.daily_active_users
|
||||||
|
stats["monthly_active_users"] = await store.count_monthly_users()
|
||||||
|
daily_active_e2ee_rooms = await store.count_daily_active_e2ee_rooms()
|
||||||
|
stats["daily_active_e2ee_rooms"] = daily_active_e2ee_rooms
|
||||||
|
stats["daily_e2ee_messages"] = await store.count_daily_e2ee_messages()
|
||||||
|
daily_sent_e2ee_messages = await store.count_daily_sent_e2ee_messages()
|
||||||
|
stats["daily_sent_e2ee_messages"] = daily_sent_e2ee_messages
|
||||||
|
stats["daily_active_rooms"] = await store.count_daily_active_rooms()
|
||||||
|
stats["daily_messages"] = await store.count_daily_messages()
|
||||||
|
daily_sent_messages = await store.count_daily_sent_messages()
|
||||||
|
stats["daily_sent_messages"] = daily_sent_messages
|
||||||
|
|
||||||
|
r30v2_results = await store.count_r30v2_users()
|
||||||
|
for name, count in r30v2_results.items():
|
||||||
|
stats["r30v2_users_" + name] = count
|
||||||
|
|
||||||
|
stats["cache_factor"] = hs.config.caches.global_factor
|
||||||
|
stats["event_cache_size"] = hs.config.caches.event_cache_size
|
||||||
|
|
||||||
|
#
|
||||||
|
# Database version
|
||||||
|
#
|
||||||
|
|
||||||
|
# This only reports info about the *main* database.
|
||||||
|
stats["database_engine"] = store.db_pool.engine.module.__name__
|
||||||
|
stats["database_server_version"] = store.db_pool.engine.server_version
|
||||||
|
|
||||||
|
#
|
||||||
|
# Logging configuration
|
||||||
|
#
|
||||||
|
synapse_logger = logging.getLogger("synapse")
|
||||||
|
log_level = synapse_logger.getEffectiveLevel()
|
||||||
|
stats["log_level"] = logging.getLevelName(log_level)
|
||||||
|
|
||||||
|
logger.info(
|
||||||
|
"Reporting stats to %s: %s", hs.config.metrics.report_stats_endpoint, stats
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
await hs.get_proxied_http_client().put_json(
|
||||||
|
hs.config.metrics.report_stats_endpoint, stats
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning("Error reporting stats: %s", e)
|
||||||
|
|
||||||
|
return run_as_background_process(
|
||||||
|
"phone_stats_home", server_name, _phone_stats_home, hs, stats, stats_process
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def start_phone_stats_home(hs: "HomeServer") -> None:
|
def start_phone_stats_home(hs: "HomeServer") -> None:
|
||||||
"""
|
"""
|
||||||
Start the background tasks which report phone home stats.
|
Start the background tasks which report phone home stats.
|
||||||
"""
|
"""
|
||||||
|
server_name = hs.hostname
|
||||||
clock = hs.get_clock()
|
clock = hs.get_clock()
|
||||||
|
|
||||||
stats: JsonDict = {}
|
stats: JsonDict = {}
|
||||||
@@ -210,25 +235,39 @@ def start_phone_stats_home(hs: "HomeServer") -> None:
|
|||||||
)
|
)
|
||||||
hs.get_datastores().main.reap_monthly_active_users()
|
hs.get_datastores().main.reap_monthly_active_users()
|
||||||
|
|
||||||
@wrap_as_background_process("generate_monthly_active_users")
|
def generate_monthly_active_users() -> "defer.Deferred[None]":
|
||||||
async def generate_monthly_active_users() -> None:
|
async def _generate_monthly_active_users() -> None:
|
||||||
current_mau_count = 0
|
current_mau_count = 0
|
||||||
current_mau_count_by_service: Mapping[str, int] = {}
|
current_mau_count_by_service: Mapping[str, int] = {}
|
||||||
reserved_users: Sized = ()
|
reserved_users: Sized = ()
|
||||||
store = hs.get_datastores().main
|
store = hs.get_datastores().main
|
||||||
if hs.config.server.limit_usage_by_mau or hs.config.server.mau_stats_only:
|
if hs.config.server.limit_usage_by_mau or hs.config.server.mau_stats_only:
|
||||||
current_mau_count = await store.get_monthly_active_count()
|
current_mau_count = await store.get_monthly_active_count()
|
||||||
current_mau_count_by_service = (
|
current_mau_count_by_service = (
|
||||||
await store.get_monthly_active_count_by_service()
|
await store.get_monthly_active_count_by_service()
|
||||||
|
)
|
||||||
|
reserved_users = await store.get_registered_reserved_users()
|
||||||
|
current_mau_gauge.labels(**{SERVER_NAME_LABEL: server_name}).set(
|
||||||
|
float(current_mau_count)
|
||||||
)
|
)
|
||||||
reserved_users = await store.get_registered_reserved_users()
|
|
||||||
current_mau_gauge.set(float(current_mau_count))
|
|
||||||
|
|
||||||
for app_service, count in current_mau_count_by_service.items():
|
for app_service, count in current_mau_count_by_service.items():
|
||||||
current_mau_by_service_gauge.labels(app_service).set(float(count))
|
current_mau_by_service_gauge.labels(
|
||||||
|
app_service=app_service, **{SERVER_NAME_LABEL: server_name}
|
||||||
|
).set(float(count))
|
||||||
|
|
||||||
registered_reserved_users_mau_gauge.set(float(len(reserved_users)))
|
registered_reserved_users_mau_gauge.labels(
|
||||||
max_mau_gauge.set(float(hs.config.server.max_mau_value))
|
**{SERVER_NAME_LABEL: server_name}
|
||||||
|
).set(float(len(reserved_users)))
|
||||||
|
max_mau_gauge.labels(**{SERVER_NAME_LABEL: server_name}).set(
|
||||||
|
float(hs.config.server.max_mau_value)
|
||||||
|
)
|
||||||
|
|
||||||
|
return run_as_background_process(
|
||||||
|
"generate_monthly_active_users",
|
||||||
|
server_name,
|
||||||
|
_generate_monthly_active_users,
|
||||||
|
)
|
||||||
|
|
||||||
if hs.config.server.limit_usage_by_mau or hs.config.server.mau_stats_only:
|
if hs.config.server.limit_usage_by_mau or hs.config.server.mau_stats_only:
|
||||||
generate_monthly_active_users()
|
generate_monthly_active_users()
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ from synapse.events import EventBase
|
|||||||
from synapse.events.utils import SerializeEventConfig, serialize_event
|
from synapse.events.utils import SerializeEventConfig, serialize_event
|
||||||
from synapse.http.client import SimpleHttpClient, is_unknown_endpoint
|
from synapse.http.client import SimpleHttpClient, is_unknown_endpoint
|
||||||
from synapse.logging import opentracing
|
from synapse.logging import opentracing
|
||||||
|
from synapse.metrics import SERVER_NAME_LABEL
|
||||||
from synapse.types import DeviceListUpdates, JsonDict, JsonMapping, ThirdPartyInstanceID
|
from synapse.types import DeviceListUpdates, JsonDict, JsonMapping, ThirdPartyInstanceID
|
||||||
from synapse.util.caches.response_cache import ResponseCache
|
from synapse.util.caches.response_cache import ResponseCache
|
||||||
|
|
||||||
@@ -59,29 +60,31 @@ logger = logging.getLogger(__name__)
|
|||||||
sent_transactions_counter = Counter(
|
sent_transactions_counter = Counter(
|
||||||
"synapse_appservice_api_sent_transactions",
|
"synapse_appservice_api_sent_transactions",
|
||||||
"Number of /transactions/ requests sent",
|
"Number of /transactions/ requests sent",
|
||||||
["service"],
|
labelnames=["service", SERVER_NAME_LABEL],
|
||||||
)
|
)
|
||||||
|
|
||||||
failed_transactions_counter = Counter(
|
failed_transactions_counter = Counter(
|
||||||
"synapse_appservice_api_failed_transactions",
|
"synapse_appservice_api_failed_transactions",
|
||||||
"Number of /transactions/ requests that failed to send",
|
"Number of /transactions/ requests that failed to send",
|
||||||
["service"],
|
labelnames=["service", SERVER_NAME_LABEL],
|
||||||
)
|
)
|
||||||
|
|
||||||
sent_events_counter = Counter(
|
sent_events_counter = Counter(
|
||||||
"synapse_appservice_api_sent_events", "Number of events sent to the AS", ["service"]
|
"synapse_appservice_api_sent_events",
|
||||||
|
"Number of events sent to the AS",
|
||||||
|
labelnames=["service", SERVER_NAME_LABEL],
|
||||||
)
|
)
|
||||||
|
|
||||||
sent_ephemeral_counter = Counter(
|
sent_ephemeral_counter = Counter(
|
||||||
"synapse_appservice_api_sent_ephemeral",
|
"synapse_appservice_api_sent_ephemeral",
|
||||||
"Number of ephemeral events sent to the AS",
|
"Number of ephemeral events sent to the AS",
|
||||||
["service"],
|
labelnames=["service", SERVER_NAME_LABEL],
|
||||||
)
|
)
|
||||||
|
|
||||||
sent_todevice_counter = Counter(
|
sent_todevice_counter = Counter(
|
||||||
"synapse_appservice_api_sent_todevice",
|
"synapse_appservice_api_sent_todevice",
|
||||||
"Number of todevice messages sent to the AS",
|
"Number of todevice messages sent to the AS",
|
||||||
["service"],
|
labelnames=["service", SERVER_NAME_LABEL],
|
||||||
)
|
)
|
||||||
|
|
||||||
HOUR_IN_MS = 60 * 60 * 1000
|
HOUR_IN_MS = 60 * 60 * 1000
|
||||||
@@ -382,6 +385,7 @@ class ApplicationServiceApi(SimpleHttpClient):
|
|||||||
"left": list(device_list_summary.left),
|
"left": list(device_list_summary.left),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
labels = {"service": service.id, SERVER_NAME_LABEL: self.server_name}
|
||||||
try:
|
try:
|
||||||
args = None
|
args = None
|
||||||
if self.config.use_appservice_legacy_authorization:
|
if self.config.use_appservice_legacy_authorization:
|
||||||
@@ -399,10 +403,10 @@ class ApplicationServiceApi(SimpleHttpClient):
|
|||||||
service.url,
|
service.url,
|
||||||
[event.get("event_id") for event in events],
|
[event.get("event_id") for event in events],
|
||||||
)
|
)
|
||||||
sent_transactions_counter.labels(service.id).inc()
|
sent_transactions_counter.labels(**labels).inc()
|
||||||
sent_events_counter.labels(service.id).inc(len(serialized_events))
|
sent_events_counter.labels(**labels).inc(len(serialized_events))
|
||||||
sent_ephemeral_counter.labels(service.id).inc(len(ephemeral))
|
sent_ephemeral_counter.labels(**labels).inc(len(ephemeral))
|
||||||
sent_todevice_counter.labels(service.id).inc(len(to_device_messages))
|
sent_todevice_counter.labels(**labels).inc(len(to_device_messages))
|
||||||
return True
|
return True
|
||||||
except CodeMessageException as e:
|
except CodeMessageException as e:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
@@ -421,7 +425,7 @@ class ApplicationServiceApi(SimpleHttpClient):
|
|||||||
ex.args,
|
ex.args,
|
||||||
exc_info=logger.isEnabledFor(logging.DEBUG),
|
exc_info=logger.isEnabledFor(logging.DEBUG),
|
||||||
)
|
)
|
||||||
failed_transactions_counter.labels(service.id).inc()
|
failed_transactions_counter.labels(**labels).inc()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def claim_client_keys(
|
async def claim_client_keys(
|
||||||
|
|||||||
@@ -103,18 +103,16 @@ MAX_TO_DEVICE_MESSAGES_PER_TRANSACTION = 100
|
|||||||
|
|
||||||
|
|
||||||
class ApplicationServiceScheduler:
|
class ApplicationServiceScheduler:
|
||||||
"""Public facing API for this module. Does the required DI to tie the
|
"""
|
||||||
components together. This also serves as the "event_pool", which in this
|
Public facing API for this module. Does the required dependency injection (DI) to
|
||||||
|
tie the components together. This also serves as the "event_pool", which in this
|
||||||
case is a simple array.
|
case is a simple array.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, hs: "HomeServer"):
|
def __init__(self, hs: "HomeServer"):
|
||||||
self.clock = hs.get_clock()
|
self.txn_ctrl = _TransactionController(hs)
|
||||||
self.store = hs.get_datastores().main
|
self.store = hs.get_datastores().main
|
||||||
self.as_api = hs.get_application_service_api()
|
self.queuer = _ServiceQueuer(self.txn_ctrl, hs)
|
||||||
|
|
||||||
self.txn_ctrl = _TransactionController(self.clock, self.store, self.as_api)
|
|
||||||
self.queuer = _ServiceQueuer(self.txn_ctrl, self.clock, hs)
|
|
||||||
|
|
||||||
async def start(self) -> None:
|
async def start(self) -> None:
|
||||||
logger.info("Starting appservice scheduler")
|
logger.info("Starting appservice scheduler")
|
||||||
@@ -184,9 +182,7 @@ class _ServiceQueuer:
|
|||||||
appservice at a given time.
|
appservice at a given time.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, txn_ctrl: "_TransactionController", hs: "HomeServer"):
|
||||||
self, txn_ctrl: "_TransactionController", clock: Clock, hs: "HomeServer"
|
|
||||||
):
|
|
||||||
# dict of {service_id: [events]}
|
# dict of {service_id: [events]}
|
||||||
self.queued_events: Dict[str, List[EventBase]] = {}
|
self.queued_events: Dict[str, List[EventBase]] = {}
|
||||||
# dict of {service_id: [events]}
|
# dict of {service_id: [events]}
|
||||||
@@ -199,10 +195,11 @@ class _ServiceQueuer:
|
|||||||
# the appservices which currently have a transaction in flight
|
# the appservices which currently have a transaction in flight
|
||||||
self.requests_in_flight: Set[str] = set()
|
self.requests_in_flight: Set[str] = set()
|
||||||
self.txn_ctrl = txn_ctrl
|
self.txn_ctrl = txn_ctrl
|
||||||
self.clock = clock
|
|
||||||
self._msc3202_transaction_extensions_enabled: bool = (
|
self._msc3202_transaction_extensions_enabled: bool = (
|
||||||
hs.config.experimental.msc3202_transaction_extensions
|
hs.config.experimental.msc3202_transaction_extensions
|
||||||
)
|
)
|
||||||
|
self.server_name = hs.hostname
|
||||||
|
self.clock = hs.get_clock()
|
||||||
self._store = hs.get_datastores().main
|
self._store = hs.get_datastores().main
|
||||||
|
|
||||||
def start_background_request(self, service: ApplicationService) -> None:
|
def start_background_request(self, service: ApplicationService) -> None:
|
||||||
@@ -210,7 +207,9 @@ class _ServiceQueuer:
|
|||||||
if service.id in self.requests_in_flight:
|
if service.id in self.requests_in_flight:
|
||||||
return
|
return
|
||||||
|
|
||||||
run_as_background_process("as-sender", self._send_request, service)
|
run_as_background_process(
|
||||||
|
"as-sender", self.server_name, self._send_request, service
|
||||||
|
)
|
||||||
|
|
||||||
async def _send_request(self, service: ApplicationService) -> None:
|
async def _send_request(self, service: ApplicationService) -> None:
|
||||||
# sanity-check: we shouldn't get here if this service already has a sender
|
# sanity-check: we shouldn't get here if this service already has a sender
|
||||||
@@ -359,10 +358,11 @@ class _TransactionController:
|
|||||||
(Note we have only have one of these in the homeserver.)
|
(Note we have only have one of these in the homeserver.)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, clock: Clock, store: DataStore, as_api: ApplicationServiceApi):
|
def __init__(self, hs: "HomeServer"):
|
||||||
self.clock = clock
|
self.server_name = hs.hostname
|
||||||
self.store = store
|
self.clock = hs.get_clock()
|
||||||
self.as_api = as_api
|
self.store = hs.get_datastores().main
|
||||||
|
self.as_api = hs.get_application_service_api()
|
||||||
|
|
||||||
# map from service id to recoverer instance
|
# map from service id to recoverer instance
|
||||||
self.recoverers: Dict[str, "_Recoverer"] = {}
|
self.recoverers: Dict[str, "_Recoverer"] = {}
|
||||||
@@ -446,7 +446,12 @@ class _TransactionController:
|
|||||||
logger.info("Starting recoverer for AS ID %s", service.id)
|
logger.info("Starting recoverer for AS ID %s", service.id)
|
||||||
assert service.id not in self.recoverers
|
assert service.id not in self.recoverers
|
||||||
recoverer = self.RECOVERER_CLASS(
|
recoverer = self.RECOVERER_CLASS(
|
||||||
self.clock, self.store, self.as_api, service, self.on_recovered
|
self.server_name,
|
||||||
|
self.clock,
|
||||||
|
self.store,
|
||||||
|
self.as_api,
|
||||||
|
service,
|
||||||
|
self.on_recovered,
|
||||||
)
|
)
|
||||||
self.recoverers[service.id] = recoverer
|
self.recoverers[service.id] = recoverer
|
||||||
recoverer.recover()
|
recoverer.recover()
|
||||||
@@ -477,21 +482,24 @@ class _Recoverer:
|
|||||||
We have one of these for each appservice which is currently considered DOWN.
|
We have one of these for each appservice which is currently considered DOWN.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
clock (synapse.util.Clock):
|
server_name: the homeserver name (used to label metrics) (this should be `hs.hostname`).
|
||||||
store (synapse.storage.DataStore):
|
clock:
|
||||||
as_api (synapse.appservice.api.ApplicationServiceApi):
|
store:
|
||||||
service (synapse.appservice.ApplicationService): the service we are managing
|
as_api:
|
||||||
callback (callable[_Recoverer]): called once the service recovers.
|
service: the service we are managing
|
||||||
|
callback: called once the service recovers.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
|
server_name: str,
|
||||||
clock: Clock,
|
clock: Clock,
|
||||||
store: DataStore,
|
store: DataStore,
|
||||||
as_api: ApplicationServiceApi,
|
as_api: ApplicationServiceApi,
|
||||||
service: ApplicationService,
|
service: ApplicationService,
|
||||||
callback: Callable[["_Recoverer"], Awaitable[None]],
|
callback: Callable[["_Recoverer"], Awaitable[None]],
|
||||||
):
|
):
|
||||||
|
self.server_name = server_name
|
||||||
self.clock = clock
|
self.clock = clock
|
||||||
self.store = store
|
self.store = store
|
||||||
self.as_api = as_api
|
self.as_api = as_api
|
||||||
@@ -504,7 +512,11 @@ class _Recoverer:
|
|||||||
delay = 2**self.backoff_counter
|
delay = 2**self.backoff_counter
|
||||||
logger.info("Scheduling retries on %s in %fs", self.service.id, delay)
|
logger.info("Scheduling retries on %s in %fs", self.service.id, delay)
|
||||||
self.scheduled_recovery = self.clock.call_later(
|
self.scheduled_recovery = self.clock.call_later(
|
||||||
delay, run_as_background_process, "as-recoverer", self.retry
|
delay,
|
||||||
|
run_as_background_process,
|
||||||
|
"as-recoverer",
|
||||||
|
self.server_name,
|
||||||
|
self.retry,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _backoff(self) -> None:
|
def _backoff(self) -> None:
|
||||||
@@ -525,6 +537,7 @@ class _Recoverer:
|
|||||||
# Run a retry, which will resechedule a recovery if it fails.
|
# Run a retry, which will resechedule a recovery if it fails.
|
||||||
run_as_background_process(
|
run_as_background_process(
|
||||||
"retry",
|
"retry",
|
||||||
|
self.server_name,
|
||||||
self.retry,
|
self.retry,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ from synapse.config import ( # noqa: F401
|
|||||||
jwt,
|
jwt,
|
||||||
key,
|
key,
|
||||||
logger,
|
logger,
|
||||||
|
mas,
|
||||||
metrics,
|
metrics,
|
||||||
modules,
|
modules,
|
||||||
oembed,
|
oembed,
|
||||||
@@ -124,6 +125,7 @@ class RootConfig:
|
|||||||
background_updates: background_updates.BackgroundUpdateConfig
|
background_updates: background_updates.BackgroundUpdateConfig
|
||||||
auto_accept_invites: auto_accept_invites.AutoAcceptInvitesConfig
|
auto_accept_invites: auto_accept_invites.AutoAcceptInvitesConfig
|
||||||
user_types: user_types.UserTypesConfig
|
user_types: user_types.UserTypesConfig
|
||||||
|
mas: mas.MasConfig
|
||||||
|
|
||||||
config_classes: List[Type["Config"]] = ...
|
config_classes: List[Type["Config"]] = ...
|
||||||
config_files: List[str]
|
config_files: List[str]
|
||||||
|
|||||||
@@ -36,13 +36,14 @@ class AuthConfig(Config):
|
|||||||
if password_config is None:
|
if password_config is None:
|
||||||
password_config = {}
|
password_config = {}
|
||||||
|
|
||||||
# The default value of password_config.enabled is True, unless msc3861 is enabled.
|
auth_delegated = (config.get("experimental_features") or {}).get(
|
||||||
msc3861_enabled = (
|
"msc3861", {}
|
||||||
(config.get("experimental_features") or {})
|
).get("enabled", False) or (
|
||||||
.get("msc3861", {})
|
config.get("matrix_authentication_service") or {}
|
||||||
.get("enabled", False)
|
).get("enabled", False)
|
||||||
)
|
|
||||||
passwords_enabled = password_config.get("enabled", not msc3861_enabled)
|
# The default value of password_config.enabled is True, unless auth is delegated
|
||||||
|
passwords_enabled = password_config.get("enabled", not auth_delegated)
|
||||||
|
|
||||||
# 'only_for_reauth' allows users who have previously set a password to use it,
|
# 'only_for_reauth' allows users who have previously set a password to use it,
|
||||||
# even though passwords would otherwise be disabled.
|
# even though passwords would otherwise be disabled.
|
||||||
|
|||||||
@@ -535,11 +535,15 @@ class ExperimentalConfig(Config):
|
|||||||
"msc4108_delegation_endpoint", None
|
"msc4108_delegation_endpoint", None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
auth_delegated = self.msc3861.enabled or (
|
||||||
|
config.get("matrix_authentication_service") or {}
|
||||||
|
).get("enabled", False)
|
||||||
|
|
||||||
if (
|
if (
|
||||||
self.msc4108_enabled or self.msc4108_delegation_endpoint is not None
|
self.msc4108_enabled or self.msc4108_delegation_endpoint is not None
|
||||||
) and not self.msc3861.enabled:
|
) and not auth_delegated:
|
||||||
raise ConfigError(
|
raise ConfigError(
|
||||||
"MSC4108 requires MSC3861 to be enabled",
|
"MSC4108 requires MSC3861 or matrix_authentication_service to be enabled",
|
||||||
("experimental", "msc4108_delegation_endpoint"),
|
("experimental", "msc4108_delegation_endpoint"),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -581,3 +585,10 @@ class ExperimentalConfig(Config):
|
|||||||
|
|
||||||
# MSC4155: Invite filtering
|
# MSC4155: Invite filtering
|
||||||
self.msc4155_enabled: bool = experimental.get("msc4155_enabled", False)
|
self.msc4155_enabled: bool = experimental.get("msc4155_enabled", False)
|
||||||
|
|
||||||
|
# MSC4293: Redact on Kick/Ban
|
||||||
|
self.msc4293_enabled: bool = experimental.get("msc4293_enabled", False)
|
||||||
|
|
||||||
|
# MSC4306: Thread Subscriptions
|
||||||
|
# (and MSC4308: sliding sync extension for thread subscriptions)
|
||||||
|
self.msc4306_enabled: bool = experimental.get("msc4306_enabled", False)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user