Compare commits
136 Commits
erikj/work
...
v1.41.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f03cafb50c | ||
|
|
6f77a3d433 | ||
|
|
5cda75fede | ||
|
|
ce6819a701 | ||
|
|
b9c35586a4 | ||
|
|
e328d8ffd9 | ||
|
|
49cb7eae97 | ||
|
|
3692f7fd33 | ||
|
|
eea2873595 | ||
|
|
5581dd7bf7 | ||
|
|
703e3a9e85 | ||
|
|
84469bdac7 | ||
|
|
c8132f4a31 | ||
|
|
5639759980 | ||
|
|
c4cf0c0473 | ||
|
|
5f7b1e1f27 | ||
|
|
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 | ||
|
|
3b354faad0 | ||
|
|
a8a27b2b8b | ||
|
|
834cdc3606 | ||
|
|
e33f14e8d5 | ||
|
|
a36d77c563 | ||
|
|
9db24cc50d | ||
|
|
684d19a11c | ||
|
|
05111f8f26 | ||
|
|
cc1cb0ab54 | ||
|
|
167335bd3d | ||
|
|
02c2f631ae | ||
|
|
e8a3e81402 | ||
|
|
c37dad67ab | ||
|
|
11540be55e | ||
|
|
c2000ab35b | ||
|
|
72935b7c50 | ||
|
|
951648f26a | ||
|
|
4b10880da3 | ||
|
|
dc46f12725 | ||
|
|
903db99ed5 | ||
|
|
6878e10653 | ||
|
|
42225aa421 | ||
|
|
da6cd82106 | ||
|
|
c80ec5d153 | ||
|
|
c8566191fc | ||
|
|
f4ac934afe | ||
|
|
a7bacccd85 | ||
|
|
2bae2c632f | ||
|
|
a6ea32a798 | ||
|
|
fb086edaed | ||
|
|
01d45fe964 | ||
|
|
ba5287f5e8 | ||
|
|
2afdb5c984 | ||
|
|
c167e09fe5 | ||
|
|
b7f7ca24b1 | ||
|
|
65f520697d | ||
|
|
a6e2c16044 | ||
|
|
3a541a7daa | ||
|
|
f8c87c65eb | ||
|
|
c36c277790 | ||
|
|
6449955920 | ||
|
|
5522a103a9 | ||
|
|
db6e7f15ea | ||
|
|
858363d0b7 | ||
|
|
d0b294ad97 | ||
|
|
8c201c97ec | ||
|
|
2254e6790f | ||
|
|
5146e19880 | ||
|
|
d9cb658c78 | ||
|
|
9643dfde6a | ||
|
|
752fe0cd98 | ||
|
|
c3b037795a | ||
|
|
0489683012 | ||
|
|
8e1febc6a1 | ||
|
|
5b22d5ee03 | ||
|
|
076deade02 | ||
|
|
31c6b30dd4 | ||
|
|
10dcfae46f | ||
|
|
74d09a43d9 | ||
|
|
92a882254b |
@@ -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: []
|
||||
53
.github/workflows/tests.yml
vendored
53
.github/workflows/tests.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -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() }}
|
||||
@@ -367,13 +358,21 @@ jobs:
|
||||
- name: Set build result
|
||||
env:
|
||||
NEEDS_CONTEXT: ${{ toJSON(needs) }}
|
||||
# the `jq` incantation dumps out a series of "<job> <result>" lines
|
||||
# the `jq` incantation dumps out a series of "<job> <result>" lines.
|
||||
# we set it to an intermediate variable to avoid a pipe, which makes it
|
||||
# hard to set $rc.
|
||||
run: |
|
||||
set -o pipefail
|
||||
jq -r 'to_entries[] | [.key,.value.result] | join(" ")' \
|
||||
<<< $NEEDS_CONTEXT |
|
||||
while read job result; do
|
||||
if [ "$result" != "success" ]; then
|
||||
echo "::set-failed ::Job $job returned $result"
|
||||
fi
|
||||
done
|
||||
rc=0
|
||||
results=$(jq -r 'to_entries[] | [.key,.value.result] | join(" ")' <<< $NEEDS_CONTEXT)
|
||||
while read job result ; do
|
||||
# The newsfile lint may be skipped on non PR builds
|
||||
if [ $result == "skipped" ] && [ $job == "lint-newsfile" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$result" != "success" ]; then
|
||||
echo "::set-failed ::Job $job returned $result"
|
||||
rc=1
|
||||
fi
|
||||
done <<< $results
|
||||
exit $rc
|
||||
|
||||
219
CHANGES.md
219
CHANGES.md
@@ -1,10 +1,225 @@
|
||||
Synapse 1.39.0rc2 (2021-07-22)
|
||||
Synapse 1.41.0 (2021-08-24)
|
||||
===========================
|
||||
|
||||
This release adds support for Debian 12 (Bookworm), but **removes support for Ubuntu 20.10 (Groovy Gorilla)**, which reached End of Life last month.
|
||||
|
||||
Note that when using workers the `/_synapse/admin/v1/users/{userId}/media` must now be handled by media workers. See the [upgrade notes](https://matrix-org.github.io/synapse/latest/upgrade.html) for more information.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Enable room capabilities ([MSC3244](https://github.com/matrix-org/matrix-doc/pull/3244)) by default and set room version 8 as the preferred room version when creating restricted rooms. ([\#10571](https://github.com/matrix-org/synapse/issues/10571))
|
||||
|
||||
|
||||
Synapse 1.41.0rc1 (2021-08-18)
|
||||
==============================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Add `get_userinfo_by_id` method to ModuleApi. ([\#9581](https://github.com/matrix-org/synapse/issues/9581))
|
||||
- Initial local support for [MSC3266](https://github.com/matrix-org/synapse/pull/10394), Room Summary over the unstable `/rooms/{roomIdOrAlias}/summary` API. ([\#10394](https://github.com/matrix-org/synapse/issues/10394))
|
||||
- Experimental support for [MSC3288](https://github.com/matrix-org/matrix-doc/pull/3288), sending `room_type` to the identity server for 3pid invites over the `/store-invite` API. ([\#10435](https://github.com/matrix-org/synapse/issues/10435))
|
||||
- Add support for sending federation requests through a proxy. Contributed by @Bubu and @dklimpel. See the [upgrade notes](https://matrix-org.github.io/synapse/latest/upgrade.html) for more information. ([\#10596](https://github.com/matrix-org/synapse/issues/10596)). ([\#10475](https://github.com/matrix-org/synapse/issues/10475))
|
||||
- Add support for "marker" events which makes historical events discoverable for servers that already have all of the scrollback history (part of [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716)). ([\#10498](https://github.com/matrix-org/synapse/issues/10498))
|
||||
- Add a configuration setting for the time a `/sync` response is cached for. ([\#10513](https://github.com/matrix-org/synapse/issues/10513))
|
||||
- The default logging handler for new installations is now `PeriodicallyFlushingMemoryHandler`, a buffered logging handler which periodically flushes itself. ([\#10518](https://github.com/matrix-org/synapse/issues/10518))
|
||||
- Add support for new redaction rules for historical events specified in [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716). ([\#10538](https://github.com/matrix-org/synapse/issues/10538))
|
||||
- Add a setting to disable TLS when sending email. ([\#10546](https://github.com/matrix-org/synapse/issues/10546))
|
||||
- Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946). ([\#10549](https://github.com/matrix-org/synapse/issues/10549), [\#10560](https://github.com/matrix-org/synapse/issues/10560), [\#10569](https://github.com/matrix-org/synapse/issues/10569), [\#10574](https://github.com/matrix-org/synapse/issues/10574), [\#10575](https://github.com/matrix-org/synapse/issues/10575), [\#10579](https://github.com/matrix-org/synapse/issues/10579), [\#10583](https://github.com/matrix-org/synapse/issues/10583))
|
||||
- Admin API to delete several media for a specific user. Contributed by @dklimpel. ([\#10558](https://github.com/matrix-org/synapse/issues/10558), [\#10628](https://github.com/matrix-org/synapse/issues/10628))
|
||||
- Add support for routing `/createRoom` to workers. ([\#10564](https://github.com/matrix-org/synapse/issues/10564))
|
||||
- Update the Synapse Grafana dashboard. ([\#10570](https://github.com/matrix-org/synapse/issues/10570))
|
||||
- Add an admin API (`GET /_synapse/admin/username_available`) to check if a username is available (regardless of registration settings). ([\#10578](https://github.com/matrix-org/synapse/issues/10578))
|
||||
- Allow editing a user's `external_ids` via the "Edit User" admin API. Contributed by @dklimpel. ([\#10598](https://github.com/matrix-org/synapse/issues/10598))
|
||||
- The Synapse manhole no longer needs coroutines to be wrapped in `defer.ensureDeferred`. ([\#10602](https://github.com/matrix-org/synapse/issues/10602))
|
||||
- Add option to allow modules to run periodic tasks on all instances, rather than just the one configured to run background tasks. ([\#10638](https://github.com/matrix-org/synapse/issues/10638))
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Add some clarification to the sample config file. Contributed by @Kentokamoto. ([\#10129](https://github.com/matrix-org/synapse/issues/10129))
|
||||
- Fix a long-standing bug where protocols which are not implemented by any appservices were incorrectly returned via `GET /_matrix/client/r0/thirdparty/protocols`. ([\#10532](https://github.com/matrix-org/synapse/issues/10532))
|
||||
- Fix exceptions in logs when failing to get remote room list. ([\#10541](https://github.com/matrix-org/synapse/issues/10541))
|
||||
- Fix longstanding bug which caused the user's presence "status message" to be reset when the user went offline. Contributed by @dklimpel. ([\#10550](https://github.com/matrix-org/synapse/issues/10550))
|
||||
- Allow public rooms to be previewed in the spaces summary APIs from [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946). ([\#10580](https://github.com/matrix-org/synapse/issues/10580))
|
||||
- Fix a bug introduced in v1.37.1 where an error could occur in the asynchronous processing of PDUs when the queue was empty. ([\#10592](https://github.com/matrix-org/synapse/issues/10592))
|
||||
- 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. ([\#10606](https://github.com/matrix-org/synapse/issues/10606))
|
||||
- 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. ([\#10611](https://github.com/matrix-org/synapse/issues/10611))
|
||||
- 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). ([\#10623](https://github.com/matrix-org/synapse/issues/10623))
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Add documentation for configuring a forward proxy. ([\#10443](https://github.com/matrix-org/synapse/issues/10443))
|
||||
- Updated the reverse proxy documentation to highlight the homserver configuration that is needed to make Synapse aware that is is intentionally reverse proxied. ([\#10551](https://github.com/matrix-org/synapse/issues/10551))
|
||||
- Update CONTRIBUTING.md to fix index links and the instructions for SyTest in docker. ([\#10599](https://github.com/matrix-org/synapse/issues/10599))
|
||||
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- No longer build `.deb` packages for Ubuntu 20.10 Groovy Gorilla, which has now EOLed. ([\#10588](https://github.com/matrix-org/synapse/issues/10588))
|
||||
- The `template_dir` configuration settings in the `sso`, `account_validity` and `email` sections of the configuration file are now deprecated in favour of the global `templates.custom_template_directory` setting. See the [upgrade notes](https://matrix-org.github.io/synapse/latest/upgrade.html) for more information. ([\#10596](https://github.com/matrix-org/synapse/issues/10596))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Improve event caching mechanism to avoid having multiple copies of an event in memory at a time. ([\#10119](https://github.com/matrix-org/synapse/issues/10119))
|
||||
- Reduce errors in PostgreSQL logs due to concurrent serialization errors. ([\#10504](https://github.com/matrix-org/synapse/issues/10504))
|
||||
- Include room ID in ignored EDU log messages. Contributed by @ilmari. ([\#10507](https://github.com/matrix-org/synapse/issues/10507))
|
||||
- Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946). ([\#10527](https://github.com/matrix-org/synapse/issues/10527), [\#10530](https://github.com/matrix-org/synapse/issues/10530))
|
||||
- Fix CI to not break when run against branches rather than pull requests. ([\#10529](https://github.com/matrix-org/synapse/issues/10529))
|
||||
- Mark all events stemming from the [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716) `/batch_send` endpoint as historical. ([\#10537](https://github.com/matrix-org/synapse/issues/10537))
|
||||
- Clean up some of the federation event authentication code for clarity. ([\#10539](https://github.com/matrix-org/synapse/issues/10539), [\#10591](https://github.com/matrix-org/synapse/issues/10591))
|
||||
- Convert `Transaction` and `Edu` objects to attrs. ([\#10542](https://github.com/matrix-org/synapse/issues/10542))
|
||||
- Update `/batch_send` endpoint to only return `state_events` created by the `state_events_from_before` passed in. ([\#10552](https://github.com/matrix-org/synapse/issues/10552))
|
||||
- Update contributing.md to warn against rebasing an open PR. ([\#10563](https://github.com/matrix-org/synapse/issues/10563))
|
||||
- Remove the unused public rooms replication stream. ([\#10565](https://github.com/matrix-org/synapse/issues/10565))
|
||||
- Clarify error message when failing to join a restricted room. ([\#10572](https://github.com/matrix-org/synapse/issues/10572))
|
||||
- Remove references to BuildKite in favour of GitHub Actions. ([\#10573](https://github.com/matrix-org/synapse/issues/10573))
|
||||
- Move `/batch_send` endpoint defined by [MSC2716](https://github.com/matrix-org/matrix-doc/pull/2716) to the `/v2_alpha` directory. ([\#10576](https://github.com/matrix-org/synapse/issues/10576))
|
||||
- Allow multiple custom directories in `read_templates`. ([\#10587](https://github.com/matrix-org/synapse/issues/10587))
|
||||
- Re-organize the `synapse.federation.transport.server` module to create smaller files. ([\#10590](https://github.com/matrix-org/synapse/issues/10590))
|
||||
- Flatten the `synapse.rest.client` package by moving the contents of `v1` and `v2_alpha` into the parent. ([\#10600](https://github.com/matrix-org/synapse/issues/10600))
|
||||
- Build Debian packages for Debian 12 (Bookworm). ([\#10612](https://github.com/matrix-org/synapse/issues/10612))
|
||||
- Fix up a couple of links to the database schema documentation. ([\#10620](https://github.com/matrix-org/synapse/issues/10620))
|
||||
- Fix a broken link to the upgrade notes. ([\#10631](https://github.com/matrix-org/synapse/issues/10631))
|
||||
|
||||
|
||||
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)
|
||||
==============================
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Always include `device_one_time_keys_count` key in `/sync` response to work around a bug in Element Android that broke encryption for new devices. ([\#10457](https://github.com/matrix-org/synapse/issues/10457))
|
||||
- Fix the `PeriodicallyFlushingMemoryHandler` inhibiting application shutdown because of its background thread. ([\#10517](https://github.com/matrix-org/synapse/issues/10517))
|
||||
- Fix a bug introduced in Synapse v1.40.0rc1 that could cause Synapse to respond with an error when clients would update read receipts. ([\#10531](https://github.com/matrix-org/synapse/issues/10531))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Fix release script to open the correct URL for the release. ([\#10516](https://github.com/matrix-org/synapse/issues/10516))
|
||||
|
||||
|
||||
Synapse 1.40.0rc1 (2021-08-03)
|
||||
==============================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Add support for [MSC2033](https://github.com/matrix-org/matrix-doc/pull/2033): `device_id` on `/account/whoami`. ([\#9918](https://github.com/matrix-org/synapse/issues/9918))
|
||||
- Update support for [MSC2716 - Incrementally importing history into existing rooms](https://github.com/matrix-org/matrix-doc/pull/2716). ([\#10245](https://github.com/matrix-org/synapse/issues/10245), [\#10432](https://github.com/matrix-org/synapse/issues/10432), [\#10463](https://github.com/matrix-org/synapse/issues/10463))
|
||||
- Update support for [MSC3083](https://github.com/matrix-org/matrix-doc/pull/3083) to consider changes in the MSC around which servers can issue join events. ([\#10254](https://github.com/matrix-org/synapse/issues/10254), [\#10447](https://github.com/matrix-org/synapse/issues/10447), [\#10489](https://github.com/matrix-org/synapse/issues/10489))
|
||||
- Initial support for [MSC3244](https://github.com/matrix-org/matrix-doc/pull/3244), Room version capabilities over the /capabilities API. ([\#10283](https://github.com/matrix-org/synapse/issues/10283))
|
||||
- Add a buffered logging handler which periodically flushes itself. ([\#10407](https://github.com/matrix-org/synapse/issues/10407), [\#10515](https://github.com/matrix-org/synapse/issues/10515))
|
||||
- Add support for https connections to a proxy server. Contributed by @Bubu and @dklimpel. ([\#10411](https://github.com/matrix-org/synapse/issues/10411))
|
||||
- Support for [MSC2285 (hidden read receipts)](https://github.com/matrix-org/matrix-doc/pull/2285). Contributed by @SimonBrandner. ([\#10413](https://github.com/matrix-org/synapse/issues/10413))
|
||||
- Email notifications now state whether an invitation is to a room or a space. ([\#10426](https://github.com/matrix-org/synapse/issues/10426))
|
||||
- Allow setting transaction limit for database connections. ([\#10440](https://github.com/matrix-org/synapse/issues/10440), [\#10511](https://github.com/matrix-org/synapse/issues/10511))
|
||||
- Add `creation_ts` to "list users" admin API. ([\#10448](https://github.com/matrix-org/synapse/issues/10448))
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Improve character set detection in URL previews by supporting underscores (in addition to hyphens). Contributed by @srividyut. ([\#10410](https://github.com/matrix-org/synapse/issues/10410))
|
||||
- Fix events being incorrectly rejected over federation if they reference auth events that the server needed to fetch. ([\#10439](https://github.com/matrix-org/synapse/issues/10439))
|
||||
- Fix `synapse_federation_server_oldest_inbound_pdu_in_staging` Prometheus metric to not report a max age of 51 years when the queue is empty. ([\#10455](https://github.com/matrix-org/synapse/issues/10455))
|
||||
- Fix a bug which caused an explicit assignment of power-level 0 to a user to be misinterpreted in rare circumstances. ([\#10499](https://github.com/matrix-org/synapse/issues/10499))
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Fix hierarchy of providers on the OpenID page. ([\#10445](https://github.com/matrix-org/synapse/issues/10445))
|
||||
- Consolidate development documentation to `docs/development/`. ([\#10453](https://github.com/matrix-org/synapse/issues/10453))
|
||||
- Add some developer docs to explain room DAG concepts like `outliers`, `state_groups`, `depth`, etc. ([\#10464](https://github.com/matrix-org/synapse/issues/10464))
|
||||
- Document how to use Complement while developing a new Synapse feature. ([\#10483](https://github.com/matrix-org/synapse/issues/10483))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Prune inbound federation queues for a room if they get too large. ([\#10390](https://github.com/matrix-org/synapse/issues/10390))
|
||||
- Add type hints to `synapse.federation.transport.client` module. ([\#10408](https://github.com/matrix-org/synapse/issues/10408))
|
||||
- Remove shebang line from module files. ([\#10415](https://github.com/matrix-org/synapse/issues/10415))
|
||||
- Drop backwards-compatibility code that was required to support Ubuntu Xenial. ([\#10429](https://github.com/matrix-org/synapse/issues/10429))
|
||||
- Use a docker image cache for the prerequisites for the debian package build. ([\#10431](https://github.com/matrix-org/synapse/issues/10431))
|
||||
- Improve servlet type hints. ([\#10437](https://github.com/matrix-org/synapse/issues/10437), [\#10438](https://github.com/matrix-org/synapse/issues/10438))
|
||||
- Replace usage of `or_ignore` in `simple_insert` with `simple_upsert` usage, to stop spamming postgres logs with spurious ERROR messages. ([\#10442](https://github.com/matrix-org/synapse/issues/10442))
|
||||
- Update the `tests-done` Github Actions status. ([\#10444](https://github.com/matrix-org/synapse/issues/10444), [\#10512](https://github.com/matrix-org/synapse/issues/10512))
|
||||
- Update type annotations to work with forthcoming Twisted 21.7.0 release. ([\#10446](https://github.com/matrix-org/synapse/issues/10446), [\#10450](https://github.com/matrix-org/synapse/issues/10450))
|
||||
- Cancel redundant GHA workflows when a new commit is pushed. ([\#10451](https://github.com/matrix-org/synapse/issues/10451))
|
||||
- Mitigate media repo XSS attacks on IE11 via the non-standard X-Content-Security-Policy header. ([\#10468](https://github.com/matrix-org/synapse/issues/10468))
|
||||
- Additional type hints in the state handler. ([\#10482](https://github.com/matrix-org/synapse/issues/10482))
|
||||
- Update syntax used to run complement tests. ([\#10488](https://github.com/matrix-org/synapse/issues/10488))
|
||||
- Fix up type annotations to work with Twisted 21.7. ([\#10490](https://github.com/matrix-org/synapse/issues/10490))
|
||||
- Improve type annotations for `ObservableDeferred`. ([\#10491](https://github.com/matrix-org/synapse/issues/10491))
|
||||
- Extend release script to also tag and create GitHub releases. ([\#10496](https://github.com/matrix-org/synapse/issues/10496))
|
||||
- Fix a bug which caused production debian packages to be incorrectly marked as 'prerelease'. ([\#10500](https://github.com/matrix-org/synapse/issues/10500))
|
||||
|
||||
|
||||
Synapse 1.39.0 (2021-07-29)
|
||||
===========================
|
||||
|
||||
No significant changes.
|
||||
|
||||
|
||||
Synapse 1.39.0rc3 (2021-07-28)
|
||||
==============================
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix a bug introduced in Synapse 1.38 which caused an exception at startup when SAML authentication was enabled. ([\#10477](https://github.com/matrix-org/synapse/issues/10477))
|
||||
- Fix a long-standing bug where Synapse would not inform clients that a device had exhausted its one-time-key pool, potentially causing problems decrypting events. ([\#10485](https://github.com/matrix-org/synapse/issues/10485))
|
||||
- Fix reporting old R30 stats as R30v2 stats. Introduced in v1.39.0rc1. ([\#10486](https://github.com/matrix-org/synapse/issues/10486))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Fix an error which prevented the Github Actions workflow to build the docker images from running. ([\#10461](https://github.com/matrix-org/synapse/issues/10461))
|
||||
- Fix release script to correctly version debian changelog when doing RCs. ([\#10465](https://github.com/matrix-org/synapse/issues/10465))
|
||||
|
||||
|
||||
Synapse 1.39.0rc2 (2021-07-22)
|
||||
==============================
|
||||
|
||||
This release also includes the changes in v1.38.1.
|
||||
|
||||
|
||||
Internal Changes
|
||||
|
||||
@@ -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)
|
||||
@@ -155,7 +156,7 @@ source ./env/bin/activate
|
||||
./scripts-dev/lint.sh path/to/file1.py path/to/file2.py path/to/folder
|
||||
```
|
||||
|
||||
## Run the unit tests.
|
||||
## Run the unit tests (Twisted trial).
|
||||
|
||||
The unit tests run parts of Synapse, including your changes, to see if anything
|
||||
was broken. They are slower than the linters but will typically catch more errors.
|
||||
@@ -186,7 +187,7 @@ SYNAPSE_TEST_LOG_LEVEL=DEBUG trial tests
|
||||
```
|
||||
|
||||
|
||||
## Run the integration tests.
|
||||
## Run the integration tests ([Sytest](https://github.com/matrix-org/sytest)).
|
||||
|
||||
The integration tests are a more comprehensive suite of tests. They
|
||||
run a full version of Synapse, including your changes, to check if
|
||||
@@ -197,12 +198,49 @@ 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).
|
||||
|
||||
|
||||
## Run the integration tests ([Complement](https://github.com/matrix-org/complement)).
|
||||
|
||||
[Complement](https://github.com/matrix-org/complement) is a suite of black box tests that can be run on any homeserver implementation. It can also be thought of as end-to-end (e2e) tests.
|
||||
|
||||
It's often nice to develop on Synapse and write Complement tests at the same time.
|
||||
Here is how to run your local Synapse checkout against your local Complement checkout.
|
||||
|
||||
(checkout [`complement`](https://github.com/matrix-org/complement) alongside your `synapse` checkout)
|
||||
```sh
|
||||
COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh
|
||||
```
|
||||
|
||||
To run a specific test file, you can pass the test name at the end of the command. The name passed comes from the naming structure in your Complement tests. If you're unsure of the name, you can do a full run and copy it from the test output:
|
||||
|
||||
```sh
|
||||
COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh TestBackfillingHistory
|
||||
```
|
||||
|
||||
To run a specific test, you can specify the whole name structure:
|
||||
|
||||
```sh
|
||||
COMPLEMENT_DIR=../complement ./scripts-dev/complement.sh TestBackfillingHistory/parallel/Backfilled_historical_events_resolve_with_proper_state_in_correct_order
|
||||
```
|
||||
|
||||
|
||||
### Access database for homeserver after Complement test runs.
|
||||
|
||||
If you're curious what the database looks like after you run some tests, here are some steps to get you going in Synapse:
|
||||
|
||||
1. In your Complement test comment out `defer deployment.Destroy(t)` and replace with `defer time.Sleep(2 * time.Hour)` to keep the homeserver running after the tests complete
|
||||
1. Start the Complement tests
|
||||
1. Find the name of the container, `docker ps -f name=complement_` (this will filter for just the Compelement related Docker containers)
|
||||
1. Access the container replacing the name with what you found in the previous step: `docker exec -it complement_1_hs_with_application_service.hs1_2 /bin/bash`
|
||||
1. Install sqlite (database driver), `apt-get update && apt-get install -y sqlite3`
|
||||
1. Then run `sqlite3` and open the database `.open /conf/homeserver.db` (this db path comes from the Synapse homeserver.yaml)
|
||||
|
||||
|
||||
# 9. Submit your patch.
|
||||
|
||||
Once you're happy with your patch, it's time to prepare a Pull Request.
|
||||
@@ -215,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,7 +1,7 @@
|
||||
Upgrading Synapse
|
||||
=================
|
||||
|
||||
This document has moved to the `Synapse documentation website <https://matrix-org.github.io/synapse/latest/upgrading>`_.
|
||||
This document has moved to the `Synapse documentation website <https://matrix-org.github.io/synapse/latest/upgrade>`_.
|
||||
Please update your links.
|
||||
|
||||
The markdown source is available in `docs/upgrade.md <docs/upgrade.md>`_.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Update support for [MSC3083](https://github.com/matrix-org/matrix-doc/pull/3083) to consider changes in the MSC around which servers can issue join events.
|
||||
@@ -1 +0,0 @@
|
||||
Initial support for MSC3244, Room version capabilities over the /capabilities API.
|
||||
@@ -1 +0,0 @@
|
||||
Add a buffered logging handler which periodically flushes itself.
|
||||
@@ -1 +0,0 @@
|
||||
Add type hints to `synapse.federation.transport.client` module.
|
||||
@@ -1 +0,0 @@
|
||||
Email notifications now state whether an invitation is to a room or a space.
|
||||
@@ -1 +0,0 @@
|
||||
Drop backwards-compatibility code that was required to support Ubuntu Xenial.
|
||||
@@ -1 +0,0 @@
|
||||
Use a docker image cache for the prerequisites for the debian package build.
|
||||
@@ -1 +0,0 @@
|
||||
Connect historical chunks together with chunk events instead of a content field (MSC2716).
|
||||
@@ -1 +0,0 @@
|
||||
Improve servlet type hints.
|
||||
@@ -1 +0,0 @@
|
||||
Improve servlet type hints.
|
||||
@@ -1 +0,0 @@
|
||||
Replace usage of `or_ignore` in `simple_insert` with `simple_upsert` usage, to stop spamming postgres logs with spurious ERROR messages.
|
||||
@@ -1 +0,0 @@
|
||||
Update the `tests-done` Github Actions status.
|
||||
@@ -1 +0,0 @@
|
||||
Fix hierarchy of providers on the OpenID page.
|
||||
@@ -1 +0,0 @@
|
||||
Update type annotations to work with forthcoming Twisted 21.7.0 release.
|
||||
@@ -1 +0,0 @@
|
||||
Add `creation_ts` to list users admin API.
|
||||
@@ -1 +0,0 @@
|
||||
Cancel redundant GHA workflows when a new commit is pushed.
|
||||
@@ -1 +0,0 @@
|
||||
Consolidate development documentation to `docs/development/`.
|
||||
@@ -1 +0,0 @@
|
||||
Fix an error which prevented the Github Actions workflow to build the docker images from running.
|
||||
@@ -1 +0,0 @@
|
||||
Disable `msc2716` Complement tests until Complement updates are merged.
|
||||
@@ -1 +0,0 @@
|
||||
Mitigate media repo XSS attacks on IE11 via the non-standard X-Content-Security-Policy header.
|
||||
@@ -1 +0,0 @@
|
||||
Additional type hints in the state handler.
|
||||
@@ -1 +0,0 @@
|
||||
Update syntax used to run complement tests.
|
||||
@@ -1 +0,0 @@
|
||||
Add support for [MSC2033](https://github.com/matrix-org/matrix-doc/pull/2033): `device_id` on `/account/whoami`.
|
||||
@@ -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
|
||||
}
|
||||
15
debian/build_virtualenv
vendored
15
debian/build_virtualenv
vendored
@@ -100,3 +100,18 @@ esac
|
||||
# add a dependency on the right version of python to substvars.
|
||||
PYPKG=`basename $SNAKE`
|
||||
echo "synapse:pydepends=$PYPKG" >> debian/matrix-synapse-py3.substvars
|
||||
|
||||
|
||||
# add a couple of triggers. This is needed so that dh-virtualenv can rebuild
|
||||
# the venv when the system python changes (see
|
||||
# https://dh-virtualenv.readthedocs.io/en/latest/tutorial.html#step-2-set-up-packaging-for-your-project)
|
||||
#
|
||||
# we do it here rather than the more conventional way of just adding it to
|
||||
# debian/matrix-synapse-py3.triggers, because we need to add a trigger on the
|
||||
# right version of python.
|
||||
cat >>"debian/.debhelper/generated/matrix-synapse-py3/triggers" <<EOF
|
||||
# triggers for dh-virtualenv
|
||||
interest-noawait $SNAKE
|
||||
interest dh-virtualenv-interpreter-update
|
||||
|
||||
EOF
|
||||
|
||||
52
debian/changelog
vendored
52
debian/changelog
vendored
@@ -1,8 +1,56 @@
|
||||
matrix-synapse-py3 (1.39.0ubuntu1) UNRELEASED; urgency=medium
|
||||
matrix-synapse-py3 (1.41.0) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.41.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 24 Aug 2021 15:31:45 +0100
|
||||
|
||||
matrix-synapse-py3 (1.41.0~rc1) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.41.0~rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Wed, 18 Aug 2021 15:52:00 +0100
|
||||
|
||||
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.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Wed, 04 Aug 2021 17:08:55 +0100
|
||||
|
||||
matrix-synapse-py3 (1.40.0~rc1) stable; urgency=medium
|
||||
|
||||
[ Richard van der Hoff ]
|
||||
* Drop backwards-compatibility code that was required to support Ubuntu Xenial.
|
||||
* Update package triggers so that the virtualenv is correctly rebuilt
|
||||
when the system python is rebuilt, on recent Python versions.
|
||||
|
||||
-- Richard van der Hoff <richard@matrix.org> Tue, 20 Jul 2021 00:10:03 +0100
|
||||
[ Synapse Packaging team ]
|
||||
* New synapse release 1.40.0~rc1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Tue, 03 Aug 2021 11:31:49 +0100
|
||||
|
||||
matrix-synapse-py3 (1.39.0) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.39.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Thu, 29 Jul 2021 09:59:00 +0100
|
||||
|
||||
matrix-synapse-py3 (1.39.0~rc3) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.39.0~rc3.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Wed, 28 Jul 2021 13:30:58 +0100
|
||||
|
||||
matrix-synapse-py3 (1.38.1) stable; urgency=medium
|
||||
|
||||
|
||||
9
debian/matrix-synapse-py3.triggers
vendored
9
debian/matrix-synapse-py3.triggers
vendored
@@ -1,9 +0,0 @@
|
||||
# Register interest in Python interpreter changes and
|
||||
# don't make the Python package dependent on the virtualenv package
|
||||
# processing (noawait)
|
||||
interest-noawait /usr/bin/python3.5
|
||||
interest-noawait /usr/bin/python3.6
|
||||
interest-noawait /usr/bin/python3.7
|
||||
|
||||
# Also provide a symbolic trigger for all dh-virtualenv packages
|
||||
interest dh-virtualenv-interpreter-update
|
||||
@@ -11,10 +11,6 @@ DIST=`cut -d ':' -f2 <<< $distro`
|
||||
cp -aT /synapse/source /synapse/build
|
||||
cd /synapse/build
|
||||
|
||||
# add an entry to the changelog for this distribution
|
||||
dch -M -l "+$DIST" "build for $DIST"
|
||||
dch -M -r "" --force-distribution --distribution "$DIST"
|
||||
|
||||
# if this is a prerelease, set the Section accordingly.
|
||||
#
|
||||
# When the package is later added to the package repo, reprepro will use the
|
||||
@@ -23,11 +19,14 @@ dch -M -r "" --force-distribution --distribution "$DIST"
|
||||
|
||||
DEB_VERSION=`dpkg-parsechangelog -SVersion`
|
||||
case $DEB_VERSION in
|
||||
*rc*|*a*|*b*|*c*)
|
||||
*~rc*|*~a*|*~b*|*~c*)
|
||||
sed -ie '/^Section:/c\Section: prerelease' debian/control
|
||||
;;
|
||||
esac
|
||||
|
||||
# add an entry to the changelog for this distribution
|
||||
dch -M -l "+$DIST" "build for $DIST"
|
||||
dch -M -r "" --force-distribution --distribution "$DIST"
|
||||
|
||||
dpkg-buildpackage -us -uc
|
||||
|
||||
|
||||
@@ -18,18 +18,31 @@ handlers:
|
||||
backupCount: 6 # Does not include the current log file.
|
||||
encoding: utf8
|
||||
|
||||
# Default to buffering writes to log file for efficiency. This means that
|
||||
# there will be a delay for INFO/DEBUG logs to get written, but WARNING/ERROR
|
||||
# logs will still be flushed immediately.
|
||||
# Default to buffering writes to log file for efficiency.
|
||||
# WARNING/ERROR logs will still be flushed immediately, but there will be a
|
||||
# delay (of up to `period` seconds, or until the buffer is full with
|
||||
# `capacity` messages) before INFO/DEBUG logs get written.
|
||||
buffer:
|
||||
class: logging.handlers.MemoryHandler
|
||||
class: synapse.logging.handlers.PeriodicallyFlushingMemoryHandler
|
||||
target: file
|
||||
# The capacity is the number of log lines that are buffered before
|
||||
# being written to disk. Increasing this will lead to better
|
||||
|
||||
# The capacity is the maximum number of log lines that are buffered
|
||||
# before being written to disk. Increasing this will lead to better
|
||||
# performance, at the expensive of it taking longer for log lines to
|
||||
# be written to disk.
|
||||
# This parameter is required.
|
||||
capacity: 10
|
||||
flushLevel: 30 # Flush for WARNING logs as well
|
||||
|
||||
# Logs with a level at or above the flush level will cause the buffer to
|
||||
# be flushed immediately.
|
||||
# Default value: 40 (ERROR)
|
||||
# Other values: 50 (CRITICAL), 30 (WARNING), 20 (INFO), 10 (DEBUG)
|
||||
flushLevel: 30 # Flush immediately for WARNING logs and higher
|
||||
|
||||
# The period of time, in seconds, between forced flushes.
|
||||
# Messages will not be delayed for longer than this time.
|
||||
# Default value: 5 seconds
|
||||
period: 5
|
||||
{% endif %}
|
||||
|
||||
console:
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
- [Installation](setup/installation.md)
|
||||
- [Using Postgres](postgres.md)
|
||||
- [Configuring a Reverse Proxy](reverse_proxy.md)
|
||||
- [Configuring a Forward/Outbound Proxy](setup/forward_proxy.md)
|
||||
- [Configuring a Turn Server](turn-howto.md)
|
||||
- [Delegation](delegate.md)
|
||||
|
||||
@@ -20,6 +21,7 @@
|
||||
- [Homeserver Sample Config File](usage/configuration/homeserver_sample_config.md)
|
||||
- [Logging Sample Config File](usage/configuration/logging_sample_config.md)
|
||||
- [Structured Logging](structured_logging.md)
|
||||
- [Templates](templates.md)
|
||||
- [User Authentication](usage/configuration/user_authentication/README.md)
|
||||
- [Single-Sign On]()
|
||||
- [OpenID Connect](openid.md)
|
||||
@@ -79,6 +81,7 @@
|
||||
- [Single Sign-On]()
|
||||
- [SAML](development/saml.md)
|
||||
- [CAS](development/cas.md)
|
||||
- [Room DAG concepts](development/room-dag-concepts.md)
|
||||
- [State Resolution]()
|
||||
- [The Auth Chain Difference Algorithm](auth_chain_difference_algorithm.md)
|
||||
- [Media Repository](media_repository.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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
79
docs/development/room-dag-concepts.md
Normal file
79
docs/development/room-dag-concepts.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Room DAG concepts
|
||||
|
||||
## Edges
|
||||
|
||||
The word "edge" comes from graph theory lingo. An edge is just a connection
|
||||
between two events. In Synapse, we connect events by specifying their
|
||||
`prev_events`. A subsequent event points back at a previous event.
|
||||
|
||||
```
|
||||
A (oldest) <---- B <---- C (most recent)
|
||||
```
|
||||
|
||||
|
||||
## Depth and stream ordering
|
||||
|
||||
Events are normally sorted by `(topological_ordering, stream_ordering)` where
|
||||
`topological_ordering` is just `depth`. In other words, we first sort by `depth`
|
||||
and then tie-break based on `stream_ordering`. `depth` is incremented as new
|
||||
messages are added to the DAG. Normally, `stream_ordering` is an auto
|
||||
incrementing integer, but backfilled events start with `stream_ordering=-1` and decrement.
|
||||
|
||||
---
|
||||
|
||||
- `/sync` returns things in the order they arrive at the server (`stream_ordering`).
|
||||
- `/messages` (and `/backfill` in the federation API) return them in the order determined by the event graph `(topological_ordering, stream_ordering)`.
|
||||
|
||||
The general idea is that, if you're following a room in real-time (i.e.
|
||||
`/sync`), you probably want to see the messages as they arrive at your server,
|
||||
rather than skipping any that arrived late; whereas if you're looking at a
|
||||
historical section of timeline (i.e. `/messages`), you want to see the best
|
||||
representation of the state of the room as others were seeing it at the time.
|
||||
|
||||
|
||||
## Forward extremity
|
||||
|
||||
Most-recent-in-time events in the DAG which are not referenced by any other events' `prev_events` yet.
|
||||
|
||||
The forward extremities of a room are used as the `prev_events` when the next event is sent.
|
||||
|
||||
|
||||
## Backwards extremity
|
||||
|
||||
The current marker of where we have backfilled up to and will generally be the
|
||||
oldest-in-time events we know of in the DAG.
|
||||
|
||||
This is an event where we haven't fetched all of the `prev_events` for.
|
||||
|
||||
Once we have fetched all of its `prev_events`, it's unmarked as a backwards
|
||||
extremity (although we may have formed new backwards extremities from the prev
|
||||
events during the backfilling process).
|
||||
|
||||
|
||||
## Outliers
|
||||
|
||||
We mark an event as an `outlier` when we haven't figured out the state for the
|
||||
room at that point in the DAG yet.
|
||||
|
||||
We won't *necessarily* have the `prev_events` of an `outlier` in the database,
|
||||
but it's entirely possible that we *might*. The status of whether we have all of
|
||||
the `prev_events` is marked as a [backwards extremity](#backwards-extremity).
|
||||
|
||||
For example, when we fetch the event auth chain or state for a given event, we
|
||||
mark all of those claimed auth events as outliers because we haven't done the
|
||||
state calculation ourself.
|
||||
|
||||
|
||||
## State groups
|
||||
|
||||
For every non-outlier event we need to know the state at that event. Instead of
|
||||
storing the full state for each event in the DB (i.e. a `event_id -> state`
|
||||
mapping), which is *very* space inefficient when state doesn't change, we
|
||||
instead assign each different set of state a "state group" and then have
|
||||
mappings of `event_id -> state_group` and `state_group -> state`.
|
||||
|
||||
|
||||
### Stage group edges
|
||||
|
||||
TODO: `state_group_edges` is a further optimization...
|
||||
notes from @Azrenbeth, https://pastebin.com/seUGVGeT
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -210,6 +210,8 @@ presence:
|
||||
#
|
||||
# This option replaces federation_ip_range_blacklist in Synapse v1.25.0.
|
||||
#
|
||||
# Note: The value is ignored when an HTTP proxy is in use
|
||||
#
|
||||
#ip_range_blacklist:
|
||||
# - '127.0.0.0/8'
|
||||
# - '10.0.0.0/8'
|
||||
@@ -563,6 +565,19 @@ retention:
|
||||
#
|
||||
#next_link_domain_whitelist: ["matrix.org"]
|
||||
|
||||
# Templates to use when generating email or HTML page contents.
|
||||
#
|
||||
templates:
|
||||
# Directory in which Synapse will try to find template files to use to generate
|
||||
# email or HTML page contents.
|
||||
# If not set, or a file is not found within the template directory, a default
|
||||
# template from within the Synapse package will be used.
|
||||
#
|
||||
# See https://matrix-org.github.io/synapse/latest/templates.html for more
|
||||
# information about using custom templates.
|
||||
#
|
||||
#custom_template_directory: /path/to/custom/templates/
|
||||
|
||||
|
||||
## TLS ##
|
||||
|
||||
@@ -711,6 +726,15 @@ caches:
|
||||
#
|
||||
#expiry_time: 30m
|
||||
|
||||
# Controls how long the results of a /sync request are cached for after
|
||||
# a successful response is returned. A higher duration can help clients with
|
||||
# intermittent connections, at the cost of higher memory usage.
|
||||
#
|
||||
# By default, this is zero, which means that sync responses are not cached
|
||||
# at all.
|
||||
#
|
||||
#sync_response_cache_duration: 2m
|
||||
|
||||
|
||||
## Database ##
|
||||
|
||||
@@ -720,6 +744,9 @@ caches:
|
||||
# 'name' gives the database engine to use: either 'sqlite3' (for SQLite) or
|
||||
# 'psycopg2' (for PostgreSQL).
|
||||
#
|
||||
# 'txn_limit' gives the maximum number of transactions to run per connection
|
||||
# before reconnecting. Defaults to 0, which means no limit.
|
||||
#
|
||||
# 'args' gives options which are passed through to the database engine,
|
||||
# except for options starting 'cp_', which are used to configure the Twisted
|
||||
# connection pool. For a reference to valid arguments, see:
|
||||
@@ -740,6 +767,7 @@ caches:
|
||||
#
|
||||
#database:
|
||||
# name: psycopg2
|
||||
# txn_limit: 10000
|
||||
# args:
|
||||
# user: synapse_user
|
||||
# password: secretpassword
|
||||
@@ -959,6 +987,8 @@ media_store_path: "DATADIR/media_store"
|
||||
# This must be specified if url_preview_enabled is set. It is recommended that
|
||||
# you uncomment the following list as a starting point.
|
||||
#
|
||||
# Note: The value is ignored when an HTTP proxy is in use
|
||||
#
|
||||
#url_preview_ip_range_blacklist:
|
||||
# - '127.0.0.0/8'
|
||||
# - '10.0.0.0/8'
|
||||
@@ -1878,6 +1908,9 @@ cas_config:
|
||||
# Additional settings to use with single-sign on systems such as OpenID Connect,
|
||||
# SAML2 and CAS.
|
||||
#
|
||||
# Server admins can configure custom templates for pages related to SSO. See
|
||||
# https://matrix-org.github.io/synapse/latest/templates.html for more information.
|
||||
#
|
||||
sso:
|
||||
# A list of client URLs which are whitelisted so that the user does not
|
||||
# have to confirm giving access to their account to the URL. Any client
|
||||
@@ -1910,169 +1943,6 @@ sso:
|
||||
#
|
||||
#update_profile_information: true
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, or the files named below are not found within the template
|
||||
# directory, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# Synapse will look for the following templates in this directory:
|
||||
#
|
||||
# * HTML page to prompt the user to choose an Identity Provider during
|
||||
# login: 'sso_login_idp_picker.html'.
|
||||
#
|
||||
# This is only used if multiple SSO Identity Providers are configured.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
# * redirect_url: the URL that the user will be redirected to after
|
||||
# login.
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * providers: a list of available Identity Providers. Each element is
|
||||
# an object with the following attributes:
|
||||
#
|
||||
# * idp_id: unique identifier for the IdP
|
||||
# * idp_name: user-facing name for the IdP
|
||||
# * idp_icon: if specified in the IdP config, an MXC URI for an icon
|
||||
# for the IdP
|
||||
# * idp_brand: if specified in the IdP config, a textual identifier
|
||||
# for the brand of the IdP
|
||||
#
|
||||
# The rendered HTML page should contain a form which submits its results
|
||||
# back as a GET request, with the following query parameters:
|
||||
#
|
||||
# * redirectUrl: the client redirect URI (ie, the `redirect_url` passed
|
||||
# to the template)
|
||||
#
|
||||
# * idp: the 'idp_id' of the chosen IDP.
|
||||
#
|
||||
# * HTML page to prompt new users to enter a userid and confirm other
|
||||
# details: 'sso_auth_account_details.html'. This is only shown if the
|
||||
# SSO implementation (with any user_mapping_provider) does not return
|
||||
# a localpart.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * idp: details of the SSO Identity Provider that the user logged in
|
||||
# with: an object with the following attributes:
|
||||
#
|
||||
# * idp_id: unique identifier for the IdP
|
||||
# * idp_name: user-facing name for the IdP
|
||||
# * idp_icon: if specified in the IdP config, an MXC URI for an icon
|
||||
# for the IdP
|
||||
# * idp_brand: if specified in the IdP config, a textual identifier
|
||||
# for the brand of the IdP
|
||||
#
|
||||
# * user_attributes: an object containing details about the user that
|
||||
# we received from the IdP. May have the following attributes:
|
||||
#
|
||||
# * display_name: the user's display_name
|
||||
# * emails: a list of email addresses
|
||||
#
|
||||
# The template should render a form which submits the following fields:
|
||||
#
|
||||
# * username: the localpart of the user's chosen user id
|
||||
#
|
||||
# * HTML page allowing the user to consent to the server's terms and
|
||||
# conditions. This is only shown for new users, and only if
|
||||
# `user_consent.require_at_registration` is set.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * user_id: the user's matrix proposed ID.
|
||||
#
|
||||
# * user_profile.display_name: the user's proposed display name, if any.
|
||||
#
|
||||
# * consent_version: the version of the terms that the user will be
|
||||
# shown
|
||||
#
|
||||
# * terms_url: a link to the page showing the terms.
|
||||
#
|
||||
# The template should render a form which submits the following fields:
|
||||
#
|
||||
# * accepted_version: the version of the terms accepted by the user
|
||||
# (ie, 'consent_version' from the input variables).
|
||||
#
|
||||
# * HTML page for a confirmation step before redirecting back to the client
|
||||
# with the login token: 'sso_redirect_confirm.html'.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
#
|
||||
# * redirect_url: the URL the user is about to be redirected to.
|
||||
#
|
||||
# * display_url: the same as `redirect_url`, but with the query
|
||||
# parameters stripped. The intention is to have a
|
||||
# human-readable URL to show to users, not to use it as
|
||||
# the final address to redirect to.
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * new_user: a boolean indicating whether this is the user's first time
|
||||
# logging in.
|
||||
#
|
||||
# * user_id: the user's matrix ID.
|
||||
#
|
||||
# * user_profile.avatar_url: an MXC URI for the user's avatar, if any.
|
||||
# None if the user has not set an avatar.
|
||||
#
|
||||
# * user_profile.display_name: the user's display name. None if the user
|
||||
# has not set a display name.
|
||||
#
|
||||
# * HTML page which notifies the user that they are authenticating to confirm
|
||||
# an operation on their account during the user interactive authentication
|
||||
# process: 'sso_auth_confirm.html'.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
# * redirect_url: the URL the user is about to be redirected to.
|
||||
#
|
||||
# * description: the operation which the user is being asked to confirm
|
||||
#
|
||||
# * idp: details of the Identity Provider that we will use to confirm
|
||||
# the user's identity: an object with the following attributes:
|
||||
#
|
||||
# * idp_id: unique identifier for the IdP
|
||||
# * idp_name: user-facing name for the IdP
|
||||
# * idp_icon: if specified in the IdP config, an MXC URI for an icon
|
||||
# for the IdP
|
||||
# * idp_brand: if specified in the IdP config, a textual identifier
|
||||
# for the brand of the IdP
|
||||
#
|
||||
# * HTML page shown after a successful user interactive authentication session:
|
||||
# 'sso_auth_success.html'.
|
||||
#
|
||||
# Note that this page must include the JavaScript which notifies of a successful authentication
|
||||
# (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
|
||||
#
|
||||
# This template has no additional variables.
|
||||
#
|
||||
# * HTML page shown after a user-interactive authentication session which
|
||||
# does not map correctly onto the expected user: 'sso_auth_bad_user.html'.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
# * server_name: the homeserver's name.
|
||||
# * user_id_to_verify: the MXID of the user that we are trying to
|
||||
# validate.
|
||||
#
|
||||
# * HTML page shown during single sign-on if a deactivated user (according to Synapse's database)
|
||||
# attempts to login: 'sso_account_deactivated.html'.
|
||||
#
|
||||
# This template has no additional variables.
|
||||
#
|
||||
# * HTML page to display to users if something goes wrong during the
|
||||
# OpenID Connect authentication process: 'sso_error.html'.
|
||||
#
|
||||
# When rendering, this template is given two variables:
|
||||
# * error: the technical name of the error
|
||||
# * error_description: a human-readable message for the error
|
||||
#
|
||||
# You can see the default templates at:
|
||||
# https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
|
||||
|
||||
# JSON web token integration. The following settings can be used to make
|
||||
# Synapse JSON web tokens for authentication, instead of its internal
|
||||
@@ -2203,6 +2073,9 @@ ui_auth:
|
||||
|
||||
# Configuration for sending emails from Synapse.
|
||||
#
|
||||
# Server admins can configure custom templates for email content. See
|
||||
# https://matrix-org.github.io/synapse/latest/templates.html for more information.
|
||||
#
|
||||
email:
|
||||
# The hostname of the outgoing SMTP server to use. Defaults to 'localhost'.
|
||||
#
|
||||
@@ -2225,6 +2098,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.
|
||||
#
|
||||
@@ -2271,49 +2152,6 @@ email:
|
||||
#
|
||||
#invite_client_location: https://app.element.io
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, or the files named below are not found within the template
|
||||
# directory, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# Synapse will look for the following templates in this directory:
|
||||
#
|
||||
# * The contents of email notifications of missed events: 'notif_mail.html' and
|
||||
# 'notif_mail.txt'.
|
||||
#
|
||||
# * The contents of account expiry notice emails: 'notice_expiry.html' and
|
||||
# 'notice_expiry.txt'.
|
||||
#
|
||||
# * The contents of password reset emails sent by the homeserver:
|
||||
# 'password_reset.html' and 'password_reset.txt'
|
||||
#
|
||||
# * An HTML page that a user will see when they follow the link in the password
|
||||
# reset email. The user will be asked to confirm the action before their
|
||||
# password is reset: 'password_reset_confirmation.html'
|
||||
#
|
||||
# * HTML pages for success and failure that a user will see when they confirm
|
||||
# the password reset flow using the page above: 'password_reset_success.html'
|
||||
# and 'password_reset_failure.html'
|
||||
#
|
||||
# * The contents of address verification emails sent during registration:
|
||||
# 'registration.html' and 'registration.txt'
|
||||
#
|
||||
# * HTML pages for success and failure that a user will see when they follow
|
||||
# the link in an address verification email sent during registration:
|
||||
# 'registration_success.html' and 'registration_failure.html'
|
||||
#
|
||||
# * The contents of address verification emails sent when an address is added
|
||||
# to a Matrix account: 'add_threepid.html' and 'add_threepid.txt'
|
||||
#
|
||||
# * HTML pages for success and failure that a user will see when they follow
|
||||
# the link in an address verification email sent when an address is added
|
||||
# to a Matrix account: 'add_threepid_success.html' and
|
||||
# 'add_threepid_failure.html'
|
||||
#
|
||||
# You can see the default templates at:
|
||||
# https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
|
||||
# Subjects to use when sending emails from Synapse.
|
||||
#
|
||||
# The placeholder '%(app)s' will be replaced with the value of the 'app_name'
|
||||
|
||||
@@ -24,20 +24,30 @@ handlers:
|
||||
backupCount: 3 # Does not include the current log file.
|
||||
encoding: utf8
|
||||
|
||||
# Default to buffering writes to log file for efficiency. This means that
|
||||
# will be a delay for INFO/DEBUG logs to get written, but WARNING/ERROR
|
||||
# logs will still be flushed immediately.
|
||||
# Default to buffering writes to log file for efficiency.
|
||||
# WARNING/ERROR logs will still be flushed immediately, but there will be a
|
||||
# delay (of up to `period` seconds, or until the buffer is full with
|
||||
# `capacity` messages) before INFO/DEBUG logs get written.
|
||||
buffer:
|
||||
class: synapse.logging.handlers.PeriodicallyFlushingMemoryHandler
|
||||
target: file
|
||||
# The capacity is the number of log lines that are buffered before
|
||||
# being written to disk. Increasing this will lead to better
|
||||
|
||||
# The capacity is the maximum number of log lines that are buffered
|
||||
# before being written to disk. Increasing this will lead to better
|
||||
# performance, at the expensive of it taking longer for log lines to
|
||||
# be written to disk.
|
||||
# This parameter is required.
|
||||
capacity: 10
|
||||
flushLevel: 30 # Flush for WARNING logs as well
|
||||
|
||||
# Logs with a level at or above the flush level will cause the buffer to
|
||||
# be flushed immediately.
|
||||
# Default value: 40 (ERROR)
|
||||
# Other values: 50 (CRITICAL), 30 (WARNING), 20 (INFO), 10 (DEBUG)
|
||||
flushLevel: 30 # Flush immediately for WARNING logs and higher
|
||||
|
||||
# The period of time, in seconds, between forced flushes.
|
||||
# Messages will not be delayed for longer than this time.
|
||||
# Default value: 5 seconds
|
||||
period: 5
|
||||
|
||||
# A handler that writes logs to stderr. Unused by default, but can be used
|
||||
|
||||
74
docs/setup/forward_proxy.md
Normal file
74
docs/setup/forward_proxy.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Using a forward proxy with Synapse
|
||||
|
||||
You can use Synapse with a forward or outbound proxy. An example of when
|
||||
this is necessary is in corporate environments behind a DMZ (demilitarized zone).
|
||||
Synapse supports routing outbound HTTP(S) requests via a proxy. Only HTTP(S)
|
||||
proxy is supported, not SOCKS proxy or anything else.
|
||||
|
||||
## Configure
|
||||
|
||||
The `http_proxy`, `https_proxy`, `no_proxy` environment variables are used to
|
||||
specify proxy settings. The environment variable is not case sensitive.
|
||||
- `http_proxy`: Proxy server to use for HTTP requests.
|
||||
- `https_proxy`: Proxy server to use for HTTPS requests.
|
||||
- `no_proxy`: Comma-separated list of hosts, IP addresses, or IP ranges in CIDR
|
||||
format which should not use the proxy. Synapse will directly connect to these hosts.
|
||||
|
||||
The `http_proxy` and `https_proxy` environment variables have the form: `[scheme://][<username>:<password>@]<host>[:<port>]`
|
||||
- Supported schemes are `http://` and `https://`. The default scheme is `http://`
|
||||
for compatibility reasons; it is recommended to set a scheme. If scheme is set
|
||||
to `https://` the connection uses TLS between Synapse and the proxy.
|
||||
|
||||
**NOTE**: Synapse validates the certificates. If the certificate is not
|
||||
valid, then the connection is dropped.
|
||||
- Default port if not given is `1080`.
|
||||
- Username and password are optional and will be used to authenticate against
|
||||
the proxy.
|
||||
|
||||
**Examples**
|
||||
- HTTP_PROXY=http://USERNAME:PASSWORD@10.0.1.1:8080/
|
||||
- HTTPS_PROXY=http://USERNAME:PASSWORD@proxy.example.com:8080/
|
||||
- NO_PROXY=master.hostname.example.com,10.1.0.0/16,172.30.0.0/16
|
||||
|
||||
**NOTE**:
|
||||
Synapse does not apply the IP blacklist to connections through the proxy (since
|
||||
the DNS resolution is done by the proxy). It is expected that the proxy or firewall
|
||||
will apply blacklisting of IP addresses.
|
||||
|
||||
## Connection types
|
||||
|
||||
The proxy will be **used** for:
|
||||
|
||||
- push
|
||||
- url previews
|
||||
- phone-home stats
|
||||
- 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
|
||||
- In worker configurations
|
||||
- connections between workers
|
||||
- connections from workers to Redis
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
If a proxy server is used with TLS (HTTPS) and no connections are established,
|
||||
it is most likely due to the proxy's certificates. To test this, the validation
|
||||
in Synapse can be deactivated.
|
||||
|
||||
**NOTE**: This has an impact on security and is for testing purposes only!
|
||||
|
||||
To deactivate the certificate validation, the following setting must be made in
|
||||
[homserver.yaml](../usage/configuration/homeserver_sample_config.md).
|
||||
|
||||
```yaml
|
||||
use_insecure_ssl_client_just_for_testing_do_not_use: true
|
||||
```
|
||||
239
docs/templates.md
Normal file
239
docs/templates.md
Normal file
@@ -0,0 +1,239 @@
|
||||
# Templates
|
||||
|
||||
Synapse uses parametrised templates to generate the content of emails it sends and
|
||||
webpages it shows to users.
|
||||
|
||||
By default, Synapse will use the templates listed [here](https://github.com/matrix-org/synapse/tree/master/synapse/res/templates).
|
||||
Server admins can configure an additional directory for Synapse to look for templates
|
||||
in, allowing them to specify custom templates:
|
||||
|
||||
```yaml
|
||||
templates:
|
||||
custom_templates_directory: /path/to/custom/templates/
|
||||
```
|
||||
|
||||
If this setting is not set, or the files named below are not found within the directory,
|
||||
default templates from within the Synapse package will be used.
|
||||
|
||||
Templates that are given variables when being rendered are rendered using [Jinja 2](https://jinja.palletsprojects.com/en/2.11.x/).
|
||||
Templates rendered by Jinja 2 can also access two functions on top of the functions
|
||||
already available as part of Jinja 2:
|
||||
|
||||
```python
|
||||
format_ts(value: int, format: str) -> str
|
||||
```
|
||||
|
||||
Formats a timestamp in milliseconds.
|
||||
|
||||
Example: `reason.last_sent_ts|format_ts("%c")`
|
||||
|
||||
```python
|
||||
mxc_to_http(value: str, width: int, height: int, resize_method: str = "crop") -> str
|
||||
```
|
||||
|
||||
Turns a `mxc://` URL for media content into an HTTP(S) one using the homeserver's
|
||||
`public_baseurl` configuration setting as the URL's base.
|
||||
|
||||
Example: `message.sender_avatar_url|mxc_to_http(32,32)`
|
||||
|
||||
|
||||
## Email templates
|
||||
|
||||
Below are the templates Synapse will look for when generating the content of an email:
|
||||
|
||||
* `notif_mail.html` and `notif_mail.txt`: The contents of email notifications of missed
|
||||
events.
|
||||
When rendering, this template is given the following variables:
|
||||
* `user_display_name`: the display name for the user receiving the notification
|
||||
* `unsubscribe_link`: the link users can click to unsubscribe from email notifications
|
||||
* `summary_text`: a summary of the notification(s). The text used can be customised
|
||||
by configuring the various settings in the `email.subjects` section of the
|
||||
configuration file.
|
||||
* `rooms`: a list of rooms containing events to include in the email. Each element is
|
||||
an object with the following attributes:
|
||||
* `title`: a human-readable name for the room
|
||||
* `hash`: a hash of the ID of the room
|
||||
* `invite`: a boolean, which is `True` if the room is an invite the user hasn't
|
||||
accepted yet, `False` otherwise
|
||||
* `notifs`: a list of events, or an empty list if `invite` is `True`. Each element
|
||||
is an object with the following attributes:
|
||||
* `link`: a `matrix.to` link to the event
|
||||
* `ts`: the time in milliseconds at which the event was received
|
||||
* `messages`: a list of messages containing one message before the event, the
|
||||
message in the event, and one message after the event. Each element is an
|
||||
object with the following attributes:
|
||||
* `event_type`: the type of the event
|
||||
* `is_historical`: a boolean, which is `False` if the message is the one
|
||||
that triggered the notification, `True` otherwise
|
||||
* `id`: the ID of the event
|
||||
* `ts`: the time in milliseconds at which the event was sent
|
||||
* `sender_name`: the display name for the event's sender
|
||||
* `sender_avatar_url`: the avatar URL (as a `mxc://` URL) for the event's
|
||||
sender
|
||||
* `sender_hash`: a hash of the user ID of the sender
|
||||
* `link`: a `matrix.to` link to the room
|
||||
* `reason`: information on the event that triggered the email to be sent. It's an
|
||||
object with the following attributes:
|
||||
* `room_id`: the ID of the room the event was sent in
|
||||
* `room_name`: a human-readable name for the room the event was sent in
|
||||
* `now`: the current time in milliseconds
|
||||
* `received_at`: the time in milliseconds at which the event was received
|
||||
* `delay_before_mail_ms`: the amount of time in milliseconds Synapse always waits
|
||||
before ever emailing about a notification (to give the user a chance to respond
|
||||
to other push or notice the window)
|
||||
* `last_sent_ts`: the time in milliseconds at which a notification was last sent
|
||||
for an event in this room
|
||||
* `throttle_ms`: the minimum amount of time in milliseconds between two
|
||||
notifications can be sent for this room
|
||||
* `password_reset.html` and `password_reset.txt`: The contents of password reset emails
|
||||
sent by the homeserver.
|
||||
When rendering, these templates are given a `link` variable which contains the link the
|
||||
user must click in order to reset their password.
|
||||
* `registration.html` and `registration.txt`: The contents of address verification emails
|
||||
sent during registration.
|
||||
When rendering, these templates are given a `link` variable which contains the link the
|
||||
user must click in order to validate their email address.
|
||||
* `add_threepid.html` and `add_threepid.txt`: The contents of address verification emails
|
||||
sent when an address is added to a Matrix account.
|
||||
When rendering, these templates are given a `link` variable which contains the link the
|
||||
user must click in order to validate their email address.
|
||||
|
||||
|
||||
## HTML page templates for registration and password reset
|
||||
|
||||
Below are the templates Synapse will look for when generating pages related to
|
||||
registration and password reset:
|
||||
|
||||
* `password_reset_confirmation.html`: An HTML page that a user will see when they follow
|
||||
the link in the password reset email. The user will be asked to confirm the action
|
||||
before their password is reset.
|
||||
When rendering, this template is given the following variables:
|
||||
* `sid`: the session ID for the password reset
|
||||
* `token`: the token for the password reset
|
||||
* `client_secret`: the client secret for the password reset
|
||||
* `password_reset_success.html` and `password_reset_failure.html`: HTML pages for success
|
||||
and failure that a user will see when they confirm the password reset flow using the
|
||||
page above.
|
||||
When rendering, `password_reset_success.html` is given no variable, and
|
||||
`password_reset_failure.html` is given a `failure_reason`, which contains the reason
|
||||
for the password reset failure.
|
||||
* `registration_success.html` and `registration_failure.html`: HTML pages for success and
|
||||
failure that a user will see when they follow the link in an address verification email
|
||||
sent during registration.
|
||||
When rendering, `registration_success.html` is given no variable, and
|
||||
`registration_failure.html` is given a `failure_reason`, which contains the reason
|
||||
for the registration failure.
|
||||
* `add_threepid_success.html` and `add_threepid_failure.html`: HTML pages for success and
|
||||
failure that a user will see when they follow the link in an address verification email
|
||||
sent when an address is added to a Matrix account.
|
||||
When rendering, `add_threepid_success.html` is given no variable, and
|
||||
`add_threepid_failure.html` is given a `failure_reason`, which contains the reason
|
||||
for the registration failure.
|
||||
|
||||
|
||||
## HTML page templates for Single Sign-On (SSO)
|
||||
|
||||
Below are the templates Synapse will look for when generating pages related to SSO:
|
||||
|
||||
* `sso_login_idp_picker.html`: HTML page to prompt the user to choose an
|
||||
Identity Provider during login.
|
||||
This is only used if multiple SSO Identity Providers are configured.
|
||||
When rendering, this template is given the following variables:
|
||||
* `redirect_url`: the URL that the user will be redirected to after
|
||||
login.
|
||||
* `server_name`: the homeserver's name.
|
||||
* `providers`: a list of available Identity Providers. Each element is
|
||||
an object with the following attributes:
|
||||
* `idp_id`: unique identifier for the IdP
|
||||
* `idp_name`: user-facing name for the IdP
|
||||
* `idp_icon`: if specified in the IdP config, an MXC URI for an icon
|
||||
for the IdP
|
||||
* `idp_brand`: if specified in the IdP config, a textual identifier
|
||||
for the brand of the IdP
|
||||
The rendered HTML page should contain a form which submits its results
|
||||
back as a GET request, with the following query parameters:
|
||||
* `redirectUrl`: the client redirect URI (ie, the `redirect_url` passed
|
||||
to the template)
|
||||
* `idp`: the 'idp_id' of the chosen IDP.
|
||||
* `sso_auth_account_details.html`: HTML page to prompt new users to enter a
|
||||
userid and confirm other details. This is only shown if the
|
||||
SSO implementation (with any `user_mapping_provider`) does not return
|
||||
a localpart.
|
||||
When rendering, this template is given the following variables:
|
||||
* `server_name`: the homeserver's name.
|
||||
* `idp`: details of the SSO Identity Provider that the user logged in
|
||||
with: an object with the following attributes:
|
||||
* `idp_id`: unique identifier for the IdP
|
||||
* `idp_name`: user-facing name for the IdP
|
||||
* `idp_icon`: if specified in the IdP config, an MXC URI for an icon
|
||||
for the IdP
|
||||
* `idp_brand`: if specified in the IdP config, a textual identifier
|
||||
for the brand of the IdP
|
||||
* `user_attributes`: an object containing details about the user that
|
||||
we received from the IdP. May have the following attributes:
|
||||
* display_name: the user's display_name
|
||||
* emails: a list of email addresses
|
||||
The template should render a form which submits the following fields:
|
||||
* `username`: the localpart of the user's chosen user id
|
||||
* `sso_new_user_consent.html`: HTML page allowing the user to consent to the
|
||||
server's terms and conditions. This is only shown for new users, and only if
|
||||
`user_consent.require_at_registration` is set.
|
||||
When rendering, this template is given the following variables:
|
||||
* `server_name`: the homeserver's name.
|
||||
* `user_id`: the user's matrix proposed ID.
|
||||
* `user_profile.display_name`: the user's proposed display name, if any.
|
||||
* consent_version: the version of the terms that the user will be
|
||||
shown
|
||||
* `terms_url`: a link to the page showing the terms.
|
||||
The template should render a form which submits the following fields:
|
||||
* `accepted_version`: the version of the terms accepted by the user
|
||||
(ie, 'consent_version' from the input variables).
|
||||
* `sso_redirect_confirm.html`: HTML page for a confirmation step before redirecting back
|
||||
to the client with the login token.
|
||||
When rendering, this template is given the following variables:
|
||||
* `redirect_url`: the URL the user is about to be redirected to.
|
||||
* `display_url`: the same as `redirect_url`, but with the query
|
||||
parameters stripped. The intention is to have a
|
||||
human-readable URL to show to users, not to use it as
|
||||
the final address to redirect to.
|
||||
* `server_name`: the homeserver's name.
|
||||
* `new_user`: a boolean indicating whether this is the user's first time
|
||||
logging in.
|
||||
* `user_id`: the user's matrix ID.
|
||||
* `user_profile.avatar_url`: an MXC URI for the user's avatar, if any.
|
||||
`None` if the user has not set an avatar.
|
||||
* `user_profile.display_name`: the user's display name. `None` if the user
|
||||
has not set a display name.
|
||||
* `sso_auth_confirm.html`: HTML page which notifies the user that they are authenticating
|
||||
to confirm an operation on their account during the user interactive authentication
|
||||
process.
|
||||
When rendering, this template is given the following variables:
|
||||
* `redirect_url`: the URL the user is about to be redirected to.
|
||||
* `description`: the operation which the user is being asked to confirm
|
||||
* `idp`: details of the Identity Provider that we will use to confirm
|
||||
the user's identity: an object with the following attributes:
|
||||
* `idp_id`: unique identifier for the IdP
|
||||
* `idp_name`: user-facing name for the IdP
|
||||
* `idp_icon`: if specified in the IdP config, an MXC URI for an icon
|
||||
for the IdP
|
||||
* `idp_brand`: if specified in the IdP config, a textual identifier
|
||||
for the brand of the IdP
|
||||
* `sso_auth_success.html`: HTML page shown after a successful user interactive
|
||||
authentication session.
|
||||
Note that this page must include the JavaScript which notifies of a successful
|
||||
authentication (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
|
||||
This template has no additional variables.
|
||||
* `sso_auth_bad_user.html`: HTML page shown after a user-interactive authentication
|
||||
session which does not map correctly onto the expected user.
|
||||
When rendering, this template is given the following variables:
|
||||
* `server_name`: the homeserver's name.
|
||||
* `user_id_to_verify`: the MXID of the user that we are trying to
|
||||
validate.
|
||||
* `sso_account_deactivated.html`: HTML page shown during single sign-on if a deactivated
|
||||
user (according to Synapse's database) attempts to login.
|
||||
This template has no additional variables.
|
||||
* `sso_error.html`: HTML page to display to users if something goes wrong during the
|
||||
OpenID Connect authentication process.
|
||||
When rendering, this template is given two variables:
|
||||
* `error`: the technical name of the error
|
||||
* `error_description`: a human-readable message for the error
|
||||
@@ -86,6 +86,50 @@ process, for example:
|
||||
```
|
||||
|
||||
|
||||
# Upgrading to v1.41.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.
|
||||
|
||||
## Deprecation of `template_dir`
|
||||
|
||||
The `template_dir` settings in the `sso`, `account_validity` and `email` sections of the
|
||||
configuration file are now deprecated. Server admins should use the new
|
||||
`templates.custom_template_directory` setting in the configuration file and use one single
|
||||
custom template directory for all aforementioned features. Template file names remain
|
||||
unchanged. See [the related documentation](https://matrix-org.github.io/synapse/latest/templates.html)
|
||||
for more information and examples.
|
||||
|
||||
We plan to remove support for these settings in October 2021.
|
||||
|
||||
## `/_synapse/admin/v1/users/{userId}/media` must be handled by media workers
|
||||
|
||||
The [media repository worker documentation](https://matrix-org.github.io/synapse/latest/workers.html#synapseappmedia_repository)
|
||||
has been updated to reflect that calls to `/_synapse/admin/v1/users/{userId}/media`
|
||||
must now be handled by media repository workers. This is due to the new `DELETE` method
|
||||
of this endpoint modifying the media store.
|
||||
|
||||
# Upgrading to v1.39.0
|
||||
|
||||
## Deprecation of the current third-party rules module interface
|
||||
@@ -142,9 +186,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 +261,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 +274,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 +309,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 +328,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 +528,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 +558,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 +628,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 +760,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 +778,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 +895,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 +998,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 +1034,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 +1049,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 +1075,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 +1096,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
|
||||
|
||||
|
||||
@@ -214,6 +214,7 @@ expressions:
|
||||
^/_matrix/federation/v1/send/
|
||||
|
||||
# Client API requests
|
||||
^/_matrix/client/(api/v1|r0|unstable)/createRoom$
|
||||
^/_matrix/client/(api/v1|r0|unstable)/publicRooms$
|
||||
^/_matrix/client/(api/v1|r0|unstable)/rooms/.*/joined_members$
|
||||
^/_matrix/client/(api/v1|r0|unstable)/rooms/.*/context/.*$
|
||||
@@ -425,10 +426,12 @@ Handles the media repository. It can handle all endpoints starting with:
|
||||
^/_synapse/admin/v1/user/.*/media.*$
|
||||
^/_synapse/admin/v1/media/.*$
|
||||
^/_synapse/admin/v1/quarantine_media/.*$
|
||||
^/_synapse/admin/v1/users/.*/media$
|
||||
|
||||
You should also set `enable_media_repo: False` in the shared configuration
|
||||
file to stop the main synapse running background jobs related to managing the
|
||||
media repository.
|
||||
media repository. Note that doing so will prevent the main process from being
|
||||
able to handle the above endpoints.
|
||||
|
||||
In the `media_repository` worker configuration file, configure the http listener to
|
||||
expose the `media` resource. For example:
|
||||
|
||||
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,
|
||||
|
||||
@@ -20,12 +20,12 @@ from concurrent.futures import ThreadPoolExecutor
|
||||
from typing import Optional, Sequence
|
||||
|
||||
DISTS = (
|
||||
"debian:buster",
|
||||
"debian:buster", # oldstable: EOL 2022-08
|
||||
"debian:bullseye",
|
||||
"debian:bookworm",
|
||||
"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
|
||||
|
||||
@@ -65,4 +65,4 @@ if [[ -n "$1" ]]; then
|
||||
fi
|
||||
|
||||
# Run the tests!
|
||||
go test -v -tags synapse_blacklist,msc2946,msc3083,msc2403 -count=1 $EXTRA_COMPLEMENT_ARGS ./tests/...
|
||||
go test -v -tags synapse_blacklist,msc2946,msc3083,msc2403,msc2716 -count=1 $EXTRA_COMPLEMENT_ARGS ./tests/...
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -14,29 +14,57 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""An interactive script for doing a release. See `run()` below.
|
||||
"""An interactive script for doing a release. See `cli()` below.
|
||||
"""
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Optional
|
||||
import urllib.request
|
||||
from os import path
|
||||
from tempfile import TemporaryDirectory
|
||||
from typing import List, Optional, Tuple
|
||||
|
||||
import attr
|
||||
import click
|
||||
import commonmark
|
||||
import git
|
||||
import redbaron
|
||||
from click.exceptions import ClickException
|
||||
from github import Github
|
||||
from packaging import version
|
||||
from redbaron import RedBaron
|
||||
|
||||
|
||||
@click.command()
|
||||
def run():
|
||||
"""An interactive script to walk through the initial stages of creating a
|
||||
release, including creating release branch, updating changelog and pushing to
|
||||
GitHub.
|
||||
@click.group()
|
||||
def cli():
|
||||
"""An interactive script to walk through the parts of creating a release.
|
||||
|
||||
Requires the dev dependencies be installed, which can be done via:
|
||||
|
||||
pip install -e .[dev]
|
||||
|
||||
Then to use:
|
||||
|
||||
./scripts-dev/release.py prepare
|
||||
|
||||
# ... ask others to look at the changelog ...
|
||||
|
||||
./scripts-dev/release.py tag
|
||||
|
||||
# ... wait for asssets to build ...
|
||||
|
||||
./scripts-dev/release.py publish
|
||||
./scripts-dev/release.py upload
|
||||
|
||||
If the env var GH_TOKEN (or GITHUB_TOKEN) is set, or passed into the
|
||||
`tag`/`publish` command, then a new draft release will be created/published.
|
||||
"""
|
||||
|
||||
|
||||
@cli.command()
|
||||
def prepare():
|
||||
"""Do the initial stages of creating a release, including creating release
|
||||
branch, updating changelog and pushing to GitHub.
|
||||
"""
|
||||
|
||||
# Make sure we're in a git repo.
|
||||
@@ -51,32 +79,8 @@ def run():
|
||||
click.secho("Updating git repo...")
|
||||
repo.remote().fetch()
|
||||
|
||||
# Parse the AST and load the `__version__` node so that we can edit it
|
||||
# later.
|
||||
with open("synapse/__init__.py") as f:
|
||||
red = RedBaron(f.read())
|
||||
|
||||
version_node = None
|
||||
for node in red:
|
||||
if node.type != "assignment":
|
||||
continue
|
||||
|
||||
if node.target.type != "name":
|
||||
continue
|
||||
|
||||
if node.target.value != "__version__":
|
||||
continue
|
||||
|
||||
version_node = node
|
||||
break
|
||||
|
||||
if not version_node:
|
||||
print("Failed to find '__version__' definition in synapse/__init__.py")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse the current version.
|
||||
current_version = version.parse(version_node.value.value.strip('"'))
|
||||
assert isinstance(current_version, version.Version)
|
||||
# Get the current version and AST from root Synapse module.
|
||||
current_version, parsed_synapse_ast, version_node = parse_version_from_module()
|
||||
|
||||
# Figure out what sort of release we're doing and calcuate the new version.
|
||||
rc = click.confirm("RC", default=True)
|
||||
@@ -139,6 +143,11 @@ def run():
|
||||
|
||||
# Switch to the release branch.
|
||||
parsed_new_version = version.parse(new_version)
|
||||
|
||||
# We assume for debian changelogs that we only do RCs or full releases.
|
||||
assert not parsed_new_version.is_devrelease
|
||||
assert not parsed_new_version.is_postrelease
|
||||
|
||||
release_branch_name = (
|
||||
f"release-v{parsed_new_version.major}.{parsed_new_version.minor}"
|
||||
)
|
||||
@@ -185,17 +194,26 @@ def run():
|
||||
# Update the `__version__` variable and write it back to the file.
|
||||
version_node.value = '"' + new_version + '"'
|
||||
with open("synapse/__init__.py", "w") as f:
|
||||
f.write(red.dumps())
|
||||
f.write(parsed_synapse_ast.dumps())
|
||||
|
||||
# Generate changelogs
|
||||
subprocess.run("python3 -m towncrier", shell=True)
|
||||
|
||||
# Generate debian changelogs if its not an RC.
|
||||
if not rc:
|
||||
subprocess.run(
|
||||
f'dch -M -v {new_version} "New synapse release {new_version}."', shell=True
|
||||
)
|
||||
subprocess.run('dch -M -r -D stable ""', shell=True)
|
||||
# Generate debian changelogs
|
||||
if parsed_new_version.pre is not None:
|
||||
# If this is an RC then we need to coerce the version string to match
|
||||
# Debian norms, e.g. 1.39.0rc2 gets converted to 1.39.0~rc2.
|
||||
base_ver = parsed_new_version.base_version
|
||||
pre_type, pre_num = parsed_new_version.pre
|
||||
debian_version = f"{base_ver}~{pre_type}{pre_num}"
|
||||
else:
|
||||
debian_version = new_version
|
||||
|
||||
subprocess.run(
|
||||
f'dch -M -v {debian_version} "New synapse release {debian_version}."',
|
||||
shell=True,
|
||||
)
|
||||
subprocess.run('dch -M -r -D stable ""', shell=True)
|
||||
|
||||
# Show the user the changes and ask if they want to edit the change log.
|
||||
repo.git.add("-u")
|
||||
@@ -226,6 +244,180 @@ def run():
|
||||
)
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--gh-token", envvar=["GH_TOKEN", "GITHUB_TOKEN"])
|
||||
def tag(gh_token: Optional[str]):
|
||||
"""Tags the release and generates a draft GitHub release"""
|
||||
|
||||
# Make sure we're in a git repo.
|
||||
try:
|
||||
repo = git.Repo()
|
||||
except git.InvalidGitRepositoryError:
|
||||
raise click.ClickException("Not in Synapse repo.")
|
||||
|
||||
if repo.is_dirty():
|
||||
raise click.ClickException("Uncommitted changes exist.")
|
||||
|
||||
click.secho("Updating git repo...")
|
||||
repo.remote().fetch()
|
||||
|
||||
# Find out the version and tag name.
|
||||
current_version, _, _ = parse_version_from_module()
|
||||
tag_name = f"v{current_version}"
|
||||
|
||||
# Check we haven't released this version.
|
||||
if tag_name in repo.tags:
|
||||
raise click.ClickException(f"Tag {tag_name} already exists!\n")
|
||||
|
||||
# Get the appropriate changelogs and tag.
|
||||
changes = get_changes_for_version(current_version)
|
||||
|
||||
click.echo_via_pager(changes)
|
||||
if click.confirm("Edit text?", default=False):
|
||||
changes = click.edit(changes, require_save=False)
|
||||
|
||||
repo.create_tag(tag_name, message=changes)
|
||||
|
||||
if not click.confirm("Push tag to GitHub?", default=True):
|
||||
print("")
|
||||
print("Run when ready to push:")
|
||||
print("")
|
||||
print(f"\tgit push {repo.remote().name} tag {current_version}")
|
||||
print("")
|
||||
return
|
||||
|
||||
repo.git.push(repo.remote().name, "tag", tag_name)
|
||||
|
||||
# If no token was given, we bail here
|
||||
if not gh_token:
|
||||
click.launch(f"https://github.com/matrix-org/synapse/releases/edit/{tag_name}")
|
||||
return
|
||||
|
||||
# Create a new draft release
|
||||
gh = Github(gh_token)
|
||||
gh_repo = gh.get_repo("matrix-org/synapse")
|
||||
release = gh_repo.create_git_release(
|
||||
tag=tag_name,
|
||||
name=tag_name,
|
||||
message=changes,
|
||||
draft=True,
|
||||
prerelease=current_version.is_prerelease,
|
||||
)
|
||||
|
||||
# Open the release and the actions where we are building the assets.
|
||||
click.launch(release.html_url)
|
||||
click.launch(
|
||||
f"https://github.com/matrix-org/synapse/actions?query=branch%3A{tag_name}"
|
||||
)
|
||||
|
||||
click.echo("Wait for release assets to be built")
|
||||
|
||||
|
||||
@cli.command()
|
||||
@click.option("--gh-token", envvar=["GH_TOKEN", "GITHUB_TOKEN"], required=True)
|
||||
def publish(gh_token: str):
|
||||
"""Publish release."""
|
||||
|
||||
# Make sure we're in a git repo.
|
||||
try:
|
||||
repo = git.Repo()
|
||||
except git.InvalidGitRepositoryError:
|
||||
raise click.ClickException("Not in Synapse repo.")
|
||||
|
||||
if repo.is_dirty():
|
||||
raise click.ClickException("Uncommitted changes exist.")
|
||||
|
||||
current_version, _, _ = parse_version_from_module()
|
||||
tag_name = f"v{current_version}"
|
||||
|
||||
if not click.confirm(f"Publish {tag_name}?", default=True):
|
||||
return
|
||||
|
||||
# Publish the draft release
|
||||
gh = Github(gh_token)
|
||||
gh_repo = gh.get_repo("matrix-org/synapse")
|
||||
for release in gh_repo.get_releases():
|
||||
if release.title == tag_name:
|
||||
break
|
||||
else:
|
||||
raise ClickException(f"Failed to find GitHub release for {tag_name}")
|
||||
|
||||
assert release.title == tag_name
|
||||
|
||||
if not release.draft:
|
||||
click.echo("Release already published.")
|
||||
return
|
||||
|
||||
release = release.update_release(
|
||||
name=release.title,
|
||||
message=release.body,
|
||||
tag_name=release.tag_name,
|
||||
prerelease=release.prerelease,
|
||||
draft=False,
|
||||
)
|
||||
|
||||
|
||||
@cli.command()
|
||||
def upload():
|
||||
"""Upload release to pypi."""
|
||||
|
||||
current_version, _, _ = parse_version_from_module()
|
||||
tag_name = f"v{current_version}"
|
||||
|
||||
pypi_asset_names = [
|
||||
f"matrix_synapse-{current_version}-py3-none-any.whl",
|
||||
f"matrix-synapse-{current_version}.tar.gz",
|
||||
]
|
||||
|
||||
with TemporaryDirectory(prefix=f"synapse_upload_{tag_name}_") as tmpdir:
|
||||
for name in pypi_asset_names:
|
||||
filename = path.join(tmpdir, name)
|
||||
url = f"https://github.com/matrix-org/synapse/releases/download/{tag_name}/{name}"
|
||||
|
||||
click.echo(f"Downloading {name} into {filename}")
|
||||
urllib.request.urlretrieve(url, filename=filename)
|
||||
|
||||
if click.confirm("Upload to PyPI?", default=True):
|
||||
subprocess.run("twine upload *", shell=True, cwd=tmpdir)
|
||||
|
||||
click.echo(
|
||||
f"Done! Remember to merge the tag {tag_name} into the appropriate branches"
|
||||
)
|
||||
|
||||
|
||||
def parse_version_from_module() -> Tuple[
|
||||
version.Version, redbaron.RedBaron, redbaron.Node
|
||||
]:
|
||||
# Parse the AST and load the `__version__` node so that we can edit it
|
||||
# later.
|
||||
with open("synapse/__init__.py") as f:
|
||||
red = redbaron.RedBaron(f.read())
|
||||
|
||||
version_node = None
|
||||
for node in red:
|
||||
if node.type != "assignment":
|
||||
continue
|
||||
|
||||
if node.target.type != "name":
|
||||
continue
|
||||
|
||||
if node.target.value != "__version__":
|
||||
continue
|
||||
|
||||
version_node = node
|
||||
break
|
||||
|
||||
if not version_node:
|
||||
print("Failed to find '__version__' definition in synapse/__init__.py")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse the current version.
|
||||
current_version = version.parse(version_node.value.value.strip('"'))
|
||||
assert isinstance(current_version, version.Version)
|
||||
|
||||
return current_version, red, version_node
|
||||
|
||||
|
||||
def find_ref(repo: git.Repo, ref_name: str) -> Optional[git.HEAD]:
|
||||
"""Find the branch/ref, looking first locally then in the remote."""
|
||||
if ref_name in repo.refs:
|
||||
@@ -242,5 +434,66 @@ def update_branch(repo: git.Repo):
|
||||
repo.git.merge(repo.active_branch.tracking_branch().name)
|
||||
|
||||
|
||||
def get_changes_for_version(wanted_version: version.Version) -> str:
|
||||
"""Get the changelogs for the given version.
|
||||
|
||||
If an RC then will only get the changelog for that RC version, otherwise if
|
||||
its a full release will get the changelog for the release and all its RCs.
|
||||
"""
|
||||
|
||||
with open("CHANGES.md") as f:
|
||||
changes = f.read()
|
||||
|
||||
# First we parse the changelog so that we can split it into sections based
|
||||
# on the release headings.
|
||||
ast = commonmark.Parser().parse(changes)
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
class VersionSection:
|
||||
title: str
|
||||
|
||||
# These are 0-based.
|
||||
start_line: int
|
||||
end_line: Optional[int] = None # Is none if its the last entry
|
||||
|
||||
headings: List[VersionSection] = []
|
||||
for node, _ in ast.walker():
|
||||
# We look for all text nodes that are in a level 1 heading.
|
||||
if node.t != "text":
|
||||
continue
|
||||
|
||||
if node.parent.t != "heading" or node.parent.level != 1:
|
||||
continue
|
||||
|
||||
# If we have a previous heading then we update its `end_line`.
|
||||
if headings:
|
||||
headings[-1].end_line = node.parent.sourcepos[0][0] - 1
|
||||
|
||||
headings.append(VersionSection(node.literal, node.parent.sourcepos[0][0] - 1))
|
||||
|
||||
changes_by_line = changes.split("\n")
|
||||
|
||||
version_changelog = [] # The lines we want to include in the changelog
|
||||
|
||||
# Go through each section and find any that match the requested version.
|
||||
regex = re.compile(r"^Synapse v?(\S+)")
|
||||
for section in headings:
|
||||
groups = regex.match(section.title)
|
||||
if not groups:
|
||||
continue
|
||||
|
||||
heading_version = version.parse(groups.group(1))
|
||||
heading_base_version = version.parse(heading_version.base_version)
|
||||
|
||||
# Check if heading version matches the requested version, or if its an
|
||||
# RC of the requested version.
|
||||
if wanted_version not in (heading_version, heading_base_version):
|
||||
continue
|
||||
|
||||
version_changelog.extend(changes_by_line[section.start_line : section.end_line])
|
||||
|
||||
return "\n".join(version_changelog)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
||||
cli()
|
||||
|
||||
2
setup.py
2
setup.py
@@ -108,6 +108,8 @@ CONDITIONAL_REQUIREMENTS["dev"] = CONDITIONAL_REQUIREMENTS["lint"] + [
|
||||
"click==7.1.2",
|
||||
"redbaron==0.9.2",
|
||||
"GitPython==3.1.14",
|
||||
"commonmark==0.9.1",
|
||||
"pygithub==1.55",
|
||||
]
|
||||
|
||||
CONDITIONAL_REQUIREMENTS["mypy"] = ["mypy==0.812", "mypy-zope==0.2.13"]
|
||||
|
||||
@@ -47,7 +47,7 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
__version__ = "1.39.0rc2"
|
||||
__version__ = "1.41.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
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -62,7 +62,7 @@ class JoinRules:
|
||||
INVITE = "invite"
|
||||
PRIVATE = "private"
|
||||
# As defined for MSC3083.
|
||||
MSC3083_RESTRICTED = "restricted"
|
||||
RESTRICTED = "restricted"
|
||||
|
||||
|
||||
class RestrictedJoinRuleTypes:
|
||||
@@ -128,6 +128,14 @@ class ToDeviceEventTypes:
|
||||
RoomKeyRequest = "m.room_key_request"
|
||||
|
||||
|
||||
class DeviceKeyAlgorithms:
|
||||
"""Spec'd algorithms for the generation of per-device keys"""
|
||||
|
||||
ED25519 = "ed25519"
|
||||
CURVE25519 = "curve25519"
|
||||
SIGNED_CURVE25519 = "signed_curve25519"
|
||||
|
||||
|
||||
class EduTypes:
|
||||
Presence = "m.presence"
|
||||
|
||||
@@ -198,9 +206,6 @@ class EventContentFields:
|
||||
MSC2716_CHUNK_ID = "org.matrix.msc2716.chunk_id"
|
||||
# For "marker" events
|
||||
MSC2716_MARKER_INSERTION = "org.matrix.msc2716.marker.insertion"
|
||||
MSC2716_MARKER_INSERTION_PREV_EVENTS = (
|
||||
"org.matrix.msc2716.marker.insertion_prev_events"
|
||||
)
|
||||
|
||||
|
||||
class RoomTypes:
|
||||
@@ -224,3 +229,7 @@ class HistoryVisibility:
|
||||
JOINED = "joined"
|
||||
SHARED = "shared"
|
||||
WORLD_READABLE = "world_readable"
|
||||
|
||||
|
||||
class ReadReceiptEventFields:
|
||||
MSC2285_HIDDEN = "org.matrix.msc2285.hidden"
|
||||
|
||||
@@ -73,6 +73,11 @@ class RoomVersion:
|
||||
# MSC2403: Allows join_rules to be set to 'knock', changes auth rules to allow sending
|
||||
# m.room.membership event with membership 'knock'.
|
||||
msc2403_knocking = attr.ib(type=bool)
|
||||
# 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:
|
||||
@@ -88,6 +93,8 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V2 = RoomVersion(
|
||||
"2",
|
||||
@@ -101,6 +108,8 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V3 = RoomVersion(
|
||||
"3",
|
||||
@@ -114,6 +123,8 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V4 = RoomVersion(
|
||||
"4",
|
||||
@@ -127,6 +138,8 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V5 = RoomVersion(
|
||||
"5",
|
||||
@@ -140,6 +153,8 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
V6 = RoomVersion(
|
||||
"6",
|
||||
@@ -153,6 +168,8 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=False,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=False,
|
||||
msc2716_historical=False,
|
||||
msc2716_redactions=False,
|
||||
)
|
||||
MSC2176 = RoomVersion(
|
||||
"org.matrix.msc2176",
|
||||
@@ -166,19 +183,8 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=True,
|
||||
msc3083_join_rules=False,
|
||||
msc2403_knocking=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",
|
||||
@@ -192,6 +198,53 @@ class RoomVersions:
|
||||
msc2176_redaction_rules=False,
|
||||
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.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=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,
|
||||
)
|
||||
|
||||
|
||||
@@ -205,8 +258,9 @@ KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {
|
||||
RoomVersions.V5,
|
||||
RoomVersions.V6,
|
||||
RoomVersions.MSC2176,
|
||||
RoomVersions.MSC3083,
|
||||
RoomVersions.V7,
|
||||
RoomVersions.MSC2716,
|
||||
RoomVersions.V8,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -239,7 +293,7 @@ MSC3244_CAPABILITIES = {
|
||||
),
|
||||
RoomVersionCapability(
|
||||
"restricted",
|
||||
None,
|
||||
RoomVersions.V8,
|
||||
lambda room_version: room_version.msc3083_join_rules,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2019 Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -39,7 +38,6 @@ from synapse.replication.slave.storage.groups import SlavedGroupServerStore
|
||||
from synapse.replication.slave.storage.push_rule import SlavedPushRuleStore
|
||||
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.server import HomeServer
|
||||
from synapse.util.logcontext import LoggingContext
|
||||
from synapse.util.versionstring import get_version_string
|
||||
@@ -59,7 +57,6 @@ class AdminCmdSlavedStore(
|
||||
SlavedPushRuleStore,
|
||||
SlavedEventStore,
|
||||
SlavedClientIpStore,
|
||||
RoomStore,
|
||||
BaseSlavedStore,
|
||||
):
|
||||
pass
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2018 New Vector Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
@@ -65,42 +64,41 @@ from synapse.replication.slave.storage.push_rule import SlavedPushRuleStore
|
||||
from synapse.replication.slave.storage.pushers import SlavedPusherStore
|
||||
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
|
||||
@@ -115,6 +113,7 @@ from synapse.storage.databases.main.monthly_active_users import (
|
||||
MonthlyActiveUsersWorkerStore,
|
||||
)
|
||||
from synapse.storage.databases.main.presence import PresenceStore
|
||||
from synapse.storage.databases.main.room import RoomWorkerStore
|
||||
from synapse.storage.databases.main.search import SearchStore
|
||||
from synapse.storage.databases.main.stats import StatsStore
|
||||
from synapse.storage.databases.main.transactions import TransactionWorkerStore
|
||||
@@ -238,7 +237,7 @@ class GenericWorkerSlavedStore(
|
||||
ClientIpWorkerStore,
|
||||
SlavedEventStore,
|
||||
SlavedKeyStore,
|
||||
RoomStore,
|
||||
RoomWorkerStore,
|
||||
DirectoryStore,
|
||||
SlavedApplicationServiceStore,
|
||||
SlavedRegistrationStore,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2014-2016 OpenMarket Ltd
|
||||
# Copyright 2019 New Vector Ltd
|
||||
#
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -109,7 +109,7 @@ async def phone_stats_home(hs, stats, stats_process=_stats_process):
|
||||
for name, count in r30_results.items():
|
||||
stats["r30_users_" + name] = count
|
||||
|
||||
r30v2_results = await store.count_r30_users()
|
||||
r30v2_results = await store.count_r30v2_users()
|
||||
for name, count in r30v2_results.items():
|
||||
stats["r30v2_users_" + name] = count
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2016 OpenMarket Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright 2017 Vector Creations Ltd
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -78,6 +78,11 @@ class AccountValidityConfig(Config):
|
||||
)
|
||||
|
||||
# Read and store template content
|
||||
custom_template_directories = (
|
||||
self.root.server.custom_template_directory,
|
||||
account_validity_template_dir,
|
||||
)
|
||||
|
||||
(
|
||||
self.account_validity_account_renewed_template,
|
||||
self.account_validity_account_previously_renewed_template,
|
||||
@@ -88,5 +93,5 @@ class AccountValidityConfig(Config):
|
||||
"account_previously_renewed.html",
|
||||
invalid_token_template_filename,
|
||||
],
|
||||
account_validity_template_dir,
|
||||
(td for td in custom_template_directories if td),
|
||||
)
|
||||
|
||||
@@ -151,6 +151,15 @@ class CacheConfig(Config):
|
||||
# entries are never evicted based on time.
|
||||
#
|
||||
#expiry_time: 30m
|
||||
|
||||
# Controls how long the results of a /sync request are cached for after
|
||||
# a successful response is returned. A higher duration can help clients with
|
||||
# intermittent connections, at the cost of higher memory usage.
|
||||
#
|
||||
# By default, this is zero, which means that sync responses are not cached
|
||||
# at all.
|
||||
#
|
||||
#sync_response_cache_duration: 2m
|
||||
"""
|
||||
|
||||
def read_config(self, config, **kwargs):
|
||||
@@ -212,6 +221,10 @@ class CacheConfig(Config):
|
||||
else:
|
||||
self.expiry_time_msec = None
|
||||
|
||||
self.sync_response_cache_duration = self.parse_duration(
|
||||
cache_config.get("sync_response_cache_duration", 0)
|
||||
)
|
||||
|
||||
# Resize all caches (if necessary) with the new factors we've loaded
|
||||
self.resize_all_caches()
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@ DEFAULT_CONFIG = """\
|
||||
# 'name' gives the database engine to use: either 'sqlite3' (for SQLite) or
|
||||
# 'psycopg2' (for PostgreSQL).
|
||||
#
|
||||
# 'txn_limit' gives the maximum number of transactions to run per connection
|
||||
# before reconnecting. Defaults to 0, which means no limit.
|
||||
#
|
||||
# 'args' gives options which are passed through to the database engine,
|
||||
# except for options starting 'cp_', which are used to configure the Twisted
|
||||
# connection pool. For a reference to valid arguments, see:
|
||||
@@ -53,6 +56,7 @@ DEFAULT_CONFIG = """\
|
||||
#
|
||||
#database:
|
||||
# name: psycopg2
|
||||
# txn_limit: 10000
|
||||
# args:
|
||||
# user: synapse_user
|
||||
# password: secretpassword
|
||||
|
||||
@@ -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,14 @@ class EmailConfig(Config):
|
||||
registration_template_success_html,
|
||||
add_threepid_template_success_html,
|
||||
],
|
||||
template_dir,
|
||||
(
|
||||
td
|
||||
for td in (
|
||||
self.root.server.custom_template_directory,
|
||||
template_dir,
|
||||
)
|
||||
if td
|
||||
), # Filter out template_dir if not provided
|
||||
)
|
||||
|
||||
# Render templates that do not contain any placeholders
|
||||
@@ -291,7 +304,14 @@ class EmailConfig(Config):
|
||||
self.email_notif_template_text,
|
||||
) = self.read_templates(
|
||||
[notif_template_html, notif_template_text],
|
||||
template_dir,
|
||||
(
|
||||
td
|
||||
for td in (
|
||||
self.root.server.custom_template_directory,
|
||||
template_dir,
|
||||
)
|
||||
if td
|
||||
), # Filter out template_dir if not provided
|
||||
)
|
||||
|
||||
self.email_notif_for_new_users = email_config.get(
|
||||
@@ -314,7 +334,14 @@ class EmailConfig(Config):
|
||||
self.account_validity_template_text,
|
||||
) = self.read_templates(
|
||||
[expiry_template_html, expiry_template_text],
|
||||
template_dir,
|
||||
(
|
||||
td
|
||||
for td in (
|
||||
self.root.server.custom_template_directory,
|
||||
template_dir,
|
||||
)
|
||||
if td
|
||||
), # Filter out template_dir if not provided
|
||||
)
|
||||
|
||||
subjects_config = email_config.get("subjects", {})
|
||||
@@ -346,6 +373,9 @@ class EmailConfig(Config):
|
||||
"""\
|
||||
# Configuration for sending emails from Synapse.
|
||||
#
|
||||
# Server admins can configure custom templates for email content. See
|
||||
# https://matrix-org.github.io/synapse/latest/templates.html for more information.
|
||||
#
|
||||
email:
|
||||
# The hostname of the outgoing SMTP server to use. Defaults to 'localhost'.
|
||||
#
|
||||
@@ -368,6 +398,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.
|
||||
#
|
||||
@@ -414,49 +452,6 @@ class EmailConfig(Config):
|
||||
#
|
||||
#invite_client_location: https://app.element.io
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, or the files named below are not found within the template
|
||||
# directory, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# Synapse will look for the following templates in this directory:
|
||||
#
|
||||
# * The contents of email notifications of missed events: 'notif_mail.html' and
|
||||
# 'notif_mail.txt'.
|
||||
#
|
||||
# * The contents of account expiry notice emails: 'notice_expiry.html' and
|
||||
# 'notice_expiry.txt'.
|
||||
#
|
||||
# * The contents of password reset emails sent by the homeserver:
|
||||
# 'password_reset.html' and 'password_reset.txt'
|
||||
#
|
||||
# * An HTML page that a user will see when they follow the link in the password
|
||||
# reset email. The user will be asked to confirm the action before their
|
||||
# password is reset: 'password_reset_confirmation.html'
|
||||
#
|
||||
# * HTML pages for success and failure that a user will see when they confirm
|
||||
# the password reset flow using the page above: 'password_reset_success.html'
|
||||
# and 'password_reset_failure.html'
|
||||
#
|
||||
# * The contents of address verification emails sent during registration:
|
||||
# 'registration.html' and 'registration.txt'
|
||||
#
|
||||
# * HTML pages for success and failure that a user will see when they follow
|
||||
# the link in an address verification email sent during registration:
|
||||
# 'registration_success.html' and 'registration_failure.html'
|
||||
#
|
||||
# * The contents of address verification emails sent when an address is added
|
||||
# to a Matrix account: 'add_threepid.html' and 'add_threepid.txt'
|
||||
#
|
||||
# * HTML pages for success and failure that a user will see when they follow
|
||||
# the link in an address verification email sent when an address is added
|
||||
# to a Matrix account: 'add_threepid_success.html' and
|
||||
# 'add_threepid_failure.html'
|
||||
#
|
||||
# You can see the default templates at:
|
||||
# https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
|
||||
# Subjects to use when sending emails from Synapse.
|
||||
#
|
||||
# The placeholder '%%(app)s' will be replaced with the value of the 'app_name'
|
||||
|
||||
@@ -33,5 +33,11 @@ class ExperimentalConfig(Config):
|
||||
# MSC2716 (backfill existing history)
|
||||
self.msc2716_enabled: bool = experimental.get("msc2716_enabled", False)
|
||||
|
||||
# MSC2285 (hidden read receipts)
|
||||
self.msc2285_enabled: bool = experimental.get("msc2285_enabled", False)
|
||||
|
||||
# MSC3244 (room version capabilities)
|
||||
self.msc3244_enabled: bool = experimental.get("msc3244_enabled", False)
|
||||
self.msc3244_enabled: bool = experimental.get("msc3244_enabled", True)
|
||||
|
||||
# MSC3266 (room summary api)
|
||||
self.msc3266_enabled: bool = experimental.get("msc3266_enabled", False)
|
||||
|
||||
@@ -67,20 +67,30 @@ handlers:
|
||||
backupCount: 3 # Does not include the current log file.
|
||||
encoding: utf8
|
||||
|
||||
# Default to buffering writes to log file for efficiency. This means that
|
||||
# will be a delay for INFO/DEBUG logs to get written, but WARNING/ERROR
|
||||
# logs will still be flushed immediately.
|
||||
# Default to buffering writes to log file for efficiency.
|
||||
# WARNING/ERROR logs will still be flushed immediately, but there will be a
|
||||
# delay (of up to `period` seconds, or until the buffer is full with
|
||||
# `capacity` messages) before INFO/DEBUG logs get written.
|
||||
buffer:
|
||||
class: synapse.logging.handlers.PeriodicallyFlushingMemoryHandler
|
||||
target: file
|
||||
# The capacity is the number of log lines that are buffered before
|
||||
# being written to disk. Increasing this will lead to better
|
||||
|
||||
# The capacity is the maximum number of log lines that are buffered
|
||||
# before being written to disk. Increasing this will lead to better
|
||||
# performance, at the expensive of it taking longer for log lines to
|
||||
# be written to disk.
|
||||
# This parameter is required.
|
||||
capacity: 10
|
||||
flushLevel: 30 # Flush for WARNING logs as well
|
||||
|
||||
# Logs with a level at or above the flush level will cause the buffer to
|
||||
# be flushed immediately.
|
||||
# Default value: 40 (ERROR)
|
||||
# Other values: 50 (CRITICAL), 30 (WARNING), 20 (INFO), 10 (DEBUG)
|
||||
flushLevel: 30 # Flush immediately for WARNING logs and higher
|
||||
|
||||
# The period of time, in seconds, between forced flushes.
|
||||
# Messages will not be delayed for longer than this time.
|
||||
# Default value: 5 seconds
|
||||
period: 5
|
||||
|
||||
# A handler that writes logs to stderr. Unused by default, but can be used
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
import os
|
||||
from collections import namedtuple
|
||||
from typing import Dict, List
|
||||
from urllib.request import getproxies_environment # type: ignore
|
||||
|
||||
from synapse.config.server import DEFAULT_IP_RANGE_BLACKLIST, generate_ip_set
|
||||
from synapse.python_dependencies import DependencyException, check_requirements
|
||||
@@ -22,6 +24,8 @@ from synapse.util.module_loader import load_module
|
||||
|
||||
from ._base import Config, ConfigError
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_THUMBNAIL_SIZES = [
|
||||
{"width": 32, "height": 32, "method": "crop"},
|
||||
{"width": 96, "height": 96, "method": "crop"},
|
||||
@@ -36,6 +40,9 @@ THUMBNAIL_SIZE_YAML = """\
|
||||
# method: %(method)s
|
||||
"""
|
||||
|
||||
HTTP_PROXY_SET_WARNING = """\
|
||||
The Synapse config url_preview_ip_range_blacklist will be ignored as an HTTP(s) proxy is configured."""
|
||||
|
||||
ThumbnailRequirement = namedtuple(
|
||||
"ThumbnailRequirement", ["width", "height", "method", "media_type"]
|
||||
)
|
||||
@@ -180,12 +187,17 @@ class ContentRepositoryConfig(Config):
|
||||
e.message # noqa: B306, DependencyException.message is a property
|
||||
)
|
||||
|
||||
proxy_env = getproxies_environment()
|
||||
if "url_preview_ip_range_blacklist" not in config:
|
||||
raise ConfigError(
|
||||
"For security, you must specify an explicit target IP address "
|
||||
"blacklist in url_preview_ip_range_blacklist for url previewing "
|
||||
"to work"
|
||||
)
|
||||
if "http" not in proxy_env or "https" not in proxy_env:
|
||||
raise ConfigError(
|
||||
"For security, you must specify an explicit target IP address "
|
||||
"blacklist in url_preview_ip_range_blacklist for url previewing "
|
||||
"to work"
|
||||
)
|
||||
else:
|
||||
if "http" in proxy_env or "https" in proxy_env:
|
||||
logger.warning("".join(HTTP_PROXY_SET_WARNING))
|
||||
|
||||
# we always blacklist '0.0.0.0' and '::', which are supposed to be
|
||||
# unroutable addresses.
|
||||
@@ -292,6 +304,8 @@ class ContentRepositoryConfig(Config):
|
||||
# This must be specified if url_preview_enabled is set. It is recommended that
|
||||
# you uncomment the following list as a starting point.
|
||||
#
|
||||
# Note: The value is ignored when an HTTP proxy is in use
|
||||
#
|
||||
#url_preview_ip_range_blacklist:
|
||||
%(ip_range_blacklist)s
|
||||
|
||||
|
||||
@@ -710,6 +710,18 @@ class ServerConfig(Config):
|
||||
# Turn the list into a set to improve lookup speed.
|
||||
self.next_link_domain_whitelist = set(next_link_domain_whitelist)
|
||||
|
||||
templates_config = config.get("templates") or {}
|
||||
if not isinstance(templates_config, dict):
|
||||
raise ConfigError("The 'templates' section must be a dictionary")
|
||||
|
||||
self.custom_template_directory = templates_config.get(
|
||||
"custom_template_directory"
|
||||
)
|
||||
if self.custom_template_directory is not None and not isinstance(
|
||||
self.custom_template_directory, str
|
||||
):
|
||||
raise ConfigError("'custom_template_directory' must be a string")
|
||||
|
||||
def has_tls_listener(self) -> bool:
|
||||
return any(listener.tls for listener in self.listeners)
|
||||
|
||||
@@ -960,6 +972,8 @@ class ServerConfig(Config):
|
||||
#
|
||||
# This option replaces federation_ip_range_blacklist in Synapse v1.25.0.
|
||||
#
|
||||
# Note: The value is ignored when an HTTP proxy is in use
|
||||
#
|
||||
#ip_range_blacklist:
|
||||
%(ip_range_blacklist)s
|
||||
|
||||
@@ -1282,6 +1296,19 @@ class ServerConfig(Config):
|
||||
# all domains.
|
||||
#
|
||||
#next_link_domain_whitelist: ["matrix.org"]
|
||||
|
||||
# Templates to use when generating email or HTML page contents.
|
||||
#
|
||||
templates:
|
||||
# Directory in which Synapse will try to find template files to use to generate
|
||||
# email or HTML page contents.
|
||||
# If not set, or a file is not found within the template directory, a default
|
||||
# template from within the Synapse package will be used.
|
||||
#
|
||||
# See https://matrix-org.github.io/synapse/latest/templates.html for more
|
||||
# information about using custom templates.
|
||||
#
|
||||
#custom_template_directory: /path/to/custom/templates/
|
||||
"""
|
||||
% locals()
|
||||
)
|
||||
|
||||
@@ -45,6 +45,11 @@ class SSOConfig(Config):
|
||||
self.sso_template_dir = sso_config.get("template_dir")
|
||||
|
||||
# Read templates from disk
|
||||
custom_template_directories = (
|
||||
self.root.server.custom_template_directory,
|
||||
self.sso_template_dir,
|
||||
)
|
||||
|
||||
(
|
||||
self.sso_login_idp_picker_template,
|
||||
self.sso_redirect_confirm_template,
|
||||
@@ -63,7 +68,7 @@ class SSOConfig(Config):
|
||||
"sso_auth_success.html",
|
||||
"sso_auth_bad_user.html",
|
||||
],
|
||||
self.sso_template_dir,
|
||||
(td for td in custom_template_directories if td),
|
||||
)
|
||||
|
||||
# These templates have no placeholders, so render them here
|
||||
@@ -94,6 +99,9 @@ class SSOConfig(Config):
|
||||
# Additional settings to use with single-sign on systems such as OpenID Connect,
|
||||
# SAML2 and CAS.
|
||||
#
|
||||
# Server admins can configure custom templates for pages related to SSO. See
|
||||
# https://matrix-org.github.io/synapse/latest/templates.html for more information.
|
||||
#
|
||||
sso:
|
||||
# A list of client URLs which are whitelisted so that the user does not
|
||||
# have to confirm giving access to their account to the URL. Any client
|
||||
@@ -125,167 +133,4 @@ class SSOConfig(Config):
|
||||
# information when first signing in. Defaults to false.
|
||||
#
|
||||
#update_profile_information: true
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, or the files named below are not found within the template
|
||||
# directory, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# Synapse will look for the following templates in this directory:
|
||||
#
|
||||
# * HTML page to prompt the user to choose an Identity Provider during
|
||||
# login: 'sso_login_idp_picker.html'.
|
||||
#
|
||||
# This is only used if multiple SSO Identity Providers are configured.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
# * redirect_url: the URL that the user will be redirected to after
|
||||
# login.
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * providers: a list of available Identity Providers. Each element is
|
||||
# an object with the following attributes:
|
||||
#
|
||||
# * idp_id: unique identifier for the IdP
|
||||
# * idp_name: user-facing name for the IdP
|
||||
# * idp_icon: if specified in the IdP config, an MXC URI for an icon
|
||||
# for the IdP
|
||||
# * idp_brand: if specified in the IdP config, a textual identifier
|
||||
# for the brand of the IdP
|
||||
#
|
||||
# The rendered HTML page should contain a form which submits its results
|
||||
# back as a GET request, with the following query parameters:
|
||||
#
|
||||
# * redirectUrl: the client redirect URI (ie, the `redirect_url` passed
|
||||
# to the template)
|
||||
#
|
||||
# * idp: the 'idp_id' of the chosen IDP.
|
||||
#
|
||||
# * HTML page to prompt new users to enter a userid and confirm other
|
||||
# details: 'sso_auth_account_details.html'. This is only shown if the
|
||||
# SSO implementation (with any user_mapping_provider) does not return
|
||||
# a localpart.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * idp: details of the SSO Identity Provider that the user logged in
|
||||
# with: an object with the following attributes:
|
||||
#
|
||||
# * idp_id: unique identifier for the IdP
|
||||
# * idp_name: user-facing name for the IdP
|
||||
# * idp_icon: if specified in the IdP config, an MXC URI for an icon
|
||||
# for the IdP
|
||||
# * idp_brand: if specified in the IdP config, a textual identifier
|
||||
# for the brand of the IdP
|
||||
#
|
||||
# * user_attributes: an object containing details about the user that
|
||||
# we received from the IdP. May have the following attributes:
|
||||
#
|
||||
# * display_name: the user's display_name
|
||||
# * emails: a list of email addresses
|
||||
#
|
||||
# The template should render a form which submits the following fields:
|
||||
#
|
||||
# * username: the localpart of the user's chosen user id
|
||||
#
|
||||
# * HTML page allowing the user to consent to the server's terms and
|
||||
# conditions. This is only shown for new users, and only if
|
||||
# `user_consent.require_at_registration` is set.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * user_id: the user's matrix proposed ID.
|
||||
#
|
||||
# * user_profile.display_name: the user's proposed display name, if any.
|
||||
#
|
||||
# * consent_version: the version of the terms that the user will be
|
||||
# shown
|
||||
#
|
||||
# * terms_url: a link to the page showing the terms.
|
||||
#
|
||||
# The template should render a form which submits the following fields:
|
||||
#
|
||||
# * accepted_version: the version of the terms accepted by the user
|
||||
# (ie, 'consent_version' from the input variables).
|
||||
#
|
||||
# * HTML page for a confirmation step before redirecting back to the client
|
||||
# with the login token: 'sso_redirect_confirm.html'.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
#
|
||||
# * redirect_url: the URL the user is about to be redirected to.
|
||||
#
|
||||
# * display_url: the same as `redirect_url`, but with the query
|
||||
# parameters stripped. The intention is to have a
|
||||
# human-readable URL to show to users, not to use it as
|
||||
# the final address to redirect to.
|
||||
#
|
||||
# * server_name: the homeserver's name.
|
||||
#
|
||||
# * new_user: a boolean indicating whether this is the user's first time
|
||||
# logging in.
|
||||
#
|
||||
# * user_id: the user's matrix ID.
|
||||
#
|
||||
# * user_profile.avatar_url: an MXC URI for the user's avatar, if any.
|
||||
# None if the user has not set an avatar.
|
||||
#
|
||||
# * user_profile.display_name: the user's display name. None if the user
|
||||
# has not set a display name.
|
||||
#
|
||||
# * HTML page which notifies the user that they are authenticating to confirm
|
||||
# an operation on their account during the user interactive authentication
|
||||
# process: 'sso_auth_confirm.html'.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
# * redirect_url: the URL the user is about to be redirected to.
|
||||
#
|
||||
# * description: the operation which the user is being asked to confirm
|
||||
#
|
||||
# * idp: details of the Identity Provider that we will use to confirm
|
||||
# the user's identity: an object with the following attributes:
|
||||
#
|
||||
# * idp_id: unique identifier for the IdP
|
||||
# * idp_name: user-facing name for the IdP
|
||||
# * idp_icon: if specified in the IdP config, an MXC URI for an icon
|
||||
# for the IdP
|
||||
# * idp_brand: if specified in the IdP config, a textual identifier
|
||||
# for the brand of the IdP
|
||||
#
|
||||
# * HTML page shown after a successful user interactive authentication session:
|
||||
# 'sso_auth_success.html'.
|
||||
#
|
||||
# Note that this page must include the JavaScript which notifies of a successful authentication
|
||||
# (see https://matrix.org/docs/spec/client_server/r0.6.0#fallback).
|
||||
#
|
||||
# This template has no additional variables.
|
||||
#
|
||||
# * HTML page shown after a user-interactive authentication session which
|
||||
# does not map correctly onto the expected user: 'sso_auth_bad_user.html'.
|
||||
#
|
||||
# When rendering, this template is given the following variables:
|
||||
# * server_name: the homeserver's name.
|
||||
# * user_id_to_verify: the MXID of the user that we are trying to
|
||||
# validate.
|
||||
#
|
||||
# * HTML page shown during single sign-on if a deactivated user (according to Synapse's database)
|
||||
# attempts to login: 'sso_account_deactivated.html'.
|
||||
#
|
||||
# This template has no additional variables.
|
||||
#
|
||||
# * HTML page to display to users if something goes wrong during the
|
||||
# OpenID Connect authentication process: 'sso_error.html'.
|
||||
#
|
||||
# When rendering, this template is given two variables:
|
||||
# * error: the technical name of the error
|
||||
# * error_description: a human-readable message for the error
|
||||
#
|
||||
# You can see the default templates at:
|
||||
# https://github.com/matrix-org/synapse/tree/master/synapse/res/templates
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
"""
|
||||
|
||||
@@ -205,6 +205,13 @@ def check(
|
||||
if event.type == EventTypes.Redaction:
|
||||
check_redaction(room_version_obj, event, auth_events)
|
||||
|
||||
if (
|
||||
event.type == EventTypes.MSC2716_INSERTION
|
||||
or event.type == EventTypes.MSC2716_CHUNK
|
||||
or event.type == EventTypes.MSC2716_MARKER
|
||||
):
|
||||
check_historical(room_version_obj, event, auth_events)
|
||||
|
||||
logger.debug("Allowing! %s", event)
|
||||
|
||||
|
||||
@@ -363,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.
|
||||
@@ -539,6 +543,37 @@ def check_redaction(
|
||||
raise AuthError(403, "You don't have permission to redact events")
|
||||
|
||||
|
||||
def check_historical(
|
||||
room_version_obj: RoomVersion,
|
||||
event: EventBase,
|
||||
auth_events: StateMap[EventBase],
|
||||
) -> None:
|
||||
"""Check whether the event sender is allowed to send historical related
|
||||
events like "insertion", "chunk", and "marker".
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
Raises:
|
||||
AuthError if the event sender is not allowed to send historical related events
|
||||
("insertion", "chunk", and "marker").
|
||||
"""
|
||||
# Ignore the auth checks in room versions that do not support historical
|
||||
# events
|
||||
if not room_version_obj.msc2716_historical:
|
||||
return
|
||||
|
||||
user_level = get_user_power_level(event.user_id, auth_events)
|
||||
|
||||
historical_level = get_named_level(auth_events, "historical", 100)
|
||||
|
||||
if user_level < historical_level:
|
||||
raise AuthError(
|
||||
403,
|
||||
'You don\'t have permission to send send historical related events ("insertion", "chunk", and "marker")',
|
||||
)
|
||||
|
||||
|
||||
def _check_power_levels(
|
||||
room_version_obj: RoomVersion,
|
||||
event: EventBase,
|
||||
@@ -654,7 +689,7 @@ def get_user_power_level(user_id: str, auth_events: StateMap[EventBase]) -> int:
|
||||
power_level_event = get_power_level_event(auth_events)
|
||||
if power_level_event:
|
||||
level = power_level_event.content.get("users", {}).get(user_id)
|
||||
if not level:
|
||||
if level is None:
|
||||
level = power_level_event.content.get("users_default", 0)
|
||||
|
||||
if level is None:
|
||||
|
||||
@@ -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(),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -109,6 +109,8 @@ def prune_event_dict(room_version: RoomVersion, event_dict: dict) -> dict:
|
||||
add_fields("creator")
|
||||
elif event_type == EventTypes.JoinRules:
|
||||
add_fields("join_rule")
|
||||
if room_version.msc3083_join_rules:
|
||||
add_fields("allow")
|
||||
elif event_type == EventTypes.PowerLevels:
|
||||
add_fields(
|
||||
"users",
|
||||
@@ -124,12 +126,21 @@ def prune_event_dict(room_version: RoomVersion, event_dict: dict) -> dict:
|
||||
if room_version.msc2176_redaction_rules:
|
||||
add_fields("invite")
|
||||
|
||||
if room_version.msc2716_historical:
|
||||
add_fields("historical")
|
||||
|
||||
elif event_type == EventTypes.Aliases and room_version.special_case_aliases_auth:
|
||||
add_fields("aliases")
|
||||
elif event_type == EventTypes.RoomHistoryVisibility:
|
||||
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}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ from typing import (
|
||||
Awaitable,
|
||||
Callable,
|
||||
Collection,
|
||||
Container,
|
||||
Dict,
|
||||
Iterable,
|
||||
List,
|
||||
@@ -513,6 +514,7 @@ class FederationClient(FederationBase):
|
||||
description: str,
|
||||
destinations: Iterable[str],
|
||||
callback: Callable[[str], Awaitable[T]],
|
||||
failover_errcodes: Optional[Container[str]] = None,
|
||||
failover_on_unknown_endpoint: bool = False,
|
||||
) -> T:
|
||||
"""Try an operation on a series of servers, until it succeeds
|
||||
@@ -533,6 +535,9 @@ class FederationClient(FederationBase):
|
||||
next server tried. Normally the stacktrace is logged but this is
|
||||
suppressed if the exception is an InvalidResponseError.
|
||||
|
||||
failover_errcodes: Error codes (specific to this endpoint) which should
|
||||
cause a failover when received as part of an HTTP 400 error.
|
||||
|
||||
failover_on_unknown_endpoint: if True, we will try other servers if it looks
|
||||
like a server doesn't support the endpoint. This is typically useful
|
||||
if the endpoint in question is new or experimental.
|
||||
@@ -544,6 +549,9 @@ class FederationClient(FederationBase):
|
||||
SynapseError if the chosen remote server returns a 300/400 code, or
|
||||
no servers were reachable.
|
||||
"""
|
||||
if failover_errcodes is None:
|
||||
failover_errcodes = ()
|
||||
|
||||
for destination in destinations:
|
||||
if destination == self.server_name:
|
||||
continue
|
||||
@@ -558,11 +566,17 @@ class FederationClient(FederationBase):
|
||||
synapse_error = e.to_synapse_error()
|
||||
failover = False
|
||||
|
||||
# Failover on an internal server error, or if the destination
|
||||
# doesn't implemented the endpoint for some reason.
|
||||
# Failover should occur:
|
||||
#
|
||||
# * On internal server errors.
|
||||
# * If the destination responds that it cannot complete the request.
|
||||
# * If the destination doesn't implemented the endpoint for some reason.
|
||||
if 500 <= e.code < 600:
|
||||
failover = True
|
||||
|
||||
elif e.code == 400 and synapse_error.errcode in failover_errcodes:
|
||||
failover = True
|
||||
|
||||
elif failover_on_unknown_endpoint and self._is_unknown_endpoint(
|
||||
e, synapse_error
|
||||
):
|
||||
@@ -678,8 +692,20 @@ class FederationClient(FederationBase):
|
||||
|
||||
return destination, ev, room_version
|
||||
|
||||
# MSC3083 defines additional error codes for room joins. Unfortunately
|
||||
# we do not yet know the room version, assume these will only be returned
|
||||
# by valid room versions.
|
||||
failover_errcodes = (
|
||||
(Codes.UNABLE_AUTHORISE_JOIN, Codes.UNABLE_TO_GRANT_JOIN)
|
||||
if membership == Membership.JOIN
|
||||
else None
|
||||
)
|
||||
|
||||
return await self._try_destination_list(
|
||||
"make_" + membership, destinations, send_request
|
||||
"make_" + membership,
|
||||
destinations,
|
||||
send_request,
|
||||
failover_errcodes=failover_errcodes,
|
||||
)
|
||||
|
||||
async def send_join(
|
||||
@@ -818,7 +844,14 @@ class FederationClient(FederationBase):
|
||||
origin=destination,
|
||||
)
|
||||
|
||||
# MSC3083 defines additional error codes for room joins.
|
||||
failover_errcodes = None
|
||||
if room_version.msc3083_join_rules:
|
||||
failover_errcodes = (
|
||||
Codes.UNABLE_AUTHORISE_JOIN,
|
||||
Codes.UNABLE_TO_GRANT_JOIN,
|
||||
)
|
||||
|
||||
# If the join is being authorised via allow rules, we need to send
|
||||
# the /send_join back to the same server that was originally used
|
||||
# with /make_join.
|
||||
@@ -827,7 +860,9 @@ class FederationClient(FederationBase):
|
||||
get_domain_from_id(pdu.content["join_authorised_via_users_server"])
|
||||
]
|
||||
|
||||
return await self._try_destination_list("send_join", destinations, send_request)
|
||||
return await self._try_destination_list(
|
||||
"send_join", destinations, send_request, failover_errcodes=failover_errcodes
|
||||
)
|
||||
|
||||
async def _do_send_join(
|
||||
self, room_version: RoomVersion, destination: str, pdu: EventBase
|
||||
@@ -1073,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
|
||||
|
||||
@@ -1254,8 +1290,136 @@ 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.
|
||||
|
||||
@attr.s(frozen=True, slots=True)
|
||||
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
|
||||
|
||||
try:
|
||||
return await self._try_destination_list(
|
||||
"fetch room hierarchy",
|
||||
destinations,
|
||||
send_request,
|
||||
failover_on_unknown_endpoint=True,
|
||||
)
|
||||
except SynapseError as e:
|
||||
# Fallback to the old federation API and translate the results if
|
||||
# no servers implement the new API.
|
||||
#
|
||||
# The algorithm below is a bit inefficient as it only attempts to
|
||||
# get information for the requested room, but the legacy API may
|
||||
# return additional layers.
|
||||
if e.code == 502:
|
||||
legacy_result = await self.get_space_summary(
|
||||
destinations,
|
||||
room_id,
|
||||
suggested_only,
|
||||
max_rooms_per_space=None,
|
||||
exclude_rooms=[],
|
||||
)
|
||||
|
||||
# Find the requested room in the response (and remove it).
|
||||
for _i, room in enumerate(legacy_result.rooms):
|
||||
if room.get("room_id") == room_id:
|
||||
break
|
||||
else:
|
||||
# The requested room was not returned, nothing we can do.
|
||||
raise
|
||||
requested_room = legacy_result.rooms.pop(_i)
|
||||
|
||||
# Find any children events of the requested room.
|
||||
children_events = []
|
||||
children_room_ids = set()
|
||||
for event in legacy_result.events:
|
||||
if event.room_id == room_id:
|
||||
children_events.append(event.data)
|
||||
children_room_ids.add(event.state_key)
|
||||
# And add them under the requested room.
|
||||
requested_room["children_state"] = children_events
|
||||
|
||||
# Find the children rooms.
|
||||
children = []
|
||||
for room in legacy_result.rooms:
|
||||
if room.get("room_id") in children_room_ids:
|
||||
children.append(room)
|
||||
|
||||
# It isn't clear from the response whether some of the rooms are
|
||||
# not accessible.
|
||||
return requested_room, children, ()
|
||||
|
||||
raise
|
||||
|
||||
|
||||
@attr.s(frozen=True, slots=True, auto_attribs=True)
|
||||
class FederationSpaceSummaryEventResult:
|
||||
"""Represents a single event in the result of a successful get_space_summary call.
|
||||
|
||||
@@ -1264,12 +1428,13 @@ class FederationSpaceSummaryEventResult:
|
||||
object attributes.
|
||||
"""
|
||||
|
||||
event_type = attr.ib(type=str)
|
||||
state_key = attr.ib(type=str)
|
||||
via = attr.ib(type=Sequence[str])
|
||||
event_type: str
|
||||
room_id: str
|
||||
state_key: str
|
||||
via: Sequence[str]
|
||||
|
||||
# the raw data, including the above keys
|
||||
data = attr.ib(type=JsonDict)
|
||||
data: JsonDict
|
||||
|
||||
@classmethod
|
||||
def from_json_dict(cls, d: JsonDict) -> "FederationSpaceSummaryEventResult":
|
||||
@@ -1286,6 +1451,10 @@ class FederationSpaceSummaryEventResult:
|
||||
if not isinstance(event_type, str):
|
||||
raise ValueError("Invalid event: 'event_type' must be a str")
|
||||
|
||||
room_id = d.get("room_id")
|
||||
if not isinstance(room_id, str):
|
||||
raise ValueError("Invalid event: 'room_id' must be a str")
|
||||
|
||||
state_key = d.get("state_key")
|
||||
if not isinstance(state_key, str):
|
||||
raise ValueError("Invalid event: 'state_key' must be a str")
|
||||
@@ -1300,15 +1469,15 @@ class FederationSpaceSummaryEventResult:
|
||||
if any(not isinstance(v, str) for v in via):
|
||||
raise ValueError("Invalid event: 'via' must be a list of strings")
|
||||
|
||||
return cls(event_type, state_key, via, d)
|
||||
return cls(event_type, room_id, state_key, via, d)
|
||||
|
||||
|
||||
@attr.s(frozen=True, slots=True)
|
||||
@attr.s(frozen=True, slots=True, auto_attribs=True)
|
||||
class FederationSpaceSummaryResult:
|
||||
"""Represents the data returned by a successful get_space_summary call."""
|
||||
|
||||
rooms = attr.ib(type=Sequence[JsonDict])
|
||||
events = attr.ib(type=Sequence[FederationSpaceSummaryEventResult])
|
||||
rooms: List[JsonDict]
|
||||
events: Sequence[FederationSpaceSummaryEventResult]
|
||||
|
||||
@classmethod
|
||||
def from_json_dict(cls, d: JsonDict) -> "FederationSpaceSummaryResult":
|
||||
@@ -1321,7 +1490,7 @@ class FederationSpaceSummaryResult:
|
||||
ValueError if d is not a valid /spaces/ response
|
||||
"""
|
||||
rooms = d.get("rooms")
|
||||
if not isinstance(rooms, Sequence):
|
||||
if not isinstance(rooms, List):
|
||||
raise ValueError("'rooms' must be a list")
|
||||
if any(not isinstance(r, dict) for r in rooms):
|
||||
raise ValueError("Invalid room in 'rooms' list")
|
||||
|
||||
@@ -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
|
||||
@@ -1024,6 +1040,23 @@ class FederationServer(FederationBase):
|
||||
|
||||
origin, event = next
|
||||
|
||||
# Prune the event queue if it's getting large.
|
||||
#
|
||||
# We do this *after* handling the first event as the common case is
|
||||
# that the queue is empty (/has the single event in), and so there's
|
||||
# no need to do this check.
|
||||
pruned = await self.store.prune_staged_events_in_room(room_id, room_version)
|
||||
if pruned:
|
||||
# If we have pruned the queue check we need to refetch the next
|
||||
# event to handle.
|
||||
next = await self.store.get_next_staged_event_for_room(
|
||||
room_id, room_version
|
||||
)
|
||||
if not next:
|
||||
break
|
||||
|
||||
origin, event = next
|
||||
|
||||
lock = await self.store.try_acquire_lock(
|
||||
_INBOUND_EVENT_HANDLING_LOCK_NAME, room_id
|
||||
)
|
||||
|
||||
@@ -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
332
synapse/federation/transport/server/__init__.py
Normal file
332
synapse/federation/transport/server/__init__.py
Normal file
@@ -0,0 +1,332 @@
|
||||
# Copyright 2014-2021 The Matrix.org Foundation C.I.C.
|
||||
# Copyright 2020 Sorunome
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import logging
|
||||
from typing import Dict, Iterable, List, Optional, Tuple, Type
|
||||
|
||||
from typing_extensions import Literal
|
||||
|
||||
from synapse.api.errors import FederationDeniedError, SynapseError
|
||||
from synapse.federation.transport.server._base import (
|
||||
Authenticator,
|
||||
BaseFederationServlet,
|
||||
)
|
||||
from synapse.federation.transport.server.federation import FEDERATION_SERVLET_CLASSES
|
||||
from synapse.federation.transport.server.groups_local import GROUP_LOCAL_SERVLET_CLASSES
|
||||
from synapse.federation.transport.server.groups_server import (
|
||||
GROUP_SERVER_SERVLET_CLASSES,
|
||||
)
|
||||
from synapse.http.server import HttpServer, JsonResource
|
||||
from synapse.http.servlet import (
|
||||
parse_boolean_from_args,
|
||||
parse_integer_from_args,
|
||||
parse_string_from_args,
|
||||
)
|
||||
from synapse.server import HomeServer
|
||||
from synapse.types import JsonDict, ThirdPartyInstanceID
|
||||
from synapse.util.ratelimitutils import FederationRateLimiter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TransportLayerServer(JsonResource):
|
||||
"""Handles incoming federation HTTP requests"""
|
||||
|
||||
def __init__(self, hs: HomeServer, servlet_groups: Optional[List[str]] = None):
|
||||
"""Initialize the TransportLayerServer
|
||||
|
||||
Will by default register all servlets. For custom behaviour, pass in
|
||||
a list of servlet_groups to register.
|
||||
|
||||
Args:
|
||||
hs: homeserver
|
||||
servlet_groups: List of servlet groups to register.
|
||||
Defaults to ``DEFAULT_SERVLET_GROUPS``.
|
||||
"""
|
||||
self.hs = hs
|
||||
self.clock = hs.get_clock()
|
||||
self.servlet_groups = servlet_groups
|
||||
|
||||
super().__init__(hs, canonical_json=False)
|
||||
|
||||
self.authenticator = Authenticator(hs)
|
||||
self.ratelimiter = hs.get_federation_ratelimiter()
|
||||
|
||||
self.register_servlets()
|
||||
|
||||
def register_servlets(self) -> None:
|
||||
register_servlets(
|
||||
self.hs,
|
||||
resource=self,
|
||||
ratelimiter=self.ratelimiter,
|
||||
authenticator=self.authenticator,
|
||||
servlet_groups=self.servlet_groups,
|
||||
)
|
||||
|
||||
|
||||
class PublicRoomList(BaseFederationServlet):
|
||||
"""
|
||||
Fetch the public room list for this server.
|
||||
|
||||
This API returns information in the same format as /publicRooms on the
|
||||
client API, but will only ever include local public rooms and hence is
|
||||
intended for consumption by other homeservers.
|
||||
|
||||
GET /publicRooms HTTP/1.1
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"chunk": [
|
||||
{
|
||||
"aliases": [
|
||||
"#test:localhost"
|
||||
],
|
||||
"guest_can_join": false,
|
||||
"name": "test room",
|
||||
"num_joined_members": 3,
|
||||
"room_id": "!whkydVegtvatLfXmPN:localhost",
|
||||
"world_readable": false
|
||||
}
|
||||
],
|
||||
"end": "END",
|
||||
"start": "START"
|
||||
}
|
||||
"""
|
||||
|
||||
PATH = "/publicRooms"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hs: HomeServer,
|
||||
authenticator: Authenticator,
|
||||
ratelimiter: FederationRateLimiter,
|
||||
server_name: str,
|
||||
):
|
||||
super().__init__(hs, authenticator, ratelimiter, server_name)
|
||||
self.handler = hs.get_room_list_handler()
|
||||
self.allow_access = hs.config.allow_public_rooms_over_federation
|
||||
|
||||
async def on_GET(
|
||||
self, origin: str, content: Literal[None], query: Dict[bytes, List[bytes]]
|
||||
) -> Tuple[int, JsonDict]:
|
||||
if not self.allow_access:
|
||||
raise FederationDeniedError(origin)
|
||||
|
||||
limit = parse_integer_from_args(query, "limit", 0)
|
||||
since_token = parse_string_from_args(query, "since", None)
|
||||
include_all_networks = parse_boolean_from_args(
|
||||
query, "include_all_networks", default=False
|
||||
)
|
||||
third_party_instance_id = parse_string_from_args(
|
||||
query, "third_party_instance_id", None
|
||||
)
|
||||
|
||||
if include_all_networks:
|
||||
network_tuple = None
|
||||
elif third_party_instance_id:
|
||||
network_tuple = ThirdPartyInstanceID.from_string(third_party_instance_id)
|
||||
else:
|
||||
network_tuple = ThirdPartyInstanceID(None, None)
|
||||
|
||||
if limit == 0:
|
||||
# zero is a special value which corresponds to no limit.
|
||||
limit = None
|
||||
|
||||
data = await self.handler.get_local_public_room_list(
|
||||
limit, since_token, network_tuple=network_tuple, from_federation=True
|
||||
)
|
||||
return 200, data
|
||||
|
||||
async def on_POST(
|
||||
self, origin: str, content: JsonDict, query: Dict[bytes, List[bytes]]
|
||||
) -> Tuple[int, JsonDict]:
|
||||
# This implements MSC2197 (Search Filtering over Federation)
|
||||
if not self.allow_access:
|
||||
raise FederationDeniedError(origin)
|
||||
|
||||
limit: Optional[int] = int(content.get("limit", 100))
|
||||
since_token = content.get("since", None)
|
||||
search_filter = content.get("filter", None)
|
||||
|
||||
include_all_networks = content.get("include_all_networks", False)
|
||||
third_party_instance_id = content.get("third_party_instance_id", None)
|
||||
|
||||
if include_all_networks:
|
||||
network_tuple = None
|
||||
if third_party_instance_id is not None:
|
||||
raise SynapseError(
|
||||
400, "Can't use include_all_networks with an explicit network"
|
||||
)
|
||||
elif third_party_instance_id is None:
|
||||
network_tuple = ThirdPartyInstanceID(None, None)
|
||||
else:
|
||||
network_tuple = ThirdPartyInstanceID.from_string(third_party_instance_id)
|
||||
|
||||
if search_filter is None:
|
||||
logger.warning("Nonefilter")
|
||||
|
||||
if limit == 0:
|
||||
# zero is a special value which corresponds to no limit.
|
||||
limit = None
|
||||
|
||||
data = await self.handler.get_local_public_room_list(
|
||||
limit=limit,
|
||||
since_token=since_token,
|
||||
search_filter=search_filter,
|
||||
network_tuple=network_tuple,
|
||||
from_federation=True,
|
||||
)
|
||||
|
||||
return 200, data
|
||||
|
||||
|
||||
class FederationGroupsRenewAttestaionServlet(BaseFederationServlet):
|
||||
"""A group or user's server renews their attestation"""
|
||||
|
||||
PATH = "/groups/(?P<group_id>[^/]*)/renew_attestation/(?P<user_id>[^/]*)"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hs: HomeServer,
|
||||
authenticator: Authenticator,
|
||||
ratelimiter: FederationRateLimiter,
|
||||
server_name: str,
|
||||
):
|
||||
super().__init__(hs, authenticator, ratelimiter, server_name)
|
||||
self.handler = hs.get_groups_attestation_renewer()
|
||||
|
||||
async def on_POST(
|
||||
self,
|
||||
origin: str,
|
||||
content: JsonDict,
|
||||
query: Dict[bytes, List[bytes]],
|
||||
group_id: str,
|
||||
user_id: str,
|
||||
) -> Tuple[int, JsonDict]:
|
||||
# We don't need to check auth here as we check the attestation signatures
|
||||
|
||||
new_content = await self.handler.on_renew_attestation(
|
||||
group_id, user_id, content
|
||||
)
|
||||
|
||||
return 200, new_content
|
||||
|
||||
|
||||
class OpenIdUserInfo(BaseFederationServlet):
|
||||
"""
|
||||
Exchange a bearer token for information about a user.
|
||||
|
||||
The response format should be compatible with:
|
||||
http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
|
||||
|
||||
GET /openid/userinfo?access_token=ABDEFGH HTTP/1.1
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"sub": "@userpart:example.org",
|
||||
}
|
||||
"""
|
||||
|
||||
PATH = "/openid/userinfo"
|
||||
|
||||
REQUIRE_AUTH = False
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hs: HomeServer,
|
||||
authenticator: Authenticator,
|
||||
ratelimiter: FederationRateLimiter,
|
||||
server_name: str,
|
||||
):
|
||||
super().__init__(hs, authenticator, ratelimiter, server_name)
|
||||
self.handler = hs.get_federation_server()
|
||||
|
||||
async def on_GET(
|
||||
self,
|
||||
origin: Optional[str],
|
||||
content: Literal[None],
|
||||
query: Dict[bytes, List[bytes]],
|
||||
) -> Tuple[int, JsonDict]:
|
||||
token = parse_string_from_args(query, "access_token")
|
||||
if token is None:
|
||||
return (
|
||||
401,
|
||||
{"errcode": "M_MISSING_TOKEN", "error": "Access Token required"},
|
||||
)
|
||||
|
||||
user_id = await self.handler.on_openid_userinfo(token)
|
||||
|
||||
if user_id is None:
|
||||
return (
|
||||
401,
|
||||
{
|
||||
"errcode": "M_UNKNOWN_TOKEN",
|
||||
"error": "Access Token unknown or expired",
|
||||
},
|
||||
)
|
||||
|
||||
return 200, {"sub": user_id}
|
||||
|
||||
|
||||
DEFAULT_SERVLET_GROUPS: Dict[str, Iterable[Type[BaseFederationServlet]]] = {
|
||||
"federation": FEDERATION_SERVLET_CLASSES,
|
||||
"room_list": (PublicRoomList,),
|
||||
"group_server": GROUP_SERVER_SERVLET_CLASSES,
|
||||
"group_local": GROUP_LOCAL_SERVLET_CLASSES,
|
||||
"group_attestation": (FederationGroupsRenewAttestaionServlet,),
|
||||
"openid": (OpenIdUserInfo,),
|
||||
}
|
||||
|
||||
|
||||
def register_servlets(
|
||||
hs: HomeServer,
|
||||
resource: HttpServer,
|
||||
authenticator: Authenticator,
|
||||
ratelimiter: FederationRateLimiter,
|
||||
servlet_groups: Optional[Iterable[str]] = None,
|
||||
):
|
||||
"""Initialize and register servlet classes.
|
||||
|
||||
Will by default register all servlets. For custom behaviour, pass in
|
||||
a list of servlet_groups to register.
|
||||
|
||||
Args:
|
||||
hs: homeserver
|
||||
resource: resource class to register to
|
||||
authenticator: authenticator to use
|
||||
ratelimiter: ratelimiter to use
|
||||
servlet_groups: List of servlet groups to register.
|
||||
Defaults to ``DEFAULT_SERVLET_GROUPS``.
|
||||
"""
|
||||
if not servlet_groups:
|
||||
servlet_groups = DEFAULT_SERVLET_GROUPS.keys()
|
||||
|
||||
for servlet_group in servlet_groups:
|
||||
# Skip unknown servlet groups.
|
||||
if servlet_group not in DEFAULT_SERVLET_GROUPS:
|
||||
raise RuntimeError(
|
||||
f"Attempting to register unknown federation servlet: '{servlet_group}'"
|
||||
)
|
||||
|
||||
for servletclass in DEFAULT_SERVLET_GROUPS[servlet_group]:
|
||||
servletclass(
|
||||
hs=hs,
|
||||
authenticator=authenticator,
|
||||
ratelimiter=ratelimiter,
|
||||
server_name=hs.hostname,
|
||||
).register(resource)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user