Compare commits
70 Commits
rei/gsgfg
...
dmr/log-ex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0dfd550e38 | ||
|
|
ee0748a42a | ||
|
|
c0233eae5e | ||
|
|
bec01c0758 | ||
|
|
6e613a10d0 | ||
|
|
964f29cb6f | ||
|
|
6a5f8fbcda | ||
|
|
430241a1e9 | ||
|
|
1a9f531c79 | ||
|
|
272b89d547 | ||
|
|
642a42edde | ||
|
|
b62eba7705 | ||
|
|
3bcd525b46 | ||
|
|
58f0d97275 | ||
|
|
ae2714c1f3 | ||
|
|
a933c2c7d8 | ||
|
|
19e51b14d2 | ||
|
|
0db8cab72c | ||
|
|
5af83efe8d | ||
|
|
0ace38b7b3 | ||
|
|
87b62f8bb2 | ||
|
|
2d9ca4ca77 | ||
|
|
7de445161f | ||
|
|
a3a7514570 | ||
|
|
d1f43b731c | ||
|
|
c8d54be44c | ||
|
|
c12b5577f2 | ||
|
|
d2ad397d3c | ||
|
|
4a76d01ff7 | ||
|
|
878528913d | ||
|
|
74fcd5aab9 | ||
|
|
314a739160 | ||
|
|
98a3355d9a | ||
|
|
915b37e5ef | ||
|
|
92a8e68ba2 | ||
|
|
cb5976ebd7 | ||
|
|
6fcc3e0bc8 | ||
|
|
3ebb6694f0 | ||
|
|
33ef86aa25 | ||
|
|
5acd8b5a96 | ||
|
|
2ae2a04616 | ||
|
|
fab352ac2c | ||
|
|
339c3918e1 | ||
|
|
8c654b7309 | ||
|
|
b924a5c2e4 | ||
|
|
fe1d0c8618 | ||
|
|
c0ebdfc77e | ||
|
|
58e5da5aa0 | ||
|
|
c5988a8eb7 | ||
|
|
3d67b8c82b | ||
|
|
03fb99a5c8 | ||
|
|
8da9e3cb69 | ||
|
|
691593bf71 | ||
|
|
52bfa2d59a | ||
|
|
b5de77cf86 | ||
|
|
9f7c038272 | ||
|
|
7afb615839 | ||
|
|
6b61debf5c | ||
|
|
189c055eb6 | ||
|
|
f8e86b7d2e | ||
|
|
ad35b7739e | ||
|
|
0c246dd4a0 | ||
|
|
1de26b3467 | ||
|
|
60f0534b6e | ||
|
|
1bebc0b78c | ||
|
|
f4ade972ad | ||
|
|
74d7336686 | ||
|
|
f5a368bb48 | ||
|
|
0cb4274dbf | ||
|
|
4578531002 |
@@ -1,13 +0,0 @@
|
||||
CI
|
||||
BUILDKITE
|
||||
BUILDKITE_BUILD_NUMBER
|
||||
BUILDKITE_BRANCH
|
||||
BUILDKITE_BUILD_NUMBER
|
||||
BUILDKITE_JOB_ID
|
||||
BUILDKITE_BUILD_URL
|
||||
BUILDKITE_PROJECT_SLUG
|
||||
BUILDKITE_COMMIT
|
||||
BUILDKITE_PULL_REQUEST
|
||||
BUILDKITE_TAG
|
||||
CODECOV_TOKEN
|
||||
TRIAL_FLAGS
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
if [[ "$BUILDKITE_BRANCH" =~ ^(develop|master|dinsic|shhs|release-.*)$ ]]; then
|
||||
echo "Not merging forward, as this is a release branch"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -z $BUILDKITE_PULL_REQUEST_BASE_BRANCH ]]; then
|
||||
echo "Not a pull request, or hasn't had a PR opened yet..."
|
||||
|
||||
# It probably hasn't had a PR opened yet. Since all PRs land on develop, we
|
||||
# can probably assume it's based on it and will be merged into it.
|
||||
GITBASE="develop"
|
||||
else
|
||||
# Get the reference, using the GitHub API
|
||||
GITBASE=$BUILDKITE_PULL_REQUEST_BASE_BRANCH
|
||||
fi
|
||||
|
||||
echo "--- merge_base_branch $GITBASE"
|
||||
|
||||
# Show what we are before
|
||||
git --no-pager show -s
|
||||
|
||||
# Set up username so it can do a merge
|
||||
git config --global user.email bot@matrix.org
|
||||
git config --global user.name "A robot"
|
||||
|
||||
# Fetch and merge. If it doesn't work, it will raise due to set -e.
|
||||
git fetch -u origin $GITBASE
|
||||
git merge --no-edit --no-commit origin/$GITBASE
|
||||
|
||||
# Show what we are after.
|
||||
git --no-pager show -s
|
||||
@@ -3,7 +3,7 @@
|
||||
# CI's Docker setup at the point where this file is considered.
|
||||
server_name: "localhost:8800"
|
||||
|
||||
signing_key_path: ".buildkite/test.signing.key"
|
||||
signing_key_path: ".ci/test.signing.key"
|
||||
|
||||
report_stats: false
|
||||
|
||||
@@ -11,7 +11,7 @@ database:
|
||||
name: "psycopg2"
|
||||
args:
|
||||
user: postgres
|
||||
host: postgres
|
||||
host: localhost
|
||||
password: postgres
|
||||
database: synapse
|
||||
|
||||
@@ -23,7 +23,7 @@ import psycopg2
|
||||
# We use "postgres" as a database because it's bound to exist and the "synapse" one
|
||||
# doesn't exist yet.
|
||||
db_conn = psycopg2.connect(
|
||||
user="postgres", host="postgres", password="postgres", dbname="postgres"
|
||||
user="postgres", host="localhost", password="postgres", dbname="postgres"
|
||||
)
|
||||
db_conn.autocommit = True
|
||||
cur = db_conn.cursor()
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# this script is run by buildkite in a plain `bionic` container; it installs the
|
||||
# this script is run by GitHub Actions in a plain `bionic` container; it installs the
|
||||
# minimal requirements for tox and hands over to the py3-old tox environment.
|
||||
|
||||
set -ex
|
||||
@@ -20,22 +20,22 @@ pip install -e .
|
||||
echo "--- Generate the signing key"
|
||||
|
||||
# Generate the server's signing key.
|
||||
python -m synapse.app.homeserver --generate-keys -c .buildkite/sqlite-config.yaml
|
||||
python -m synapse.app.homeserver --generate-keys -c .ci/sqlite-config.yaml
|
||||
|
||||
echo "--- Prepare test database"
|
||||
|
||||
# Make sure the SQLite3 database is using the latest schema and has no pending background update.
|
||||
scripts-dev/update_database --database-config .buildkite/sqlite-config.yaml
|
||||
scripts-dev/update_database --database-config .ci/sqlite-config.yaml
|
||||
|
||||
# Create the PostgreSQL database.
|
||||
./.buildkite/scripts/postgres_exec.py "CREATE DATABASE synapse"
|
||||
.ci/scripts/postgres_exec.py "CREATE DATABASE synapse"
|
||||
|
||||
echo "+++ Run synapse_port_db against test database"
|
||||
coverage run scripts/synapse_port_db --sqlite-database .buildkite/test_db.db --postgres-config .buildkite/postgres-config.yaml
|
||||
coverage run scripts/synapse_port_db --sqlite-database .ci/test_db.db --postgres-config .ci/postgres-config.yaml
|
||||
|
||||
# We should be able to run twice against the same database.
|
||||
echo "+++ Run synapse_port_db a second time"
|
||||
coverage run scripts/synapse_port_db --sqlite-database .buildkite/test_db.db --postgres-config .buildkite/postgres-config.yaml
|
||||
coverage run scripts/synapse_port_db --sqlite-database .ci/test_db.db --postgres-config .ci/postgres-config.yaml
|
||||
|
||||
#####
|
||||
|
||||
@@ -44,14 +44,14 @@ coverage run scripts/synapse_port_db --sqlite-database .buildkite/test_db.db --p
|
||||
echo "--- Prepare empty SQLite database"
|
||||
|
||||
# we do this by deleting the sqlite db, and then doing the same again.
|
||||
rm .buildkite/test_db.db
|
||||
rm .ci/test_db.db
|
||||
|
||||
scripts-dev/update_database --database-config .buildkite/sqlite-config.yaml
|
||||
scripts-dev/update_database --database-config .ci/sqlite-config.yaml
|
||||
|
||||
# re-create the PostgreSQL database.
|
||||
./.buildkite/scripts/postgres_exec.py \
|
||||
.ci/scripts/postgres_exec.py \
|
||||
"DROP DATABASE synapse" \
|
||||
"CREATE DATABASE synapse"
|
||||
|
||||
echo "+++ Run synapse_port_db against empty database"
|
||||
coverage run scripts/synapse_port_db --sqlite-database .buildkite/test_db.db --postgres-config .buildkite/postgres-config.yaml
|
||||
coverage run scripts/synapse_port_db --sqlite-database .ci/test_db.db --postgres-config .ci/postgres-config.yaml
|
||||
@@ -3,14 +3,14 @@
|
||||
# schema and run background updates on it.
|
||||
server_name: "localhost:8800"
|
||||
|
||||
signing_key_path: ".buildkite/test.signing.key"
|
||||
signing_key_path: ".ci/test.signing.key"
|
||||
|
||||
report_stats: false
|
||||
|
||||
database:
|
||||
name: "sqlite3"
|
||||
args:
|
||||
database: ".buildkite/test_db.db"
|
||||
database: ".ci/test_db.db"
|
||||
|
||||
# Suppress the key server warning.
|
||||
trusted_key_servers: []
|
||||
25
.github/workflows/tests.yml
vendored
25
.github/workflows/tests.yml
vendored
@@ -38,20 +38,15 @@ jobs:
|
||||
if: ${{ github.base_ref == 'develop' || contains(github.base_ref, 'release-') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Note: This and the script can be simplified once we drop Buildkite. See:
|
||||
# https://github.com/actions/checkout/issues/266#issuecomment-638346893
|
||||
# https://github.com/actions/checkout/issues/416
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v2
|
||||
- run: pip install tox
|
||||
- name: Patch Buildkite-specific test script
|
||||
run: |
|
||||
sed -i -e 's/\$BUILDKITE_PULL_REQUEST/${{ github.event.number }}/' \
|
||||
scripts-dev/check-newsfragment
|
||||
- run: scripts-dev/check-newsfragment
|
||||
env:
|
||||
PULL_REQUEST_NUMBER: ${{ github.event.number }}
|
||||
|
||||
lint-sdist:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -144,7 +139,7 @@ jobs:
|
||||
uses: docker://ubuntu:bionic # For old python and sqlite
|
||||
with:
|
||||
workdir: /github/workspace
|
||||
entrypoint: .buildkite/scripts/test_old_deps.sh
|
||||
entrypoint: .ci/scripts/test_old_deps.sh
|
||||
env:
|
||||
TRIAL_FLAGS: "--jobs=2"
|
||||
- name: Dump logs
|
||||
@@ -197,12 +192,12 @@ jobs:
|
||||
volumes:
|
||||
- ${{ github.workspace }}:/src
|
||||
env:
|
||||
BUILDKITE_BRANCH: ${{ github.head_ref }}
|
||||
POSTGRES: ${{ matrix.postgres && 1}}
|
||||
MULTI_POSTGRES: ${{ (matrix.postgres == 'multi-postgres') && 1}}
|
||||
WORKERS: ${{ matrix.workers && 1 }}
|
||||
REDIS: ${{ matrix.redis && 1 }}
|
||||
BLACKLIST: ${{ matrix.workers && 'synapse-blacklist-with-workers' }}
|
||||
TOP: ${{ github.workspace }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -232,7 +227,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Prepare test blacklist
|
||||
run: cat sytest-blacklist .buildkite/worker-blacklist > synapse-blacklist-with-workers
|
||||
run: cat sytest-blacklist .ci/worker-blacklist > synapse-blacklist-with-workers
|
||||
- name: Run SyTest
|
||||
run: /bootstrap.sh synapse
|
||||
working-directory: /src
|
||||
@@ -252,6 +247,8 @@ jobs:
|
||||
if: ${{ !failure() && !cancelled() }} # Allow previous steps to be skipped, but not fail
|
||||
needs: linting-done
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TOP: ${{ github.workspace }}
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
@@ -281,13 +278,7 @@ jobs:
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Patch Buildkite-specific test scripts
|
||||
run: |
|
||||
sed -i -e 's/host="postgres"/host="localhost"/' .buildkite/scripts/postgres_exec.py
|
||||
sed -i -e 's/host: postgres/host: localhost/' .buildkite/postgres-config.yaml
|
||||
sed -i -e 's|/src/||' .buildkite/{sqlite,postgres}-config.yaml
|
||||
sed -i -e 's/\$TOP/\$GITHUB_WORKSPACE/' .coveragerc
|
||||
- run: .buildkite/scripts/test_synapse_port_db.sh
|
||||
- run: .ci/scripts/test_synapse_port_db.sh
|
||||
|
||||
complement:
|
||||
if: ${{ !failure() && !cancelled() }}
|
||||
|
||||
27
CHANGES.md
27
CHANGES.md
@@ -1,3 +1,30 @@
|
||||
Synapse 1.40.0 (2021-08-10)
|
||||
===========================
|
||||
|
||||
No significant changes.
|
||||
|
||||
|
||||
Synapse 1.40.0rc3 (2021-08-09)
|
||||
==============================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Support [MSC3289: room version 8](https://github.com/matrix-org/matrix-doc/pull/3289). ([\#10449](https://github.com/matrix-org/synapse/issues/10449))
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Mark the experimental room version from [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716) as unstable. ([\#10449](https://github.com/matrix-org/synapse/issues/10449))
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Fix broken links in `upgrade.md`. Contributed by @dklimpel. ([\#10543](https://github.com/matrix-org/synapse/issues/10543))
|
||||
|
||||
|
||||
Synapse 1.40.0rc2 (2021-08-04)
|
||||
==============================
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@ This document aims to get you started with contributing to this repo!
|
||||
- [7. Turn coffee and documentation into code and documentation!](#7-turn-coffee-and-documentation-into-code-and-documentation)
|
||||
- [8. Test, test, test!](#8-test-test-test)
|
||||
* [Run the linters.](#run-the-linters)
|
||||
* [Run the unit tests.](#run-the-unit-tests)
|
||||
* [Run the integration tests.](#run-the-integration-tests)
|
||||
* [Run the unit tests.](#run-the-unit-tests-twisted-trial)
|
||||
* [Run the integration tests (SyTest).](#run-the-integration-tests-sytest)
|
||||
* [Run the integration tests (Complement).](#run-the-integration-tests-complement)
|
||||
- [9. Submit your patch.](#9-submit-your-patch)
|
||||
* [Changelog](#changelog)
|
||||
+ [How do I know what to call the changelog file before I create the PR?](#how-do-i-know-what-to-call-the-changelog-file-before-i-create-the-pr)
|
||||
@@ -197,7 +198,7 @@ The following command will let you run the integration test with the most common
|
||||
configuration:
|
||||
|
||||
```sh
|
||||
$ docker run --rm -it -v /path/where/you/have/cloned/the/repository\:/src:ro -v /path/to/where/you/want/logs\:/logs matrixdotorg/sytest-synapse:py37
|
||||
$ docker run --rm -it -v /path/where/you/have/cloned/the/repository\:/src:ro -v /path/to/where/you/want/logs\:/logs matrixdotorg/sytest-synapse:buster
|
||||
```
|
||||
|
||||
This configuration should generally cover your needs. For more details about other configurations, see [documentation in the SyTest repo](https://github.com/matrix-org/sytest/blob/develop/docker/README.md).
|
||||
@@ -252,6 +253,7 @@ To prepare a Pull Request, please:
|
||||
4. on GitHub, [create the Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request);
|
||||
5. add a [changelog entry](#changelog) and push it to your Pull Request;
|
||||
6. for most contributors, that's all - however, if you are a member of the organization `matrix-org`, on GitHub, please request a review from `matrix.org / Synapse Core`.
|
||||
7. if you need to update your PR, please avoid rebasing and just add new commits to your branch.
|
||||
|
||||
|
||||
## Changelog
|
||||
|
||||
@@ -44,9 +44,9 @@ include book.toml
|
||||
include pyproject.toml
|
||||
recursive-include changelog.d *
|
||||
|
||||
prune .buildkite
|
||||
prune .circleci
|
||||
prune .github
|
||||
prune .ci
|
||||
prune contrib
|
||||
prune debian
|
||||
prune demo/etc
|
||||
|
||||
1
changelog.d/10394.feature
Normal file
1
changelog.d/10394.feature
Normal file
@@ -0,0 +1 @@
|
||||
Initial local support for [MSC3266](https://github.com/matrix-org/synapse/pull/10394), Room Summary over the unstable `/rooms/{roomIdOrAlias}/summary` API.
|
||||
1
changelog.d/10475.feature
Normal file
1
changelog.d/10475.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add support for sending federation requests through a proxy. Contributed by @Bubu and @dklimpel.
|
||||
1
changelog.d/10524.feature
Normal file
1
changelog.d/10524.feature
Normal file
@@ -0,0 +1 @@
|
||||
Port the PresenceRouter module interface to the new generic interface.
|
||||
@@ -1 +1 @@
|
||||
Prepare for the new spaces summary endpoint (updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946)).
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
|
||||
1
changelog.d/10530.misc
Normal file
1
changelog.d/10530.misc
Normal file
@@ -0,0 +1 @@
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10537.misc
Normal file
1
changelog.d/10537.misc
Normal file
@@ -0,0 +1 @@
|
||||
Mark all events stemming from the MSC2716 `/batch_send` endpoint as historical.
|
||||
1
changelog.d/10538.feature
Normal file
1
changelog.d/10538.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add support for new redaction rules for historical events specified in [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716).
|
||||
1
changelog.d/10539.misc
Normal file
1
changelog.d/10539.misc
Normal file
@@ -0,0 +1 @@
|
||||
Clean up some of the federation event authentication code for clarity.
|
||||
1
changelog.d/10541.bugfix
Normal file
1
changelog.d/10541.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix exceptions in logs when failing to get remote room list.
|
||||
1
changelog.d/10542.misc
Normal file
1
changelog.d/10542.misc
Normal file
@@ -0,0 +1 @@
|
||||
Convert `Transaction` and `Edu` objects to attrs.
|
||||
1
changelog.d/10546.feature
Normal file
1
changelog.d/10546.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add a setting to disable TLS when sending email.
|
||||
1
changelog.d/10549.feature
Normal file
1
changelog.d/10549.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10550.bugfix
Normal file
1
changelog.d/10550.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix longstanding bug which caused the user "status" to be reset when the user went offline. Contributed by @dklimpel.
|
||||
1
changelog.d/10551.doc
Normal file
1
changelog.d/10551.doc
Normal file
@@ -0,0 +1 @@
|
||||
Updated the reverse proxy documentation to highlight the homserver configuration that is needed to make Synapse aware that is is intentionally reverse proxied.
|
||||
1
changelog.d/10552.misc
Normal file
1
changelog.d/10552.misc
Normal file
@@ -0,0 +1 @@
|
||||
Update `/batch_send` endpoint to only return `state_events` created by the `state_events_from_before` passed in.
|
||||
1
changelog.d/10558.feature
Normal file
1
changelog.d/10558.feature
Normal file
@@ -0,0 +1 @@
|
||||
Admin API to delete several media for a specific user. Contributed by @dklimpel.
|
||||
1
changelog.d/10560.feature
Normal file
1
changelog.d/10560.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10561.bugfix
Normal file
1
changelog.d/10561.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Display an error on User-Interactive Authentication fallback pages when authentication fails. Contributed by Callum Brown.
|
||||
1
changelog.d/10563.misc
Normal file
1
changelog.d/10563.misc
Normal file
@@ -0,0 +1 @@
|
||||
Update contributing.md to warn against rebasing an open PR.
|
||||
1
changelog.d/10569.feature
Normal file
1
changelog.d/10569.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10570.feature
Normal file
1
changelog.d/10570.feature
Normal file
@@ -0,0 +1 @@
|
||||
Update the Synapse Grafana dashboard.
|
||||
1
changelog.d/10572.misc
Normal file
1
changelog.d/10572.misc
Normal file
@@ -0,0 +1 @@
|
||||
Clarify error message when failing to join a restricted room.
|
||||
1
changelog.d/10573.misc
Normal file
1
changelog.d/10573.misc
Normal file
@@ -0,0 +1 @@
|
||||
Remove references to BuildKite in favour of GitHub Actions.
|
||||
1
changelog.d/10574.feature
Normal file
1
changelog.d/10574.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10575.feature
Normal file
1
changelog.d/10575.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10576.misc
Normal file
1
changelog.d/10576.misc
Normal file
@@ -0,0 +1 @@
|
||||
Move `/batch_send` endpoint defined by [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716) to the `/v2_alpha` directory.
|
||||
1
changelog.d/10578.feature
Normal file
1
changelog.d/10578.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add an admin API (`GET /_synapse/admin/username_available`) to check if a username is available (regardless of registration settings).
|
||||
1
changelog.d/10579.feature
Normal file
1
changelog.d/10579.feature
Normal file
@@ -0,0 +1 @@
|
||||
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10580.bugfix
Normal file
1
changelog.d/10580.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Allow public rooms to be previewed in the spaces summary APIs from [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
|
||||
1
changelog.d/10587.misc
Normal file
1
changelog.d/10587.misc
Normal file
@@ -0,0 +1 @@
|
||||
Allow multiple custom directories in `read_templates`.
|
||||
1
changelog.d/10588.removal
Normal file
1
changelog.d/10588.removal
Normal file
@@ -0,0 +1 @@
|
||||
No longer build `.dev` packages for Ubuntu 20.10 LTS Groovy Gorilla, which has now EOLed.
|
||||
1
changelog.d/10590.misc
Normal file
1
changelog.d/10590.misc
Normal file
@@ -0,0 +1 @@
|
||||
Re-organize the `synapse.federation.transport.server` module to create smaller files.
|
||||
1
changelog.d/10591.misc
Normal file
1
changelog.d/10591.misc
Normal file
@@ -0,0 +1 @@
|
||||
Clean up some of the federation event authentication code for clarity.
|
||||
1
changelog.d/10592.bugfix
Normal file
1
changelog.d/10592.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix a bug introduced in v1.37.1 where an error could occur in the asyncronous processing of PDUs when the queue was empty.
|
||||
1
changelog.d/10598.feature
Normal file
1
changelog.d/10598.feature
Normal file
@@ -0,0 +1 @@
|
||||
Allow editing a user's `external_ids` via the "Edit User" admin API. Contributed by @dklimpel.
|
||||
1
changelog.d/10599.doc
Normal file
1
changelog.d/10599.doc
Normal file
@@ -0,0 +1 @@
|
||||
Update CONTRIBUTING.md to fix index links and the instructions for SyTest in docker.
|
||||
1
changelog.d/10600.misc
Normal file
1
changelog.d/10600.misc
Normal file
@@ -0,0 +1 @@
|
||||
Flatten the `synapse.rest.client` package by moving the contents of `v1` and `v2_alpha` into the parent.
|
||||
1
changelog.d/10602.feature
Normal file
1
changelog.d/10602.feature
Normal file
@@ -0,0 +1 @@
|
||||
The Synapse manhole no longer needs coroutines to be wrapped in `defer.ensureDeferred`.
|
||||
1
changelog.d/10606.bugfix
Normal file
1
changelog.d/10606.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Fix errors on /sync when read receipt data is a string. Only affects homeservers with the experimental flag for [MSC2285](https://github.com/matrix-org/matrix-doc/pull/2285) enabled. Contributed by @SimonBrandner.
|
||||
1
changelog.d/10611.bugfix
Normal file
1
changelog.d/10611.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Additional validation for the spaces summary API to avoid errors like `ValueError: Stop argument for islice() must be None or an integer`. The missing validation has existed since v1.31.0.
|
||||
1
changelog.d/10614.misc
Normal file
1
changelog.d/10614.misc
Normal file
@@ -0,0 +1 @@
|
||||
Clean up some of the federation event authentication code for clarity.
|
||||
1
changelog.d/10615.misc
Normal file
1
changelog.d/10615.misc
Normal file
@@ -0,0 +1 @@
|
||||
Clean up some of the federation event authentication code for clarity.
|
||||
1
changelog.d/10620.misc
Normal file
1
changelog.d/10620.misc
Normal file
@@ -0,0 +1 @@
|
||||
Fix up a couple of links to the database schema documentation.
|
||||
1
changelog.d/10623.bugfix
Normal file
1
changelog.d/10623.bugfix
Normal file
@@ -0,0 +1 @@
|
||||
Revert behaviour introduced in v1.38.0 that strips `org.matrix.msc2732.device_unused_fallback_key_types` from `/sync` when its value is empty. This field should instead always be present according to [MSC2732](https://github.com/matrix-org/matrix-doc/blob/master/proposals/2732-olm-fallback-keys.md).
|
||||
1
changelog.d/10629.misc
Normal file
1
changelog.d/10629.misc
Normal file
@@ -0,0 +1 @@
|
||||
Convert room member storage tuples to `attrs` classes.
|
||||
1
changelog.d/10630.misc
Normal file
1
changelog.d/10630.misc
Normal file
@@ -0,0 +1 @@
|
||||
Use auto-attribs for the attrs classes used in sync.
|
||||
1
changelog.d/10657.misc
Normal file
1
changelog.d/10657.misc
Normal file
@@ -0,0 +1 @@
|
||||
Log errors in tests to stderr.
|
||||
1
changelog.d/8830.removal
Normal file
1
changelog.d/8830.removal
Normal file
@@ -0,0 +1 @@
|
||||
Remove deprecated Shutdown Room and Purge Room Admin API.
|
||||
@@ -54,7 +54,7 @@
|
||||
"gnetId": null,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"iteration": 1621258266004,
|
||||
"iteration": 1628606819564,
|
||||
"links": [
|
||||
{
|
||||
"asDropdown": false,
|
||||
@@ -307,7 +307,6 @@
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"$$hashKey": "object:283",
|
||||
"colorMode": "warning",
|
||||
"fill": false,
|
||||
"line": true,
|
||||
@@ -316,7 +315,6 @@
|
||||
"yaxis": "left"
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:284",
|
||||
"colorMode": "critical",
|
||||
"fill": false,
|
||||
"line": true,
|
||||
@@ -344,7 +342,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:255",
|
||||
"decimals": null,
|
||||
"format": "s",
|
||||
"label": "",
|
||||
@@ -354,7 +351,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:256",
|
||||
"format": "hertz",
|
||||
"label": "",
|
||||
"logBase": 1,
|
||||
@@ -429,7 +425,6 @@
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"$$hashKey": "object:566",
|
||||
"colorMode": "critical",
|
||||
"fill": true,
|
||||
"line": true,
|
||||
@@ -457,7 +452,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:538",
|
||||
"decimals": null,
|
||||
"format": "percentunit",
|
||||
"label": null,
|
||||
@@ -467,7 +461,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:539",
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -573,7 +566,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:1560",
|
||||
"format": "bytes",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
@@ -581,7 +573,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:1561",
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
@@ -641,7 +632,6 @@
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"$$hashKey": "object:639",
|
||||
"alias": "/max$/",
|
||||
"color": "#890F02",
|
||||
"fill": 0,
|
||||
@@ -693,7 +683,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:650",
|
||||
"decimals": null,
|
||||
"format": "none",
|
||||
"label": "",
|
||||
@@ -703,7 +692,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:651",
|
||||
"decimals": null,
|
||||
"format": "short",
|
||||
"label": null,
|
||||
@@ -783,11 +771,9 @@
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"$$hashKey": "object:1240",
|
||||
"alias": "/user/"
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:1241",
|
||||
"alias": "/system/"
|
||||
}
|
||||
],
|
||||
@@ -817,7 +803,6 @@
|
||||
],
|
||||
"thresholds": [
|
||||
{
|
||||
"$$hashKey": "object:1278",
|
||||
"colorMode": "custom",
|
||||
"fillColor": "rgba(255, 255, 255, 1)",
|
||||
"line": true,
|
||||
@@ -827,7 +812,6 @@
|
||||
"yaxis": "left"
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:1279",
|
||||
"colorMode": "custom",
|
||||
"fillColor": "rgba(255, 255, 255, 1)",
|
||||
"line": true,
|
||||
@@ -837,7 +821,6 @@
|
||||
"yaxis": "left"
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:1498",
|
||||
"colorMode": "critical",
|
||||
"fill": true,
|
||||
"line": true,
|
||||
@@ -865,7 +848,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:1250",
|
||||
"decimals": null,
|
||||
"format": "percentunit",
|
||||
"label": "",
|
||||
@@ -875,7 +857,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:1251",
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
@@ -1427,7 +1408,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:572",
|
||||
"format": "percentunit",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -1436,7 +1416,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:573",
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -1720,7 +1699,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:102",
|
||||
"format": "hertz",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
@@ -1728,7 +1706,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:103",
|
||||
"format": "short",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
@@ -3425,7 +3402,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 33
|
||||
"y": 6
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 79,
|
||||
@@ -3442,9 +3419,12 @@
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.3",
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
@@ -3526,7 +3506,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 33
|
||||
"y": 6
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 83,
|
||||
@@ -3543,9 +3523,12 @@
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.3",
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
@@ -3629,7 +3612,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 42
|
||||
"y": 15
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 109,
|
||||
@@ -3646,9 +3629,12 @@
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.3",
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
@@ -3733,7 +3719,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 42
|
||||
"y": 15
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 111,
|
||||
@@ -3750,9 +3736,12 @@
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.3",
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
@@ -3831,7 +3820,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 51
|
||||
"y": 24
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 142,
|
||||
@@ -3847,8 +3836,11 @@
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.3",
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
@@ -3931,7 +3923,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 51
|
||||
"y": 24
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 140,
|
||||
@@ -3948,9 +3940,12 @@
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.3",
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
@@ -4079,7 +4074,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 59
|
||||
"y": 32
|
||||
},
|
||||
"heatmap": {},
|
||||
"hideZeroBuckets": false,
|
||||
@@ -4145,7 +4140,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 60
|
||||
"y": 33
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 162,
|
||||
@@ -4163,9 +4158,12 @@
|
||||
"linewidth": 0,
|
||||
"links": [],
|
||||
"nullPointMode": "connected",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.1.3",
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
@@ -4350,7 +4348,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 68
|
||||
"y": 41
|
||||
},
|
||||
"heatmap": {},
|
||||
"hideZeroBuckets": false,
|
||||
@@ -4396,6 +4394,311 @@
|
||||
"yBucketBound": "auto",
|
||||
"yBucketNumber": null,
|
||||
"yBucketSize": null
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"grid": {},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 42
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 203,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "synapse_federation_server_oldest_inbound_pdu_in_staging{job=\"$job\",index=~\"$index\",instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "rss {{index}}",
|
||||
"refId": "A",
|
||||
"step": 4
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Age of oldest event in staging area",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "ms",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"editable": true,
|
||||
"error": false,
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"grid": {},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 50
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 202,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 2,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"paceLength": 10,
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "synapse_federation_server_number_inbound_pdu_in_staging{job=\"$job\",index=~\"$index\",instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "rss {{index}}",
|
||||
"refId": "A",
|
||||
"step": 4
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Number of events in federation staging area",
|
||||
"tooltip": {
|
||||
"msResolution": false,
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "cumulative"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "none",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "${DS_PROMETHEUS}",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 51
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 205,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 2,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(rate(synapse_federation_soft_failed_events_total{instance=\"$instance\"}[$bucket_size]))",
|
||||
"interval": "",
|
||||
"legendFormat": "soft-failed events",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Soft-failed event rate",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "hertz",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"title": "Federation",
|
||||
@@ -4647,7 +4950,7 @@
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 8
|
||||
"y": 33
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 48,
|
||||
@@ -4749,7 +5052,7 @@
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 8
|
||||
"y": 33
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 104,
|
||||
@@ -4877,7 +5180,7 @@
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 15
|
||||
"y": 40
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 10,
|
||||
@@ -4981,7 +5284,7 @@
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 15
|
||||
"y": 40
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 11,
|
||||
@@ -5086,7 +5389,7 @@
|
||||
"h": 7,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 22
|
||||
"y": 47
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 180,
|
||||
@@ -5168,6 +5471,126 @@
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"custom": {},
|
||||
"links": []
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"fill": 6,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 47
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 200,
|
||||
"legend": {
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"show": true,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"options": {
|
||||
"alertThreshold": true
|
||||
},
|
||||
"percentage": false,
|
||||
"pluginVersion": "7.3.7",
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "histogram_quantile(0.99, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "99%",
|
||||
"refId": "D"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.9, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "90%",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.75, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "75%",
|
||||
"refId": "C"
|
||||
},
|
||||
{
|
||||
"expr": "histogram_quantile(0.5, sum(rate(synapse_storage_schedule_time_bucket{index=~\"$index\",instance=\"$instance\",job=\"$job\"}[$bucket_size])) by (le))",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 1,
|
||||
"legendFormat": "50%",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeRegions": [],
|
||||
"timeShift": null,
|
||||
"title": "Time waiting for DB connection quantiles",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 2,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"decimals": null,
|
||||
"format": "s",
|
||||
"label": "",
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": "0",
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": false
|
||||
}
|
||||
],
|
||||
"yaxis": {
|
||||
"align": false,
|
||||
"alignLevel": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"repeat": null,
|
||||
@@ -5916,7 +6339,7 @@
|
||||
"h": 10,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 84
|
||||
"y": 35
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 1,
|
||||
@@ -6022,7 +6445,7 @@
|
||||
"h": 10,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 84
|
||||
"y": 35
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 8,
|
||||
@@ -6126,7 +6549,7 @@
|
||||
"h": 10,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 94
|
||||
"y": 45
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 38,
|
||||
@@ -6226,7 +6649,7 @@
|
||||
"h": 10,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 94
|
||||
"y": 45
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 39,
|
||||
@@ -6258,8 +6681,9 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "topk(10, rate(synapse_util_caches_cache:total{job=\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]) - rate(synapse_util_caches_cache:hits{job=\"$job\",instance=\"$instance\"}[$bucket_size]))",
|
||||
"expr": "topk(10, rate(synapse_util_caches_cache:total{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]) - rate(synapse_util_caches_cache:hits{job=~\"$job\",index=~\"$index\",instance=\"$instance\"}[$bucket_size]))",
|
||||
"format": "time_series",
|
||||
"interval": "",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{name}} {{job}}-{{index}}",
|
||||
"refId": "A",
|
||||
@@ -6326,7 +6750,7 @@
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 104
|
||||
"y": 55
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 65,
|
||||
@@ -9051,7 +9475,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 119
|
||||
"y": 41
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 156,
|
||||
@@ -9089,7 +9513,7 @@
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "synapse_admin_mau:current{instance=\"$instance\"}",
|
||||
"expr": "synapse_admin_mau:current{instance=\"$instance\", job=~\"$job\"}",
|
||||
"format": "time_series",
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
@@ -9097,7 +9521,7 @@
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "synapse_admin_mau:max{instance=\"$instance\"}",
|
||||
"expr": "synapse_admin_mau:max{instance=\"$instance\", job=~\"$job\"}",
|
||||
"format": "time_series",
|
||||
"interval": "",
|
||||
"intervalFactor": 1,
|
||||
@@ -9164,7 +9588,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 119
|
||||
"y": 41
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 160,
|
||||
@@ -9484,7 +9908,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 73
|
||||
"y": 43
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 168,
|
||||
@@ -9516,7 +9940,7 @@
|
||||
{
|
||||
"expr": "rate(synapse_appservice_api_sent_events{instance=\"$instance\"}[$bucket_size])",
|
||||
"interval": "",
|
||||
"legendFormat": "{{exported_service}}",
|
||||
"legendFormat": "{{service}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -9579,7 +10003,7 @@
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 73
|
||||
"y": 43
|
||||
},
|
||||
"hiddenSeries": false,
|
||||
"id": 171,
|
||||
@@ -9611,7 +10035,7 @@
|
||||
{
|
||||
"expr": "rate(synapse_appservice_api_sent_transactions{instance=\"$instance\"}[$bucket_size])",
|
||||
"interval": "",
|
||||
"legendFormat": "{{exported_service}}",
|
||||
"legendFormat": "{{service}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
@@ -9959,7 +10383,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:165",
|
||||
"format": "hertz",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -9968,7 +10391,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:166",
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -10071,7 +10493,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:390",
|
||||
"format": "hertz",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -10080,7 +10501,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:391",
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -10169,7 +10589,6 @@
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"$$hashKey": "object:390",
|
||||
"format": "hertz",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -10178,7 +10597,6 @@
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"$$hashKey": "object:391",
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
@@ -10470,5 +10888,5 @@
|
||||
"timezone": "",
|
||||
"title": "Synapse",
|
||||
"uid": "000000012",
|
||||
"version": 90
|
||||
"version": 99
|
||||
}
|
||||
12
debian/changelog
vendored
12
debian/changelog
vendored
@@ -1,3 +1,15 @@
|
||||
matrix-synapse-py3 (1.40.0) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.40.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 10 Aug 2021 13:50:48 +0100
|
||||
|
||||
matrix-synapse-py3 (1.40.0~rc3) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.40.0~rc3.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Mon, 09 Aug 2021 13:41:08 +0100
|
||||
|
||||
matrix-synapse-py3 (1.40.0~rc2) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.40.0~rc2.
|
||||
|
||||
@@ -51,12 +51,10 @@
|
||||
- [Event Reports](admin_api/event_reports.md)
|
||||
- [Media](admin_api/media_admin_api.md)
|
||||
- [Purge History](admin_api/purge_history_api.md)
|
||||
- [Purge Rooms](admin_api/purge_room.md)
|
||||
- [Register Users](admin_api/register_api.md)
|
||||
- [Manipulate Room Membership](admin_api/room_membership.md)
|
||||
- [Rooms](admin_api/rooms.md)
|
||||
- [Server Notices](admin_api/server_notices.md)
|
||||
- [Shutdown Room](admin_api/shutdown_room.md)
|
||||
- [Statistics](admin_api/statistics.md)
|
||||
- [Users](admin_api/user_admin_api.md)
|
||||
- [Server Version](admin_api/version_api.md)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
- [Delete local media](#delete-local-media)
|
||||
* [Delete a specific local media](#delete-a-specific-local-media)
|
||||
* [Delete local media by date or size](#delete-local-media-by-date-or-size)
|
||||
* [Delete media uploaded by a user](#delete-media-uploaded-by-a-user)
|
||||
- [Purge Remote Media API](#purge-remote-media-api)
|
||||
|
||||
# Querying media
|
||||
@@ -47,7 +48,8 @@ The API returns a JSON body like the following:
|
||||
## List all media uploaded by a user
|
||||
|
||||
Listing all media that has been uploaded by a local user can be achieved through
|
||||
the use of the [List media of a user](user_admin_api.md#list-media-of-a-user)
|
||||
the use of the
|
||||
[List media uploaded by a user](user_admin_api.md#list-media-uploaded-by-a-user)
|
||||
Admin API.
|
||||
|
||||
# Quarantine media
|
||||
@@ -281,6 +283,11 @@ The following fields are returned in the JSON response body:
|
||||
* `deleted_media`: an array of strings - List of deleted `media_id`
|
||||
* `total`: integer - Total number of deleted `media_id`
|
||||
|
||||
## Delete media uploaded by a user
|
||||
|
||||
You can find details of how to delete multiple media uploaded by a user in
|
||||
[User Admin API](user_admin_api.md#delete-media-uploaded-by-a-user).
|
||||
|
||||
# Purge Remote Media API
|
||||
|
||||
The purge remote media API allows server admins to purge old cached remote media.
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
Deprecated: Purge room API
|
||||
==========================
|
||||
|
||||
**The old Purge room API is deprecated and will be removed in a future release.
|
||||
See the new [Delete Room API](rooms.md#delete-room-api) for more details.**
|
||||
|
||||
This API will remove all trace of a room from your database.
|
||||
|
||||
All local users must have left the room before it can be removed.
|
||||
|
||||
The API is:
|
||||
|
||||
```
|
||||
POST /_synapse/admin/v1/purge_room
|
||||
|
||||
{
|
||||
"room_id": "!room:id"
|
||||
}
|
||||
```
|
||||
|
||||
You must authenticate using the access token of an admin user.
|
||||
@@ -1,102 +0,0 @@
|
||||
# Deprecated: Shutdown room API
|
||||
|
||||
**The old Shutdown room API is deprecated and will be removed in a future release.
|
||||
See the new [Delete Room API](rooms.md#delete-room-api) for more details.**
|
||||
|
||||
Shuts down a room, preventing new joins and moves local users and room aliases automatically
|
||||
to a new room. The new room will be created with the user specified by the
|
||||
`new_room_user_id` parameter as room administrator and will contain a message
|
||||
explaining what happened. Users invited to the new room will have power level
|
||||
-10 by default, and thus be unable to speak. The old room's power levels will be changed to
|
||||
disallow any further invites or joins.
|
||||
|
||||
The local server will only have the power to move local user and room aliases to
|
||||
the new room. Users on other servers will be unaffected.
|
||||
|
||||
## API
|
||||
|
||||
You will need to authenticate with an access token for an admin user.
|
||||
|
||||
### URL
|
||||
|
||||
`POST /_synapse/admin/v1/shutdown_room/{room_id}`
|
||||
|
||||
### URL Parameters
|
||||
|
||||
* `room_id` - The ID of the room (e.g `!someroom:example.com`)
|
||||
|
||||
### JSON Body Parameters
|
||||
|
||||
* `new_room_user_id` - Required. A string representing the user ID of the user that will admin
|
||||
the new room that all users in the old room will be moved to.
|
||||
* `room_name` - Optional. A string representing the name of the room that new users will be
|
||||
invited to.
|
||||
* `message` - Optional. A string containing the first message that will be sent as
|
||||
`new_room_user_id` in the new room. Ideally this will clearly convey why the
|
||||
original room was shut down.
|
||||
|
||||
If not specified, the default value of `room_name` is "Content Violation
|
||||
Notification". The default value of `message` is "Sharing illegal content on
|
||||
othis server is not permitted and rooms in violation will be blocked."
|
||||
|
||||
### Response Parameters
|
||||
|
||||
* `kicked_users` - An integer number representing the number of users that
|
||||
were kicked.
|
||||
* `failed_to_kick_users` - An integer number representing the number of users
|
||||
that were not kicked.
|
||||
* `local_aliases` - An array of strings representing the local aliases that were migrated from
|
||||
the old room to the new.
|
||||
* `new_room_id` - A string representing the room ID of the new room.
|
||||
|
||||
## Example
|
||||
|
||||
Request:
|
||||
|
||||
```
|
||||
POST /_synapse/admin/v1/shutdown_room/!somebadroom%3Aexample.com
|
||||
|
||||
{
|
||||
"new_room_user_id": "@someuser:example.com",
|
||||
"room_name": "Content Violation Notification",
|
||||
"message": "Bad Room has been shutdown due to content violations on this server. Please review our Terms of Service."
|
||||
}
|
||||
```
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
{
|
||||
"kicked_users": 5,
|
||||
"failed_to_kick_users": 0,
|
||||
"local_aliases": ["#badroom:example.com", "#evilsaloon:example.com],
|
||||
"new_room_id": "!newroomid:example.com",
|
||||
},
|
||||
```
|
||||
|
||||
## Undoing room shutdowns
|
||||
|
||||
*Note*: This guide may be outdated by the time you read it. By nature of room shutdowns being performed at the database level,
|
||||
the structure can and does change without notice.
|
||||
|
||||
First, it's important to understand that a room shutdown is very destructive. Undoing a shutdown is not as simple as pretending it
|
||||
never happened - work has to be done to move forward instead of resetting the past. In fact, in some cases it might not be possible
|
||||
to recover at all:
|
||||
|
||||
* If the room was invite-only, your users will need to be re-invited.
|
||||
* If the room no longer has any members at all, it'll be impossible to rejoin.
|
||||
* The first user to rejoin will have to do so via an alias on a different server.
|
||||
|
||||
With all that being said, if you still want to try and recover the room:
|
||||
|
||||
1. For safety reasons, shut down Synapse.
|
||||
2. In the database, run `DELETE FROM blocked_rooms WHERE room_id = '!example:example.org';`
|
||||
* For caution: it's recommended to run this in a transaction: `BEGIN; DELETE ...;`, verify you got 1 result, then `COMMIT;`.
|
||||
* The room ID is the same one supplied to the shutdown room API, not the Content Violation room.
|
||||
3. Restart Synapse.
|
||||
|
||||
You will have to manually handle, if you so choose, the following:
|
||||
|
||||
* Aliases that would have been redirected to the Content Violation room.
|
||||
* Users that would have been booted from the room (and will have been force-joined to the Content Violation room).
|
||||
* Removal of the Content Violation room if desired.
|
||||
@@ -81,6 +81,16 @@ with a body of:
|
||||
"address": "<user_mail_2>"
|
||||
}
|
||||
],
|
||||
"external_ids": [
|
||||
{
|
||||
"auth_provider": "<provider1>",
|
||||
"external_id": "<user_id_provider_1>"
|
||||
},
|
||||
{
|
||||
"auth_provider": "<provider2>",
|
||||
"external_id": "<user_id_provider_2>"
|
||||
}
|
||||
],
|
||||
"avatar_url": "<avatar_url>",
|
||||
"admin": false,
|
||||
"deactivated": false
|
||||
@@ -90,26 +100,34 @@ with a body of:
|
||||
To use it, you will need to authenticate by providing an `access_token` for a
|
||||
server admin: [Admin API](../usage/administration/admin_api)
|
||||
|
||||
Returns HTTP status code:
|
||||
- `201` - When a new user object was created.
|
||||
- `200` - When a user was modified.
|
||||
|
||||
URL parameters:
|
||||
|
||||
- `user_id`: fully-qualified user id: for example, `@user:server.com`.
|
||||
|
||||
Body parameters:
|
||||
|
||||
- `password`, optional. If provided, the user's password is updated and all
|
||||
- `password` - string, optional. If provided, the user's password is updated and all
|
||||
devices are logged out.
|
||||
|
||||
- `displayname`, optional, defaults to the value of `user_id`.
|
||||
|
||||
- `threepids`, optional, allows setting the third-party IDs (email, msisdn)
|
||||
- `displayname` - string, optional, defaults to the value of `user_id`.
|
||||
- `threepids` - array, optional, allows setting the third-party IDs (email, msisdn)
|
||||
- `medium` - string. Kind of third-party ID, either `email` or `msisdn`.
|
||||
- `address` - string. Value of third-party ID.
|
||||
belonging to a user.
|
||||
|
||||
- `avatar_url`, optional, must be a
|
||||
- `external_ids` - array, optional. Allow setting the identifier of the external identity
|
||||
provider for SSO (Single sign-on). Details in
|
||||
[Sample Configuration File](../usage/configuration/homeserver_sample_config.html)
|
||||
section `sso` and `oidc_providers`.
|
||||
- `auth_provider` - string. ID of the external identity provider. Value of `idp_id`
|
||||
in homeserver configuration.
|
||||
- `external_id` - string, user ID in the external identity provider.
|
||||
- `avatar_url` - string, optional, must be a
|
||||
[MXC URI](https://matrix.org/docs/spec/client_server/r0.6.0#matrix-content-mxc-uris).
|
||||
|
||||
- `admin`, optional, defaults to `false`.
|
||||
|
||||
- `deactivated`, optional. If unspecified, deactivation state will be left
|
||||
- `admin` - bool, optional, defaults to `false`.
|
||||
- `deactivated` - bool, optional. If unspecified, deactivation state will be left
|
||||
unchanged on existing accounts and set to `false` for new accounts.
|
||||
A user cannot be erased by deactivating with this API. For details on
|
||||
deactivating users see [Deactivate Account](#deactivate-account).
|
||||
@@ -443,8 +461,9 @@ The following fields are returned in the JSON response body:
|
||||
- `joined_rooms` - An array of `room_id`.
|
||||
- `total` - Number of rooms.
|
||||
|
||||
## User media
|
||||
|
||||
## List media of a user
|
||||
### List media uploaded by a user
|
||||
Gets a list of all local media that a specific `user_id` has created.
|
||||
By default, the response is ordered by descending creation date and ascending media ID.
|
||||
The newest media is on top. You can change the order with parameters
|
||||
@@ -543,7 +562,6 @@ The following fields are returned in the JSON response body:
|
||||
|
||||
- `media` - An array of objects, each containing information about a media.
|
||||
Media objects contain the following fields:
|
||||
|
||||
- `created_ts` - integer - Timestamp when the content was uploaded in ms.
|
||||
- `last_access_ts` - integer - Timestamp when the content was last accessed in ms.
|
||||
- `media_id` - string - The id used to refer to the media.
|
||||
@@ -551,13 +569,58 @@ The following fields are returned in the JSON response body:
|
||||
- `media_type` - string - The MIME-type of the media.
|
||||
- `quarantined_by` - string - The user ID that initiated the quarantine request
|
||||
for this media.
|
||||
|
||||
- `safe_from_quarantine` - bool - Status if this media is safe from quarantining.
|
||||
- `upload_name` - string - The name the media was uploaded with.
|
||||
|
||||
- `next_token`: integer - Indication for pagination. See above.
|
||||
- `total` - integer - Total number of media.
|
||||
|
||||
### Delete media uploaded by a user
|
||||
|
||||
This API deletes the *local* media from the disk of your own server
|
||||
that a specific `user_id` has created. This includes any local thumbnails.
|
||||
|
||||
This API will not affect media that has been uploaded to external
|
||||
media repositories (e.g https://github.com/turt2live/matrix-media-repo/).
|
||||
|
||||
By default, the API deletes media ordered by descending creation date and ascending media ID.
|
||||
The newest media is deleted first. You can change the order with parameters
|
||||
`order_by` and `dir`. If no `limit` is set the API deletes `100` files per request.
|
||||
|
||||
The API is:
|
||||
|
||||
```
|
||||
DELETE /_synapse/admin/v1/users/<user_id>/media
|
||||
```
|
||||
|
||||
To use it, you will need to authenticate by providing an `access_token` for a
|
||||
server admin: [Admin API](../usage/administration/admin_api)
|
||||
|
||||
A response body like the following is returned:
|
||||
|
||||
```json
|
||||
{
|
||||
"deleted_media": [
|
||||
"abcdefghijklmnopqrstuvwx"
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
The following fields are returned in the JSON response body:
|
||||
|
||||
* `deleted_media`: an array of strings - List of deleted `media_id`
|
||||
* `total`: integer - Total number of deleted `media_id`
|
||||
|
||||
**Note**: There is no `next_token`. This is not useful for deleting media, because
|
||||
after deleting media the remaining media have a new order.
|
||||
|
||||
**Parameters**
|
||||
|
||||
This API has the same parameters as
|
||||
[List media uploaded by a user](#list-media-uploaded-by-a-user).
|
||||
With the parameters you can for example limit the number of files to delete at once or
|
||||
delete largest/smallest or newest/oldest files first.
|
||||
|
||||
## Login as a user
|
||||
|
||||
Get an access token that can be used to authenticate as that user. Useful for
|
||||
@@ -1013,3 +1076,22 @@ The following parameters should be set in the URL:
|
||||
- `user_id` - The fully qualified MXID: for example, `@user:server.com`. The user must
|
||||
be local.
|
||||
|
||||
### Check username availability
|
||||
|
||||
Checks to see if a username is available, and valid, for the server. See [the client-server
|
||||
API](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-register-available)
|
||||
for more information.
|
||||
|
||||
This endpoint will work even if registration is disabled on the server, unlike
|
||||
`/_matrix/client/r0/register/available`.
|
||||
|
||||
The API is:
|
||||
|
||||
```
|
||||
POST /_synapse/admin/v1/username_availabile?username=$localpart
|
||||
```
|
||||
|
||||
The request and response format is the same as the [/_matrix/client/r0/register/available](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-register-available) API.
|
||||
|
||||
To use it, you will need to authenticate by providing an `access_token` for a
|
||||
server admin: [Admin API](../usage/administration/admin_api)
|
||||
|
||||
@@ -67,7 +67,7 @@ This gives a Python REPL in which `hs` gives access to the
|
||||
`synapse.server.HomeServer` object - which in turn gives access to many other
|
||||
parts of the process.
|
||||
|
||||
Note that any call which returns a coroutine will need to be wrapped in `ensureDeferred`.
|
||||
Note that, prior to Synapse 1.41, any call which returns a coroutine will need to be wrapped in `ensureDeferred`.
|
||||
|
||||
As a simple example, retrieving an event from the database:
|
||||
|
||||
|
||||
@@ -282,6 +282,52 @@ the request is a server admin.
|
||||
Modules can modify the `request_content` (by e.g. adding events to its `initial_state`),
|
||||
or deny the room's creation by raising a `module_api.errors.SynapseError`.
|
||||
|
||||
#### Presence router callbacks
|
||||
|
||||
Presence router callbacks allow module developers to specify additional users (local or remote)
|
||||
to receive certain presence updates from local users. Presence router callbacks can be
|
||||
registered using the module API's `register_presence_router_callbacks` method.
|
||||
|
||||
The available presence router callbacks are:
|
||||
|
||||
```python
|
||||
async def get_users_for_states(
|
||||
self,
|
||||
state_updates: Iterable["synapse.api.UserPresenceState"],
|
||||
) -> Dict[str, Set["synapse.api.UserPresenceState"]]:
|
||||
```
|
||||
**Requires** `get_interested_users` to also be registered
|
||||
|
||||
Called when processing updates to the presence state of one or more users. This callback can
|
||||
be used to instruct the server to forward that presence state to specific users. The module
|
||||
must return a dictionary that maps from Matrix user IDs (which can be local or remote) to the
|
||||
`UserPresenceState` changes that they should be forwarded.
|
||||
|
||||
Synapse will then attempt to send the specified presence updates to each user when possible.
|
||||
|
||||
```python
|
||||
async def get_interested_users(
|
||||
self,
|
||||
user_id: str
|
||||
) -> Union[Set[str], "synapse.module_api.PRESENCE_ALL_USERS"]
|
||||
```
|
||||
**Requires** `get_users_for_states` to also be registered
|
||||
|
||||
Called when determining which users someone should be able to see the presence state of. This
|
||||
callback should return complementary results to `get_users_for_state` or the presence information
|
||||
may not be properly forwarded.
|
||||
|
||||
The callback is given the Matrix user ID for a local user that is requesting presence data and
|
||||
should return the Matrix user IDs of the users whose presence state they are allowed to
|
||||
query. The returned users can be local or remote.
|
||||
|
||||
Alternatively the callback can return `synapse.module_api.PRESENCE_ALL_USERS`
|
||||
to indicate that the user should receive updates from all known users.
|
||||
|
||||
For example, if the user `@alice:example.org` is passed to this method, and the Set
|
||||
`{"@bob:example.com", "@charlie:somewhere.org"}` is returned, this signifies that Alice
|
||||
should receive presence updates sent by Bob and Charlie, regardless of whether these users
|
||||
share a room.
|
||||
|
||||
### Porting an existing module that uses the old interface
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
<h2 style="color:red">
|
||||
This page of the Synapse documentation is now deprecated. For up to date
|
||||
documentation on setting up or writing a presence router module, please see
|
||||
<a href="modules.md">this page</a>.
|
||||
</h2>
|
||||
|
||||
# Presence Router Module
|
||||
|
||||
Synapse supports configuring a module that can specify additional users
|
||||
|
||||
@@ -33,6 +33,19 @@ Let's assume that we expect clients to connect to our server at
|
||||
`https://example.com:8448`. The following sections detail the configuration of
|
||||
the reverse proxy and the homeserver.
|
||||
|
||||
|
||||
## Homeserver Configuration
|
||||
|
||||
The HTTP configuration will need to be updated for Synapse to correctly record
|
||||
client IP addresses and generate redirect URLs while behind a reverse proxy.
|
||||
|
||||
In `homeserver.yaml` set `x_forwarded: true` in the port 8008 section and
|
||||
consider setting `bind_addresses: ['127.0.0.1']` so that the server only
|
||||
listens to traffic on localhost. (Do not change `bind_addresses` to `127.0.0.1`
|
||||
when using a containerized Synapse, as that will prevent it from responding
|
||||
to proxied traffic.)
|
||||
|
||||
|
||||
## Reverse-proxy configuration examples
|
||||
|
||||
**NOTE**: You only need one of these.
|
||||
@@ -239,16 +252,6 @@ relay "matrix_federation" {
|
||||
}
|
||||
```
|
||||
|
||||
## Homeserver Configuration
|
||||
|
||||
You will also want to set `bind_addresses: ['127.0.0.1']` and
|
||||
`x_forwarded: true` for port 8008 in `homeserver.yaml` to ensure that
|
||||
client IP addresses are recorded correctly.
|
||||
|
||||
Having done so, you can then use `https://matrix.example.com` (instead
|
||||
of `https://matrix.example.com:8448`) as the "Custom server" when
|
||||
connecting to Synapse from a client.
|
||||
|
||||
|
||||
## Health check endpoint
|
||||
|
||||
|
||||
@@ -108,20 +108,6 @@ presence:
|
||||
#
|
||||
#enabled: false
|
||||
|
||||
# Presence routers are third-party modules that can specify additional logic
|
||||
# to where presence updates from users are routed.
|
||||
#
|
||||
presence_router:
|
||||
# The custom module's class. Uncomment to use a custom presence router module.
|
||||
#
|
||||
#module: "my_custom_router.PresenceRouter"
|
||||
|
||||
# Configuration options of the custom module. Refer to your module's
|
||||
# documentation for available options.
|
||||
#
|
||||
#config:
|
||||
# example_option: 'something'
|
||||
|
||||
# Whether to require authentication to retrieve profile data (avatars,
|
||||
# display names) of other users through the client API. Defaults to
|
||||
# 'false'. Note that profile data is also available via the federation
|
||||
@@ -2242,6 +2228,14 @@ email:
|
||||
#
|
||||
#require_transport_security: true
|
||||
|
||||
# Uncomment the following to disable TLS for SMTP.
|
||||
#
|
||||
# By default, if the server supports TLS, it will be used, and the server
|
||||
# must present a certificate that is valid for 'smtp_host'. If this option
|
||||
# is set to false, TLS will not be used.
|
||||
#
|
||||
#enable_tls: false
|
||||
|
||||
# notif_from defines the "From" address to use when sending emails.
|
||||
# It must be set if email sending is enabled.
|
||||
#
|
||||
|
||||
@@ -45,18 +45,18 @@ The proxy will be **used** for:
|
||||
- recaptcha validation
|
||||
- CAS auth validation
|
||||
- OpenID Connect
|
||||
- Outbound federation
|
||||
- Federation (checking public key revocation)
|
||||
- Fetching public keys of other servers
|
||||
- Downloading remote media
|
||||
|
||||
It will **not be used** for:
|
||||
|
||||
- Application Services
|
||||
- Identity servers
|
||||
- Outbound federation
|
||||
- In worker configurations
|
||||
- connections between workers
|
||||
- connections from workers to Redis
|
||||
- Fetching public keys of other servers
|
||||
- Downloading remote media
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
@@ -85,6 +85,54 @@ process, for example:
|
||||
dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
|
||||
```
|
||||
|
||||
# Upgrading to v1.xx.0
|
||||
|
||||
## Removal of old Room Admin API
|
||||
|
||||
The following admin APIs were deprecated in [Synapse 1.25](https://github.com/matrix-org/synapse/blob/v1.25.0/CHANGES.md#removal-warning)
|
||||
(released on 2021-01-13) and have now been removed:
|
||||
|
||||
- `POST /_synapse/admin/v1/purge_room`
|
||||
- `POST /_synapse/admin/v1/shutdown_room/<room_id>`
|
||||
|
||||
Any scripts still using the above APIs should be converted to use the
|
||||
[Delete Room API](https://matrix-org.github.io/synapse/latest/admin_api/rooms.html#delete-room-api).
|
||||
|
||||
|
||||
# Upgrading to v1.xx.0
|
||||
|
||||
## Add support for routing outbound HTTP requests via a proxy for federation
|
||||
|
||||
Since Synapse 1.6.0 (2019-11-26) you can set a proxy for outbound HTTP requests via
|
||||
http_proxy/https_proxy environment variables. This proxy was set for:
|
||||
- push
|
||||
- url previews
|
||||
- phone-home stats
|
||||
- recaptcha validation
|
||||
- CAS auth validation
|
||||
- OpenID Connect
|
||||
- Federation (checking public key revocation)
|
||||
|
||||
In this version we have added support for outbound requests for:
|
||||
- Outbound federation
|
||||
- Downloading remote media
|
||||
- Fetching public keys of other servers
|
||||
|
||||
These requests use the same proxy configuration. If you have a proxy configuration we
|
||||
recommend to verify the configuration. It may be necessary to adjust the `no_proxy`
|
||||
environment variable.
|
||||
|
||||
See [using a forward proxy with Synapse documentation](setup/forward_proxy.md) for
|
||||
details.
|
||||
|
||||
## User-interactive authentication fallback templates can now display errors
|
||||
|
||||
This may affect you if you make use of custom HTML templates for the
|
||||
[reCAPTCHA](../synapse/res/templates/recaptcha.html) or
|
||||
[terms](../synapse/res/templates/terms.html) fallback pages.
|
||||
|
||||
The template is now provided an `error` variable if the authentication
|
||||
process failed. See the default templates linked above for an example.
|
||||
|
||||
# Upgrading to v1.39.0
|
||||
|
||||
@@ -142,9 +190,9 @@ SQLite databases are unaffected by this change.
|
||||
|
||||
The current spam checker interface is deprecated in favour of a new generic modules system.
|
||||
Authors of spam checker modules can refer to [this
|
||||
documentation](https://matrix-org.github.io/synapse/develop/modules.html#porting-an-existing-module-that-uses-the-old-interface)
|
||||
documentation](modules.md#porting-an-existing-module-that-uses-the-old-interface)
|
||||
to update their modules. Synapse administrators can refer to [this
|
||||
documentation](https://matrix-org.github.io/synapse/develop/modules.html#using-modules)
|
||||
documentation](modules.md#using-modules)
|
||||
to update their configuration once the modules they are using have been updated.
|
||||
|
||||
We plan to remove support for the current spam checker interface in August 2021.
|
||||
@@ -217,8 +265,7 @@ Instructions for doing so are provided
|
||||
|
||||
## Dropping support for old Python, Postgres and SQLite versions
|
||||
|
||||
In line with our [deprecation
|
||||
policy](https://github.com/matrix-org/synapse/blob/release-v1.32.0/docs/deprecation_policy.md),
|
||||
In line with our [deprecation policy](deprecation_policy.md),
|
||||
we've dropped support for Python 3.5 and PostgreSQL 9.5, as they are no
|
||||
longer supported upstream.
|
||||
|
||||
@@ -231,8 +278,7 @@ The deprecated v1 "list accounts" admin API
|
||||
(`GET /_synapse/admin/v1/users/<user_id>`) has been removed in this
|
||||
version.
|
||||
|
||||
The [v2 list accounts
|
||||
API](https://github.com/matrix-org/synapse/blob/master/docs/admin_api/user_admin_api.rst#list-accounts)
|
||||
The [v2 list accounts API](admin_api/user_admin_api.md#list-accounts)
|
||||
has been available since Synapse 1.7.0 (2019-12-13), and is accessible
|
||||
under `GET /_synapse/admin/v2/users`.
|
||||
|
||||
@@ -267,7 +313,7 @@ by the client.
|
||||
|
||||
Synapse also requires the [Host]{.title-ref} header to be preserved.
|
||||
|
||||
See the [reverse proxy documentation](../reverse_proxy.md), where the
|
||||
See the [reverse proxy documentation](reverse_proxy.md), where the
|
||||
example configurations have been updated to show how to set these
|
||||
headers.
|
||||
|
||||
@@ -286,7 +332,7 @@ identity providers:
|
||||
`[synapse public baseurl]/_synapse/client/oidc/callback` to the list
|
||||
of permitted "redirect URIs" at the identity provider.
|
||||
|
||||
See the [OpenID docs](../openid.md) for more information on setting
|
||||
See the [OpenID docs](openid.md) for more information on setting
|
||||
up OpenID Connect.
|
||||
|
||||
- If your server is configured for single sign-on via a SAML2 identity
|
||||
@@ -486,8 +532,7 @@ lock down external access to the Admin API endpoints.
|
||||
This release deprecates use of the `structured: true` logging
|
||||
configuration for structured logging. If your logging configuration
|
||||
contains `structured: true` then it should be modified based on the
|
||||
[structured logging
|
||||
documentation](../structured_logging.md).
|
||||
[structured logging documentation](structured_logging.md).
|
||||
|
||||
The `structured` and `drains` logging options are now deprecated and
|
||||
should be replaced by standard logging configuration of `handlers` and
|
||||
@@ -517,14 +562,13 @@ acts the same as the `http_client` argument previously passed to
|
||||
|
||||
## Forwarding `/_synapse/client` through your reverse proxy
|
||||
|
||||
The [reverse proxy
|
||||
documentation](https://github.com/matrix-org/synapse/blob/develop/docs/reverse_proxy.md)
|
||||
The [reverse proxy documentation](reverse_proxy.md)
|
||||
has been updated to include reverse proxy directives for
|
||||
`/_synapse/client/*` endpoints. As the user password reset flow now uses
|
||||
endpoints under this prefix, **you must update your reverse proxy
|
||||
configurations for user password reset to work**.
|
||||
|
||||
Additionally, note that the [Synapse worker documentation](https://github.com/matrix-org/synapse/blob/develop/docs/workers.md) has been updated to
|
||||
Additionally, note that the [Synapse worker documentation](workers.md) has been updated to
|
||||
|
||||
: state that the `/_synapse/client/password_reset/email/submit_token`
|
||||
endpoint can be handled
|
||||
@@ -588,7 +632,7 @@ updated.
|
||||
When setting up worker processes, we now recommend the use of a Redis
|
||||
server for replication. **The old direct TCP connection method is
|
||||
deprecated and will be removed in a future release.** See
|
||||
[workers](../workers.md) for more details.
|
||||
[workers](workers.md) for more details.
|
||||
|
||||
# Upgrading to v1.14.0
|
||||
|
||||
@@ -720,8 +764,7 @@ participating in many rooms.
|
||||
omitting the `CONCURRENTLY` keyword. Note however that this
|
||||
operation may in itself cause Synapse to stop running for some time.
|
||||
Synapse admins are reminded that [SQLite is not recommended for use
|
||||
outside a test
|
||||
environment](https://github.com/matrix-org/synapse/blob/master/README.rst#using-postgresql).
|
||||
outside a test environment](postgres.md).
|
||||
|
||||
3. Once the index has been created, the `SELECT` query in step 1 above
|
||||
should complete quickly. It is therefore safe to upgrade to Synapse
|
||||
@@ -739,7 +782,7 @@ participating in many rooms.
|
||||
Synapse will now log a warning on start up if used with a PostgreSQL
|
||||
database that has a non-recommended locale set.
|
||||
|
||||
See [Postgres](../postgres.md) for details.
|
||||
See [Postgres](postgres.md) for details.
|
||||
|
||||
# Upgrading to v1.8.0
|
||||
|
||||
@@ -856,8 +899,8 @@ section headed `email`, and be sure to have at least the
|
||||
You may also need to set `smtp_user`, `smtp_pass`, and
|
||||
`require_transport_security`.
|
||||
|
||||
See the [sample configuration file](docs/sample_config.yaml) for more
|
||||
details on these settings.
|
||||
See the [sample configuration file](usage/configuration/homeserver_sample_config.md)
|
||||
for more details on these settings.
|
||||
|
||||
#### Delegate email to an identity server
|
||||
|
||||
@@ -959,7 +1002,7 @@ back to v1.3.1, subject to the following:
|
||||
|
||||
Some counter metrics have been renamed, with the old names deprecated.
|
||||
See [the metrics
|
||||
documentation](../metrics-howto.md#renaming-of-metrics--deprecation-of-old-names-in-12)
|
||||
documentation](metrics-howto.md#renaming-of-metrics--deprecation-of-old-names-in-12)
|
||||
for details.
|
||||
|
||||
# Upgrading to v1.1.0
|
||||
@@ -995,7 +1038,7 @@ more details on upgrading your database.
|
||||
Synapse v1.0 is the first release to enforce validation of TLS
|
||||
certificates for the federation API. It is therefore essential that your
|
||||
certificates are correctly configured. See the
|
||||
[FAQ](../MSC1711_certificates_FAQ.md) for more information.
|
||||
[FAQ](MSC1711_certificates_FAQ.md) for more information.
|
||||
|
||||
Note, v1.0 installations will also no longer be able to federate with
|
||||
servers that have not correctly configured their certificates.
|
||||
@@ -1010,8 +1053,8 @@ ways:-
|
||||
- Configure a whitelist of server domains to trust via
|
||||
`federation_certificate_verification_whitelist`.
|
||||
|
||||
See the [sample configuration file](docs/sample_config.yaml) for more
|
||||
details on these settings.
|
||||
See the [sample configuration file](usage/configuration/homeserver_sample_config.md)
|
||||
for more details on these settings.
|
||||
|
||||
## Email
|
||||
|
||||
@@ -1036,8 +1079,8 @@ If you are absolutely certain that you wish to continue using an
|
||||
identity server for password resets, set
|
||||
`trust_identity_server_for_password_resets` to `true`.
|
||||
|
||||
See the [sample configuration file](docs/sample_config.yaml) for more
|
||||
details on these settings.
|
||||
See the [sample configuration file](usage/configuration/homeserver_sample_config.md)
|
||||
for more details on these settings.
|
||||
|
||||
## New email templates
|
||||
|
||||
@@ -1057,11 +1100,11 @@ sent to them.
|
||||
|
||||
Please be aware that, before Synapse v1.0 is released around March 2019,
|
||||
you will need to replace any self-signed certificates with those
|
||||
verified by a root CA. Information on how to do so can be found at [the
|
||||
ACME docs](../ACME.md).
|
||||
verified by a root CA. Information on how to do so can be found at the
|
||||
ACME docs.
|
||||
|
||||
For more information on configuring TLS certificates see the
|
||||
[FAQ](../MSC1711_certificates_FAQ.md).
|
||||
[FAQ](MSC1711_certificates_FAQ.md).
|
||||
|
||||
# Upgrading to v0.34.0
|
||||
|
||||
|
||||
1
mypy.ini
1
mypy.ini
@@ -86,6 +86,7 @@ files =
|
||||
tests/test_event_auth.py,
|
||||
tests/test_utils,
|
||||
tests/handlers/test_password_providers.py,
|
||||
tests/handlers/test_room_summary.py,
|
||||
tests/rest/client/v1/test_login.py,
|
||||
tests/rest/client/v2_alpha/test_auth.py,
|
||||
tests/util/test_itertools.py,
|
||||
|
||||
@@ -25,7 +25,6 @@ DISTS = (
|
||||
"debian:sid",
|
||||
"ubuntu:bionic", # 18.04 LTS (our EOL forced by Py36 on 2021-12-23)
|
||||
"ubuntu:focal", # 20.04 LTS (our EOL forced by Py38 on 2024-10-14)
|
||||
"ubuntu:groovy", # 20.10 (EOL 2021-07-07)
|
||||
"ubuntu:hirsute", # 21.04 (EOL 2022-01-05)
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ set -e
|
||||
git remote set-branches --add origin develop
|
||||
git fetch -q origin develop
|
||||
|
||||
pr="$BUILDKITE_PULL_REQUEST"
|
||||
pr="$PULL_REQUEST_NUMBER"
|
||||
|
||||
# if there are changes in the debian directory, check that the debian changelog
|
||||
# has been updated
|
||||
|
||||
@@ -94,7 +94,7 @@ else
|
||||
"scripts-dev/build_debian_packages"
|
||||
"scripts-dev/sign_json"
|
||||
"scripts-dev/update_database"
|
||||
"contrib" "synctl" "setup.py" "synmark" "stubs" ".buildkite"
|
||||
"contrib" "synctl" "setup.py" "synmark" "stubs" ".ci"
|
||||
)
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -47,7 +47,7 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
__version__ = "1.40.0rc2"
|
||||
__version__ = "1.40.0"
|
||||
|
||||
if bool(os.environ.get("SYNAPSE_TEST_PATCH_LOG_CONTEXTS", False)):
|
||||
# We import here so that we don't have to install a bunch of deps when
|
||||
|
||||
@@ -62,7 +62,7 @@ class JoinRules:
|
||||
INVITE = "invite"
|
||||
PRIVATE = "private"
|
||||
# As defined for MSC3083.
|
||||
MSC3083_RESTRICTED = "restricted"
|
||||
RESTRICTED = "restricted"
|
||||
|
||||
|
||||
class RestrictedJoinRuleTypes:
|
||||
|
||||
@@ -76,6 +76,8 @@ class RoomVersion:
|
||||
# MSC2716: Adds m.room.power_levels -> content.historical field to control
|
||||
# whether "insertion", "chunk", "marker" events can be sent
|
||||
msc2716_historical = attr.ib(type=bool)
|
||||
# MSC2716: Adds support for redacting "insertion", "chunk", and "marker" events
|
||||
msc2716_redactions = attr.ib(type=bool)
|
||||
|
||||
|
||||
class RoomVersions:
|
||||
@@ -92,6 +94,7 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V2 = RoomVersion(
|
||||
"2",
|
||||
@@ -106,6 +109,7 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V3 = RoomVersion(
|
||||
"3",
|
||||
@@ -120,6 +124,7 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V4 = RoomVersion(
|
||||
"4",
|
||||
@@ -134,6 +139,7 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V5 = RoomVersion(
|
||||
"5",
|
||||
@@ -148,6 +154,7 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V6 = RoomVersion(
|
||||
"6",
|
||||
@@ -162,6 +169,7 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
MSC2176 = RoomVersion(
|
||||
"org.matrix.msc2176",
|
||||
@@ -176,20 +184,7 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
)
|
||||
MSC3083 = RoomVersion(
|
||||
"org.matrix.msc3083.v2",
|
||||
RoomDisposition.UNSTABLE,
|
||||
EventFormatVersions.V3,
|
||||
StateResolutionVersions.V2,
|
||||
enforce_key_validity=True,
|
||||
special_case_aliases_auth=False,
|
||||
strict_canonicaljson=True,
|
||||
limit_notifications_power_levels=True,
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=True,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V7 = RoomVersion(
|
||||
"7",
|
||||
@@ -204,10 +199,26 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=True,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V8 = RoomVersion(
|
||||
"8",
|
||||
RoomDisposition.STABLE,
|
||||
EventFormatVersions.V3,
|
||||
StateResolutionVersions.V2,
|
||||
enforce_key_validity=True,
|
||||
special_case_aliases_auth=False,
|
||||
strict_canonicaljson=True,
|
||||
limit_notifications_power_levels=True,
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=True,
|
||||
msc2403_knocking=True,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
MSC2716 = RoomVersion(
|
||||
"org.matrix.msc2716",
|
||||
RoomDisposition.STABLE,
|
||||
RoomDisposition.UNSTABLE,
|
||||
EventFormatVersions.V3,
|
||||
StateResolutionVersions.V2,
|
||||
enforce_key_validity=True,
|
||||
@@ -218,6 +229,22 @@ class RoomVersions:
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=True,
|
||||
msc2716_historical=True,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
MSC2716v2 = RoomVersion(
|
||||
"org.matrix.msc2716v2",
|
||||
RoomDisposition.UNSTABLE,
|
||||
EventFormatVersions.V3,
|
||||
StateResolutionVersions.V2,
|
||||
enforce_key_validity=True,
|
||||
special_case_aliases_auth=False,
|
||||
strict_canonicaljson=True,
|
||||
limit_notifications_power_levels=True,
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=True,
|
||||
msc2716_historical=True,
|
||||
msc2716_redactions=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -231,9 +258,9 @@ KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {
|
||||
RoomVersions.V5,
|
||||
RoomVersions.V6,
|
||||
RoomVersions.MSC2176,
|
||||
RoomVersions.MSC3083,
|
||||
RoomVersions.V7,
|
||||
RoomVersions.MSC2716,
|
||||
RoomVersions.V8,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ from synapse.app import check_bind_error
|
||||
from synapse.app.phone_stats_home import start_phone_stats_home
|
||||
from synapse.config.homeserver import HomeServerConfig
|
||||
from synapse.crypto import context_factory
|
||||
from synapse.events.presence_router import load_legacy_presence_router
|
||||
from synapse.events.spamcheck import load_legacy_spam_checkers
|
||||
from synapse.events.third_party_rules import load_legacy_third_party_event_rules
|
||||
from synapse.logging.context import PreserveLoggingContext
|
||||
@@ -370,6 +371,7 @@ async def start(hs: "HomeServer"):
|
||||
|
||||
load_legacy_spam_checkers(hs)
|
||||
load_legacy_third_party_event_rules(hs)
|
||||
load_legacy_presence_router(hs)
|
||||
|
||||
# If we've configured an expiry time for caches, start the background job now.
|
||||
setup_expire_lru_cache_entries(hs)
|
||||
|
||||
@@ -66,40 +66,40 @@ from synapse.replication.slave.storage.receipts import SlavedReceiptsStore
|
||||
from synapse.replication.slave.storage.registration import SlavedRegistrationStore
|
||||
from synapse.replication.slave.storage.room import RoomStore
|
||||
from synapse.rest.admin import register_servlets_for_media_repo
|
||||
from synapse.rest.client.v1 import events, login, presence, room
|
||||
from synapse.rest.client.v1.initial_sync import InitialSyncRestServlet
|
||||
from synapse.rest.client.v1.profile import (
|
||||
ProfileAvatarURLRestServlet,
|
||||
ProfileDisplaynameRestServlet,
|
||||
ProfileRestServlet,
|
||||
)
|
||||
from synapse.rest.client.v1.push_rule import PushRuleRestServlet
|
||||
from synapse.rest.client.v1.voip import VoipRestServlet
|
||||
from synapse.rest.client.v2_alpha import (
|
||||
from synapse.rest.client import (
|
||||
account_data,
|
||||
events,
|
||||
groups,
|
||||
login,
|
||||
presence,
|
||||
read_marker,
|
||||
receipts,
|
||||
room,
|
||||
room_keys,
|
||||
sync,
|
||||
tags,
|
||||
user_directory,
|
||||
)
|
||||
from synapse.rest.client.v2_alpha._base import client_patterns
|
||||
from synapse.rest.client.v2_alpha.account import ThreepidRestServlet
|
||||
from synapse.rest.client.v2_alpha.account_data import (
|
||||
AccountDataServlet,
|
||||
RoomAccountDataServlet,
|
||||
)
|
||||
from synapse.rest.client.v2_alpha.devices import DevicesRestServlet
|
||||
from synapse.rest.client.v2_alpha.keys import (
|
||||
from synapse.rest.client._base import client_patterns
|
||||
from synapse.rest.client.account import ThreepidRestServlet
|
||||
from synapse.rest.client.account_data import AccountDataServlet, RoomAccountDataServlet
|
||||
from synapse.rest.client.devices import DevicesRestServlet
|
||||
from synapse.rest.client.initial_sync import InitialSyncRestServlet
|
||||
from synapse.rest.client.keys import (
|
||||
KeyChangesServlet,
|
||||
KeyQueryServlet,
|
||||
OneTimeKeyServlet,
|
||||
)
|
||||
from synapse.rest.client.v2_alpha.register import RegisterRestServlet
|
||||
from synapse.rest.client.v2_alpha.sendtodevice import SendToDeviceRestServlet
|
||||
from synapse.rest.client.profile import (
|
||||
ProfileAvatarURLRestServlet,
|
||||
ProfileDisplaynameRestServlet,
|
||||
ProfileRestServlet,
|
||||
)
|
||||
from synapse.rest.client.push_rule import PushRuleRestServlet
|
||||
from synapse.rest.client.register import RegisterRestServlet
|
||||
from synapse.rest.client.sendtodevice import SendToDeviceRestServlet
|
||||
from synapse.rest.client.versions import VersionsRestServlet
|
||||
from synapse.rest.client.voip import VoipRestServlet
|
||||
from synapse.rest.health import HealthResource
|
||||
from synapse.rest.key.v2 import KeyApiV2Resource
|
||||
from synapse.rest.synapse.client import build_synapse_client_resource_tree
|
||||
|
||||
@@ -237,13 +237,14 @@ class Config:
|
||||
def read_templates(
|
||||
self,
|
||||
filenames: List[str],
|
||||
custom_template_directory: Optional[str] = None,
|
||||
custom_template_directories: Optional[Iterable[str]] = None,
|
||||
) -> List[jinja2.Template]:
|
||||
"""Load a list of template files from disk using the given variables.
|
||||
|
||||
This function will attempt to load the given templates from the default Synapse
|
||||
template directory. If `custom_template_directory` is supplied, that directory
|
||||
is tried first.
|
||||
template directory. If `custom_template_directories` is supplied, any directory
|
||||
in this list is tried (in the order they appear in the list) before trying
|
||||
Synapse's default directory.
|
||||
|
||||
Files read are treated as Jinja templates. The templates are not rendered yet
|
||||
and have autoescape enabled.
|
||||
@@ -251,8 +252,8 @@ class Config:
|
||||
Args:
|
||||
filenames: A list of template filenames to read.
|
||||
|
||||
custom_template_directory: A directory to try to look for the templates
|
||||
before using the default Synapse template directory instead.
|
||||
custom_template_directories: A list of directory to try to look for the
|
||||
templates before using the default Synapse template directory instead.
|
||||
|
||||
Raises:
|
||||
ConfigError: if the file's path is incorrect or otherwise cannot be read.
|
||||
@@ -260,20 +261,26 @@ class Config:
|
||||
Returns:
|
||||
A list of jinja2 templates.
|
||||
"""
|
||||
search_directories = [self.default_template_dir]
|
||||
search_directories = []
|
||||
|
||||
# The loader will first look in the custom template directory (if specified) for the
|
||||
# given filename. If it doesn't find it, it will use the default template dir instead
|
||||
if custom_template_directory:
|
||||
# Check that the given template directory exists
|
||||
if not self.path_exists(custom_template_directory):
|
||||
raise ConfigError(
|
||||
"Configured template directory does not exist: %s"
|
||||
% (custom_template_directory,)
|
||||
)
|
||||
# The loader will first look in the custom template directories (if specified)
|
||||
# for the given filename. If it doesn't find it, it will use the default
|
||||
# template dir instead.
|
||||
if custom_template_directories is not None:
|
||||
for custom_template_directory in custom_template_directories:
|
||||
# Check that the given template directory exists
|
||||
if not self.path_exists(custom_template_directory):
|
||||
raise ConfigError(
|
||||
"Configured template directory does not exist: %s"
|
||||
% (custom_template_directory,)
|
||||
)
|
||||
|
||||
# Search the custom template directory as well
|
||||
search_directories.insert(0, custom_template_directory)
|
||||
# Search the custom template directory as well
|
||||
search_directories.append(custom_template_directory)
|
||||
|
||||
# Append the default directory at the end of the list so Jinja can fallback on it
|
||||
# if a template is missing from any custom directory.
|
||||
search_directories.append(self.default_template_dir)
|
||||
|
||||
# TODO: switch to synapse.util.templates.build_jinja_env
|
||||
loader = jinja2.FileSystemLoader(search_directories)
|
||||
|
||||
@@ -88,5 +88,5 @@ class AccountValidityConfig(Config):
|
||||
"account_previously_renewed.html",
|
||||
invalid_token_template_filename,
|
||||
],
|
||||
account_validity_template_dir,
|
||||
(td for td in (account_validity_template_dir,) if td),
|
||||
)
|
||||
|
||||
@@ -80,6 +80,12 @@ class EmailConfig(Config):
|
||||
self.require_transport_security = email_config.get(
|
||||
"require_transport_security", False
|
||||
)
|
||||
self.enable_smtp_tls = email_config.get("enable_tls", True)
|
||||
if self.require_transport_security and not self.enable_smtp_tls:
|
||||
raise ConfigError(
|
||||
"email.require_transport_security requires email.enable_tls to be true"
|
||||
)
|
||||
|
||||
if "app_name" in email_config:
|
||||
self.email_app_name = email_config["app_name"]
|
||||
else:
|
||||
@@ -251,7 +257,9 @@ class EmailConfig(Config):
|
||||
registration_template_success_html,
|
||||
add_threepid_template_success_html,
|
||||
],
|
||||
template_dir,
|
||||
(
|
||||
td for td in (template_dir,) if td
|
||||
), # Filter out template_dir if not provided
|
||||
)
|
||||
|
||||
# Render templates that do not contain any placeholders
|
||||
@@ -291,7 +299,7 @@ class EmailConfig(Config):
|
||||
self.email_notif_template_text,
|
||||
) = self.read_templates(
|
||||
[notif_template_html, notif_template_text],
|
||||
template_dir,
|
||||
(td for td in (template_dir,) if td),
|
||||
)
|
||||
|
||||
self.email_notif_for_new_users = email_config.get(
|
||||
@@ -314,7 +322,7 @@ class EmailConfig(Config):
|
||||
self.account_validity_template_text,
|
||||
) = self.read_templates(
|
||||
[expiry_template_html, expiry_template_text],
|
||||
template_dir,
|
||||
(td for td in (template_dir,) if td),
|
||||
)
|
||||
|
||||
subjects_config = email_config.get("subjects", {})
|
||||
@@ -368,6 +376,14 @@ class EmailConfig(Config):
|
||||
#
|
||||
#require_transport_security: true
|
||||
|
||||
# Uncomment the following to disable TLS for SMTP.
|
||||
#
|
||||
# By default, if the server supports TLS, it will be used, and the server
|
||||
# must present a certificate that is valid for 'smtp_host'. If this option
|
||||
# is set to false, TLS will not be used.
|
||||
#
|
||||
#enable_tls: false
|
||||
|
||||
# notif_from defines the "From" address to use when sending emails.
|
||||
# It must be set if email sending is enabled.
|
||||
#
|
||||
|
||||
@@ -38,3 +38,6 @@ class ExperimentalConfig(Config):
|
||||
|
||||
# MSC3244 (room version capabilities)
|
||||
self.msc3244_enabled: bool = experimental.get("msc3244_enabled", False)
|
||||
|
||||
# MSC3266 (room summary api)
|
||||
self.msc3266_enabled: bool = experimental.get("msc3266_enabled", False)
|
||||
|
||||
@@ -248,6 +248,7 @@ class ServerConfig(Config):
|
||||
self.use_presence = config.get("use_presence", True)
|
||||
|
||||
# Custom presence router module
|
||||
# This is the legacy way of configuring it (the config should now be put in the modules section)
|
||||
self.presence_router_module_class = None
|
||||
self.presence_router_config = None
|
||||
presence_router_config = presence_config.get("presence_router")
|
||||
@@ -858,20 +859,6 @@ class ServerConfig(Config):
|
||||
#
|
||||
#enabled: false
|
||||
|
||||
# Presence routers are third-party modules that can specify additional logic
|
||||
# to where presence updates from users are routed.
|
||||
#
|
||||
presence_router:
|
||||
# The custom module's class. Uncomment to use a custom presence router module.
|
||||
#
|
||||
#module: "my_custom_router.PresenceRouter"
|
||||
|
||||
# Configuration options of the custom module. Refer to your module's
|
||||
# documentation for available options.
|
||||
#
|
||||
#config:
|
||||
# example_option: 'something'
|
||||
|
||||
# Whether to require authentication to retrieve profile data (avatars,
|
||||
# display names) of other users through the client API. Defaults to
|
||||
# 'false'. Note that profile data is also available via the federation
|
||||
|
||||
@@ -63,7 +63,7 @@ class SSOConfig(Config):
|
||||
"sso_auth_success.html",
|
||||
"sso_auth_bad_user.html",
|
||||
],
|
||||
self.sso_template_dir,
|
||||
(td for td in (self.sso_template_dir,) if td),
|
||||
)
|
||||
|
||||
# These templates have no placeholders, so render them here
|
||||
|
||||
@@ -370,10 +370,7 @@ def _is_membership_change_allowed(
|
||||
raise AuthError(403, "You are banned from this room")
|
||||
elif join_rule == JoinRules.PUBLIC:
|
||||
pass
|
||||
elif (
|
||||
room_version.msc3083_join_rules
|
||||
and join_rule == JoinRules.MSC3083_RESTRICTED
|
||||
):
|
||||
elif room_version.msc3083_join_rules and join_rule == JoinRules.RESTRICTED:
|
||||
# This is the same as public, but the event must contain a reference
|
||||
# to the server who authorised the join. If the event does not contain
|
||||
# the proper content it is rejected.
|
||||
|
||||
@@ -396,10 +396,11 @@ class FrozenEvent(EventBase):
|
||||
return self.__repr__()
|
||||
|
||||
def __repr__(self):
|
||||
return "<FrozenEvent event_id=%r, type=%r, state_key=%r>" % (
|
||||
return "<FrozenEvent event_id=%r, type=%r, state_key=%r, outlier=%s>" % (
|
||||
self.get("event_id", None),
|
||||
self.get("type", None),
|
||||
self.get("state_key", None),
|
||||
self.internal_metadata.is_outlier(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -11,45 +11,115 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from typing import TYPE_CHECKING, Dict, Iterable, Set, Union
|
||||
import logging
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Awaitable,
|
||||
Callable,
|
||||
Dict,
|
||||
Iterable,
|
||||
List,
|
||||
Optional,
|
||||
Set,
|
||||
Union,
|
||||
)
|
||||
|
||||
from synapse.api.presence import UserPresenceState
|
||||
from synapse.util.async_helpers import maybe_awaitable
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from synapse.server import HomeServer
|
||||
|
||||
GET_USERS_FOR_STATES_CALLBACK = Callable[
|
||||
[Iterable[UserPresenceState]], Awaitable[Dict[str, Set[UserPresenceState]]]
|
||||
]
|
||||
GET_INTERESTED_USERS_CALLBACK = Callable[
|
||||
[str], Awaitable[Union[Set[str], "PresenceRouter.ALL_USERS"]]
|
||||
]
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def load_legacy_presence_router(hs: "HomeServer"):
|
||||
"""Wrapper that loads a presence router module configured using the old
|
||||
configuration, and registers the hooks they implement.
|
||||
"""
|
||||
|
||||
if hs.config.presence_router_module_class is None:
|
||||
return
|
||||
|
||||
module = hs.config.presence_router_module_class
|
||||
config = hs.config.presence_router_config
|
||||
api = hs.get_module_api()
|
||||
|
||||
presence_router = module(config=config, module_api=api)
|
||||
|
||||
# The known hooks. If a module implements a method which name appears in this set,
|
||||
# we'll want to register it.
|
||||
presence_router_methods = {
|
||||
"get_users_for_states",
|
||||
"get_interested_users",
|
||||
}
|
||||
|
||||
# All methods that the module provides should be async, but this wasn't enforced
|
||||
# in the old module system, so we wrap them if needed
|
||||
def async_wrapper(f: Optional[Callable]) -> Optional[Callable[..., Awaitable]]:
|
||||
# f might be None if the callback isn't implemented by the module. In this
|
||||
# case we don't want to register a callback at all so we return None.
|
||||
if f is None:
|
||||
return None
|
||||
|
||||
def run(*args, **kwargs):
|
||||
# mypy doesn't do well across function boundaries so we need to tell it
|
||||
# f is definitely not None.
|
||||
assert f is not None
|
||||
|
||||
return maybe_awaitable(f(*args, **kwargs))
|
||||
|
||||
return run
|
||||
|
||||
# Register the hooks through the module API.
|
||||
hooks = {
|
||||
hook: async_wrapper(getattr(presence_router, hook, None))
|
||||
for hook in presence_router_methods
|
||||
}
|
||||
|
||||
api.register_presence_router_callbacks(**hooks)
|
||||
|
||||
|
||||
class PresenceRouter:
|
||||
"""
|
||||
A module that the homeserver will call upon to help route user presence updates to
|
||||
additional destinations. If a custom presence router is configured, calls will be
|
||||
passed to that instead.
|
||||
additional destinations.
|
||||
"""
|
||||
|
||||
ALL_USERS = "ALL"
|
||||
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
self.custom_presence_router = None
|
||||
# Initially there are no callbacks
|
||||
self._get_users_for_states_callbacks: List[GET_USERS_FOR_STATES_CALLBACK] = []
|
||||
self._get_interested_users_callbacks: List[GET_INTERESTED_USERS_CALLBACK] = []
|
||||
|
||||
# Check whether a custom presence router module has been configured
|
||||
if hs.config.presence_router_module_class:
|
||||
# Initialise the module
|
||||
self.custom_presence_router = hs.config.presence_router_module_class(
|
||||
config=hs.config.presence_router_config, module_api=hs.get_module_api()
|
||||
def register_presence_router_callbacks(
|
||||
self,
|
||||
get_users_for_states: Optional[GET_USERS_FOR_STATES_CALLBACK] = None,
|
||||
get_interested_users: Optional[GET_INTERESTED_USERS_CALLBACK] = None,
|
||||
):
|
||||
# PresenceRouter modules are required to implement both of these methods
|
||||
# or neither of them as they are assumed to act in a complementary manner
|
||||
paired_methods = [get_users_for_states, get_interested_users]
|
||||
if paired_methods.count(None) == 1:
|
||||
raise RuntimeError(
|
||||
"PresenceRouter modules must register neither or both of the paired callbacks: "
|
||||
"[get_users_for_states, get_interested_users]"
|
||||
)
|
||||
|
||||
# Ensure the module has implemented the required methods
|
||||
required_methods = ["get_users_for_states", "get_interested_users"]
|
||||
for method_name in required_methods:
|
||||
if not hasattr(self.custom_presence_router, method_name):
|
||||
raise Exception(
|
||||
"PresenceRouter module '%s' must implement all required methods: %s"
|
||||
% (
|
||||
hs.config.presence_router_module_class.__name__,
|
||||
", ".join(required_methods),
|
||||
)
|
||||
)
|
||||
# Append the methods provided to the lists of callbacks
|
||||
if get_users_for_states is not None:
|
||||
self._get_users_for_states_callbacks.append(get_users_for_states)
|
||||
|
||||
if get_interested_users is not None:
|
||||
self._get_interested_users_callbacks.append(get_interested_users)
|
||||
|
||||
async def get_users_for_states(
|
||||
self,
|
||||
@@ -66,14 +136,40 @@ class PresenceRouter:
|
||||
A dictionary of user_id -> set of UserPresenceState, indicating which
|
||||
presence updates each user should receive.
|
||||
"""
|
||||
if self.custom_presence_router is not None:
|
||||
# Ask the custom module
|
||||
return await self.custom_presence_router.get_users_for_states(
|
||||
state_updates=state_updates
|
||||
)
|
||||
|
||||
# Don't include any extra destinations for presence updates
|
||||
return {}
|
||||
# Bail out early if we don't have any callbacks to run.
|
||||
if len(self._get_users_for_states_callbacks) == 0:
|
||||
# Don't include any extra destinations for presence updates
|
||||
return {}
|
||||
|
||||
users_for_states = {}
|
||||
# run all the callbacks for get_users_for_states and combine the results
|
||||
for callback in self._get_users_for_states_callbacks:
|
||||
try:
|
||||
result = await callback(state_updates)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to run module API callback %s: %s", callback, e)
|
||||
continue
|
||||
|
||||
if not isinstance(result, Dict):
|
||||
logger.warning(
|
||||
"Wrong type returned by module API callback %s: %s, expected Dict",
|
||||
callback,
|
||||
result,
|
||||
)
|
||||
continue
|
||||
|
||||
for key, new_entries in result.items():
|
||||
if not isinstance(new_entries, Set):
|
||||
logger.warning(
|
||||
"Wrong type returned by module API callback %s: %s, expected Set",
|
||||
callback,
|
||||
new_entries,
|
||||
)
|
||||
break
|
||||
users_for_states.setdefault(key, set()).update(new_entries)
|
||||
|
||||
return users_for_states
|
||||
|
||||
async def get_interested_users(self, user_id: str) -> Union[Set[str], ALL_USERS]:
|
||||
"""
|
||||
@@ -92,12 +188,36 @@ class PresenceRouter:
|
||||
A set of user IDs to return presence updates for, or ALL_USERS to return all
|
||||
known updates.
|
||||
"""
|
||||
if self.custom_presence_router is not None:
|
||||
# Ask the custom module for interested users
|
||||
return await self.custom_presence_router.get_interested_users(
|
||||
user_id=user_id
|
||||
)
|
||||
|
||||
# A custom presence router is not defined.
|
||||
# Don't report any additional interested users
|
||||
return set()
|
||||
# Bail out early if we don't have any callbacks to run.
|
||||
if len(self._get_interested_users_callbacks) == 0:
|
||||
# Don't report any additional interested users
|
||||
return set()
|
||||
|
||||
interested_users = set()
|
||||
# run all the callbacks for get_interested_users and combine the results
|
||||
for callback in self._get_interested_users_callbacks:
|
||||
try:
|
||||
result = await callback(user_id)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to run module API callback %s: %s", callback, e)
|
||||
continue
|
||||
|
||||
# If one of the callbacks returns ALL_USERS then we can stop calling all
|
||||
# of the other callbacks, since the set of interested_users is already as
|
||||
# large as it can possibly be
|
||||
if result == PresenceRouter.ALL_USERS:
|
||||
return PresenceRouter.ALL_USERS
|
||||
|
||||
if not isinstance(result, Set):
|
||||
logger.warning(
|
||||
"Wrong type returned by module API callback %s: %s, expected set",
|
||||
callback,
|
||||
result,
|
||||
)
|
||||
continue
|
||||
|
||||
# Add the new interested users to the set
|
||||
interested_users.update(result)
|
||||
|
||||
return interested_users
|
||||
|
||||
@@ -17,7 +17,7 @@ from typing import Any, Mapping, Union
|
||||
|
||||
from frozendict import frozendict
|
||||
|
||||
from synapse.api.constants import EventTypes, RelationTypes
|
||||
from synapse.api.constants import EventContentFields, EventTypes, RelationTypes
|
||||
from synapse.api.errors import Codes, SynapseError
|
||||
from synapse.api.room_versions import RoomVersion
|
||||
from synapse.util.async_helpers import yieldable_gather_results
|
||||
@@ -135,6 +135,12 @@ def prune_event_dict(room_version: RoomVersion, event_dict: dict) -> dict:
|
||||
add_fields("history_visibility")
|
||||
elif event_type == EventTypes.Redaction and room_version.msc2176_redaction_rules:
|
||||
add_fields("redacts")
|
||||
elif room_version.msc2716_redactions and event_type == EventTypes.MSC2716_INSERTION:
|
||||
add_fields(EventContentFields.MSC2716_NEXT_CHUNK_ID)
|
||||
elif room_version.msc2716_redactions and event_type == EventTypes.MSC2716_CHUNK:
|
||||
add_fields(EventContentFields.MSC2716_CHUNK_ID)
|
||||
elif room_version.msc2716_redactions and event_type == EventTypes.MSC2716_MARKER:
|
||||
add_fields(EventContentFields.MSC2716_MARKER_INSERTION)
|
||||
|
||||
allowed_fields = {k: v for k, v in event_dict.items() if k in allowed_keys}
|
||||
|
||||
|
||||
@@ -1108,7 +1108,8 @@ class FederationClient(FederationBase):
|
||||
The response from the remote server.
|
||||
|
||||
Raises:
|
||||
HttpResponseException: There was an exception returned from the remote server
|
||||
HttpResponseException / RequestSendFailed: There was an exception
|
||||
returned from the remote server
|
||||
SynapseException: M_FORBIDDEN when the remote server has disallowed publicRoom
|
||||
requests over federation
|
||||
|
||||
@@ -1289,6 +1290,88 @@ class FederationClient(FederationBase):
|
||||
failover_on_unknown_endpoint=True,
|
||||
)
|
||||
|
||||
async def get_room_hierarchy(
|
||||
self,
|
||||
destinations: Iterable[str],
|
||||
room_id: str,
|
||||
suggested_only: bool,
|
||||
) -> Tuple[JsonDict, Sequence[JsonDict], Sequence[str]]:
|
||||
"""
|
||||
Call other servers to get a hierarchy of the given room.
|
||||
|
||||
Performs simple data validates and parsing of the response.
|
||||
|
||||
Args:
|
||||
destinations: The remote servers. We will try them in turn, omitting any
|
||||
that have been blacklisted.
|
||||
room_id: ID of the space to be queried
|
||||
suggested_only: If true, ask the remote server to only return children
|
||||
with the "suggested" flag set
|
||||
|
||||
Returns:
|
||||
A tuple of:
|
||||
The room as a JSON dictionary.
|
||||
A list of children rooms, as JSON dictionaries.
|
||||
A list of inaccessible children room IDs.
|
||||
|
||||
Raises:
|
||||
SynapseError if we were unable to get a valid summary from any of the
|
||||
remote servers
|
||||
"""
|
||||
|
||||
async def send_request(
|
||||
destination: str,
|
||||
) -> Tuple[JsonDict, Sequence[JsonDict], Sequence[str]]:
|
||||
res = await self.transport_layer.get_room_hierarchy(
|
||||
destination=destination,
|
||||
room_id=room_id,
|
||||
suggested_only=suggested_only,
|
||||
)
|
||||
|
||||
room = res.get("room")
|
||||
if not isinstance(room, dict):
|
||||
raise InvalidResponseError("'room' must be a dict")
|
||||
|
||||
# Validate children_state of the room.
|
||||
children_state = room.get("children_state", [])
|
||||
if not isinstance(children_state, Sequence):
|
||||
raise InvalidResponseError("'room.children_state' must be a list")
|
||||
if any(not isinstance(e, dict) for e in children_state):
|
||||
raise InvalidResponseError("Invalid event in 'children_state' list")
|
||||
try:
|
||||
[
|
||||
FederationSpaceSummaryEventResult.from_json_dict(e)
|
||||
for e in children_state
|
||||
]
|
||||
except ValueError as e:
|
||||
raise InvalidResponseError(str(e))
|
||||
|
||||
# Validate the children rooms.
|
||||
children = res.get("children", [])
|
||||
if not isinstance(children, Sequence):
|
||||
raise InvalidResponseError("'children' must be a list")
|
||||
if any(not isinstance(r, dict) for r in children):
|
||||
raise InvalidResponseError("Invalid room in 'children' list")
|
||||
|
||||
# Validate the inaccessible children.
|
||||
inaccessible_children = res.get("inaccessible_children", [])
|
||||
if not isinstance(inaccessible_children, Sequence):
|
||||
raise InvalidResponseError("'inaccessible_children' must be a list")
|
||||
if any(not isinstance(r, str) for r in inaccessible_children):
|
||||
raise InvalidResponseError(
|
||||
"Invalid room ID in 'inaccessible_children' list"
|
||||
)
|
||||
|
||||
return room, children, inaccessible_children
|
||||
|
||||
# TODO Fallback to the old federation API and translate the results.
|
||||
return await self._try_destination_list(
|
||||
"fetch room hierarchy",
|
||||
destinations,
|
||||
send_request,
|
||||
failover_on_unknown_endpoint=True,
|
||||
)
|
||||
|
||||
|
||||
@attr.s(frozen=True, slots=True, auto_attribs=True)
|
||||
class FederationSpaceSummaryEventResult:
|
||||
|
||||
@@ -195,13 +195,17 @@ class FederationServer(FederationBase):
|
||||
origin, room_id, versions, limit
|
||||
)
|
||||
|
||||
res = self._transaction_from_pdus(pdus).get_dict()
|
||||
res = self._transaction_dict_from_pdus(pdus)
|
||||
|
||||
return 200, res
|
||||
|
||||
async def on_incoming_transaction(
|
||||
self, origin: str, transaction_data: JsonDict
|
||||
) -> Tuple[int, Dict[str, Any]]:
|
||||
self,
|
||||
origin: str,
|
||||
transaction_id: str,
|
||||
destination: str,
|
||||
transaction_data: JsonDict,
|
||||
) -> Tuple[int, JsonDict]:
|
||||
# If we receive a transaction we should make sure that kick off handling
|
||||
# any old events in the staging area.
|
||||
if not self._started_handling_of_staged_events:
|
||||
@@ -212,8 +216,14 @@ class FederationServer(FederationBase):
|
||||
# accurate as possible.
|
||||
request_time = self._clock.time_msec()
|
||||
|
||||
transaction = Transaction(**transaction_data)
|
||||
transaction_id = transaction.transaction_id # type: ignore
|
||||
transaction = Transaction(
|
||||
transaction_id=transaction_id,
|
||||
destination=destination,
|
||||
origin=origin,
|
||||
origin_server_ts=transaction_data.get("origin_server_ts"), # type: ignore
|
||||
pdus=transaction_data.get("pdus"), # type: ignore
|
||||
edus=transaction_data.get("edus"),
|
||||
)
|
||||
|
||||
if not transaction_id:
|
||||
raise Exception("Transaction missing transaction_id")
|
||||
@@ -221,9 +231,7 @@ class FederationServer(FederationBase):
|
||||
logger.debug("[%s] Got transaction", transaction_id)
|
||||
|
||||
# Reject malformed transactions early: reject if too many PDUs/EDUs
|
||||
if len(transaction.pdus) > 50 or ( # type: ignore
|
||||
hasattr(transaction, "edus") and len(transaction.edus) > 100 # type: ignore
|
||||
):
|
||||
if len(transaction.pdus) > 50 or len(transaction.edus) > 100:
|
||||
logger.info("Transaction PDU or EDU count too large. Returning 400")
|
||||
return 400, {}
|
||||
|
||||
@@ -263,7 +271,7 @@ class FederationServer(FederationBase):
|
||||
# CRITICAL SECTION: the first thing we must do (before awaiting) is
|
||||
# add an entry to _active_transactions.
|
||||
assert origin not in self._active_transactions
|
||||
self._active_transactions[origin] = transaction.transaction_id # type: ignore
|
||||
self._active_transactions[origin] = transaction.transaction_id
|
||||
|
||||
try:
|
||||
result = await self._handle_incoming_transaction(
|
||||
@@ -291,11 +299,11 @@ class FederationServer(FederationBase):
|
||||
if response:
|
||||
logger.debug(
|
||||
"[%s] We've already responded to this request",
|
||||
transaction.transaction_id, # type: ignore
|
||||
transaction.transaction_id,
|
||||
)
|
||||
return response
|
||||
|
||||
logger.debug("[%s] Transaction is new", transaction.transaction_id) # type: ignore
|
||||
logger.debug("[%s] Transaction is new", transaction.transaction_id)
|
||||
|
||||
# We process PDUs and EDUs in parallel. This is important as we don't
|
||||
# want to block things like to device messages from reaching clients
|
||||
@@ -334,7 +342,7 @@ class FederationServer(FederationBase):
|
||||
report back to the sending server.
|
||||
"""
|
||||
|
||||
received_pdus_counter.inc(len(transaction.pdus)) # type: ignore
|
||||
received_pdus_counter.inc(len(transaction.pdus))
|
||||
|
||||
origin_host, _ = parse_server_name(origin)
|
||||
|
||||
@@ -342,7 +350,7 @@ class FederationServer(FederationBase):
|
||||
|
||||
newest_pdu_ts = 0
|
||||
|
||||
for p in transaction.pdus: # type: ignore
|
||||
for p in transaction.pdus:
|
||||
# FIXME (richardv): I don't think this works:
|
||||
# https://github.com/matrix-org/synapse/issues/8429
|
||||
if "unsigned" in p:
|
||||
@@ -436,10 +444,10 @@ class FederationServer(FederationBase):
|
||||
|
||||
return pdu_results
|
||||
|
||||
async def _handle_edus_in_txn(self, origin: str, transaction: Transaction):
|
||||
async def _handle_edus_in_txn(self, origin: str, transaction: Transaction) -> None:
|
||||
"""Process the EDUs in a received transaction."""
|
||||
|
||||
async def _process_edu(edu_dict):
|
||||
async def _process_edu(edu_dict: JsonDict) -> None:
|
||||
received_edus_counter.inc()
|
||||
|
||||
edu = Edu(
|
||||
@@ -452,7 +460,7 @@ class FederationServer(FederationBase):
|
||||
|
||||
await concurrently_execute(
|
||||
_process_edu,
|
||||
getattr(transaction, "edus", []),
|
||||
transaction.edus,
|
||||
TRANSACTION_CONCURRENCY_LIMIT,
|
||||
)
|
||||
|
||||
@@ -538,7 +546,7 @@ class FederationServer(FederationBase):
|
||||
pdu = await self.handler.get_persisted_pdu(origin, event_id)
|
||||
|
||||
if pdu:
|
||||
return 200, self._transaction_from_pdus([pdu]).get_dict()
|
||||
return 200, self._transaction_dict_from_pdus([pdu])
|
||||
else:
|
||||
return 404, ""
|
||||
|
||||
@@ -879,18 +887,20 @@ class FederationServer(FederationBase):
|
||||
ts_now_ms = self._clock.time_msec()
|
||||
return await self.store.get_user_id_for_open_id_token(token, ts_now_ms)
|
||||
|
||||
def _transaction_from_pdus(self, pdu_list: List[EventBase]) -> Transaction:
|
||||
def _transaction_dict_from_pdus(self, pdu_list: List[EventBase]) -> JsonDict:
|
||||
"""Returns a new Transaction containing the given PDUs suitable for
|
||||
transmission.
|
||||
"""
|
||||
time_now = self._clock.time_msec()
|
||||
pdus = [p.get_pdu_json(time_now) for p in pdu_list]
|
||||
return Transaction(
|
||||
# Just need a dummy transaction ID and destination since it won't be used.
|
||||
transaction_id="",
|
||||
origin=self.server_name,
|
||||
pdus=pdus,
|
||||
origin_server_ts=int(time_now),
|
||||
destination=None,
|
||||
)
|
||||
destination="",
|
||||
).get_dict()
|
||||
|
||||
async def _handle_received_pdu(self, origin: str, pdu: EventBase) -> None:
|
||||
"""Process a PDU received in a federation /send/ transaction.
|
||||
@@ -962,13 +972,18 @@ class FederationServer(FederationBase):
|
||||
# the room, so instead of pulling the event out of the DB and parsing
|
||||
# the event we just pull out the next event ID and check if that matches.
|
||||
if latest_event is not None and latest_origin is not None:
|
||||
(
|
||||
next_origin,
|
||||
next_event_id,
|
||||
) = await self.store.get_next_staged_event_id_for_room(room_id)
|
||||
if next_origin != latest_origin or next_event_id != latest_event.event_id:
|
||||
result = await self.store.get_next_staged_event_id_for_room(room_id)
|
||||
if result is None:
|
||||
latest_origin = None
|
||||
latest_event = None
|
||||
else:
|
||||
next_origin, next_event_id = result
|
||||
if (
|
||||
next_origin != latest_origin
|
||||
or next_event_id != latest_event.event_id
|
||||
):
|
||||
latest_origin = None
|
||||
latest_event = None
|
||||
|
||||
if latest_origin is None or latest_event is None:
|
||||
next = await self.store.get_next_staged_event_for_room(
|
||||
@@ -988,6 +1003,7 @@ class FederationServer(FederationBase):
|
||||
# has started processing).
|
||||
while True:
|
||||
async with lock:
|
||||
logger.info("handling received PDU: %s", event)
|
||||
try:
|
||||
await self.handler.on_receive_pdu(
|
||||
origin, event, sent_to_us_directly=True
|
||||
|
||||
@@ -45,7 +45,7 @@ class TransactionActions:
|
||||
`None` if we have not previously responded to this transaction or a
|
||||
2-tuple of `(int, dict)` representing the response code and response body.
|
||||
"""
|
||||
transaction_id = transaction.transaction_id # type: ignore
|
||||
transaction_id = transaction.transaction_id
|
||||
if not transaction_id:
|
||||
raise RuntimeError("Cannot persist a transaction with no transaction_id")
|
||||
|
||||
@@ -56,7 +56,7 @@ class TransactionActions:
|
||||
self, origin: str, transaction: Transaction, code: int, response: JsonDict
|
||||
) -> None:
|
||||
"""Persist how we responded to a transaction."""
|
||||
transaction_id = transaction.transaction_id # type: ignore
|
||||
transaction_id = transaction.transaction_id
|
||||
if not transaction_id:
|
||||
raise RuntimeError("Cannot persist a transaction with no transaction_id")
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ from synapse.logging.opentracing import (
|
||||
tags,
|
||||
whitelisted_homeserver,
|
||||
)
|
||||
from synapse.types import JsonDict
|
||||
from synapse.util import json_decoder
|
||||
from synapse.util.metrics import measure_func
|
||||
|
||||
@@ -104,13 +105,13 @@ class TransactionManager:
|
||||
len(edus),
|
||||
)
|
||||
|
||||
transaction = Transaction.create_new(
|
||||
transaction = Transaction(
|
||||
origin_server_ts=int(self.clock.time_msec()),
|
||||
transaction_id=txn_id,
|
||||
origin=self._server_name,
|
||||
destination=destination,
|
||||
pdus=pdus,
|
||||
edus=edus,
|
||||
pdus=[p.get_pdu_json() for p in pdus],
|
||||
edus=[edu.get_dict() for edu in edus],
|
||||
)
|
||||
|
||||
self._next_txn_id += 1
|
||||
@@ -131,7 +132,7 @@ class TransactionManager:
|
||||
# FIXME (richardv): I also believe it no longer works. We (now?) store
|
||||
# "age_ts" in "unsigned" rather than at the top level. See
|
||||
# https://github.com/matrix-org/synapse/issues/8429.
|
||||
def json_data_cb():
|
||||
def json_data_cb() -> JsonDict:
|
||||
data = transaction.get_dict()
|
||||
now = int(self.clock.time_msec())
|
||||
if "pdus" in data:
|
||||
|
||||
@@ -143,7 +143,7 @@ class TransportLayerClient:
|
||||
"""Sends the given Transaction to its destination
|
||||
|
||||
Args:
|
||||
transaction (Transaction)
|
||||
transaction
|
||||
|
||||
Returns:
|
||||
Succeeds when we get a 2xx HTTP response. The result
|
||||
@@ -1177,6 +1177,28 @@ class TransportLayerClient:
|
||||
destination=destination, path=path, data=params
|
||||
)
|
||||
|
||||
async def get_room_hierarchy(
|
||||
self,
|
||||
destination: str,
|
||||
room_id: str,
|
||||
suggested_only: bool,
|
||||
) -> JsonDict:
|
||||
"""
|
||||
Args:
|
||||
destination: The remote server
|
||||
room_id: The room ID to ask about.
|
||||
suggested_only: if True, only suggested rooms will be returned
|
||||
"""
|
||||
path = _create_path(
|
||||
FEDERATION_UNSTABLE_PREFIX, "/org.matrix.msc2946/hierarchy/%s", room_id
|
||||
)
|
||||
|
||||
return await self.client.get_json(
|
||||
destination=destination,
|
||||
path=path,
|
||||
args={"suggested_only": "true" if suggested_only else "false"},
|
||||
)
|
||||
|
||||
|
||||
def _create_path(federation_prefix: str, path: str, *args: str) -> str:
|
||||
"""
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user