Compare commits
137 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bc0b59e51a | |||
| 9915139bef | |||
| fa8bc0ba39 | |||
| 62ac8b9c0d | |||
| 422d40e82f | |||
| 3af0672350 | |||
| 0a34cdfc66 | |||
| 1d55c7b567 | |||
| dc016c66ae | |||
| 80a992d7b9 | |||
| c64002e1c1 | |||
| 1821f7cc26 | |||
| a5f7aff5e5 | |||
| 344ab0b53a | |||
| 6ff34e00d9 | |||
| 43bf3c5178 | |||
| a4a5c7a35e | |||
| 3e8292d483 | |||
| cf7d3c90d6 | |||
| 9bbbb11ac2 | |||
| 57068eae75 | |||
| fd83debcc0 | |||
| 320e8c8064 | |||
| adfc9cb53d | |||
| 1cec3d1457 | |||
| 9b26a4ac87 | |||
| 0eb9b2f866 | |||
| 3ce2f303f1 | |||
| cd9e72b185 | |||
| 1a9553045c | |||
| ab7a24cc6b | |||
| 36ba73f53d | |||
| 025fa06fc7 | |||
| ff1f0ee094 | |||
| 1f3748f033 | |||
| 92d87c6882 | |||
| 02e588856a | |||
| 96358cb424 | |||
| df4b1e9c74 | |||
| b774c555d8 | |||
| df3e6a23a7 | |||
| 112f6bd49e | |||
| 2602514f34 | |||
| 693dab487c | |||
| 22c6c19f91 | |||
| 295c209cdd | |||
| 6e4f71c057 | |||
| cf3b8156be | |||
| 66f75c5b74 | |||
| 269ba1bc84 | |||
| ed5172852a | |||
| f347f0cd58 | |||
| 935732768c | |||
| 0bac276890 | |||
| 92ce4a5258 | |||
| b751624ff8 | |||
| c834f1d67a | |||
| 76469898ee | |||
| 90cf1eec44 | |||
| 7ea85302f3 | |||
| 30fba62108 | |||
| c5b6abd53d | |||
| 693516e756 | |||
| 0fed46ebe5 | |||
| c4675e1b24 | |||
| e41720d85f | |||
| c67af840aa | |||
| 53b12688dd | |||
| 8388384a64 | |||
| c21bdc813f | |||
| d3ed93504b | |||
| edb3d3f827 | |||
| 4d9496559d | |||
| 9edff901d1 | |||
| 3f0cba657c | |||
| 89f7930730 | |||
| ddc4343683 | |||
| 09ac0569fe | |||
| d1be293f00 | |||
| 59e18a1333 | |||
| 9f0f274fe0 | |||
| f8d13ca13d | |||
| 17fa58bdd1 | |||
| ca60822b34 | |||
| a090b86209 | |||
| 856eab606b | |||
| 5cbe8d93fe | |||
| 1cd356765e | |||
| 382b4e83f1 | |||
| 7c43447477 | |||
| 14f81a6d24 | |||
| 3f0ff53158 | |||
| 2b110dda2a | |||
| d963c69ba5 | |||
| 968939bdac | |||
| 4fd222ad70 | |||
| f38676d161 | |||
| b08dc7effe | |||
| 97b35ee259 | |||
| e3d7806704 | |||
| 6fde6aa9c0 | |||
| 7127855741 | |||
| 59a995f38d | |||
| 8ca120df7c | |||
| 476b8c0ae6 | |||
| 1091bcea3e | |||
| 79bfe966e0 | |||
| 53a6f5ddf0 | |||
| 950bb0305f | |||
| 51338491c9 | |||
| 03e392f787 | |||
| d356588339 | |||
| b690542a34 | |||
| deff8f628d | |||
| ee382025b0 | |||
| e487d9fabc | |||
| 473dfec1e5 | |||
| f737368a26 | |||
| 0ce31ef614 | |||
| acfe3b3065 | |||
| be8fa65d0b | |||
| 129ae841e5 | |||
| 1f41422c98 | |||
| 3dc1871219 | |||
| f125895475 | |||
| c3e3552ec4 | |||
| 4f76eef0e8 | |||
| bebfb9a97b | |||
| 791d7cd6f0 | |||
| ebc405446e | |||
| 0d33c53534 | |||
| cfd895a22e | |||
| 70c0d47989 | |||
| 9debe657a3 | |||
| d3523e3e97 | |||
| f1de4bb58b | |||
| e8d0853739 |
@@ -6,7 +6,7 @@
|
||||
set -ex
|
||||
|
||||
apt-get update
|
||||
apt-get install -y python3.5 python3.5-dev python3-pip libxml2-dev libxslt-dev zlib1g-dev tox
|
||||
apt-get install -y python3.5 python3.5-dev python3-pip libxml2-dev libxslt-dev xmlsec1 zlib1g-dev tox
|
||||
|
||||
export LANG="C.UTF-8"
|
||||
|
||||
|
||||
@@ -5,9 +5,10 @@ jobs:
|
||||
- image: docker:git
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- docker_prepare
|
||||
- run: docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD
|
||||
# for release builds, we want to get the amd64 image out asap, so first
|
||||
# we do an amd64-only build, before following up with a multiarch build.
|
||||
- docker_build:
|
||||
tag: -t matrixdotorg/synapse:${CIRCLE_TAG}
|
||||
platforms: linux/amd64
|
||||
@@ -20,12 +21,10 @@ jobs:
|
||||
- image: docker:git
|
||||
steps:
|
||||
- checkout
|
||||
- setup_remote_docker
|
||||
- docker_prepare
|
||||
- run: docker login --username $DOCKER_HUB_USERNAME --password $DOCKER_HUB_PASSWORD
|
||||
- docker_build:
|
||||
tag: -t matrixdotorg/synapse:latest
|
||||
platforms: linux/amd64
|
||||
# for `latest`, we don't want the arm images to disappear, so don't update the tag
|
||||
# until all of the platforms are built.
|
||||
- docker_build:
|
||||
tag: -t matrixdotorg/synapse:latest
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
@@ -46,12 +45,16 @@ workflows:
|
||||
|
||||
commands:
|
||||
docker_prepare:
|
||||
description: Downloads the buildx cli plugin and enables multiarch images
|
||||
description: Sets up a remote docker server, downloads the buildx cli plugin, and enables multiarch images
|
||||
parameters:
|
||||
buildx_version:
|
||||
type: string
|
||||
default: "v0.4.1"
|
||||
steps:
|
||||
- setup_remote_docker:
|
||||
# 19.03.13 was the most recent available on circleci at the time of
|
||||
# writing.
|
||||
version: 19.03.13
|
||||
- run: apk add --no-cache curl
|
||||
- run: mkdir -vp ~/.docker/cli-plugins/ ~/dockercache
|
||||
- run: curl --silent -L "https://github.com/docker/buildx/releases/download/<< parameters.buildx_version >>/buildx-<< parameters.buildx_version >>.linux-amd64" > ~/.docker/cli-plugins/docker-buildx
|
||||
|
||||
+346
-150
@@ -1,3 +1,203 @@
|
||||
Synapse 1.25.0 (2020-xx-xx)
|
||||
===========================
|
||||
|
||||
Removal warning
|
||||
---------------
|
||||
|
||||
The old [Purge Room API](https://github.com/matrix-org/synapse/tree/master/docs/admin_api/purge_room.md)
|
||||
and [Shutdown Room API](https://github.com/matrix-org/synapse/tree/master/docs/admin_api/shutdown_room.md)
|
||||
are deprecated and will be removed in a future release. They will be replaced by the
|
||||
[Delete Room API](https://github.com/matrix-org/synapse/tree/master/docs/admin_api/rooms.md#delete-room-api).
|
||||
|
||||
`POST /_synapse/admin/v1/rooms/<room_id>/delete` replaces `POST /_synapse/admin/v1/purge_room` and
|
||||
`POST /_synapse/admin/v1/shutdown_room/<room_id>`.
|
||||
|
||||
|
||||
Synapse 1.24.0 (2020-12-09)
|
||||
===========================
|
||||
|
||||
Due to the two security issues highlighted below, server administrators are
|
||||
encouraged to update Synapse. We are not aware of these vulnerabilities being
|
||||
exploited in the wild.
|
||||
|
||||
Security advisory
|
||||
-----------------
|
||||
|
||||
The following issues are fixed in v1.23.1 and v1.24.0.
|
||||
|
||||
- There is a denial of service attack
|
||||
([CVE-2020-26257](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26257))
|
||||
against the federation APIs in which future events will not be correctly sent
|
||||
to other servers over federation. This affects all servers that participate in
|
||||
open federation. (Fixed in [#8776](https://github.com/matrix-org/synapse/pull/8776)).
|
||||
|
||||
- Synapse may be affected by OpenSSL
|
||||
[CVE-2020-1971](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1971).
|
||||
Synapse administrators should ensure that they have the latest versions of
|
||||
the cryptography Python package installed.
|
||||
|
||||
To upgrade Synapse along with the cryptography package:
|
||||
|
||||
* Administrators using the [`matrix.org` Docker
|
||||
image](https://hub.docker.com/r/matrixdotorg/synapse/) or the [Debian/Ubuntu
|
||||
packages from
|
||||
`matrix.org`](https://github.com/matrix-org/synapse/blob/master/INSTALL.md#matrixorg-packages)
|
||||
should ensure that they have version 1.24.0 or 1.23.1 installed: these images include
|
||||
the updated packages.
|
||||
* Administrators who have [installed Synapse from
|
||||
source](https://github.com/matrix-org/synapse/blob/master/INSTALL.md#installing-from-source)
|
||||
should upgrade the cryptography package within their virtualenv by running:
|
||||
```sh
|
||||
<path_to_virtualenv>/bin/pip install 'cryptography>=3.3'
|
||||
```
|
||||
* Administrators who have installed Synapse from distribution packages should
|
||||
consult the information from their distributions.
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Add a maximum version for pysaml2 on Python 3.5. ([\#8898](https://github.com/matrix-org/synapse/issues/8898))
|
||||
|
||||
|
||||
Synapse 1.23.1 (2020-12-09)
|
||||
===========================
|
||||
|
||||
Due to the two security issues highlighted below, server administrators are
|
||||
encouraged to update Synapse. We are not aware of these vulnerabilities being
|
||||
exploited in the wild.
|
||||
|
||||
Security advisory
|
||||
-----------------
|
||||
|
||||
The following issues are fixed in v1.23.1 and v1.24.0.
|
||||
|
||||
- There is a denial of service attack
|
||||
([CVE-2020-26257](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-26257))
|
||||
against the federation APIs in which future events will not be correctly sent
|
||||
to other servers over federation. This affects all servers that participate in
|
||||
open federation. (Fixed in [#8776](https://github.com/matrix-org/synapse/pull/8776)).
|
||||
|
||||
- Synapse may be affected by OpenSSL
|
||||
[CVE-2020-1971](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1971).
|
||||
Synapse administrators should ensure that they have the latest versions of
|
||||
the cryptography Python package installed.
|
||||
|
||||
To upgrade Synapse along with the cryptography package:
|
||||
|
||||
* Administrators using the [`matrix.org` Docker
|
||||
image](https://hub.docker.com/r/matrixdotorg/synapse/) or the [Debian/Ubuntu
|
||||
packages from
|
||||
`matrix.org`](https://github.com/matrix-org/synapse/blob/master/INSTALL.md#matrixorg-packages)
|
||||
should ensure that they have version 1.24.0 or 1.23.1 installed: these images include
|
||||
the updated packages.
|
||||
* Administrators who have [installed Synapse from
|
||||
source](https://github.com/matrix-org/synapse/blob/master/INSTALL.md#installing-from-source)
|
||||
should upgrade the cryptography package within their virtualenv by running:
|
||||
```sh
|
||||
<path_to_virtualenv>/bin/pip install 'cryptography>=3.3'
|
||||
```
|
||||
* Administrators who have installed Synapse from distribution packages should
|
||||
consult the information from their distributions.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix a bug in some federation APIs which could lead to unexpected behaviour if different parameters were set in the URI and the request body. ([\#8776](https://github.com/matrix-org/synapse/issues/8776))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Add a maximum version for pysaml2 on Python 3.5. ([\#8898](https://github.com/matrix-org/synapse/issues/8898))
|
||||
|
||||
|
||||
Synapse 1.24.0rc2 (2020-12-04)
|
||||
==============================
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix a regression in v1.24.0rc1 which failed to allow SAML mapping providers which were unable to redirect users to an additional page. ([\#8878](https://github.com/matrix-org/synapse/issues/8878))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Add support for the `prometheus_client` newer than 0.9.0. Contributed by Jordan Bancino. ([\#8875](https://github.com/matrix-org/synapse/issues/8875))
|
||||
|
||||
|
||||
Synapse 1.24.0rc1 (2020-12-02)
|
||||
==============================
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Add admin API for logging in as a user. ([\#8617](https://github.com/matrix-org/synapse/issues/8617))
|
||||
- Allow specification of the SAML IdP if the metadata returns multiple IdPs. ([\#8630](https://github.com/matrix-org/synapse/issues/8630))
|
||||
- Add support for re-trying generation of a localpart for OpenID Connect mapping providers. ([\#8801](https://github.com/matrix-org/synapse/issues/8801), [\#8855](https://github.com/matrix-org/synapse/issues/8855))
|
||||
- Allow the `Date` header through CORS. Contributed by Nicolas Chamo. ([\#8804](https://github.com/matrix-org/synapse/issues/8804))
|
||||
- Add a config option, `push.group_by_unread_count`, which controls whether unread message counts in push notifications are defined as "the number of rooms with unread messages" or "total unread messages". ([\#8820](https://github.com/matrix-org/synapse/issues/8820))
|
||||
- Add `force_purge` option to delete-room admin api. ([\#8843](https://github.com/matrix-org/synapse/issues/8843))
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix a bug where appservices may be sent an excessive amount of read receipts and presence. Broke in v1.22.0. ([\#8744](https://github.com/matrix-org/synapse/issues/8744))
|
||||
- Fix a bug in some federation APIs which could lead to unexpected behaviour if different parameters were set in the URI and the request body. ([\#8776](https://github.com/matrix-org/synapse/issues/8776))
|
||||
- Fix a bug where synctl could spawn duplicate copies of a worker. Contributed by Waylon Cude. ([\#8798](https://github.com/matrix-org/synapse/issues/8798))
|
||||
- Allow per-room profiles to be used for the server notice user. ([\#8799](https://github.com/matrix-org/synapse/issues/8799))
|
||||
- Fix a bug where logging could break after a call to SIGHUP. ([\#8817](https://github.com/matrix-org/synapse/issues/8817))
|
||||
- Fix `register_new_matrix_user` failing with "Bad Request" when trailing slash is included in server URL. Contributed by @angdraug. ([\#8823](https://github.com/matrix-org/synapse/issues/8823))
|
||||
- Fix a minor long-standing bug in login, where we would offer the `password` login type if a custom auth provider supported it, even if password login was disabled. ([\#8835](https://github.com/matrix-org/synapse/issues/8835))
|
||||
- Fix a long-standing bug which caused Synapse to require unspecified parameters during user-interactive authentication. ([\#8848](https://github.com/matrix-org/synapse/issues/8848))
|
||||
- Fix a bug introduced in v1.20.0 where the user-agent and IP address reported during user registration for CAS, OpenID Connect, and SAML were of the wrong form. ([\#8784](https://github.com/matrix-org/synapse/issues/8784))
|
||||
|
||||
|
||||
Improved Documentation
|
||||
----------------------
|
||||
|
||||
- Clarify the usecase for a msisdn delegate. Contributed by Adrian Wannenmacher. ([\#8734](https://github.com/matrix-org/synapse/issues/8734))
|
||||
- Remove extraneous comma from JSON example in User Admin API docs. ([\#8771](https://github.com/matrix-org/synapse/issues/8771))
|
||||
- Update `turn-howto.md` with troubleshooting notes. ([\#8779](https://github.com/matrix-org/synapse/issues/8779))
|
||||
- Fix the example on how to set the `Content-Type` header in nginx for the Client Well-Known URI. ([\#8793](https://github.com/matrix-org/synapse/issues/8793))
|
||||
- Improve the documentation for the admin API to list all media in a room with respect to encrypted events. ([\#8795](https://github.com/matrix-org/synapse/issues/8795))
|
||||
- Update the formatting of the `push` section of the homeserver config file to better align with the [code style guidelines](https://github.com/matrix-org/synapse/blob/develop/docs/code_style.md#configuration-file-format). ([\#8818](https://github.com/matrix-org/synapse/issues/8818))
|
||||
- Improve documentation how to configure prometheus for workers. ([\#8822](https://github.com/matrix-org/synapse/issues/8822))
|
||||
- Update example prometheus console. ([\#8824](https://github.com/matrix-org/synapse/issues/8824))
|
||||
|
||||
|
||||
Deprecations and Removals
|
||||
-------------------------
|
||||
|
||||
- Remove old `/_matrix/client/*/admin` endpoints which were deprecated since Synapse 1.20.0. ([\#8785](https://github.com/matrix-org/synapse/issues/8785))
|
||||
- Disable pretty printing JSON responses for curl. Users who want pretty-printed output should use [jq](https://stedolan.github.io/jq/) in combination with curl. Contributed by @tulir. ([\#8833](https://github.com/matrix-org/synapse/issues/8833))
|
||||
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- Simplify the way the `HomeServer` object caches its internal attributes. ([\#8565](https://github.com/matrix-org/synapse/issues/8565), [\#8851](https://github.com/matrix-org/synapse/issues/8851))
|
||||
- Add an example and documentation for clock skew to the SAML2 sample configuration to allow for clock/time difference between the homserver and IdP. Contributed by @localguru. ([\#8731](https://github.com/matrix-org/synapse/issues/8731))
|
||||
- Generalise `RoomMemberHandler._locally_reject_invite` to apply to more flows than just invite. ([\#8751](https://github.com/matrix-org/synapse/issues/8751))
|
||||
- Generalise `RoomStore.maybe_store_room_on_invite` to handle other, non-invite membership events. ([\#8754](https://github.com/matrix-org/synapse/issues/8754))
|
||||
- Refactor test utilities for injecting HTTP requests. ([\#8757](https://github.com/matrix-org/synapse/issues/8757), [\#8758](https://github.com/matrix-org/synapse/issues/8758), [\#8759](https://github.com/matrix-org/synapse/issues/8759), [\#8760](https://github.com/matrix-org/synapse/issues/8760), [\#8761](https://github.com/matrix-org/synapse/issues/8761), [\#8777](https://github.com/matrix-org/synapse/issues/8777))
|
||||
- Consolidate logic between the OpenID Connect and SAML code. ([\#8765](https://github.com/matrix-org/synapse/issues/8765))
|
||||
- Use `TYPE_CHECKING` instead of magic `MYPY` variable. ([\#8770](https://github.com/matrix-org/synapse/issues/8770))
|
||||
- Add a commandline script to sign arbitrary json objects. ([\#8772](https://github.com/matrix-org/synapse/issues/8772))
|
||||
- Minor log line improvements for the SSO mapping code used to generate Matrix IDs from SSO IDs. ([\#8773](https://github.com/matrix-org/synapse/issues/8773))
|
||||
- Add additional error checking for OpenID Connect and SAML mapping providers. ([\#8774](https://github.com/matrix-org/synapse/issues/8774), [\#8800](https://github.com/matrix-org/synapse/issues/8800))
|
||||
- Add type hints to HTTP abstractions. ([\#8806](https://github.com/matrix-org/synapse/issues/8806), [\#8812](https://github.com/matrix-org/synapse/issues/8812))
|
||||
- Remove unnecessary function arguments and add typing to several membership replication classes. ([\#8809](https://github.com/matrix-org/synapse/issues/8809))
|
||||
- Optimise the lookup for an invite from another homeserver when trying to reject it. ([\#8815](https://github.com/matrix-org/synapse/issues/8815))
|
||||
- Add tests for `password_auth_provider`s. ([\#8819](https://github.com/matrix-org/synapse/issues/8819))
|
||||
- Drop redundant database index on `event_json`. ([\#8845](https://github.com/matrix-org/synapse/issues/8845))
|
||||
- Simplify `uk.half-shot.msc2778.login.application_service` login handler. ([\#8847](https://github.com/matrix-org/synapse/issues/8847))
|
||||
- Refactor `password_auth_provider` support code. ([\#8849](https://github.com/matrix-org/synapse/issues/8849))
|
||||
- Add missing `ordering` to background database updates. ([\#8850](https://github.com/matrix-org/synapse/issues/8850))
|
||||
- Allow for specifying a room version when creating a room in unit tests via `RestHelper.create_room_as`. ([\#8854](https://github.com/matrix-org/synapse/issues/8854))
|
||||
|
||||
|
||||
Synapse 1.23.0 (2020-11-18)
|
||||
===========================
|
||||
|
||||
@@ -6322,8 +6522,8 @@ Changes in synapse 0.5.1 (2014-11-26)
|
||||
|
||||
See UPGRADES.rst for specific instructions on how to upgrade.
|
||||
|
||||
> - Fix bug where we served up an Event that did not match its signatures.
|
||||
> - Fix regression where we no longer correctly handled the case where a homeserver receives an event for a room it doesn\'t recognise (but is in.)
|
||||
- Fix bug where we served up an Event that did not match its signatures.
|
||||
- Fix regression where we no longer correctly handled the case where a homeserver receives an event for a room it doesn\'t recognise (but is in.)
|
||||
|
||||
Changes in synapse 0.5.0 (2014-11-19)
|
||||
=====================================
|
||||
@@ -6334,44 +6534,44 @@ This release also changes the internal database schemas and so requires servers
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Add authentication and authorization to the federation protocol. Events are now signed by their originating homeservers.
|
||||
- Implement the new authorization model for rooms.
|
||||
- Split out web client into a seperate repository: matrix-angular-sdk.
|
||||
- Change the structure of PDUs.
|
||||
- Fix bug where user could not join rooms via an alias containing 4-byte UTF-8 characters.
|
||||
- Merge concept of PDUs and Events internally.
|
||||
- Improve logging by adding request ids to log lines.
|
||||
- Implement a very basic room initial sync API.
|
||||
- Implement the new invite/join federation APIs.
|
||||
- Add authentication and authorization to the federation protocol. Events are now signed by their originating homeservers.
|
||||
- Implement the new authorization model for rooms.
|
||||
- Split out web client into a seperate repository: matrix-angular-sdk.
|
||||
- Change the structure of PDUs.
|
||||
- Fix bug where user could not join rooms via an alias containing 4-byte UTF-8 characters.
|
||||
- Merge concept of PDUs and Events internally.
|
||||
- Improve logging by adding request ids to log lines.
|
||||
- Implement a very basic room initial sync API.
|
||||
- Implement the new invite/join federation APIs.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - The webclient has been moved to a seperate repository.
|
||||
- The webclient has been moved to a seperate repository.
|
||||
|
||||
Changes in synapse 0.4.2 (2014-10-31)
|
||||
=====================================
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Fix bugs where we did not notify users of correct presence updates.
|
||||
- Fix bug where we did not handle sub second event stream timeouts.
|
||||
- Fix bugs where we did not notify users of correct presence updates.
|
||||
- Fix bug where we did not handle sub second event stream timeouts.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Add ability to click on messages to see JSON.
|
||||
- Add ability to redact messages.
|
||||
- Add ability to view and edit all room state JSON.
|
||||
- Handle incoming redactions.
|
||||
- Improve feedback on errors.
|
||||
- Fix bugs in mobile CSS.
|
||||
- Fix bugs with desktop notifications.
|
||||
- Add ability to click on messages to see JSON.
|
||||
- Add ability to redact messages.
|
||||
- Add ability to view and edit all room state JSON.
|
||||
- Handle incoming redactions.
|
||||
- Improve feedback on errors.
|
||||
- Fix bugs in mobile CSS.
|
||||
- Fix bugs with desktop notifications.
|
||||
|
||||
Changes in synapse 0.4.1 (2014-10-17)
|
||||
=====================================
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Fix bug with display of timestamps.
|
||||
- Fix bug with display of timestamps.
|
||||
|
||||
Changes in synpase 0.4.0 (2014-10-17)
|
||||
=====================================
|
||||
@@ -6384,8 +6584,8 @@ You will also need an updated syutil and config. See UPGRADES.rst.
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Sign federation transactions to assert strong identity over federation.
|
||||
- Rename timestamp keys in PDUs and events from \'ts\' and \'hsob\_ts\' to \'origin\_server\_ts\'.
|
||||
- Sign federation transactions to assert strong identity over federation.
|
||||
- Rename timestamp keys in PDUs and events from \'ts\' and \'hsob\_ts\' to \'origin\_server\_ts\'.
|
||||
|
||||
Changes in synapse 0.3.4 (2014-09-25)
|
||||
=====================================
|
||||
@@ -6394,48 +6594,48 @@ This version adds support for using a TURN server. See docs/turn-howto.rst on ho
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Add support for redaction of messages.
|
||||
- Fix bug where inviting a user on a remote home server could take up to 20-30s.
|
||||
- Implement a get current room state API.
|
||||
- Add support specifying and retrieving turn server configuration.
|
||||
- Add support for redaction of messages.
|
||||
- Fix bug where inviting a user on a remote home server could take up to 20-30s.
|
||||
- Implement a get current room state API.
|
||||
- Add support specifying and retrieving turn server configuration.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Add button to send messages to users from the home page.
|
||||
- Add support for using TURN for VoIP calls.
|
||||
- Show display name change messages.
|
||||
- Fix bug where the client didn\'t get the state of a newly joined room until after it has been refreshed.
|
||||
- Fix bugs with tab complete.
|
||||
- Fix bug where holding down the down arrow caused chrome to chew 100% CPU.
|
||||
- Fix bug where desktop notifications occasionally used \"Undefined\" as the display name.
|
||||
- Fix more places where we sometimes saw room IDs incorrectly.
|
||||
- Fix bug which caused lag when entering text in the text box.
|
||||
- Add button to send messages to users from the home page.
|
||||
- Add support for using TURN for VoIP calls.
|
||||
- Show display name change messages.
|
||||
- Fix bug where the client didn\'t get the state of a newly joined room until after it has been refreshed.
|
||||
- Fix bugs with tab complete.
|
||||
- Fix bug where holding down the down arrow caused chrome to chew 100% CPU.
|
||||
- Fix bug where desktop notifications occasionally used \"Undefined\" as the display name.
|
||||
- Fix more places where we sometimes saw room IDs incorrectly.
|
||||
- Fix bug which caused lag when entering text in the text box.
|
||||
|
||||
Changes in synapse 0.3.3 (2014-09-22)
|
||||
=====================================
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Fix bug where you continued to get events for rooms you had left.
|
||||
- Fix bug where you continued to get events for rooms you had left.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Add support for video calls with basic UI.
|
||||
- Fix bug where one to one chats were named after your display name rather than the other person\'s.
|
||||
- Fix bug which caused lag when typing in the textarea.
|
||||
- Refuse to run on browsers we know won\'t work.
|
||||
- Trigger pagination when joining new rooms.
|
||||
- Fix bug where we sometimes didn\'t display invitations in recents.
|
||||
- Automatically join room when accepting a VoIP call.
|
||||
- Disable outgoing and reject incoming calls on browsers we don\'t support VoIP in.
|
||||
- Don\'t display desktop notifications for messages in the room you are non-idle and speaking in.
|
||||
- Add support for video calls with basic UI.
|
||||
- Fix bug where one to one chats were named after your display name rather than the other person\'s.
|
||||
- Fix bug which caused lag when typing in the textarea.
|
||||
- Refuse to run on browsers we know won\'t work.
|
||||
- Trigger pagination when joining new rooms.
|
||||
- Fix bug where we sometimes didn\'t display invitations in recents.
|
||||
- Automatically join room when accepting a VoIP call.
|
||||
- Disable outgoing and reject incoming calls on browsers we don\'t support VoIP in.
|
||||
- Don\'t display desktop notifications for messages in the room you are non-idle and speaking in.
|
||||
|
||||
Changes in synapse 0.3.2 (2014-09-18)
|
||||
=====================================
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Fix bug where an empty \"bing words\" list in old accounts didn\'t send notifications when it should have done.
|
||||
- Fix bug where an empty \"bing words\" list in old accounts didn\'t send notifications when it should have done.
|
||||
|
||||
Changes in synapse 0.3.1 (2014-09-18)
|
||||
=====================================
|
||||
@@ -6444,8 +6644,8 @@ This is a release to hotfix v0.3.0 to fix two regressions.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Fix a regression where we sometimes displayed duplicate events.
|
||||
- Fix a regression where we didn\'t immediately remove rooms you were banned in from the recents list.
|
||||
- Fix a regression where we sometimes displayed duplicate events.
|
||||
- Fix a regression where we didn\'t immediately remove rooms you were banned in from the recents list.
|
||||
|
||||
Changes in synapse 0.3.0 (2014-09-18)
|
||||
=====================================
|
||||
@@ -6454,91 +6654,91 @@ See UPGRADE for information about changes to the client server API, including br
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - When a user changes their displayname or avatar the server will now update all their join states to reflect this.
|
||||
- The server now adds \"age\" key to events to indicate how old they are. This is clock independent, so at no point does any server or webclient have to assume their clock is in sync with everyone else.
|
||||
- Fix bug where we didn\'t correctly pull in missing PDUs.
|
||||
- Fix bug where prev\_content key wasn\'t always returned.
|
||||
- Add support for password resets.
|
||||
- When a user changes their displayname or avatar the server will now update all their join states to reflect this.
|
||||
- The server now adds \"age\" key to events to indicate how old they are. This is clock independent, so at no point does any server or webclient have to assume their clock is in sync with everyone else.
|
||||
- Fix bug where we didn\'t correctly pull in missing PDUs.
|
||||
- Fix bug where prev\_content key wasn\'t always returned.
|
||||
- Add support for password resets.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Improve page content loading.
|
||||
- Join/parts now trigger desktop notifications.
|
||||
- Always show room aliases in the UI if one is present.
|
||||
- No longer show user-count in the recents side panel.
|
||||
- Add up & down arrow support to the text box for message sending to step through your sent history.
|
||||
- Don\'t display notifications for our own messages.
|
||||
- Emotes are now formatted correctly in desktop notifications.
|
||||
- The recents list now differentiates between public & private rooms.
|
||||
- Fix bug where when switching between rooms the pagination flickered before the view jumped to the bottom of the screen.
|
||||
- Add bing word support.
|
||||
- Improve page content loading.
|
||||
- Join/parts now trigger desktop notifications.
|
||||
- Always show room aliases in the UI if one is present.
|
||||
- No longer show user-count in the recents side panel.
|
||||
- Add up & down arrow support to the text box for message sending to step through your sent history.
|
||||
- Don\'t display notifications for our own messages.
|
||||
- Emotes are now formatted correctly in desktop notifications.
|
||||
- The recents list now differentiates between public & private rooms.
|
||||
- Fix bug where when switching between rooms the pagination flickered before the view jumped to the bottom of the screen.
|
||||
- Add bing word support.
|
||||
|
||||
Registration API:
|
||||
|
||||
: - The registration API has been overhauled to function like the login API. In practice, this means registration requests must now include the following: \'type\':\'m.login.password\'. See UPGRADE for more information on this.
|
||||
- The \'user\_id\' key has been renamed to \'user\' to better match the login API.
|
||||
- There is an additional login type: \'m.login.email.identity\'.
|
||||
- The command client and web client have been updated to reflect these changes.
|
||||
- The registration API has been overhauled to function like the login API. In practice, this means registration requests must now include the following: \'type\':\'m.login.password\'. See UPGRADE for more information on this.
|
||||
- The \'user\_id\' key has been renamed to \'user\' to better match the login API.
|
||||
- There is an additional login type: \'m.login.email.identity\'.
|
||||
- The command client and web client have been updated to reflect these changes.
|
||||
|
||||
Changes in synapse 0.2.3 (2014-09-12)
|
||||
=====================================
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Fix bug where we stopped sending events to remote home servers if a user from that home server left, even if there were some still in the room.
|
||||
- Fix bugs in the state conflict resolution where it was incorrectly rejecting events.
|
||||
- Fix bug where we stopped sending events to remote home servers if a user from that home server left, even if there were some still in the room.
|
||||
- Fix bugs in the state conflict resolution where it was incorrectly rejecting events.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Display room names and topics.
|
||||
- Allow setting/editing of room names and topics.
|
||||
- Display information about rooms on the main page.
|
||||
- Handle ban and kick events in real time.
|
||||
- VoIP UI and reliability improvements.
|
||||
- Add glare support for VoIP.
|
||||
- Improvements to initial startup speed.
|
||||
- Don\'t display duplicate join events.
|
||||
- Local echo of messages.
|
||||
- Differentiate sending and sent of local echo.
|
||||
- Various minor bug fixes.
|
||||
- Display room names and topics.
|
||||
- Allow setting/editing of room names and topics.
|
||||
- Display information about rooms on the main page.
|
||||
- Handle ban and kick events in real time.
|
||||
- VoIP UI and reliability improvements.
|
||||
- Add glare support for VoIP.
|
||||
- Improvements to initial startup speed.
|
||||
- Don\'t display duplicate join events.
|
||||
- Local echo of messages.
|
||||
- Differentiate sending and sent of local echo.
|
||||
- Various minor bug fixes.
|
||||
|
||||
Changes in synapse 0.2.2 (2014-09-06)
|
||||
=====================================
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - When the server returns state events it now also includes the previous content.
|
||||
- Add support for inviting people when creating a new room.
|
||||
- Make the homeserver inform the room via m.room.aliases when a new alias is added for a room.
|
||||
- Validate m.room.power\_level events.
|
||||
- When the server returns state events it now also includes the previous content.
|
||||
- Add support for inviting people when creating a new room.
|
||||
- Make the homeserver inform the room via m.room.aliases when a new alias is added for a room.
|
||||
- Validate m.room.power\_level events.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Add support for captchas on registration.
|
||||
- Handle m.room.aliases events.
|
||||
- Asynchronously send messages and show a local echo.
|
||||
- Inform the UI when a message failed to send.
|
||||
- Only autoscroll on receiving a new message if the user was already at the bottom of the screen.
|
||||
- Add support for ban/kick reasons.
|
||||
- Add support for captchas on registration.
|
||||
- Handle m.room.aliases events.
|
||||
- Asynchronously send messages and show a local echo.
|
||||
- Inform the UI when a message failed to send.
|
||||
- Only autoscroll on receiving a new message if the user was already at the bottom of the screen.
|
||||
- Add support for ban/kick reasons.
|
||||
|
||||
Changes in synapse 0.2.1 (2014-09-03)
|
||||
=====================================
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Added support for signing up with a third party id.
|
||||
- Add synctl scripts.
|
||||
- Added rate limiting.
|
||||
- Add option to change the external address the content repo uses.
|
||||
- Presence bug fixes.
|
||||
- Added support for signing up with a third party id.
|
||||
- Add synctl scripts.
|
||||
- Added rate limiting.
|
||||
- Add option to change the external address the content repo uses.
|
||||
- Presence bug fixes.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Added support for signing up with a third party id.
|
||||
- Added support for banning and kicking users.
|
||||
- Added support for displaying and setting ops.
|
||||
- Added support for room names.
|
||||
- Fix bugs with room membership event display.
|
||||
- Added support for signing up with a third party id.
|
||||
- Added support for banning and kicking users.
|
||||
- Added support for displaying and setting ops.
|
||||
- Added support for room names.
|
||||
- Fix bugs with room membership event display.
|
||||
|
||||
Changes in synapse 0.2.0 (2014-09-02)
|
||||
=====================================
|
||||
@@ -6547,36 +6747,36 @@ This update changes many configuration options, updates the database schema and
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Require SSL for server-server connections.
|
||||
- Add SSL listener for client-server connections.
|
||||
- Add ability to use config files.
|
||||
- Add support for kicking/banning and power levels.
|
||||
- Allow setting of room names and topics on creation.
|
||||
- Change presence to include last seen time of the user.
|
||||
- Change url path prefix to /\_matrix/\...
|
||||
- Bug fixes to presence.
|
||||
- Require SSL for server-server connections.
|
||||
- Add SSL listener for client-server connections.
|
||||
- Add ability to use config files.
|
||||
- Add support for kicking/banning and power levels.
|
||||
- Allow setting of room names and topics on creation.
|
||||
- Change presence to include last seen time of the user.
|
||||
- Change url path prefix to /\_matrix/\...
|
||||
- Bug fixes to presence.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Reskin the CSS for registration and login.
|
||||
- Various improvements to rooms CSS.
|
||||
- Support changes in client-server API.
|
||||
- Bug fixes to VOIP UI.
|
||||
- Various bug fixes to handling of changes to room member list.
|
||||
- Reskin the CSS for registration and login.
|
||||
- Various improvements to rooms CSS.
|
||||
- Support changes in client-server API.
|
||||
- Bug fixes to VOIP UI.
|
||||
- Various bug fixes to handling of changes to room member list.
|
||||
|
||||
Changes in synapse 0.1.2 (2014-08-29)
|
||||
=====================================
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Add basic call state UI for VoIP calls.
|
||||
- Add basic call state UI for VoIP calls.
|
||||
|
||||
Changes in synapse 0.1.1 (2014-08-29)
|
||||
=====================================
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Fix bug that caused the event stream to not notify some clients about changes.
|
||||
- Fix bug that caused the event stream to not notify some clients about changes.
|
||||
|
||||
Changes in synapse 0.1.0 (2014-08-29)
|
||||
=====================================
|
||||
@@ -6585,26 +6785,22 @@ Presence has been reenabled in this release.
|
||||
|
||||
Homeserver:
|
||||
|
||||
: -
|
||||
|
||||
Update client to server API, including:
|
||||
|
||||
: - Use a more consistent url scheme.
|
||||
- Provide more useful information in the initial sync api.
|
||||
|
||||
- Change the presence handling to be much more efficient.
|
||||
- Change the presence server to server API to not require explicit polling of all users who share a room with a user.
|
||||
- Fix races in the event streaming logic.
|
||||
- Update client to server API, including:
|
||||
- Use a more consistent url scheme.
|
||||
- Provide more useful information in the initial sync api.
|
||||
- Change the presence handling to be much more efficient.
|
||||
- Change the presence server to server API to not require explicit polling of all users who share a room with a user.
|
||||
- Fix races in the event streaming logic.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Update to use new client to server API.
|
||||
- Add basic VOIP support.
|
||||
- Add idle timers that change your status to away.
|
||||
- Add recent rooms column when viewing a room.
|
||||
- Various network efficiency improvements.
|
||||
- Add basic mobile browser support.
|
||||
- Add a settings page.
|
||||
- Update to use new client to server API.
|
||||
- Add basic VOIP support.
|
||||
- Add idle timers that change your status to away.
|
||||
- Add recent rooms column when viewing a room.
|
||||
- Various network efficiency improvements.
|
||||
- Add basic mobile browser support.
|
||||
- Add a settings page.
|
||||
|
||||
Changes in synapse 0.0.1 (2014-08-22)
|
||||
=====================================
|
||||
@@ -6613,26 +6809,26 @@ Presence has been disabled in this release due to a bug that caused the homeserv
|
||||
|
||||
Homeserver:
|
||||
|
||||
: - Completely change the database schema to support generic event types.
|
||||
- Improve presence reliability.
|
||||
- Improve reliability of joining remote rooms.
|
||||
- Fix bug where room join events were duplicated.
|
||||
- Improve initial sync API to return more information to the client.
|
||||
- Stop generating fake messages for room membership events.
|
||||
- Completely change the database schema to support generic event types.
|
||||
- Improve presence reliability.
|
||||
- Improve reliability of joining remote rooms.
|
||||
- Fix bug where room join events were duplicated.
|
||||
- Improve initial sync API to return more information to the client.
|
||||
- Stop generating fake messages for room membership events.
|
||||
|
||||
Webclient:
|
||||
|
||||
: - Add tab completion of names.
|
||||
- Add ability to upload and send images.
|
||||
- Add profile pages.
|
||||
- Improve CSS layout of room.
|
||||
- Disambiguate identical display names.
|
||||
- Don\'t get remote users display names and avatars individually.
|
||||
- Use the new initial sync API to reduce number of round trips to the homeserver.
|
||||
- Change url scheme to use room aliases instead of room ids where known.
|
||||
- Increase longpoll timeout.
|
||||
- Add tab completion of names.
|
||||
- Add ability to upload and send images.
|
||||
- Add profile pages.
|
||||
- Improve CSS layout of room.
|
||||
- Disambiguate identical display names.
|
||||
- Don\'t get remote users display names and avatars individually.
|
||||
- Use the new initial sync API to reduce number of round trips to the homeserver.
|
||||
- Change url scheme to use room aliases instead of room ids where known.
|
||||
- Increase longpoll timeout.
|
||||
|
||||
Changes in synapse 0.0.0 (2014-08-13)
|
||||
=====================================
|
||||
|
||||
> - Initial alpha release
|
||||
- Initial alpha release
|
||||
|
||||
+4
-5
@@ -487,7 +487,7 @@ In nginx this would be something like:
|
||||
```
|
||||
location /.well-known/matrix/client {
|
||||
return 200 '{"m.homeserver": {"base_url": "https://<matrix.example.com>"}}';
|
||||
add_header Content-Type application/json;
|
||||
default_type application/json;
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
}
|
||||
```
|
||||
@@ -557,10 +557,9 @@ This is critical from a security perspective to stop arbitrary Matrix users
|
||||
spidering 'internal' URLs on your network. At the very least we recommend that
|
||||
your loopback and RFC1918 IP addresses are blacklisted.
|
||||
|
||||
This also requires the optional `lxml` and `netaddr` python dependencies to be
|
||||
installed. This in turn requires the `libxml2` library to be available - on
|
||||
Debian/Ubuntu this means `apt-get install libxml2-dev`, or equivalent for
|
||||
your OS.
|
||||
This also requires the optional `lxml` python dependency to be installed. This
|
||||
in turn requires the `libxml2` library to be available - on Debian/Ubuntu this
|
||||
means `apt-get install libxml2-dev`, or equivalent for your OS.
|
||||
|
||||
# Troubleshooting Installation
|
||||
|
||||
|
||||
+73
@@ -75,6 +75,79 @@ for example:
|
||||
wget https://packages.matrix.org/debian/pool/main/m/matrix-synapse-py3/matrix-synapse-py3_1.3.0+stretch1_amd64.deb
|
||||
dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb
|
||||
|
||||
Upgrading to v1.25.0
|
||||
====================
|
||||
|
||||
Blacklisting IP ranges
|
||||
----------------------
|
||||
|
||||
Synapse v1.25.0 includes new settings, ``ip_range_blacklist`` and
|
||||
``ip_range_whitelist``, for controlling outgoing requests from Synapse for federation,
|
||||
identity servers, push, and for checking key validity for third-party invite events.
|
||||
The previous setting, ``federation_ip_range_blacklist``, is deprecated. The new
|
||||
``ip_range_blacklist`` defaults to private IP ranges if it is not defined.
|
||||
|
||||
If you have never customised ``federation_ip_range_blacklist`` it is recommended
|
||||
that you remove that setting.
|
||||
|
||||
If you have customised ``federation_ip_range_blacklist`` you should update the
|
||||
setting name to ``ip_range_blacklist``.
|
||||
|
||||
If you have a custom push server that is reached via private IP space you may
|
||||
need to customise ``ip_range_blacklist`` or ``ip_range_whitelist``.
|
||||
|
||||
Upgrading to v1.24.0
|
||||
====================
|
||||
|
||||
Custom OpenID Connect mapping provider breaking change
|
||||
------------------------------------------------------
|
||||
|
||||
This release allows the OpenID Connect mapping provider to perform normalisation
|
||||
of the localpart of the Matrix ID. This allows for the mapping provider to
|
||||
specify different algorithms, instead of the [default way](https://matrix.org/docs/spec/appendices#mapping-from-other-character-sets).
|
||||
|
||||
If your Synapse configuration uses a custom mapping provider
|
||||
(`oidc_config.user_mapping_provider.module` is specified and not equal to
|
||||
`synapse.handlers.oidc_handler.JinjaOidcMappingProvider`) then you *must* ensure
|
||||
that `map_user_attributes` of the mapping provider performs some normalisation
|
||||
of the `localpart` returned. To match previous behaviour you can use the
|
||||
`map_username_to_mxid_localpart` function provided by Synapse. An example is
|
||||
shown below:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from synapse.types import map_username_to_mxid_localpart
|
||||
|
||||
class MyMappingProvider:
|
||||
def map_user_attributes(self, userinfo, token):
|
||||
# ... your custom logic ...
|
||||
sso_user_id = ...
|
||||
localpart = map_username_to_mxid_localpart(sso_user_id)
|
||||
|
||||
return {"localpart": localpart}
|
||||
|
||||
Removal historical Synapse Admin API
|
||||
------------------------------------
|
||||
|
||||
Historically, the Synapse Admin API has been accessible under:
|
||||
|
||||
* ``/_matrix/client/api/v1/admin``
|
||||
* ``/_matrix/client/unstable/admin``
|
||||
* ``/_matrix/client/r0/admin``
|
||||
* ``/_synapse/admin/v1``
|
||||
|
||||
The endpoints with ``/_matrix/client/*`` prefixes have been removed as of v1.24.0.
|
||||
The Admin API is now only accessible under:
|
||||
|
||||
* ``/_synapse/admin/v1``
|
||||
|
||||
The only exception is the `/admin/whois` endpoint, which is
|
||||
`also available via the client-server API <https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-admin-whois-userid>`_.
|
||||
|
||||
The deprecation of the old endpoints was announced with Synapse 1.20.0 (released
|
||||
on 2020-09-22) and makes it easier for homeserver admins to lock down external
|
||||
access to the Admin API endpoints.
|
||||
|
||||
Upgrading to v1.23.0
|
||||
====================
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Fix the "Event persist rate" section of the included grafana dashboard by adding missing prometheus rules.
|
||||
@@ -0,0 +1 @@
|
||||
Apply an IP range blacklist to push and key revocation requests.
|
||||
@@ -0,0 +1 @@
|
||||
Fix bug where we might not correctly calculate the current state for rooms with multiple extremities.
|
||||
@@ -0,0 +1 @@
|
||||
Deprecate Shutdown Room and Purge Room Admin APIs.
|
||||
@@ -0,0 +1 @@
|
||||
Fix a long standing bug in the register admin endpoint (`/_synapse/admin/v1/register`) when the `mac` field was not provided. The endpoint now properly returns a 400 error. Contributed by @edwargix.
|
||||
@@ -0,0 +1 @@
|
||||
Combine related media admin API docs.
|
||||
@@ -0,0 +1 @@
|
||||
Add optional HTTP authentication to replication endpoints.
|
||||
@@ -0,0 +1 @@
|
||||
Fix a long-standing bug on Synapse instances supporting Single-Sign-On, where users would be prompted to enter their password to confirm certain actions, even though they have not set a password.
|
||||
@@ -0,0 +1 @@
|
||||
Remove some unnecessary stubbing from unit tests.
|
||||
@@ -0,0 +1 @@
|
||||
Fix a longstanding bug where a 500 error would be returned if the `Content-Length` header was not provided to the upload media resource.
|
||||
@@ -0,0 +1 @@
|
||||
Remove unused `FakeResponse` class from unit tests.
|
||||
@@ -0,0 +1 @@
|
||||
Add additional validation to pusher URLs to be compliant with the specification.
|
||||
@@ -0,0 +1 @@
|
||||
Fix the error code that is returned when a user tries to register on a homeserver on which new-user registration has been disabled.
|
||||
@@ -0,0 +1 @@
|
||||
Apply an IP range blacklist to push and key revocation requests.
|
||||
@@ -0,0 +1 @@
|
||||
Fix a bug where `PUT /_synapse/admin/v2/users/<user_id>` failed to create a new user when `avatar_url` is specified. Bug introduced in Synapse v1.9.0.
|
||||
@@ -0,0 +1 @@
|
||||
Fix an error in the documentation for the SAML username mapping provider.
|
||||
@@ -0,0 +1 @@
|
||||
Improve the error messages printed as a result of configuration problems for extension modules.
|
||||
@@ -0,0 +1 @@
|
||||
Pass `room_id` to `get_auth_chain_difference`.
|
||||
@@ -0,0 +1 @@
|
||||
Add type hints to push module.
|
||||
@@ -0,0 +1 @@
|
||||
Simplify logic for handling user-interactive-auth via single-sign-on servers.
|
||||
@@ -0,0 +1 @@
|
||||
Add type hints to push module.
|
||||
@@ -0,0 +1 @@
|
||||
Fix a 500 error when attempting to preview an empty HTML file.
|
||||
@@ -0,0 +1 @@
|
||||
Add number of local devices to Room Details Admin API. Contributed by @dklimpel.
|
||||
@@ -0,0 +1 @@
|
||||
Add `X-Robots-Tag` header to stop web crawlers from indexing media.
|
||||
@@ -0,0 +1 @@
|
||||
Clarify comments around template directories in `sample_config.yaml`.
|
||||
@@ -0,0 +1 @@
|
||||
Add support for allowing users to pick their own user ID during a single-sign-on login.
|
||||
@@ -0,0 +1 @@
|
||||
Add support for allowing users to pick their own user ID during a single-sign-on login.
|
||||
@@ -0,0 +1 @@
|
||||
Skip the SAML tests if the requirements (`pysaml2` and `xmlsec1`) aren't available.
|
||||
@@ -0,0 +1 @@
|
||||
Fix multiarch docker image builds.
|
||||
@@ -0,0 +1 @@
|
||||
Don't publish `latest` docker image until all archs are built.
|
||||
@@ -0,0 +1 @@
|
||||
Improve structured logging tests.
|
||||
@@ -0,0 +1 @@
|
||||
Fix occasional deadlock when handling SIGHUP.
|
||||
@@ -0,0 +1 @@
|
||||
Fix bug where we ratelimited auto joining of rooms on registration (using `auto_join_rooms` config).
|
||||
@@ -20,6 +20,7 @@ Add a new job to the main prometheus.conf file:
|
||||
```
|
||||
|
||||
### for Prometheus v2
|
||||
|
||||
Add a new job to the main prometheus.yml file:
|
||||
|
||||
```yaml
|
||||
@@ -29,14 +30,17 @@ Add a new job to the main prometheus.yml file:
|
||||
scheme: "https"
|
||||
|
||||
static_configs:
|
||||
- targets: ['SERVER.LOCATION:PORT']
|
||||
- targets: ["my.server.here:port"]
|
||||
```
|
||||
|
||||
An example of a Prometheus configuration with workers can be found in
|
||||
[metrics-howto.md](https://github.com/matrix-org/synapse/blob/master/docs/metrics-howto.md).
|
||||
|
||||
To use `synapse.rules` add
|
||||
|
||||
```yaml
|
||||
rule_files:
|
||||
- "/PATH/TO/synapse-v2.rules"
|
||||
rule_files:
|
||||
- "/PATH/TO/synapse-v2.rules"
|
||||
```
|
||||
|
||||
Metrics are disabled by default when running synapse; they must be enabled
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#process_resource_utime"),
|
||||
expr: "rate(process_cpu_seconds_total[2m]) * 100",
|
||||
name: "[[job]]",
|
||||
name: "[[job]]-[[index]]",
|
||||
min: 0,
|
||||
max: 100,
|
||||
renderer: "line",
|
||||
@@ -22,12 +22,12 @@ new PromConsole.Graph({
|
||||
</script>
|
||||
|
||||
<h3>Memory</h3>
|
||||
<div id="process_resource_maxrss"></div>
|
||||
<div id="process_resident_memory_bytes"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#process_resource_maxrss"),
|
||||
expr: "process_psutil_rss:max",
|
||||
name: "Maxrss",
|
||||
node: document.querySelector("#process_resident_memory_bytes"),
|
||||
expr: "process_resident_memory_bytes",
|
||||
name: "[[job]]-[[index]]",
|
||||
min: 0,
|
||||
renderer: "line",
|
||||
height: 150,
|
||||
@@ -43,8 +43,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#process_fds"),
|
||||
expr: "process_open_fds{job='synapse'}",
|
||||
name: "FDs",
|
||||
expr: "process_open_fds",
|
||||
name: "[[job]]-[[index]]",
|
||||
min: 0,
|
||||
renderer: "line",
|
||||
height: 150,
|
||||
@@ -62,8 +62,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#reactor_total_time"),
|
||||
expr: "rate(python_twisted_reactor_tick_time:total[2m]) / 1000",
|
||||
name: "time",
|
||||
expr: "rate(python_twisted_reactor_tick_time_sum[2m])",
|
||||
name: "[[job]]-[[index]]",
|
||||
max: 1,
|
||||
min: 0,
|
||||
renderer: "area",
|
||||
@@ -80,8 +80,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#reactor_average_time"),
|
||||
expr: "rate(python_twisted_reactor_tick_time:total[2m]) / rate(python_twisted_reactor_tick_time:count[2m]) / 1000",
|
||||
name: "time",
|
||||
expr: "rate(python_twisted_reactor_tick_time_sum[2m]) / rate(python_twisted_reactor_tick_time_count[2m])",
|
||||
name: "[[job]]-[[index]]",
|
||||
min: 0,
|
||||
renderer: "line",
|
||||
height: 150,
|
||||
@@ -97,14 +97,14 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#reactor_pending_calls"),
|
||||
expr: "rate(python_twisted_reactor_pending_calls:total[30s])/rate(python_twisted_reactor_pending_calls:count[30s])",
|
||||
name: "calls",
|
||||
expr: "rate(python_twisted_reactor_pending_calls_sum[30s]) / rate(python_twisted_reactor_pending_calls_count[30s])",
|
||||
name: "[[job]]-[[index]]",
|
||||
min: 0,
|
||||
renderer: "line",
|
||||
height: 150,
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yTitle: "Pending Cals"
|
||||
yTitle: "Pending Calls"
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -115,7 +115,7 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_storage_query_time"),
|
||||
expr: "rate(synapse_storage_query_time:count[2m])",
|
||||
expr: "sum(rate(synapse_storage_query_time_count[2m])) by (verb)",
|
||||
name: "[[verb]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
@@ -129,8 +129,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_storage_transaction_time"),
|
||||
expr: "rate(synapse_storage_transaction_time:count[2m])",
|
||||
name: "[[desc]]",
|
||||
expr: "topk(10, rate(synapse_storage_transaction_time_count[2m]))",
|
||||
name: "[[job]]-[[index]] [[desc]]",
|
||||
min: 0,
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
@@ -140,12 +140,12 @@ new PromConsole.Graph({
|
||||
</script>
|
||||
|
||||
<h3>Transaction execution time</h3>
|
||||
<div id="synapse_storage_transactions_time_msec"></div>
|
||||
<div id="synapse_storage_transactions_time_sec"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_storage_transactions_time_msec"),
|
||||
expr: "rate(synapse_storage_transaction_time:total[2m]) / 1000",
|
||||
name: "[[desc]]",
|
||||
node: document.querySelector("#synapse_storage_transactions_time_sec"),
|
||||
expr: "rate(synapse_storage_transaction_time_sum[2m])",
|
||||
name: "[[job]]-[[index]] [[desc]]",
|
||||
min: 0,
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
@@ -154,34 +154,33 @@ new PromConsole.Graph({
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Database scheduling latency</h3>
|
||||
<div id="synapse_storage_schedule_time"></div>
|
||||
<h3>Average time waiting for database connection</h3>
|
||||
<div id="synapse_storage_avg_waiting_time"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_storage_schedule_time"),
|
||||
expr: "rate(synapse_storage_schedule_time:total[2m]) / 1000",
|
||||
name: "Total latency",
|
||||
node: document.querySelector("#synapse_storage_avg_waiting_time"),
|
||||
expr: "rate(synapse_storage_schedule_time_sum[2m]) / rate(synapse_storage_schedule_time_count[2m])",
|
||||
name: "[[job]]-[[index]]",
|
||||
min: 0,
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "s/s",
|
||||
yTitle: "Usage"
|
||||
yUnits: "s",
|
||||
yTitle: "Time"
|
||||
})
|
||||
</script>
|
||||
|
||||
<h3>Cache hit ratio</h3>
|
||||
<div id="synapse_cache_ratio"></div>
|
||||
<h3>Cache request rate</h3>
|
||||
<div id="synapse_cache_request_rate"></div>
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_cache_ratio"),
|
||||
expr: "rate(synapse_util_caches_cache:total[2m]) * 100",
|
||||
name: "[[name]]",
|
||||
node: document.querySelector("#synapse_cache_request_rate"),
|
||||
expr: "rate(synapse_util_caches_cache:total[2m])",
|
||||
name: "[[job]]-[[index]] [[name]]",
|
||||
min: 0,
|
||||
max: 100,
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yUnits: "%",
|
||||
yTitle: "Percentage"
|
||||
yUnits: "rps",
|
||||
yTitle: "Cache request rate"
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -191,7 +190,7 @@ new PromConsole.Graph({
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_cache_size"),
|
||||
expr: "synapse_util_caches_cache:size",
|
||||
name: "[[name]]",
|
||||
name: "[[job]]-[[index]] [[name]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yUnits: "",
|
||||
@@ -206,8 +205,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_http_server_request_count_servlet"),
|
||||
expr: "rate(synapse_http_server_request_count:servlet[2m])",
|
||||
name: "[[servlet]]",
|
||||
expr: "rate(synapse_http_server_in_flight_requests_count[2m])",
|
||||
name: "[[job]]-[[index]] [[method]] [[servlet]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "req/s",
|
||||
@@ -219,8 +218,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_http_server_request_count_servlet_minus_events"),
|
||||
expr: "rate(synapse_http_server_request_count:servlet{servlet!=\"EventStreamRestServlet\", servlet!=\"SyncRestServlet\"}[2m])",
|
||||
name: "[[servlet]]",
|
||||
expr: "rate(synapse_http_server_in_flight_requests_count{servlet!=\"EventStreamRestServlet\", servlet!=\"SyncRestServlet\"}[2m])",
|
||||
name: "[[job]]-[[index]] [[method]] [[servlet]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "req/s",
|
||||
@@ -233,8 +232,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_http_server_response_time_avg"),
|
||||
expr: "rate(synapse_http_server_response_time_seconds[2m]) / rate(synapse_http_server_response_count[2m]) / 1000",
|
||||
name: "[[servlet]]",
|
||||
expr: "rate(synapse_http_server_response_time_seconds_sum[2m]) / rate(synapse_http_server_response_count[2m])",
|
||||
name: "[[job]]-[[index]] [[servlet]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "s/req",
|
||||
@@ -277,7 +276,7 @@ new PromConsole.Graph({
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_http_server_response_ru_utime"),
|
||||
expr: "rate(synapse_http_server_response_ru_utime_seconds[2m])",
|
||||
name: "[[servlet]]",
|
||||
name: "[[job]]-[[index]] [[servlet]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "s/s",
|
||||
@@ -292,7 +291,7 @@ new PromConsole.Graph({
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_http_server_response_db_txn_duration"),
|
||||
expr: "rate(synapse_http_server_response_db_txn_duration_seconds[2m])",
|
||||
name: "[[servlet]]",
|
||||
name: "[[job]]-[[index]] [[servlet]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "s/s",
|
||||
@@ -306,8 +305,8 @@ new PromConsole.Graph({
|
||||
<script>
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_http_server_send_time_avg"),
|
||||
expr: "rate(synapse_http_server_response_time_second{servlet='RoomSendEventRestServlet'}[2m]) / rate(synapse_http_server_response_count{servlet='RoomSendEventRestServlet'}[2m]) / 1000",
|
||||
name: "[[servlet]]",
|
||||
expr: "rate(synapse_http_server_response_time_seconds_sum{servlet='RoomSendEventRestServlet'}[2m]) / rate(synapse_http_server_response_count{servlet='RoomSendEventRestServlet'}[2m])",
|
||||
name: "[[job]]-[[index]] [[servlet]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "s/req",
|
||||
@@ -323,7 +322,7 @@ new PromConsole.Graph({
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_federation_client_sent"),
|
||||
expr: "rate(synapse_federation_client_sent[2m])",
|
||||
name: "[[type]]",
|
||||
name: "[[job]]-[[index]] [[type]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "req/s",
|
||||
@@ -337,7 +336,7 @@ new PromConsole.Graph({
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_federation_server_received"),
|
||||
expr: "rate(synapse_federation_server_received[2m])",
|
||||
name: "[[type]]",
|
||||
name: "[[job]]-[[index]] [[type]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "req/s",
|
||||
@@ -367,7 +366,7 @@ new PromConsole.Graph({
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_notifier_listeners"),
|
||||
expr: "synapse_notifier_listeners",
|
||||
name: "listeners",
|
||||
name: "[[job]]-[[index]]",
|
||||
min: 0,
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanizeNoSmallPrefix,
|
||||
@@ -382,7 +381,7 @@ new PromConsole.Graph({
|
||||
new PromConsole.Graph({
|
||||
node: document.querySelector("#synapse_notifier_notified_events"),
|
||||
expr: "rate(synapse_notifier_notified_events[2m])",
|
||||
name: "events",
|
||||
name: "[[job]]-[[index]]",
|
||||
yAxisFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yHoverFormatter: PromConsole.NumberFormatter.humanize,
|
||||
yUnits: "events/s",
|
||||
|
||||
@@ -58,3 +58,21 @@ groups:
|
||||
labels:
|
||||
type: "PDU"
|
||||
expr: 'synapse_federation_transaction_queue_pending_pdus + 0'
|
||||
|
||||
- record: synapse_storage_events_persisted_by_source_type
|
||||
expr: sum without(type, origin_type, origin_entity) (synapse_storage_events_persisted_events_sep{origin_type="remote"})
|
||||
labels:
|
||||
type: remote
|
||||
- record: synapse_storage_events_persisted_by_source_type
|
||||
expr: sum without(type, origin_type, origin_entity) (synapse_storage_events_persisted_events_sep{origin_entity="*client*",origin_type="local"})
|
||||
labels:
|
||||
type: local
|
||||
- record: synapse_storage_events_persisted_by_source_type
|
||||
expr: sum without(type, origin_type, origin_entity) (synapse_storage_events_persisted_events_sep{origin_entity!="*client*",origin_type="local"})
|
||||
labels:
|
||||
type: bridges
|
||||
- record: synapse_storage_events_persisted_by_event_type
|
||||
expr: sum without(origin_entity, origin_type) (synapse_storage_events_persisted_events_sep)
|
||||
- record: synapse_storage_events_persisted_by_origin
|
||||
expr: sum without(type) (synapse_storage_events_persisted_events_sep)
|
||||
|
||||
|
||||
Vendored
+12
@@ -1,3 +1,15 @@
|
||||
matrix-synapse-py3 (1.24.0) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.24.0.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Wed, 09 Dec 2020 10:14:30 +0000
|
||||
|
||||
matrix-synapse-py3 (1.23.1) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.23.1.
|
||||
|
||||
-- Synapse Packaging team <packages@matrix.org> Wed, 09 Dec 2020 10:40:39 +0000
|
||||
|
||||
matrix-synapse-py3 (1.23.0) stable; urgency=medium
|
||||
|
||||
* New synapse release 1.23.0.
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ RUN pip install --prefix="/install" --no-warn-script-location \
|
||||
jaeger-client \
|
||||
opentracing \
|
||||
# Match the version constraints of Synapse
|
||||
"prometheus_client>=0.4.0,<0.9.0" \
|
||||
"prometheus_client>=0.4.0" \
|
||||
psycopg2 \
|
||||
pycparser \
|
||||
pyrsistent \
|
||||
|
||||
@@ -69,7 +69,8 @@ RUN apt-get update -qq -o Acquire::Languages=none \
|
||||
python3-setuptools \
|
||||
python3-venv \
|
||||
sqlite3 \
|
||||
libpq-dev
|
||||
libpq-dev \
|
||||
xmlsec1
|
||||
|
||||
COPY --from=builder /dh-virtualenv_1.2~dev-1_all.deb /
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Inherit from the official Synapse docker image
|
||||
FROM matrixdotorg/synapse
|
||||
|
||||
# Install deps
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y supervisor redis nginx
|
||||
|
||||
# Copy the worker process and log configuration files
|
||||
COPY ./docker/workers /conf/workers/
|
||||
|
||||
# Expose nginx listener port
|
||||
EXPOSE 8008/tcp
|
||||
|
||||
# Volume for user-editable config files, logs etc.
|
||||
VOLUME ["/data"]
|
||||
|
||||
# A script to read environment variables and create the necessary
|
||||
# files to run the desired worker configuration. Will start supervisord.
|
||||
COPY ./docker/configure_workers_and_start.py /configure_workers_and_start.py
|
||||
ENTRYPOINT ["/configure_workers_and_start.py"]
|
||||
|
||||
# TODO: Healthcheck? Which worker to ask? Can we ask supervisord?
|
||||
@@ -0,0 +1,35 @@
|
||||
# This dockerfile builds on top of Dockerfile-worker and includes a built-in postgres instance.
|
||||
# It is intended to be used for Complement testing
|
||||
|
||||
FROM matrixdotorg/synapse:workers
|
||||
|
||||
# Install postgres
|
||||
RUN apt-get update
|
||||
RUN apt-get install -y postgres
|
||||
|
||||
# Create required databases in postgres
|
||||
|
||||
# Create a user without a password
|
||||
RUN sudo -u postgres createuser -w synapse_user
|
||||
|
||||
# Then set their password
|
||||
RUN sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'somesecret';"
|
||||
|
||||
# Create the synapse database
|
||||
RUN sudo -u postgres psql -c "CREATE DATABASE synapse \
|
||||
ENCODING 'UTF8' \
|
||||
LC_COLLATE='C' \
|
||||
LC_CTYPE='C' \
|
||||
template=template0 \
|
||||
OWNER synapse_user;"
|
||||
|
||||
# Modify Synapse's database config to point to the local postgres
|
||||
COPY ./docker/synapse_use_local_postgres.py /synapse_use_local_postgres.py
|
||||
RUN /synapse_use_local_postgres.py
|
||||
|
||||
VOLUME ["/data"]
|
||||
|
||||
EXPOSE 8008/tcp 8009/tcp 8448/tcp
|
||||
|
||||
# Start supervisord
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
@@ -27,8 +27,7 @@ log_config: "{{ SYNAPSE_LOG_CONFIG }}"
|
||||
|
||||
listeners:
|
||||
{% if not SYNAPSE_NO_TLS %}
|
||||
-
|
||||
port: 8448
|
||||
- port: 8448
|
||||
bind_addresses: ['::']
|
||||
type: http
|
||||
tls: true
|
||||
@@ -52,6 +51,15 @@ listeners:
|
||||
- names: [federation]
|
||||
compress: false
|
||||
|
||||
{% if SYNAPSE_WORKERS %}
|
||||
# The HTTP replication port
|
||||
- port: 9093
|
||||
bind_address: '127.0.0.1'
|
||||
type: http
|
||||
resources:
|
||||
- names: [replication]
|
||||
{% endif %}
|
||||
|
||||
## Database ##
|
||||
|
||||
{% if POSTGRES_PASSWORD %}
|
||||
|
||||
Executable
+347
@@ -0,0 +1,347 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# This script reads environment variables and generates a shared Synapse worker,
|
||||
# nginx and supervisord configs depending on the workers requested
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import jinja2
|
||||
|
||||
|
||||
# Utility functions
|
||||
def log(txt):
|
||||
print(txt)
|
||||
|
||||
|
||||
def error(txt):
|
||||
log(txt)
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def convert(src, dst, environ):
|
||||
"""Generate a file from a template
|
||||
|
||||
Args:
|
||||
src (str): path to input file
|
||||
dst (str): path to file to write
|
||||
environ (dict): environment dictionary, for replacement mappings.
|
||||
"""
|
||||
with open(src) as infile:
|
||||
template = infile.read()
|
||||
rendered = jinja2.Template(template, autoescape=True).render(**environ)
|
||||
with open(dst, "w") as outfile:
|
||||
outfile.write(rendered)
|
||||
|
||||
|
||||
def generate_base_homeserver_config():
|
||||
"""Starts Synapse and generates a basic homeserver config, which will later be
|
||||
modified for worker support.
|
||||
|
||||
Raises: CalledProcessError if calling start.py return a non-zero exit code.
|
||||
"""
|
||||
# start.py already does this for us, so just call that.
|
||||
# note that this script is copied in in the official, monolith dockerfile
|
||||
subprocess.check_output(["/usr/local/bin/python", "/start.py", "generate"])
|
||||
|
||||
|
||||
def generate_worker_files(environ, config_path: str, data_dir: str):
|
||||
"""Read the desired list of workers from environment variables and generate
|
||||
shared homeserver, nginx and supervisord configs.
|
||||
|
||||
Args:
|
||||
environ: _Environ[str]
|
||||
config_path: Where to output the generated Synapse main worker config file.
|
||||
data_dir: The location of the synapse data directory. Where log and
|
||||
user-facing config files live.
|
||||
"""
|
||||
# Note that yaml cares about indentation, so care should be taken to insert lines
|
||||
# into files at the correct indentation below.
|
||||
|
||||
# The contents of a Synapse config file that will be added alongside the generated
|
||||
# config when running the main Synapse process.
|
||||
# It is intended mainly for disabling functionality when certain workers are spun up.
|
||||
homeserver_config = """
|
||||
redis:
|
||||
enabled: true
|
||||
|
||||
# TODO: remove before prod
|
||||
suppress_key_server_warning: true
|
||||
"""
|
||||
|
||||
# The supervisord config
|
||||
supervisord_config = """
|
||||
[supervisord]
|
||||
nodaemon=true
|
||||
|
||||
[program:nginx]
|
||||
command=/usr/sbin/nginx -g "daemon off;"
|
||||
priority=900
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
username=www-data
|
||||
autorestart=true
|
||||
|
||||
[program:synapse_main]
|
||||
command=/usr/local/bin/python -m synapse.app.homeserver \
|
||||
--config-path="%s" \
|
||||
--config-path=/conf/workers/shared.yaml
|
||||
|
||||
# Log startup failures to supervisord's stdout/err
|
||||
# Regular synapse logs will still go in the configured data directory
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
autorestart=unexpected
|
||||
exitcodes=0
|
||||
|
||||
""" % (config_path,)
|
||||
|
||||
# An nginx site config. Will live in /etc/nginx/conf.d
|
||||
nginx_config_template_header = """
|
||||
server {
|
||||
# Listen on Synapse's default HTTP port number
|
||||
listen 8008;
|
||||
listen [::]:8008;
|
||||
|
||||
server_name localhost;
|
||||
"""
|
||||
nginx_config_body = "" # to modify below
|
||||
nginx_config_template_end = """
|
||||
# Send all other traffic to the main process
|
||||
location ~* ^(\/_matrix|\/_synapse) {
|
||||
proxy_pass http://localhost:18008;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
|
||||
# TODO: Can we move this to the default nginx.conf so all locations are
|
||||
# affected?
|
||||
#
|
||||
# Nginx by default only allows file uploads up to 1M in size
|
||||
# Increase client_max_body_size to match max_upload_size defined in homeserver.yaml
|
||||
client_max_body_size 50M;
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# Read desired worker configuration from environment
|
||||
if "SYNAPSE_WORKERS" not in environ:
|
||||
error("Environment variable 'SYNAPSE_WORKERS' is mandatory.")
|
||||
|
||||
worker_types = environ.get("SYNAPSE_WORKERS")
|
||||
worker_types = worker_types.split(",")
|
||||
|
||||
for worker_type in worker_types:
|
||||
worker_type = worker_type.strip()
|
||||
|
||||
if worker_type == "pusher":
|
||||
# Disable push handling from the main process
|
||||
homeserver_config += """
|
||||
start_pushers: false
|
||||
"""
|
||||
|
||||
# Enable the pusher worker in supervisord
|
||||
supervisord_config += """
|
||||
[program:synapse_pusher]
|
||||
command=/usr/local/bin/python -m synapse.app.pusher \
|
||||
--config-path="%s" \
|
||||
--config-path=/conf/workers/shared.yaml \
|
||||
--config-path=/conf/workers/pusher.yaml
|
||||
autorestart=unexpected
|
||||
exitcodes=0
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
""" % (config_path,)
|
||||
|
||||
# This worker does not handle any REST endpoints
|
||||
|
||||
elif worker_type == "appservice":
|
||||
# Disable appservice traffic sending from the main process
|
||||
homeserver_config += """
|
||||
notify_appservices: false
|
||||
"""
|
||||
|
||||
# Enable the pusher worker in supervisord
|
||||
supervisord_config += """
|
||||
[program:synapse_appservice]
|
||||
command=/usr/local/bin/python -m synapse.app.appservice \
|
||||
--config-path="%s" \
|
||||
--config-path=/conf/workers/shared.yaml \
|
||||
--config-path=/conf/workers/appservice.yaml
|
||||
autorestart=unexpected
|
||||
exitcodes=0
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
""" % (config_path,)
|
||||
|
||||
# This worker does not handle any REST endpoints
|
||||
|
||||
elif worker_type == "user_dir":
|
||||
# Disable user directory updates on the main process
|
||||
homeserver_config += """
|
||||
update_user_directory: false
|
||||
"""
|
||||
|
||||
# Enable the user directory worker in supervisord
|
||||
supervisord_config += """
|
||||
[program:synapse_user_dir]
|
||||
command=/usr/local/bin/python -m synapse.app.user_dir \
|
||||
--config-path="%s" \
|
||||
--config-path=/conf/workers/shared.yaml \
|
||||
--config-path=/conf/workers/user_dir.yaml
|
||||
autorestart=unexpected
|
||||
exitcodes=0
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
""" % (config_path,)
|
||||
|
||||
# Route user directory requests to this worker
|
||||
nginx_config_body += """
|
||||
location ~* ^/_matrix/client/(api/v1|r0|unstable)/user_directory/search$ {
|
||||
proxy_pass http://localhost:8010;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
}
|
||||
"""
|
||||
|
||||
elif worker_type == "federation_sender":
|
||||
# Disable user directory updates on the main process
|
||||
homeserver_config += """
|
||||
send_federation: False
|
||||
"""
|
||||
|
||||
# Enable the user directory worker in supervisord
|
||||
supervisord_config += """
|
||||
[program:synapse_user_dir]
|
||||
command=/usr/local/bin/python -m synapse.app.user_dir \
|
||||
--config-path="%s" \
|
||||
--config-path=/conf/workers/shared.yaml \
|
||||
--config-path=/conf/workers/user_dir.yaml
|
||||
autorestart=unexpected
|
||||
exitcodes=0
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
""" % (config_path,)
|
||||
|
||||
# This worker does not handle any REST endpoints
|
||||
|
||||
elif worker_type == "media_repository":
|
||||
# Disable user directory updates on the main process
|
||||
homeserver_config += """
|
||||
update_user_directory: false
|
||||
"""
|
||||
|
||||
# Enable the user directory worker in supervisord
|
||||
supervisord_config += """
|
||||
[program:synapse_user_dir]
|
||||
command=/usr/local/bin/python -m synapse.app.user_dir \
|
||||
--config-path="%s" \
|
||||
--config-path=/conf/workers/shared.yaml \
|
||||
--config-path=/conf/workers/user_dir.yaml
|
||||
autorestart=unexpected
|
||||
exitcodes=0
|
||||
stdout_logfile=/dev/stdout
|
||||
stdout_logfile_maxbytes=0
|
||||
stderr_logfile=/dev/stderr
|
||||
stderr_logfile_maxbytes=0
|
||||
""" % (config_path,)
|
||||
|
||||
# Route user directory requests to this worker
|
||||
nginx_config_body += """
|
||||
location ~* (^/_matrix/media/.*$|^/_synapse/admin/v1/(purge_media_cache$|(room|user)/.*/media.*$|media/.*$|quarantine_media/.*$) {
|
||||
proxy_pass http://localhost:8010;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
}
|
||||
"""
|
||||
|
||||
# Write out the config files
|
||||
|
||||
# Shared homeserver config
|
||||
print(homeserver_config)
|
||||
with open("/conf/workers/shared.yaml", "w") as f:
|
||||
f.write(homeserver_config)
|
||||
|
||||
# Nginx config
|
||||
print()
|
||||
print(nginx_config_template_header)
|
||||
print(nginx_config_body)
|
||||
print(nginx_config_template_end)
|
||||
with open("/etc/nginx/conf.d/matrix-synapse.conf", "w") as f:
|
||||
f.write(nginx_config_template_header)
|
||||
f.write(nginx_config_body)
|
||||
f.write(nginx_config_template_end)
|
||||
|
||||
# Supervisord config
|
||||
print()
|
||||
print(supervisord_config)
|
||||
with open("/etc/supervisor/conf.d/supervisord.conf", "w") as f:
|
||||
f.write(supervisord_config)
|
||||
|
||||
# Generate worker log config files from the templates.
|
||||
# The templates are mainly there so that we can inject some environment variable
|
||||
# values into them.
|
||||
log_config_template_dir = "/conf/workers/log_config_templates/"
|
||||
log_config_dir = "/conf/workers/"
|
||||
for log_config_filename in os.listdir(log_config_template_dir):
|
||||
template_path = log_config_template_dir + log_config_filename
|
||||
out_path = log_config_dir + log_config_filename
|
||||
|
||||
convert(template_path, out_path, environ)
|
||||
|
||||
# Ensure the logging directory exists
|
||||
log_dir = data_dir + "/logs"
|
||||
if not os.path.exists(log_dir):
|
||||
os.mkdir(log_dir)
|
||||
|
||||
|
||||
def start_supervisord():
|
||||
"""Starts up supervisord which then starts and monitors all other necessary processes
|
||||
|
||||
Raises: CalledProcessError if calling start.py return a non-zero exit code.
|
||||
"""
|
||||
subprocess.check_output(["/usr/bin/supervisord"])
|
||||
|
||||
|
||||
def main(args, environ):
|
||||
config_dir = environ.get("SYNAPSE_CONFIG_DIR", "/data")
|
||||
config_path = environ.get("SYNAPSE_CONFIG_PATH", config_dir + "/homeserver.yaml")
|
||||
data_dir = environ.get("SYNAPSE_DATA_DIR", "/data")
|
||||
|
||||
# Generate the base homeserver config if one does not yet exist
|
||||
if not os.path.exists(config_path):
|
||||
log("Generating base homeserver config")
|
||||
generate_base_homeserver_config()
|
||||
|
||||
# Always regenerate all other config files
|
||||
generate_worker_files(environ, config_path, data_dir)
|
||||
|
||||
# Start supervisord, which will start Synapse, all of the configured worker
|
||||
# processes, redis, nginx etc. according to the config we created above.
|
||||
start_supervisord()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv, os.environ)
|
||||
@@ -177,7 +177,6 @@ def run_generate_config(environ, ownership):
|
||||
else:
|
||||
os.execv("/usr/local/bin/python", args)
|
||||
|
||||
|
||||
def main(args, environ):
|
||||
mode = args[1] if len(args) > 1 else "run"
|
||||
desired_uid = int(environ.get("UID", "991"))
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
version: 1
|
||||
|
||||
formatters:
|
||||
precise:
|
||||
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
|
||||
|
||||
handlers:
|
||||
file:
|
||||
class: logging.handlers.TimedRotatingFileHandler
|
||||
formatter: precise
|
||||
filename: "{{ SYNAPSE_DATA_DIR or '/data' }}/logs/pusher1.log"
|
||||
when: midnight
|
||||
backupCount: 3 # Does not include the current log file.
|
||||
encoding: utf8
|
||||
|
||||
console:
|
||||
class: logging.StreamHandler
|
||||
formatter: precise
|
||||
|
||||
loggers:
|
||||
synapse.storage.SQL:
|
||||
# beware: increasing this to DEBUG will make synapse log sensitive
|
||||
# information such as access tokens.
|
||||
level: INFO
|
||||
|
||||
root:
|
||||
level: {{ SYNAPSE_LOG_LEVEL or "INFO" }}
|
||||
handlers: [console]
|
||||
|
||||
disable_existing_loggers: false
|
||||
@@ -0,0 +1,30 @@
|
||||
version: 1
|
||||
|
||||
formatters:
|
||||
precise:
|
||||
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
|
||||
|
||||
handlers:
|
||||
file:
|
||||
class: logging.handlers.TimedRotatingFileHandler
|
||||
formatter: precise
|
||||
filename: "{{ SYNAPSE_DATA_DIR or '/data' }}/logs/pusher1.log"
|
||||
when: midnight
|
||||
backupCount: 3 # Does not include the current log file.
|
||||
encoding: utf8
|
||||
|
||||
console:
|
||||
class: logging.StreamHandler
|
||||
formatter: precise
|
||||
|
||||
loggers:
|
||||
synapse.storage.SQL:
|
||||
# beware: increasing this to DEBUG will make synapse log sensitive
|
||||
# information such as access tokens.
|
||||
level: INFO
|
||||
|
||||
root:
|
||||
level: {{ SYNAPSE_LOG_LEVEL or "INFO" }}
|
||||
handlers: [console]
|
||||
|
||||
disable_existing_loggers: false
|
||||
@@ -0,0 +1,13 @@
|
||||
worker_app: synapse.app.pusher
|
||||
worker_name: pusher
|
||||
|
||||
# The replication listener on the main synapse process.
|
||||
worker_replication_host: 127.0.0.1
|
||||
worker_replication_http_port: 9093
|
||||
|
||||
worker_listeners:
|
||||
- type: http
|
||||
port: 8083
|
||||
resources: []
|
||||
|
||||
worker_log_config: /conf/workers/pusher_log.yaml
|
||||
@@ -0,0 +1,13 @@
|
||||
worker_app: synapse.app.user_dir
|
||||
worker_name: user_dir
|
||||
|
||||
# The replication listener on the main synapse process.
|
||||
worker_replication_host: 127.0.0.1
|
||||
worker_replication_http_port: 9093
|
||||
|
||||
worker_listeners:
|
||||
- type: http
|
||||
port: 8084
|
||||
resources: []
|
||||
|
||||
worker_log_config: /conf/workers/user_dir_log.yaml
|
||||
@@ -1,6 +1,18 @@
|
||||
# Contents
|
||||
- [List all media in a room](#list-all-media-in-a-room)
|
||||
- [Quarantine media](#quarantine-media)
|
||||
* [Quarantining media by ID](#quarantining-media-by-id)
|
||||
* [Quarantining media in a room](#quarantining-media-in-a-room)
|
||||
* [Quarantining all media of a user](#quarantining-all-media-of-a-user)
|
||||
- [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)
|
||||
- [Purge Remote Media API](#purge-remote-media-api)
|
||||
|
||||
# List all media in a room
|
||||
|
||||
This API gets a list of known media in a room.
|
||||
However, it only shows media from unencrypted events or rooms.
|
||||
|
||||
The API is:
|
||||
```
|
||||
@@ -10,16 +22,16 @@ To use it, you will need to authenticate by providing an `access_token` for a
|
||||
server admin: see [README.rst](README.rst).
|
||||
|
||||
The API returns a JSON body like the following:
|
||||
```
|
||||
```json
|
||||
{
|
||||
"local": [
|
||||
"mxc://localhost/xwvutsrqponmlkjihgfedcba",
|
||||
"mxc://localhost/abcdefghijklmnopqrstuvwx"
|
||||
],
|
||||
"remote": [
|
||||
"mxc://matrix.org/xwvutsrqponmlkjihgfedcba",
|
||||
"mxc://matrix.org/abcdefghijklmnopqrstuvwx"
|
||||
]
|
||||
"local": [
|
||||
"mxc://localhost/xwvutsrqponmlkjihgfedcba",
|
||||
"mxc://localhost/abcdefghijklmnopqrstuvwx"
|
||||
],
|
||||
"remote": [
|
||||
"mxc://matrix.org/xwvutsrqponmlkjihgfedcba",
|
||||
"mxc://matrix.org/abcdefghijklmnopqrstuvwx"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
@@ -47,7 +59,7 @@ form of `abcdefg12345...`.
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```json
|
||||
{}
|
||||
```
|
||||
|
||||
@@ -67,14 +79,18 @@ Where `room_id` is in the form of `!roomid12345:example.org`.
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```json
|
||||
{
|
||||
"num_quarantined": 10 # The number of media items successfully quarantined
|
||||
"num_quarantined": 10
|
||||
}
|
||||
```
|
||||
|
||||
The following fields are returned in the JSON response body:
|
||||
|
||||
* `num_quarantined`: integer - The number of media items successfully quarantined
|
||||
|
||||
Note that there is a legacy endpoint, `POST
|
||||
/_synapse/admin/v1/quarantine_media/<room_id >`, that operates the same.
|
||||
/_synapse/admin/v1/quarantine_media/<room_id>`, that operates the same.
|
||||
However, it is deprecated and may be removed in a future release.
|
||||
|
||||
## Quarantining all media of a user
|
||||
@@ -91,23 +107,29 @@ POST /_synapse/admin/v1/user/<user_id>/media/quarantine
|
||||
{}
|
||||
```
|
||||
|
||||
Where `user_id` is in the form of `@bob:example.org`.
|
||||
URL Parameters
|
||||
|
||||
* `user_id`: string - User ID in the form of `@bob:example.org`
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```json
|
||||
{
|
||||
"num_quarantined": 10 # The number of media items successfully quarantined
|
||||
"num_quarantined": 10
|
||||
}
|
||||
```
|
||||
|
||||
The following fields are returned in the JSON response body:
|
||||
|
||||
* `num_quarantined`: integer - The number of media items successfully quarantined
|
||||
|
||||
# Delete local media
|
||||
This API deletes the *local* media from the disk of your own server.
|
||||
This includes any local thumbnails and copies of media downloaded from
|
||||
remote homeservers.
|
||||
This API will not affect media that has been uploaded to external
|
||||
media repositories (e.g https://github.com/turt2live/matrix-media-repo/).
|
||||
See also [purge_remote_media.rst](purge_remote_media.rst).
|
||||
See also [Purge Remote Media API](#purge-remote-media-api).
|
||||
|
||||
## Delete a specific local media
|
||||
Delete a specific `media_id`.
|
||||
@@ -128,12 +150,12 @@ URL Parameters
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"deleted_media": [
|
||||
"abcdefghijklmnopqrstuvwx"
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
{
|
||||
"deleted_media": [
|
||||
"abcdefghijklmnopqrstuvwx"
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
The following fields are returned in the JSON response body:
|
||||
@@ -166,16 +188,51 @@ If `false` these files will be deleted. Defaults to `true`.
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"deleted_media": [
|
||||
"abcdefghijklmnopqrstuvwx",
|
||||
"abcdefghijklmnopqrstuvwz"
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
{
|
||||
"deleted_media": [
|
||||
"abcdefghijklmnopqrstuvwx",
|
||||
"abcdefghijklmnopqrstuvwz"
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
```
|
||||
|
||||
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`
|
||||
|
||||
# Purge Remote Media API
|
||||
|
||||
The purge remote media API allows server admins to purge old cached remote media.
|
||||
|
||||
The API is:
|
||||
|
||||
```
|
||||
POST /_synapse/admin/v1/purge_media_cache?before_ts=<unix_timestamp_in_ms>
|
||||
|
||||
{}
|
||||
```
|
||||
|
||||
URL Parameters
|
||||
|
||||
* `unix_timestamp_in_ms`: string representing a positive integer - Unix timestamp in ms.
|
||||
All cached media that was last accessed before this timestamp will be removed.
|
||||
|
||||
Response:
|
||||
|
||||
```json
|
||||
{
|
||||
"deleted": 10
|
||||
}
|
||||
```
|
||||
|
||||
The following fields are returned in the JSON response body:
|
||||
|
||||
* `deleted`: integer - The number of media items successfully deleted
|
||||
|
||||
To use it, you will need to authenticate by providing an `access_token` for a
|
||||
server admin: see [README.rst](README.rst).
|
||||
|
||||
If the user re-requests purged remote media, synapse will re-request the media
|
||||
from the originating server.
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
Purge Remote Media API
|
||||
======================
|
||||
|
||||
The purge remote media API allows server admins to purge old cached remote
|
||||
media.
|
||||
|
||||
The API is::
|
||||
|
||||
POST /_synapse/admin/v1/purge_media_cache?before_ts=<unix_timestamp_in_ms>
|
||||
|
||||
{}
|
||||
|
||||
\... which will remove all cached media that was last accessed before
|
||||
``<unix_timestamp_in_ms>``.
|
||||
|
||||
To use it, you will need to authenticate by providing an ``access_token`` for a
|
||||
server admin: see `README.rst <README.rst>`_.
|
||||
|
||||
If the user re-requests purged remote media, synapse will re-request the media
|
||||
from the originating server.
|
||||
@@ -1,12 +1,13 @@
|
||||
Purge room API
|
||||
==============
|
||||
Deprecated: Purge room API
|
||||
==========================
|
||||
|
||||
**The old Purge room API is deprecated and will be removed in a future release.
|
||||
See the new [Delete Room API](rooms.md#delete-room-api) for more details.**
|
||||
|
||||
This API will remove all trace of a room from your database.
|
||||
|
||||
All local users must have left the room before it can be removed.
|
||||
|
||||
See also: [Delete Room API](rooms.md#delete-room-api)
|
||||
|
||||
The API is:
|
||||
|
||||
```
|
||||
|
||||
+56
-14
@@ -1,3 +1,14 @@
|
||||
# Contents
|
||||
- [List Room API](#list-room-api)
|
||||
* [Parameters](#parameters)
|
||||
* [Usage](#usage)
|
||||
- [Room Details API](#room-details-api)
|
||||
- [Room Members API](#room-members-api)
|
||||
- [Delete Room API](#delete-room-api)
|
||||
* [Parameters](#parameters-1)
|
||||
* [Response](#response)
|
||||
* [Undoing room shutdowns](#undoing-room-shutdowns)
|
||||
|
||||
# List Room API
|
||||
|
||||
The List Room admin API allows server admins to get a list of rooms on their
|
||||
@@ -76,7 +87,7 @@ GET /_synapse/admin/v1/rooms
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```jsonc
|
||||
{
|
||||
"rooms": [
|
||||
{
|
||||
@@ -128,7 +139,7 @@ GET /_synapse/admin/v1/rooms?search_term=TWIM
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```json
|
||||
{
|
||||
"rooms": [
|
||||
{
|
||||
@@ -163,7 +174,7 @@ GET /_synapse/admin/v1/rooms?order_by=size
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```jsonc
|
||||
{
|
||||
"rooms": [
|
||||
{
|
||||
@@ -219,14 +230,14 @@ GET /_synapse/admin/v1/rooms?order_by=size&from=100
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```jsonc
|
||||
{
|
||||
"rooms": [
|
||||
{
|
||||
"room_id": "!mscvqgqpHYjBGDxNym:matrix.org",
|
||||
"name": "Music Theory",
|
||||
"canonical_alias": "#musictheory:matrix.org",
|
||||
"joined_members": 127
|
||||
"joined_members": 127,
|
||||
"joined_local_members": 2,
|
||||
"version": "1",
|
||||
"creator": "@foo:matrix.org",
|
||||
@@ -243,7 +254,7 @@ Response:
|
||||
"room_id": "!twcBhHVdZlQWuuxBhN:termina.org.uk",
|
||||
"name": "weechat-matrix",
|
||||
"canonical_alias": "#weechat-matrix:termina.org.uk",
|
||||
"joined_members": 137
|
||||
"joined_members": 137,
|
||||
"joined_local_members": 20,
|
||||
"version": "4",
|
||||
"creator": "@foo:termina.org.uk",
|
||||
@@ -278,6 +289,7 @@ The following fields are possible in the JSON response body:
|
||||
* `canonical_alias` - The canonical (main) alias address of the room.
|
||||
* `joined_members` - How many users are currently in the room.
|
||||
* `joined_local_members` - How many local users are currently in the room.
|
||||
* `joined_local_devices` - How many local devices are currently in the room.
|
||||
* `version` - The version of the room as a string.
|
||||
* `creator` - The `user_id` of the room creator.
|
||||
* `encryption` - Algorithm of end-to-end encryption of messages. Is `null` if encryption is not active.
|
||||
@@ -300,15 +312,16 @@ GET /_synapse/admin/v1/rooms/<room_id>
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```json
|
||||
{
|
||||
"room_id": "!mscvqgqpHYjBGDxNym:matrix.org",
|
||||
"name": "Music Theory",
|
||||
"avatar": "mxc://matrix.org/AQDaVFlbkQoErdOgqWRgiGSV",
|
||||
"topic": "Theory, Composition, Notation, Analysis",
|
||||
"canonical_alias": "#musictheory:matrix.org",
|
||||
"joined_members": 127
|
||||
"joined_members": 127,
|
||||
"joined_local_members": 2,
|
||||
"joined_local_devices": 2,
|
||||
"version": "1",
|
||||
"creator": "@foo:matrix.org",
|
||||
"encryption": null,
|
||||
@@ -342,13 +355,13 @@ GET /_synapse/admin/v1/rooms/<room_id>/members
|
||||
|
||||
Response:
|
||||
|
||||
```
|
||||
```json
|
||||
{
|
||||
"members": [
|
||||
"@foo:matrix.org",
|
||||
"@bar:matrix.org",
|
||||
"@foobar:matrix.org
|
||||
],
|
||||
"@foobar:matrix.org"
|
||||
],
|
||||
"total": 3
|
||||
}
|
||||
```
|
||||
@@ -357,8 +370,6 @@ Response:
|
||||
|
||||
The Delete Room admin API allows server admins to remove rooms from server
|
||||
and block these rooms.
|
||||
It is a combination and improvement of "[Shutdown room](shutdown_room.md)"
|
||||
and "[Purge room](purge_room.md)" API.
|
||||
|
||||
Shuts down a room. Moves all local users and room aliases automatically to a
|
||||
new room if `new_room_user_id` is set. Otherwise local users only
|
||||
@@ -382,7 +393,7 @@ the new room. Users on other servers will be unaffected.
|
||||
|
||||
The API is:
|
||||
|
||||
```json
|
||||
```
|
||||
POST /_synapse/admin/v1/rooms/<room_id>/delete
|
||||
```
|
||||
|
||||
@@ -439,6 +450,10 @@ The following JSON body parameters are available:
|
||||
future attempts to join the room. Defaults to `false`.
|
||||
* `purge` - Optional. If set to `true`, it will remove all traces of the room from your database.
|
||||
Defaults to `true`.
|
||||
* `force_purge` - Optional, and ignored unless `purge` is `true`. If set to `true`, it
|
||||
will force a purge to go ahead even if there are local users still in the room. Do not
|
||||
use this unless a regular `purge` operation fails, as it could leave those users'
|
||||
clients in a confused state.
|
||||
|
||||
The JSON body must not be empty. The body must be at least `{}`.
|
||||
|
||||
@@ -451,3 +466,30 @@ The following fields are returned in the JSON response body:
|
||||
* `local_aliases` - An array of strings representing the local aliases that were migrated from
|
||||
the old room to the new.
|
||||
* `new_room_id` - A string representing the room ID of the new room.
|
||||
|
||||
## Undoing room shutdowns
|
||||
|
||||
*Note*: This guide may be outdated by the time you read it. By nature of room shutdowns being performed at the database level,
|
||||
the structure can and does change without notice.
|
||||
|
||||
First, it's important to understand that a room shutdown is very destructive. Undoing a shutdown is not as simple as pretending it
|
||||
never happened - work has to be done to move forward instead of resetting the past. In fact, in some cases it might not be possible
|
||||
to recover at all:
|
||||
|
||||
* If the room was invite-only, your users will need to be re-invited.
|
||||
* If the room no longer has any members at all, it'll be impossible to rejoin.
|
||||
* The first user to rejoin will have to do so via an alias on a different server.
|
||||
|
||||
With all that being said, if you still want to try and recover the room:
|
||||
|
||||
1. For safety reasons, shut down Synapse.
|
||||
2. In the database, run `DELETE FROM blocked_rooms WHERE room_id = '!example:example.org';`
|
||||
* For caution: it's recommended to run this in a transaction: `BEGIN; DELETE ...;`, verify you got 1 result, then `COMMIT;`.
|
||||
* The room ID is the same one supplied to the shutdown room API, not the Content Violation room.
|
||||
3. Restart Synapse.
|
||||
|
||||
You will have to manually handle, if you so choose, the following:
|
||||
|
||||
* Aliases that would have been redirected to the Content Violation room.
|
||||
* Users that would have been booted from the room (and will have been force-joined to the Content Violation room).
|
||||
* Removal of the Content Violation room if desired.
|
||||
@@ -1,4 +1,7 @@
|
||||
# Shutdown room API
|
||||
# Deprecated: Shutdown room API
|
||||
|
||||
**The old Shutdown room API is deprecated and will be removed in a future release.
|
||||
See the new [Delete Room API](rooms.md#delete-room-api) for more details.**
|
||||
|
||||
Shuts down a room, preventing new joins and moves local users and room aliases automatically
|
||||
to a new room. The new room will be created with the user specified by the
|
||||
@@ -10,8 +13,6 @@ disallow any further invites or joins.
|
||||
The local server will only have the power to move local user and room aliases to
|
||||
the new room. Users on other servers will be unaffected.
|
||||
|
||||
See also: [Delete Room API](rooms.md#delete-room-api)
|
||||
|
||||
## API
|
||||
|
||||
You will need to authenticate with an access token for an admin user.
|
||||
|
||||
@@ -176,6 +176,13 @@ The api is::
|
||||
|
||||
GET /_synapse/admin/v1/whois/<user_id>
|
||||
|
||||
and::
|
||||
|
||||
GET /_matrix/client/r0/admin/whois/<userId>
|
||||
|
||||
See also: `Client Server API Whois
|
||||
<https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-admin-whois-userid>`_
|
||||
|
||||
To use it, you will need to authenticate by providing an ``access_token`` for a
|
||||
server admin: see `README.rst <README.rst>`_.
|
||||
|
||||
@@ -254,7 +261,7 @@ with a body of:
|
||||
|
||||
{
|
||||
"new_password": "<secret>",
|
||||
"logout_devices": true,
|
||||
"logout_devices": true
|
||||
}
|
||||
|
||||
To use it, you will need to authenticate by providing an ``access_token`` for a
|
||||
@@ -424,6 +431,41 @@ The following fields are returned in the JSON response body:
|
||||
- ``next_token``: integer - Indication for pagination. See above.
|
||||
- ``total`` - integer - Total number of media.
|
||||
|
||||
Login as a user
|
||||
===============
|
||||
|
||||
Get an access token that can be used to authenticate as that user. Useful for
|
||||
when admins wish to do actions on behalf of a user.
|
||||
|
||||
The API is::
|
||||
|
||||
POST /_synapse/admin/v1/users/<user_id>/login
|
||||
{}
|
||||
|
||||
An optional ``valid_until_ms`` field can be specified in the request body as an
|
||||
integer timestamp that specifies when the token should expire. By default tokens
|
||||
do not expire.
|
||||
|
||||
A response body like the following is returned:
|
||||
|
||||
.. code:: json
|
||||
|
||||
{
|
||||
"access_token": "<opaque_access_token_string>"
|
||||
}
|
||||
|
||||
|
||||
This API does *not* generate a new device for the user, and so will not appear
|
||||
their ``/devices`` list, and in general the target user should not be able to
|
||||
tell they have been logged in as.
|
||||
|
||||
To expire the token call the standard ``/logout`` API with the token.
|
||||
|
||||
Note: The token will expire if the *admin* user calls ``/logout/all`` from any
|
||||
of their devices, but the token will *not* expire if the target user does the
|
||||
same.
|
||||
|
||||
|
||||
User devices
|
||||
============
|
||||
|
||||
|
||||
+57
-17
@@ -13,10 +13,12 @@
|
||||
can be enabled by adding the \"metrics\" resource to the existing
|
||||
listener as such:
|
||||
|
||||
resources:
|
||||
- names:
|
||||
- client
|
||||
- metrics
|
||||
```yaml
|
||||
resources:
|
||||
- names:
|
||||
- client
|
||||
- metrics
|
||||
```
|
||||
|
||||
This provides a simple way of adding metrics to your Synapse
|
||||
installation, and serves under `/_synapse/metrics`. If you do not
|
||||
@@ -31,11 +33,13 @@
|
||||
|
||||
Add a new listener to homeserver.yaml:
|
||||
|
||||
listeners:
|
||||
- type: metrics
|
||||
port: 9000
|
||||
bind_addresses:
|
||||
- '0.0.0.0'
|
||||
```yaml
|
||||
listeners:
|
||||
- type: metrics
|
||||
port: 9000
|
||||
bind_addresses:
|
||||
- '0.0.0.0'
|
||||
```
|
||||
|
||||
For both options, you will need to ensure that `enable_metrics` is
|
||||
set to `True`.
|
||||
@@ -47,10 +51,13 @@
|
||||
It needs to set the `metrics_path` to a non-default value (under
|
||||
`scrape_configs`):
|
||||
|
||||
- job_name: "synapse"
|
||||
metrics_path: "/_synapse/metrics"
|
||||
static_configs:
|
||||
- targets: ["my.server.here:port"]
|
||||
```yaml
|
||||
- job_name: "synapse"
|
||||
scrape_interval: 15s
|
||||
metrics_path: "/_synapse/metrics"
|
||||
static_configs:
|
||||
- targets: ["my.server.here:port"]
|
||||
```
|
||||
|
||||
where `my.server.here` is the IP address of Synapse, and `port` is
|
||||
the listener port configured with the `metrics` resource.
|
||||
@@ -60,7 +67,8 @@
|
||||
|
||||
1. Restart Prometheus.
|
||||
|
||||
1. Consider using the [grafana dashboard](https://github.com/matrix-org/synapse/tree/master/contrib/grafana/) and required [recording rules](https://github.com/matrix-org/synapse/tree/master/contrib/prometheus/)
|
||||
1. Consider using the [grafana dashboard](https://github.com/matrix-org/synapse/tree/master/contrib/grafana/)
|
||||
and required [recording rules](https://github.com/matrix-org/synapse/tree/master/contrib/prometheus/)
|
||||
|
||||
## Monitoring workers
|
||||
|
||||
@@ -76,9 +84,9 @@ To allow collecting metrics from a worker, you need to add a
|
||||
under `worker_listeners`:
|
||||
|
||||
```yaml
|
||||
- type: metrics
|
||||
bind_address: ''
|
||||
port: 9101
|
||||
- type: metrics
|
||||
bind_address: ''
|
||||
port: 9101
|
||||
```
|
||||
|
||||
The `bind_address` and `port` parameters should be set so that
|
||||
@@ -87,6 +95,38 @@ don't clash with an existing worker.
|
||||
With this example, the worker's metrics would then be available
|
||||
on `http://127.0.0.1:9101`.
|
||||
|
||||
Example Prometheus target for Synapse with workers:
|
||||
|
||||
```yaml
|
||||
- job_name: "synapse"
|
||||
scrape_interval: 15s
|
||||
metrics_path: "/_synapse/metrics"
|
||||
static_configs:
|
||||
- targets: ["my.server.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "master"
|
||||
index: 1
|
||||
- targets: ["my.workerserver.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "generic_worker"
|
||||
index: 1
|
||||
- targets: ["my.workerserver.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "generic_worker"
|
||||
index: 2
|
||||
- targets: ["my.workerserver.here:port"]
|
||||
labels:
|
||||
instance: "my.server"
|
||||
job: "media_repository"
|
||||
index: 1
|
||||
```
|
||||
|
||||
Labels (`instance`, `job`, `index`) can be defined as anything.
|
||||
The labels are used to group graphs in grafana.
|
||||
|
||||
## Renaming of metrics & deprecation of old names in 1.2
|
||||
|
||||
Synapse 1.2 updates the Prometheus metrics to match the naming
|
||||
|
||||
@@ -26,6 +26,7 @@ Password auth provider classes must provide the following methods:
|
||||
|
||||
It should perform any appropriate sanity checks on the provided
|
||||
configuration, and return an object which is then passed into
|
||||
`__init__`.
|
||||
|
||||
This method should have the `@staticmethod` decoration.
|
||||
|
||||
|
||||
+156
-94
@@ -144,6 +144,35 @@ pid_file: DATADIR/homeserver.pid
|
||||
#
|
||||
#enable_search: false
|
||||
|
||||
# Prevent outgoing requests from being sent to the following blacklisted IP address
|
||||
# CIDR ranges. If this option is not specified then it defaults to private IP
|
||||
# address ranges (see the example below).
|
||||
#
|
||||
# The blacklist applies to the outbound requests for federation, identity servers,
|
||||
# push servers, and for checking key validity for third-party invite events.
|
||||
#
|
||||
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
|
||||
# listed here, since they correspond to unroutable addresses.)
|
||||
#
|
||||
# This option replaces federation_ip_range_blacklist in Synapse v1.25.0.
|
||||
#
|
||||
#ip_range_blacklist:
|
||||
# - '127.0.0.0/8'
|
||||
# - '10.0.0.0/8'
|
||||
# - '172.16.0.0/12'
|
||||
# - '192.168.0.0/16'
|
||||
# - '100.64.0.0/10'
|
||||
# - '192.0.0.0/24'
|
||||
# - '169.254.0.0/16'
|
||||
# - '198.18.0.0/15'
|
||||
# - '192.0.2.0/24'
|
||||
# - '198.51.100.0/24'
|
||||
# - '203.0.113.0/24'
|
||||
# - '224.0.0.0/4'
|
||||
# - '::1/128'
|
||||
# - 'fe80::/10'
|
||||
# - 'fc00::/7'
|
||||
|
||||
# List of ports that Synapse should listen on, their purpose and their
|
||||
# configuration.
|
||||
#
|
||||
@@ -642,26 +671,17 @@ acme:
|
||||
# - nyc.example.com
|
||||
# - syd.example.com
|
||||
|
||||
# Prevent federation requests from being sent to the following
|
||||
# blacklist IP address CIDR ranges. If this option is not specified, or
|
||||
# specified with an empty list, no ip range blacklist will be enforced.
|
||||
# List of IP address CIDR ranges that should be allowed for federation,
|
||||
# identity servers, push servers, and for checking key validity for
|
||||
# third-party invite events. This is useful for specifying exceptions to
|
||||
# wide-ranging blacklisted target IP ranges - e.g. for communication with
|
||||
# a push server only visible in your network.
|
||||
#
|
||||
# As of Synapse v1.4.0 this option also affects any outbound requests to identity
|
||||
# servers provided by user input.
|
||||
# This whitelist overrides ip_range_blacklist and defaults to an empty
|
||||
# list.
|
||||
#
|
||||
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
|
||||
# listed here, since they correspond to unroutable addresses.)
|
||||
#
|
||||
federation_ip_range_blacklist:
|
||||
- '127.0.0.0/8'
|
||||
- '10.0.0.0/8'
|
||||
- '172.16.0.0/12'
|
||||
- '192.168.0.0/16'
|
||||
- '100.64.0.0/10'
|
||||
- '169.254.0.0/16'
|
||||
- '::1/128'
|
||||
- 'fe80::/64'
|
||||
- 'fc00::/7'
|
||||
#ip_range_whitelist:
|
||||
# - '192.168.1.1'
|
||||
|
||||
# Report prometheus metrics on the age of PDUs being sent to and received from
|
||||
# the following domains. This can be used to give an idea of "delay" on inbound
|
||||
@@ -953,9 +973,15 @@ media_store_path: "DATADIR/media_store"
|
||||
# - '172.16.0.0/12'
|
||||
# - '192.168.0.0/16'
|
||||
# - '100.64.0.0/10'
|
||||
# - '192.0.0.0/24'
|
||||
# - '169.254.0.0/16'
|
||||
# - '198.18.0.0/15'
|
||||
# - '192.0.2.0/24'
|
||||
# - '198.51.100.0/24'
|
||||
# - '203.0.113.0/24'
|
||||
# - '224.0.0.0/4'
|
||||
# - '::1/128'
|
||||
# - 'fe80::/64'
|
||||
# - 'fe80::/10'
|
||||
# - 'fc00::/7'
|
||||
|
||||
# List of IP address CIDR ranges that the URL preview spider is allowed
|
||||
@@ -1085,15 +1111,8 @@ url_preview_accept_language:
|
||||
#turn_allow_guests: true
|
||||
|
||||
|
||||
## Registration ##
|
||||
## Account Validity ##
|
||||
#
|
||||
# Registration can be rate-limited using the parameters in the "Ratelimiting"
|
||||
# section of this file.
|
||||
|
||||
# Enable registration for new users.
|
||||
#
|
||||
#enable_registration: false
|
||||
|
||||
# Optional account validity configuration. This allows for accounts to be denied
|
||||
# any request after a given period.
|
||||
#
|
||||
@@ -1105,57 +1124,67 @@ url_preview_accept_language:
|
||||
# after that the validity period changes and Synapse is restarted, the users'
|
||||
# expiration dates won't be updated unless their account is manually renewed. This
|
||||
# date will be randomly selected within a range [now + period - d ; now + period],
|
||||
# where d is equal to 10% of the validity period.
|
||||
# where d is equal to 10%% of the validity period.
|
||||
#
|
||||
account_validity:
|
||||
# The account validity feature is disabled by default. Uncomment the
|
||||
# following line to enable it.
|
||||
#
|
||||
#enabled: true
|
||||
# The account validity feature is disabled by default. Uncomment the
|
||||
# following line to enable it.
|
||||
#
|
||||
#enabled: true
|
||||
|
||||
# The period after which an account is valid after its registration. When
|
||||
# renewing the account, its validity period will be extended by this amount
|
||||
# of time. This parameter is required when using the account validity
|
||||
# feature.
|
||||
#
|
||||
#period: 6w
|
||||
# The period after which an account is valid after its registration. When
|
||||
# renewing the account, its validity period will be extended by this amount
|
||||
# of time. This parameter is required when using the account validity
|
||||
# feature.
|
||||
#
|
||||
#period: 6w
|
||||
|
||||
# The amount of time before an account's expiry date at which Synapse will
|
||||
# send an email to the account's email address with a renewal link. By
|
||||
# default, no such emails are sent.
|
||||
#
|
||||
# If you enable this setting, you will also need to fill out the 'email' and
|
||||
# 'public_baseurl' configuration sections.
|
||||
#
|
||||
#renew_at: 1w
|
||||
# The amount of time before an account's expiry date at which Synapse will
|
||||
# send an email to the account's email address with a renewal link. By
|
||||
# default, no such emails are sent.
|
||||
#
|
||||
# If you enable this setting, you will also need to fill out the 'email' and
|
||||
# 'public_baseurl' configuration sections.
|
||||
#
|
||||
#renew_at: 1w
|
||||
|
||||
# The subject of the email sent out with the renewal link. '%(app)s' can be
|
||||
# used as a placeholder for the 'app_name' parameter from the 'email'
|
||||
# section.
|
||||
#
|
||||
# Note that the placeholder must be written '%(app)s', including the
|
||||
# trailing 's'.
|
||||
#
|
||||
# If this is not set, a default value is used.
|
||||
#
|
||||
#renew_email_subject: "Renew your %(app)s account"
|
||||
# The subject of the email sent out with the renewal link. '%%(app)s' can be
|
||||
# used as a placeholder for the 'app_name' parameter from the 'email'
|
||||
# section.
|
||||
#
|
||||
# Note that the placeholder must be written '%%(app)s', including the
|
||||
# trailing 's'.
|
||||
#
|
||||
# If this is not set, a default value is used.
|
||||
#
|
||||
#renew_email_subject: "Renew your %%(app)s account"
|
||||
|
||||
# Directory in which Synapse will try to find templates for the HTML files to
|
||||
# serve to the user when trying to renew an account. If not set, default
|
||||
# templates from within the Synapse package will be used.
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
# Directory in which Synapse will try to find templates for the HTML files to
|
||||
# serve to the user when trying to renew an account. If not set, default
|
||||
# templates from within the Synapse package will be used.
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
|
||||
# File within 'template_dir' giving the HTML to be displayed to the user after
|
||||
# they successfully renewed their account. If not set, default text is used.
|
||||
#
|
||||
#account_renewed_html_path: "account_renewed.html"
|
||||
# File within 'template_dir' giving the HTML to be displayed to the user after
|
||||
# they successfully renewed their account. If not set, default text is used.
|
||||
#
|
||||
#account_renewed_html_path: "account_renewed.html"
|
||||
|
||||
# File within 'template_dir' giving the HTML to be displayed when the user
|
||||
# tries to renew an account with an invalid renewal token. If not set,
|
||||
# default text is used.
|
||||
#
|
||||
#invalid_token_html_path: "invalid_token.html"
|
||||
# File within 'template_dir' giving the HTML to be displayed when the user
|
||||
# tries to renew an account with an invalid renewal token. If not set,
|
||||
# default text is used.
|
||||
#
|
||||
#invalid_token_html_path: "invalid_token.html"
|
||||
|
||||
|
||||
## Registration ##
|
||||
#
|
||||
# Registration can be rate-limited using the parameters in the "Ratelimiting"
|
||||
# section of this file.
|
||||
|
||||
# Enable registration for new users.
|
||||
#
|
||||
#enable_registration: false
|
||||
|
||||
# Time that a user's session remains valid for, after they log in.
|
||||
#
|
||||
@@ -1230,8 +1259,9 @@ account_validity:
|
||||
# email will be globally disabled.
|
||||
#
|
||||
# Additionally, if `msisdn` is not set, registration and password resets via msisdn
|
||||
# will be disabled regardless. This is due to Synapse currently not supporting any
|
||||
# method of sending SMS messages on its own.
|
||||
# will be disabled regardless, and users will not be able to associate an msisdn
|
||||
# identifier to their account. This is due to Synapse currently not supporting
|
||||
# any method of sending SMS messages on its own.
|
||||
#
|
||||
# To enable using an identity server for operations regarding a particular third-party
|
||||
# identifier type, set the value to the URL of that identity server as shown in the
|
||||
@@ -1545,6 +1575,12 @@ saml2_config:
|
||||
# remote:
|
||||
# - url: https://our_idp/metadata.xml
|
||||
|
||||
# Allowed clock difference in seconds between the homeserver and IdP.
|
||||
#
|
||||
# Uncomment the below to increase the accepted time difference from 0 to 3 seconds.
|
||||
#
|
||||
#accepted_time_diff: 3
|
||||
|
||||
# By default, the user has to go to our login page first. If you'd like
|
||||
# to allow IdP-initiated login, set 'allow_unsolicited: true' in a
|
||||
# 'service.sp' section:
|
||||
@@ -1667,6 +1703,14 @@ saml2_config:
|
||||
# - attribute: department
|
||||
# value: "sales"
|
||||
|
||||
# If the metadata XML contains multiple IdP entities then the `idp_entityid`
|
||||
# option must be set to the entity to redirect users to.
|
||||
#
|
||||
# Most deployments only have a single IdP entity and so should omit this
|
||||
# option.
|
||||
#
|
||||
#idp_entityid: 'https://our_idp/entityid'
|
||||
|
||||
|
||||
# Enable OpenID Connect (OIDC) / OAuth 2.0 for registration and login.
|
||||
#
|
||||
@@ -1862,11 +1906,8 @@ sso:
|
||||
# - https://my.custom.client/
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates.
|
||||
# If you *do* uncomment it, you will need to make sure that all the templates
|
||||
# below are in the directory.
|
||||
# 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:
|
||||
#
|
||||
@@ -2096,9 +2137,8 @@ email:
|
||||
#validation_token_lifetime: 15m
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# Do not uncomment this setting unless you want to customise the templates.
|
||||
# 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:
|
||||
#
|
||||
@@ -2236,20 +2276,35 @@ password_providers:
|
||||
|
||||
|
||||
|
||||
# Clients requesting push notifications can either have the body of
|
||||
# the message sent in the notification poke along with other details
|
||||
# like the sender, or just the event ID and room ID (`event_id_only`).
|
||||
# If clients choose the former, this option controls whether the
|
||||
# notification request includes the content of the event (other details
|
||||
# like the sender are still included). For `event_id_only` push, it
|
||||
# has no effect.
|
||||
#
|
||||
# For modern android devices the notification content will still appear
|
||||
# because it is loaded by the app. iPhone, however will send a
|
||||
# notification saying only that a message arrived and who it came from.
|
||||
#
|
||||
#push:
|
||||
# include_content: true
|
||||
## Push ##
|
||||
|
||||
push:
|
||||
# Clients requesting push notifications can either have the body of
|
||||
# the message sent in the notification poke along with other details
|
||||
# like the sender, or just the event ID and room ID (`event_id_only`).
|
||||
# If clients choose the former, this option controls whether the
|
||||
# notification request includes the content of the event (other details
|
||||
# like the sender are still included). For `event_id_only` push, it
|
||||
# has no effect.
|
||||
#
|
||||
# For modern android devices the notification content will still appear
|
||||
# because it is loaded by the app. iPhone, however will send a
|
||||
# notification saying only that a message arrived and who it came from.
|
||||
#
|
||||
# The default value is "true" to include message details. Uncomment to only
|
||||
# include the event ID and room ID in push notification payloads.
|
||||
#
|
||||
#include_content: false
|
||||
|
||||
# When a push notification is received, an unread count is also sent.
|
||||
# This number can either be calculated as the number of unread messages
|
||||
# for the user, or the number of *rooms* the user has unread messages in.
|
||||
#
|
||||
# The default value is "true", meaning push clients will see the number of
|
||||
# rooms with unread messages in them. Uncomment to instead send the number
|
||||
# of unread messages.
|
||||
#
|
||||
#group_unread_count_by_room: false
|
||||
|
||||
|
||||
# Spam checkers are third-party modules that can block specific actions
|
||||
@@ -2557,6 +2612,13 @@ opentracing:
|
||||
#
|
||||
#run_background_tasks_on: worker1
|
||||
|
||||
# A shared secret used by the replication APIs to authenticate HTTP requests
|
||||
# from workers.
|
||||
#
|
||||
# By default this is unused and traffic is not authenticated.
|
||||
#
|
||||
#worker_replication_secret: ""
|
||||
|
||||
|
||||
# Configuration for Redis when using workers. This *must* be enabled when
|
||||
# using workers (unless using old style direct TCP configuration).
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
# Log configuration for Synapse.
|
||||
#
|
||||
# This is a YAML file containing a standard Python logging configuration
|
||||
# dictionary. See [1] for details on the valid settings.
|
||||
#
|
||||
# Synapse also supports structured logging for machine readable logs which can
|
||||
# be ingested by ELK stacks. See [2] for details.
|
||||
#
|
||||
# [1]: https://docs.python.org/3.7/library/logging.config.html#configuration-dictionary-schema
|
||||
# [2]: https://github.com/matrix-org/synapse/blob/master/docs/structured_logging.md
|
||||
|
||||
version: 1
|
||||
|
||||
formatters:
|
||||
precise:
|
||||
format: '%(asctime)s - %(name)s - %(lineno)d - %(levelname)s - %(request)s - %(message)s'
|
||||
|
||||
handlers:
|
||||
file:
|
||||
class: logging.handlers.TimedRotatingFileHandler
|
||||
formatter: precise
|
||||
filename: /var/log/matrix-synapse/homeserver.log
|
||||
when: midnight
|
||||
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.
|
||||
buffer:
|
||||
class: logging.handlers.MemoryHandler
|
||||
target: file
|
||||
# The capacity is the 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.
|
||||
capacity: 10
|
||||
flushLevel: 30 # Flush for WARNING logs as well
|
||||
|
||||
# A handler that writes logs to stderr. Unused by default, but can be used
|
||||
# instead of "buffer" and "file" in the logger handlers.
|
||||
console:
|
||||
class: logging.StreamHandler
|
||||
formatter: precise
|
||||
|
||||
loggers:
|
||||
synapse.storage.SQL:
|
||||
# beware: increasing this to DEBUG will make synapse log sensitive
|
||||
# information such as access tokens.
|
||||
level: INFO
|
||||
|
||||
twisted:
|
||||
# We send the twisted logging directly to the file handler,
|
||||
# to work around https://github.com/matrix-org/synapse/issues/3471
|
||||
# when using "buffer" logger. Use "console" to log to stderr instead.
|
||||
handlers: [file]
|
||||
propagate: false
|
||||
|
||||
root:
|
||||
level: INFO
|
||||
|
||||
# Write logs to the `buffer` handler, which will buffer them together in memory,
|
||||
# then write them to a file.
|
||||
#
|
||||
# Replace "buffer" with "console" to log to stderr instead. (Note that you'll
|
||||
# also need to update the configuration for the `twisted` logger above, in
|
||||
# this case.)
|
||||
#
|
||||
handlers: [buffer]
|
||||
|
||||
disable_existing_loggers: false
|
||||
|
||||
@@ -15,8 +15,15 @@ where SAML mapping providers come into play.
|
||||
SSO mapping providers are currently supported for OpenID and SAML SSO
|
||||
configurations. Please see the details below for how to implement your own.
|
||||
|
||||
It is the responsibility of the mapping provider to normalise the SSO attributes
|
||||
and map them to a valid Matrix ID. The
|
||||
[specification for Matrix IDs](https://matrix.org/docs/spec/appendices#user-identifiers)
|
||||
has some information about what is considered valid. Alternately an easy way to
|
||||
ensure it is valid is to use a Synapse utility function:
|
||||
`synapse.types.map_username_to_mxid_localpart`.
|
||||
|
||||
External mapping providers are provided to Synapse in the form of an external
|
||||
Python module. You can retrieve this module from [PyPi](https://pypi.org) or elsewhere,
|
||||
Python module. You can retrieve this module from [PyPI](https://pypi.org) or elsewhere,
|
||||
but it must be importable via Synapse (e.g. it must be in the same virtualenv
|
||||
as Synapse). The Synapse config is then modified to point to the mapping provider
|
||||
(and optionally provide additional configuration for it).
|
||||
@@ -56,13 +63,22 @@ A custom mapping provider must specify the following methods:
|
||||
information from.
|
||||
- This method must return a string, which is the unique identifier for the
|
||||
user. Commonly the ``sub`` claim of the response.
|
||||
* `map_user_attributes(self, userinfo, token)`
|
||||
* `map_user_attributes(self, userinfo, token, failures)`
|
||||
- This method must be async.
|
||||
- Arguments:
|
||||
- `userinfo` - A `authlib.oidc.core.claims.UserInfo` object to extract user
|
||||
information from.
|
||||
- `token` - A dictionary which includes information necessary to make
|
||||
further requests to the OpenID provider.
|
||||
- `failures` - An `int` that represents the amount of times the returned
|
||||
mxid localpart mapping has failed. This should be used
|
||||
to create a deduplicated mxid localpart which should be
|
||||
returned instead. For example, if this method returns
|
||||
`john.doe` as the value of `localpart` in the returned
|
||||
dict, and that is already taken on the homeserver, this
|
||||
method will be called again with the same parameters but
|
||||
with failures=1. The method should then return a different
|
||||
`localpart` value, such as `john.doe1`.
|
||||
- Returns a dictionary with two keys:
|
||||
- localpart: A required string, used to generate the Matrix ID.
|
||||
- displayname: An optional string, the display name for the user.
|
||||
@@ -100,11 +116,13 @@ comment these options out and use those specified by the module instead.
|
||||
|
||||
A custom mapping provider must specify the following methods:
|
||||
|
||||
* `__init__(self, parsed_config)`
|
||||
* `__init__(self, parsed_config, module_api)`
|
||||
- Arguments:
|
||||
- `parsed_config` - A configuration object that is the return value of the
|
||||
`parse_config` method. You should set any configuration options needed by
|
||||
the module here.
|
||||
- `module_api` - a `synapse.module_api.ModuleApi` object which provides the
|
||||
stable API available for extension modules.
|
||||
* `parse_config(config)`
|
||||
- This method should have the `@staticmethod` decoration.
|
||||
- Arguments:
|
||||
@@ -152,6 +170,13 @@ A custom mapping provider must specify the following methods:
|
||||
the value of `mxid_localpart`.
|
||||
* `emails` - A list of emails for the new user. If not provided, will
|
||||
default to an empty list.
|
||||
|
||||
Alternatively it can raise a `synapse.api.errors.RedirectException` to
|
||||
redirect the user to another page. This is useful to prompt the user for
|
||||
additional information, e.g. if you want them to provide their own username.
|
||||
It is the responsibility of the mapping provider to either redirect back
|
||||
to `client_redirect_url` (including any additional information) or to
|
||||
complete registration using methods from the `ModuleApi`.
|
||||
|
||||
### Default SAML Mapping Provider
|
||||
|
||||
|
||||
+123
-8
@@ -42,10 +42,10 @@ This will install and start a systemd service called `coturn`.
|
||||
|
||||
./configure
|
||||
|
||||
> You may need to install `libevent2`: if so, you should do so in
|
||||
> the way recommended by your operating system. You can ignore
|
||||
> warnings about lack of database support: a database is unnecessary
|
||||
> for this purpose.
|
||||
You may need to install `libevent2`: if so, you should do so in
|
||||
the way recommended by your operating system. You can ignore
|
||||
warnings about lack of database support: a database is unnecessary
|
||||
for this purpose.
|
||||
|
||||
1. Build and install it:
|
||||
|
||||
@@ -66,6 +66,19 @@ This will install and start a systemd service called `coturn`.
|
||||
|
||||
pwgen -s 64 1
|
||||
|
||||
A `realm` must be specified, but its value is somewhat arbitrary. (It is
|
||||
sent to clients as part of the authentication flow.) It is conventional to
|
||||
set it to be your server name.
|
||||
|
||||
1. You will most likely want to configure coturn to write logs somewhere. The
|
||||
easiest way is normally to send them to the syslog:
|
||||
|
||||
syslog
|
||||
|
||||
(in which case, the logs will be available via `journalctl -u coturn` on a
|
||||
systemd system). Alternatively, coturn can be configured to write to a
|
||||
logfile - check the example config file supplied with coturn.
|
||||
|
||||
1. Consider your security settings. TURN lets users request a relay which will
|
||||
connect to arbitrary IP addresses and ports. The following configuration is
|
||||
suggested as a minimum starting point:
|
||||
@@ -96,11 +109,31 @@ This will install and start a systemd service called `coturn`.
|
||||
# TLS private key file
|
||||
pkey=/path/to/privkey.pem
|
||||
|
||||
In this case, replace the `turn:` schemes in the `turn_uri` settings below
|
||||
with `turns:`.
|
||||
|
||||
We recommend that you only try to set up TLS/DTLS once you have set up a
|
||||
basic installation and got it working.
|
||||
|
||||
1. Ensure your firewall allows traffic into the TURN server on the ports
|
||||
you've configured it to listen on (By default: 3478 and 5349 for the TURN(s)
|
||||
you've configured it to listen on (By default: 3478 and 5349 for TURN
|
||||
traffic (remember to allow both TCP and UDP traffic), and ports 49152-65535
|
||||
for the UDP relay.)
|
||||
|
||||
1. We do not recommend running a TURN server behind NAT, and are not aware of
|
||||
anyone doing so successfully.
|
||||
|
||||
If you want to try it anyway, you will at least need to tell coturn its
|
||||
external IP address:
|
||||
|
||||
external-ip=192.88.99.1
|
||||
|
||||
... and your NAT gateway must forward all of the relayed ports directly
|
||||
(eg, port 56789 on the external IP must be always be forwarded to port
|
||||
56789 on the internal IP).
|
||||
|
||||
If you get this working, let us know!
|
||||
|
||||
1. (Re)start the turn server:
|
||||
|
||||
* If you used the Debian package (or have set up a systemd unit yourself):
|
||||
@@ -137,9 +170,10 @@ Your home server configuration file needs the following extra keys:
|
||||
without having gone through a CAPTCHA or similar to register a
|
||||
real account.
|
||||
|
||||
As an example, here is the relevant section of the config file for matrix.org:
|
||||
As an example, here is the relevant section of the config file for `matrix.org`. The
|
||||
`turn_uris` are appropriate for TURN servers listening on the default ports, with no TLS.
|
||||
|
||||
turn_uris: [ "turn:turn.matrix.org:3478?transport=udp", "turn:turn.matrix.org:3478?transport=tcp" ]
|
||||
turn_uris: [ "turn:turn.matrix.org?transport=udp", "turn:turn.matrix.org?transport=tcp" ]
|
||||
turn_shared_secret: "n0t4ctuAllymatr1Xd0TorgSshar3d5ecret4obvIousreAsons"
|
||||
turn_user_lifetime: 86400000
|
||||
turn_allow_guests: True
|
||||
@@ -155,5 +189,86 @@ After updating the homeserver configuration, you must restart synapse:
|
||||
```
|
||||
systemctl restart synapse.service
|
||||
```
|
||||
... and then reload any clients (or wait an hour for them to refresh their
|
||||
settings).
|
||||
|
||||
..and your Home Server now supports VoIP relaying!
|
||||
## Troubleshooting
|
||||
|
||||
The normal symptoms of a misconfigured TURN server are that calls between
|
||||
devices on different networks ring, but get stuck at "call
|
||||
connecting". Unfortunately, troubleshooting this can be tricky.
|
||||
|
||||
Here are a few things to try:
|
||||
|
||||
* Check that your TURN server is not behind NAT. As above, we're not aware of
|
||||
anyone who has successfully set this up.
|
||||
|
||||
* Check that you have opened your firewall to allow TCP and UDP traffic to the
|
||||
TURN ports (normally 3478 and 5479).
|
||||
|
||||
* Check that you have opened your firewall to allow UDP traffic to the UDP
|
||||
relay ports (49152-65535 by default).
|
||||
|
||||
* Some WebRTC implementations (notably, that of Google Chrome) appear to get
|
||||
confused by TURN servers which are reachable over IPv6 (this appears to be
|
||||
an unexpected side-effect of its handling of multiple IP addresses as
|
||||
defined by
|
||||
[`draft-ietf-rtcweb-ip-handling`](https://tools.ietf.org/html/draft-ietf-rtcweb-ip-handling-12)).
|
||||
|
||||
Try removing any AAAA records for your TURN server, so that it is only
|
||||
reachable over IPv4.
|
||||
|
||||
* Enable more verbose logging in coturn via the `verbose` setting:
|
||||
|
||||
```
|
||||
verbose
|
||||
```
|
||||
|
||||
... and then see if there are any clues in its logs.
|
||||
|
||||
* If you are using a browser-based client under Chrome, check
|
||||
`chrome://webrtc-internals/` for insights into the internals of the
|
||||
negotiation. On Firefox, check the "Connection Log" on `about:webrtc`.
|
||||
|
||||
(Understanding the output is beyond the scope of this document!)
|
||||
|
||||
* There is a WebRTC test tool at
|
||||
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/. To
|
||||
use it, you will need a username/password for your TURN server. You can
|
||||
either:
|
||||
|
||||
* look for the `GET /_matrix/client/r0/voip/turnServer` request made by a
|
||||
matrix client to your homeserver in your browser's network inspector. In
|
||||
the response you should see `username` and `password`. Or:
|
||||
|
||||
* Use the following shell commands:
|
||||
|
||||
```sh
|
||||
secret=staticAuthSecretHere
|
||||
|
||||
u=$((`date +%s` + 3600)):test
|
||||
p=$(echo -n $u | openssl dgst -hmac $secret -sha1 -binary | base64)
|
||||
echo -e "username: $u\npassword: $p"
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
* Temporarily configure coturn to accept a static username/password. To do
|
||||
this, comment out `use-auth-secret` and `static-auth-secret` and add the
|
||||
following:
|
||||
|
||||
```
|
||||
lt-cred-mech
|
||||
user=username:password
|
||||
```
|
||||
|
||||
**Note**: these settings will not take effect unless `use-auth-secret`
|
||||
and `static-auth-secret` are disabled.
|
||||
|
||||
Restart coturn after changing the configuration file.
|
||||
|
||||
Remember to restore the original settings to go back to testing with
|
||||
Matrix clients!
|
||||
|
||||
If the TURN server is working correctly, you should see at least one `relay`
|
||||
entry in the results.
|
||||
|
||||
+5
-1
@@ -89,7 +89,8 @@ shared configuration file.
|
||||
Normally, only a couple of changes are needed to make an existing configuration
|
||||
file suitable for use with workers. First, you need to enable an "HTTP replication
|
||||
listener" for the main process; and secondly, you need to enable redis-based
|
||||
replication. For example:
|
||||
replication. Optionally, a shared secret can be used to authenticate HTTP
|
||||
traffic between workers. For example:
|
||||
|
||||
|
||||
```yaml
|
||||
@@ -103,6 +104,9 @@ listeners:
|
||||
resources:
|
||||
- names: [replication]
|
||||
|
||||
# Add a random shared secret to authenticate traffic.
|
||||
worker_replication_secret: ""
|
||||
|
||||
redis:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
@@ -8,6 +8,7 @@ show_traceback = True
|
||||
mypy_path = stubs
|
||||
warn_unreachable = True
|
||||
files =
|
||||
scripts-dev/sign_json,
|
||||
synapse/api,
|
||||
synapse/appservice,
|
||||
synapse/config,
|
||||
@@ -37,19 +38,28 @@ files =
|
||||
synapse/handlers/presence.py,
|
||||
synapse/handlers/profile.py,
|
||||
synapse/handlers/read_marker.py,
|
||||
synapse/handlers/register.py,
|
||||
synapse/handlers/room.py,
|
||||
synapse/handlers/room_member.py,
|
||||
synapse/handlers/room_member_worker.py,
|
||||
synapse/handlers/saml_handler.py,
|
||||
synapse/handlers/sso.py,
|
||||
synapse/handlers/sync.py,
|
||||
synapse/handlers/ui_auth,
|
||||
synapse/http/client.py,
|
||||
synapse/http/federation/matrix_federation_agent.py,
|
||||
synapse/http/federation/well_known_resolver.py,
|
||||
synapse/http/matrixfederationclient.py,
|
||||
synapse/http/server.py,
|
||||
synapse/http/site.py,
|
||||
synapse/logging,
|
||||
synapse/metrics,
|
||||
synapse/module_api,
|
||||
synapse/notifier.py,
|
||||
synapse/push/emailpusher.py,
|
||||
synapse/push/httppusher.py,
|
||||
synapse/push/mailer.py,
|
||||
synapse/push/pusher.py,
|
||||
synapse/push/pusherpool.py,
|
||||
synapse/push/push_rule_evaluator.py,
|
||||
synapse/replication,
|
||||
@@ -75,6 +85,7 @@ files =
|
||||
synapse/util/metrics.py,
|
||||
tests/replication,
|
||||
tests/test_utils,
|
||||
tests/handlers/test_password_providers.py,
|
||||
tests/rest/client/v2_alpha/test_auth.py,
|
||||
tests/util/test_stream_change_cache.py
|
||||
|
||||
@@ -105,7 +116,7 @@ ignore_missing_imports = True
|
||||
[mypy-opentracing]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-OpenSSL]
|
||||
[mypy-OpenSSL.*]
|
||||
ignore_missing_imports = True
|
||||
|
||||
[mypy-netaddr]
|
||||
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from json import JSONDecodeError
|
||||
|
||||
import yaml
|
||||
from signedjson.key import read_signing_keys
|
||||
from signedjson.sign import sign_json
|
||||
|
||||
from synapse.util import json_encoder
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""Adds a signature to a JSON object.
|
||||
|
||||
Example usage:
|
||||
|
||||
$ scripts-dev/sign_json.py -N test -k localhost.signing.key "{}"
|
||||
{"signatures":{"test":{"ed25519:a_ZnZh":"LmPnml6iM0iR..."}}}
|
||||
""",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-N",
|
||||
"--server-name",
|
||||
help="Name to give as the local homeserver. If unspecified, will be "
|
||||
"read from the config file.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-k",
|
||||
"--signing-key-path",
|
||||
help="Path to the file containing the private ed25519 key to sign the "
|
||||
"request with.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-c",
|
||||
"--config",
|
||||
default="homeserver.yaml",
|
||||
help=(
|
||||
"Path to synapse config file, from which the server name and/or signing "
|
||||
"key path will be read. Ignored if --server-name and --signing-key-path "
|
||||
"are both given."
|
||||
),
|
||||
)
|
||||
|
||||
input_args = parser.add_mutually_exclusive_group()
|
||||
|
||||
input_args.add_argument("input_data", nargs="?", help="Raw JSON to be signed.")
|
||||
|
||||
input_args.add_argument(
|
||||
"-i",
|
||||
"--input",
|
||||
type=argparse.FileType("r"),
|
||||
default=sys.stdin,
|
||||
help=(
|
||||
"A file from which to read the JSON to be signed. If neither --input nor "
|
||||
"input_data are given, JSON will be read from stdin."
|
||||
),
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
type=argparse.FileType("w"),
|
||||
default=sys.stdout,
|
||||
help="Where to write the signed JSON. Defaults to stdout.",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.server_name or not args.signing_key_path:
|
||||
read_args_from_config(args)
|
||||
|
||||
with open(args.signing_key_path) as f:
|
||||
key = read_signing_keys(f)[0]
|
||||
|
||||
json_to_sign = args.input_data
|
||||
if json_to_sign is None:
|
||||
json_to_sign = args.input.read()
|
||||
|
||||
try:
|
||||
obj = json.loads(json_to_sign)
|
||||
except JSONDecodeError as e:
|
||||
print("Unable to parse input as JSON: %s" % e, file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
print("Input json was not an object", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
sign_json(obj, args.server_name, key)
|
||||
for c in json_encoder.iterencode(obj):
|
||||
args.output.write(c)
|
||||
args.output.write("\n")
|
||||
|
||||
|
||||
def read_args_from_config(args: argparse.Namespace) -> None:
|
||||
with open(args.config, "r") as fh:
|
||||
config = yaml.safe_load(fh)
|
||||
if not args.server_name:
|
||||
args.server_name = config["server_name"]
|
||||
if not args.signing_key_path:
|
||||
args.signing_key_path = config["signing_key_path"]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+1
-1
@@ -48,7 +48,7 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
__version__ = "1.23.0"
|
||||
__version__ = "1.24.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
|
||||
|
||||
@@ -37,7 +37,7 @@ def request_registration(
|
||||
exit=sys.exit,
|
||||
):
|
||||
|
||||
url = "%s/_matrix/client/r0/admin/register" % (server_location,)
|
||||
url = "%s/_synapse/admin/v1/register" % (server_location.rstrip("/"),)
|
||||
|
||||
# Get the nonce
|
||||
r = requests.get(url, verify=False)
|
||||
|
||||
+2
-2
@@ -76,7 +76,7 @@ class Auth:
|
||||
|
||||
self._auth_blocking = AuthBlocking(self.hs)
|
||||
|
||||
self._account_validity = hs.config.account_validity
|
||||
self._account_validity_enabled = hs.config.account_validity_enabled
|
||||
self._track_appservice_user_ips = hs.config.track_appservice_user_ips
|
||||
self._macaroon_secret_key = hs.config.macaroon_secret_key
|
||||
|
||||
@@ -219,7 +219,7 @@ class Auth:
|
||||
shadow_banned = user_info.shadow_banned
|
||||
|
||||
# Deny the request if the user account has expired.
|
||||
if self._account_validity.enabled and not allow_expired:
|
||||
if self._account_validity_enabled and not allow_expired:
|
||||
if await self.store.is_account_expired(
|
||||
user_info.user_id, self.clock.time_msec()
|
||||
):
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
# limitations under the License.
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
from synapse.api.constants import LimitBlockingTypes, UserTypes
|
||||
from synapse.api.errors import Codes, ResourceLimitError
|
||||
from synapse.config.server import is_threepid_reserved
|
||||
from synapse.types import Requester
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -33,24 +35,47 @@ class AuthBlocking:
|
||||
self._max_mau_value = hs.config.max_mau_value
|
||||
self._limit_usage_by_mau = hs.config.limit_usage_by_mau
|
||||
self._mau_limits_reserved_threepids = hs.config.mau_limits_reserved_threepids
|
||||
self._server_name = hs.hostname
|
||||
|
||||
async def check_auth_blocking(self, user_id=None, threepid=None, user_type=None):
|
||||
async def check_auth_blocking(
|
||||
self,
|
||||
user_id: Optional[str] = None,
|
||||
threepid: Optional[dict] = None,
|
||||
user_type: Optional[str] = None,
|
||||
requester: Optional[Requester] = None,
|
||||
):
|
||||
"""Checks if the user should be rejected for some external reason,
|
||||
such as monthly active user limiting or global disable flag
|
||||
|
||||
Args:
|
||||
user_id(str|None): If present, checks for presence against existing
|
||||
user_id: If present, checks for presence against existing
|
||||
MAU cohort
|
||||
|
||||
threepid(dict|None): If present, checks for presence against configured
|
||||
threepid: If present, checks for presence against configured
|
||||
reserved threepid. Used in cases where the user is trying register
|
||||
with a MAU blocked server, normally they would be rejected but their
|
||||
threepid is on the reserved list. user_id and
|
||||
threepid should never be set at the same time.
|
||||
|
||||
user_type(str|None): If present, is used to decide whether to check against
|
||||
user_type: If present, is used to decide whether to check against
|
||||
certain blocking reasons like MAU.
|
||||
|
||||
requester: If present, and the authenticated entity is a user, checks for
|
||||
presence against existing MAU cohort. Passing in both a `user_id` and
|
||||
`requester` is an error.
|
||||
"""
|
||||
if requester and user_id:
|
||||
raise Exception(
|
||||
"Passed in both 'user_id' and 'requester' to 'check_auth_blocking'"
|
||||
)
|
||||
|
||||
if requester:
|
||||
if requester.authenticated_entity.startswith("@"):
|
||||
user_id = requester.authenticated_entity
|
||||
elif requester.authenticated_entity == self._server_name:
|
||||
# We never block the server from doing actions on behalf of
|
||||
# users.
|
||||
return
|
||||
|
||||
# Never fail an auth check for the server notices users or support user
|
||||
# This can be a problem where event creation is prohibited due to blocking
|
||||
|
||||
+13
-1
@@ -32,6 +32,7 @@ from synapse.app.phone_stats_home import start_phone_stats_home
|
||||
from synapse.config.server import ListenerConfig
|
||||
from synapse.crypto import context_factory
|
||||
from synapse.logging.context import PreserveLoggingContext
|
||||
from synapse.metrics.background_process_metrics import wrap_as_background_process
|
||||
from synapse.util.async_helpers import Linearizer
|
||||
from synapse.util.daemonize import daemonize_process
|
||||
from synapse.util.rlimit import change_resource_limit
|
||||
@@ -244,6 +245,9 @@ def start(hs: "synapse.server.HomeServer", listeners: Iterable[ListenerConfig]):
|
||||
# Set up the SIGHUP machinery.
|
||||
if hasattr(signal, "SIGHUP"):
|
||||
|
||||
reactor = hs.get_reactor()
|
||||
|
||||
@wrap_as_background_process("sighup")
|
||||
def handle_sighup(*args, **kwargs):
|
||||
# Tell systemd our state, if we're using it. This will silently fail if
|
||||
# we're not using systemd.
|
||||
@@ -254,7 +258,15 @@ def start(hs: "synapse.server.HomeServer", listeners: Iterable[ListenerConfig]):
|
||||
|
||||
sdnotify(b"READY=1")
|
||||
|
||||
signal.signal(signal.SIGHUP, handle_sighup)
|
||||
# We defer running the sighup handlers until next reactor tick. This
|
||||
# is so that we're in a sane state, e.g. flushing the logs may fail
|
||||
# if the sighup happens in the middle of writing a log entry.
|
||||
def run_sighup(*args, **kwargs):
|
||||
# `callFromThread` should be "signal safe" as well as thread
|
||||
# safe.
|
||||
reactor.callFromThread(handle_sighup, *args, **kwargs)
|
||||
|
||||
signal.signal(signal.SIGHUP, run_sighup)
|
||||
|
||||
register_sighup(refresh_certificate, hs)
|
||||
|
||||
|
||||
@@ -266,7 +266,6 @@ class GenericWorkerPresence(BasePresenceHandler):
|
||||
super().__init__(hs)
|
||||
self.hs = hs
|
||||
self.is_mine_id = hs.is_mine_id
|
||||
self.http_client = hs.get_simple_http_client()
|
||||
|
||||
self._presence_enabled = hs.config.use_presence
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import gc
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from typing import Iterable
|
||||
from typing import Iterable, Iterator
|
||||
|
||||
from twisted.application import service
|
||||
from twisted.internet import defer, reactor
|
||||
@@ -90,7 +90,7 @@ class SynapseHomeServer(HomeServer):
|
||||
tls = listener_config.tls
|
||||
site_tag = listener_config.http_options.tag
|
||||
if site_tag is None:
|
||||
site_tag = port
|
||||
site_tag = str(port)
|
||||
|
||||
# We always include a health resource.
|
||||
resources = {"/health": HealthResource()}
|
||||
@@ -107,7 +107,10 @@ class SynapseHomeServer(HomeServer):
|
||||
logger.debug("Configuring additional resources: %r", additional_resources)
|
||||
module_api = self.get_module_api()
|
||||
for path, resmodule in additional_resources.items():
|
||||
handler_cls, config = load_module(resmodule)
|
||||
handler_cls, config = load_module(
|
||||
resmodule,
|
||||
("listeners", site_tag, "additional_resources", "<%s>" % (path,)),
|
||||
)
|
||||
handler = handler_cls(config, module_api)
|
||||
if IResource.providedBy(handler):
|
||||
resource = handler
|
||||
@@ -342,7 +345,10 @@ def setup(config_options):
|
||||
"Synapse Homeserver", config_options
|
||||
)
|
||||
except ConfigError as e:
|
||||
sys.stderr.write("\nERROR: %s\n" % (e,))
|
||||
sys.stderr.write("\n")
|
||||
for f in format_config_error(e):
|
||||
sys.stderr.write(f)
|
||||
sys.stderr.write("\n")
|
||||
sys.exit(1)
|
||||
|
||||
if not config:
|
||||
@@ -445,6 +451,38 @@ def setup(config_options):
|
||||
return hs
|
||||
|
||||
|
||||
def format_config_error(e: ConfigError) -> Iterator[str]:
|
||||
"""
|
||||
Formats a config error neatly
|
||||
|
||||
The idea is to format the immediate error, plus the "causes" of those errors,
|
||||
hopefully in a way that makes sense to the user. For example:
|
||||
|
||||
Error in configuration at 'oidc_config.user_mapping_provider.config.display_name_template':
|
||||
Failed to parse config for module 'JinjaOidcMappingProvider':
|
||||
invalid jinja template:
|
||||
unexpected end of template, expected 'end of print statement'.
|
||||
|
||||
Args:
|
||||
e: the error to be formatted
|
||||
|
||||
Returns: An iterator which yields string fragments to be formatted
|
||||
"""
|
||||
yield "Error in configuration"
|
||||
|
||||
if e.path:
|
||||
yield " at '%s'" % (".".join(e.path),)
|
||||
|
||||
yield ":\n %s" % (e.msg,)
|
||||
|
||||
e = e.__cause__
|
||||
indent = 1
|
||||
while e:
|
||||
indent += 1
|
||||
yield ":\n%s%s" % (" " * indent, str(e))
|
||||
e = e.__cause__
|
||||
|
||||
|
||||
class SynapseService(service.Service):
|
||||
"""
|
||||
A twisted Service class that will start synapse. Used to run synapse
|
||||
|
||||
+12
-2
@@ -23,7 +23,7 @@ import urllib.parse
|
||||
from collections import OrderedDict
|
||||
from hashlib import sha256
|
||||
from textwrap import dedent
|
||||
from typing import Any, Callable, List, MutableMapping, Optional
|
||||
from typing import Any, Callable, Iterable, List, MutableMapping, Optional
|
||||
|
||||
import attr
|
||||
import jinja2
|
||||
@@ -32,7 +32,17 @@ import yaml
|
||||
|
||||
|
||||
class ConfigError(Exception):
|
||||
pass
|
||||
"""Represents a problem parsing the configuration
|
||||
|
||||
Args:
|
||||
msg: A textual description of the error.
|
||||
path: Where appropriate, an indication of where in the configuration
|
||||
the problem lies.
|
||||
"""
|
||||
|
||||
def __init__(self, msg: str, path: Optional[Iterable[str]] = None):
|
||||
self.msg = msg
|
||||
self.path = path
|
||||
|
||||
|
||||
# We split these messages out to allow packages to override with package
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from typing import Any, List, Optional
|
||||
from typing import Any, Iterable, List, Optional
|
||||
|
||||
from synapse.config import (
|
||||
account_validity,
|
||||
api,
|
||||
appservice,
|
||||
captcha,
|
||||
@@ -35,7 +36,10 @@ from synapse.config import (
|
||||
workers,
|
||||
)
|
||||
|
||||
class ConfigError(Exception): ...
|
||||
class ConfigError(Exception):
|
||||
def __init__(self, msg: str, path: Optional[Iterable[str]] = None):
|
||||
self.msg = msg
|
||||
self.path = path
|
||||
|
||||
MISSING_REPORT_STATS_CONFIG_INSTRUCTIONS: str
|
||||
MISSING_REPORT_STATS_SPIEL: str
|
||||
@@ -52,6 +56,7 @@ class RootConfig:
|
||||
media: repository.ContentRepositoryConfig
|
||||
captcha: captcha.CaptchaConfig
|
||||
voip: voip.VoipConfig
|
||||
accountvalidity: account_validity.AccountValidityConfig
|
||||
registration: registration.RegistrationConfig
|
||||
metrics: metrics.MetricsConfig
|
||||
api: api.ApiConfig
|
||||
|
||||
+23
-10
@@ -38,14 +38,27 @@ def validate_config(
|
||||
try:
|
||||
jsonschema.validate(config, json_schema)
|
||||
except jsonschema.ValidationError as e:
|
||||
# copy `config_path` before modifying it.
|
||||
path = list(config_path)
|
||||
for p in list(e.path):
|
||||
if isinstance(p, int):
|
||||
path.append("<item %i>" % p)
|
||||
else:
|
||||
path.append(str(p))
|
||||
raise json_error_to_config_error(e, config_path)
|
||||
|
||||
raise ConfigError(
|
||||
"Unable to parse configuration: %s at %s" % (e.message, ".".join(path))
|
||||
)
|
||||
|
||||
def json_error_to_config_error(
|
||||
e: jsonschema.ValidationError, config_path: Iterable[str]
|
||||
) -> ConfigError:
|
||||
"""Converts a json validation error to a user-readable ConfigError
|
||||
|
||||
Args:
|
||||
e: the exception to be converted
|
||||
config_path: the path within the config file. This will be used as a basis
|
||||
for the error message.
|
||||
|
||||
Returns:
|
||||
a ConfigError
|
||||
"""
|
||||
# copy `config_path` before modifying it.
|
||||
path = list(config_path)
|
||||
for p in list(e.path):
|
||||
if isinstance(p, int):
|
||||
path.append("<item %i>" % p)
|
||||
else:
|
||||
path.append(str(p))
|
||||
return ConfigError(e.message, path)
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
import os
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from synapse.config._base import Config, ConfigError
|
||||
|
||||
|
||||
class AccountValidityConfig(Config):
|
||||
section = "accountvalidity"
|
||||
|
||||
def read_config(self, config, **kwargs):
|
||||
account_validity_config = config.get("account_validity", {})
|
||||
self.account_validity_enabled = account_validity_config.get("enabled", False)
|
||||
self.account_validity_renew_by_email_enabled = (
|
||||
"renew_at" in account_validity_config
|
||||
)
|
||||
|
||||
if self.account_validity_enabled:
|
||||
if "period" in config:
|
||||
self.account_validity_period = self.parse_duration(config["period"])
|
||||
else:
|
||||
raise ConfigError("'period' is required when using account validity")
|
||||
|
||||
if "renew_at" in config:
|
||||
self.account_validity_renew_at = self.parse_duration(config["renew_at"])
|
||||
|
||||
if "renew_email_subject" in config:
|
||||
self.account_validity_renew_email_subject = config[
|
||||
"renew_email_subject"
|
||||
]
|
||||
else:
|
||||
self.account_validity_renew_email_subject = "Renew your %(app)s account"
|
||||
|
||||
self.account_validity_startup_job_max_delta = self.period * 10.0 / 100.0
|
||||
|
||||
if self.account_validity_renew_by_email_enabled:
|
||||
if not self.public_baseurl:
|
||||
raise ConfigError("Can't send renewal emails without 'public_baseurl'")
|
||||
|
||||
template_dir = config.get("template_dir")
|
||||
|
||||
if not template_dir:
|
||||
template_dir = pkg_resources.resource_filename("synapse", "res/templates")
|
||||
|
||||
if "account_renewed_html_path" in config:
|
||||
file_path = os.path.join(template_dir, config["account_renewed_html_path"])
|
||||
|
||||
self.account_validity_account_renewed_html_content = self.read_file(
|
||||
file_path, "account_validity.account_renewed_html_path"
|
||||
)
|
||||
else:
|
||||
self.account_validity_account_renewed_html_content = (
|
||||
"<html><body>Your account has been successfully renewed.</body><html>"
|
||||
)
|
||||
|
||||
if "invalid_token_html_path" in config:
|
||||
file_path = os.path.join(template_dir, config["invalid_token_html_path"])
|
||||
|
||||
self.account_validity_invalid_token_html_content = self.read_file(
|
||||
file_path, "account_validity.invalid_token_html_path"
|
||||
)
|
||||
else:
|
||||
self.account_validity_invalid_token_html_content = (
|
||||
"<html><body>Invalid renewal token.</body><html>"
|
||||
)
|
||||
|
||||
# Load account validity templates.
|
||||
# We do this here instead of in AccountValidityConfig as read_templates
|
||||
# relies on state that hasn't been initialised in AccountValidityConfig
|
||||
account_renewed_template_filename = config.get(
|
||||
"account_renewed_html_path", "account_renewed.html"
|
||||
)
|
||||
account_previously_renewed_template_filename = config.get(
|
||||
"account_previously_renewed_html_path", "account_previously_renewed.html"
|
||||
)
|
||||
invalid_token_template_filename = config.get(
|
||||
"invalid_token_html_path", "invalid_token.html"
|
||||
)
|
||||
(
|
||||
self.account_validity.account_renewed_template,
|
||||
self.account_validity.account_previously_renewed_template,
|
||||
self.account_validity.invalid_token_template,
|
||||
) = self.read_templates(
|
||||
[
|
||||
account_renewed_template_filename,
|
||||
account_previously_renewed_template_filename,
|
||||
invalid_token_template_filename,
|
||||
]
|
||||
)
|
||||
|
||||
def generate_config_section(self, **kwargs):
|
||||
return """\
|
||||
## Account Validity ##
|
||||
#
|
||||
# Optional account validity configuration. This allows for accounts to be denied
|
||||
# any request after a given period.
|
||||
#
|
||||
# Once this feature is enabled, Synapse will look for registered users without an
|
||||
# expiration date at startup and will add one to every account it found using the
|
||||
# current settings at that time.
|
||||
# This means that, if a validity period is set, and Synapse is restarted (it will
|
||||
# then derive an expiration date from the current validity period), and some time
|
||||
# after that the validity period changes and Synapse is restarted, the users'
|
||||
# expiration dates won't be updated unless their account is manually renewed. This
|
||||
# date will be randomly selected within a range [now + period - d ; now + period],
|
||||
# where d is equal to 10%% of the validity period.
|
||||
#
|
||||
account_validity:
|
||||
# The account validity feature is disabled by default. Uncomment the
|
||||
# following line to enable it.
|
||||
#
|
||||
#enabled: true
|
||||
|
||||
# The period after which an account is valid after its registration. When
|
||||
# renewing the account, its validity period will be extended by this amount
|
||||
# of time. This parameter is required when using the account validity
|
||||
# feature.
|
||||
#
|
||||
#period: 6w
|
||||
|
||||
# The amount of time before an account's expiry date at which Synapse will
|
||||
# send an email to the account's email address with a renewal link. By
|
||||
# default, no such emails are sent.
|
||||
#
|
||||
# If you enable this setting, you will also need to fill out the 'email' and
|
||||
# 'public_baseurl' configuration sections.
|
||||
#
|
||||
#renew_at: 1w
|
||||
|
||||
# The subject of the email sent out with the renewal link. '%%(app)s' can be
|
||||
# used as a placeholder for the 'app_name' parameter from the 'email'
|
||||
# section.
|
||||
#
|
||||
# Note that the placeholder must be written '%%(app)s', including the
|
||||
# trailing 's'.
|
||||
#
|
||||
# If this is not set, a default value is used.
|
||||
#
|
||||
#renew_email_subject: "Renew your %%(app)s account"
|
||||
|
||||
# Directory in which Synapse will try to find templates for the HTML files to
|
||||
# serve to the user when trying to renew an account. If not set, default
|
||||
# templates from within the Synapse package will be used.
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
|
||||
# File within 'template_dir' giving the HTML to be displayed to the user after
|
||||
# they successfully renewed their account. If not set, default text is used.
|
||||
#
|
||||
#account_renewed_html_path: "account_renewed.html"
|
||||
|
||||
# File within 'template_dir' giving the HTML to be displayed when the user
|
||||
# tries to renew an account with an invalid renewal token. If not set,
|
||||
# default text is used.
|
||||
#
|
||||
#invalid_token_html_path: "invalid_token.html"
|
||||
"""
|
||||
@@ -390,9 +390,8 @@ class EmailConfig(Config):
|
||||
#validation_token_lifetime: 15m
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# Do not uncomment this setting unless you want to customise the templates.
|
||||
# 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:
|
||||
#
|
||||
|
||||
@@ -12,12 +12,9 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from netaddr import IPSet
|
||||
|
||||
from synapse.config._base import Config, ConfigError
|
||||
from synapse.config._base import Config
|
||||
from synapse.config._util import validate_config
|
||||
|
||||
|
||||
@@ -36,23 +33,6 @@ class FederationConfig(Config):
|
||||
for domain in federation_domain_whitelist:
|
||||
self.federation_domain_whitelist[domain] = True
|
||||
|
||||
self.federation_ip_range_blacklist = config.get(
|
||||
"federation_ip_range_blacklist", []
|
||||
)
|
||||
|
||||
# Attempt to create an IPSet from the given ranges
|
||||
try:
|
||||
self.federation_ip_range_blacklist = IPSet(
|
||||
self.federation_ip_range_blacklist
|
||||
)
|
||||
|
||||
# Always blacklist 0.0.0.0, ::
|
||||
self.federation_ip_range_blacklist.update(["0.0.0.0", "::"])
|
||||
except Exception as e:
|
||||
raise ConfigError(
|
||||
"Invalid range(s) provided in federation_ip_range_blacklist: %s" % e
|
||||
)
|
||||
|
||||
federation_metrics_domains = config.get("federation_metrics_domains") or []
|
||||
validate_config(
|
||||
_METRICS_FOR_DOMAINS_SCHEMA,
|
||||
@@ -76,26 +56,17 @@ class FederationConfig(Config):
|
||||
# - nyc.example.com
|
||||
# - syd.example.com
|
||||
|
||||
# Prevent federation requests from being sent to the following
|
||||
# blacklist IP address CIDR ranges. If this option is not specified, or
|
||||
# specified with an empty list, no ip range blacklist will be enforced.
|
||||
# List of IP address CIDR ranges that should be allowed for federation,
|
||||
# identity servers, push servers, and for checking key validity for
|
||||
# third-party invite events. This is useful for specifying exceptions to
|
||||
# wide-ranging blacklisted target IP ranges - e.g. for communication with
|
||||
# a push server only visible in your network.
|
||||
#
|
||||
# As of Synapse v1.4.0 this option also affects any outbound requests to identity
|
||||
# servers provided by user input.
|
||||
# This whitelist overrides ip_range_blacklist and defaults to an empty
|
||||
# list.
|
||||
#
|
||||
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
|
||||
# listed here, since they correspond to unroutable addresses.)
|
||||
#
|
||||
federation_ip_range_blacklist:
|
||||
- '127.0.0.0/8'
|
||||
- '10.0.0.0/8'
|
||||
- '172.16.0.0/12'
|
||||
- '192.168.0.0/16'
|
||||
- '100.64.0.0/10'
|
||||
- '169.254.0.0/16'
|
||||
- '::1/128'
|
||||
- 'fe80::/64'
|
||||
- 'fc00::/7'
|
||||
#ip_range_whitelist:
|
||||
# - '192.168.1.1'
|
||||
|
||||
# Report prometheus metrics on the age of PDUs being sent to and received from
|
||||
# the following domains. This can be used to give an idea of "delay" on inbound
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from ._base import RootConfig
|
||||
from .account_validity import AccountValidityConfig
|
||||
from .api import ApiConfig
|
||||
from .appservice import AppServiceConfig
|
||||
from .cache import CacheConfig
|
||||
@@ -66,6 +66,7 @@ class HomeServerConfig(RootConfig):
|
||||
ContentRepositoryConfig,
|
||||
CaptchaConfig,
|
||||
VoipConfig,
|
||||
AccountValidityConfig,
|
||||
RegistrationConfig,
|
||||
MetricsConfig,
|
||||
ApiConfig,
|
||||
|
||||
@@ -66,7 +66,7 @@ class OIDCConfig(Config):
|
||||
(
|
||||
self.oidc_user_mapping_provider_class,
|
||||
self.oidc_user_mapping_provider_config,
|
||||
) = load_module(ump_config)
|
||||
) = load_module(ump_config, ("oidc_config", "user_mapping_provider"))
|
||||
|
||||
# Ensure loaded user mapping module has defined all necessary methods
|
||||
required_methods = [
|
||||
|
||||
@@ -36,7 +36,7 @@ class PasswordAuthProviderConfig(Config):
|
||||
providers.append({"module": LDAP_PROVIDER, "config": ldap_config})
|
||||
|
||||
providers.extend(config.get("password_providers") or [])
|
||||
for provider in providers:
|
||||
for i, provider in enumerate(providers):
|
||||
mod_name = provider["module"]
|
||||
|
||||
# This is for backwards compat when the ldap auth provider resided
|
||||
@@ -45,7 +45,8 @@ class PasswordAuthProviderConfig(Config):
|
||||
mod_name = LDAP_PROVIDER
|
||||
|
||||
(provider_class, provider_config) = load_module(
|
||||
{"module": mod_name, "config": provider["config"]}
|
||||
{"module": mod_name, "config": provider["config"]},
|
||||
("password_providers", "<item %i>" % i),
|
||||
)
|
||||
|
||||
self.password_providers.append((provider_class, provider_config))
|
||||
|
||||
+33
-15
@@ -21,8 +21,11 @@ class PushConfig(Config):
|
||||
section = "push"
|
||||
|
||||
def read_config(self, config, **kwargs):
|
||||
push_config = config.get("push", {})
|
||||
push_config = config.get("push") or {}
|
||||
self.push_include_content = push_config.get("include_content", True)
|
||||
self.push_group_unread_count_by_room = push_config.get(
|
||||
"group_unread_count_by_room", True
|
||||
)
|
||||
|
||||
pusher_instances = config.get("pusher_instances") or []
|
||||
self.pusher_shard_config = ShardedWorkerHandlingConfig(pusher_instances)
|
||||
@@ -49,18 +52,33 @@ class PushConfig(Config):
|
||||
|
||||
def generate_config_section(self, config_dir_path, server_name, **kwargs):
|
||||
return """
|
||||
# Clients requesting push notifications can either have the body of
|
||||
# the message sent in the notification poke along with other details
|
||||
# like the sender, or just the event ID and room ID (`event_id_only`).
|
||||
# If clients choose the former, this option controls whether the
|
||||
# notification request includes the content of the event (other details
|
||||
# like the sender are still included). For `event_id_only` push, it
|
||||
# has no effect.
|
||||
#
|
||||
# For modern android devices the notification content will still appear
|
||||
# because it is loaded by the app. iPhone, however will send a
|
||||
# notification saying only that a message arrived and who it came from.
|
||||
#
|
||||
#push:
|
||||
# include_content: true
|
||||
## Push ##
|
||||
|
||||
push:
|
||||
# Clients requesting push notifications can either have the body of
|
||||
# the message sent in the notification poke along with other details
|
||||
# like the sender, or just the event ID and room ID (`event_id_only`).
|
||||
# If clients choose the former, this option controls whether the
|
||||
# notification request includes the content of the event (other details
|
||||
# like the sender are still included). For `event_id_only` push, it
|
||||
# has no effect.
|
||||
#
|
||||
# For modern android devices the notification content will still appear
|
||||
# because it is loaded by the app. iPhone, however will send a
|
||||
# notification saying only that a message arrived and who it came from.
|
||||
#
|
||||
# The default value is "true" to include message details. Uncomment to only
|
||||
# include the event ID and room ID in push notification payloads.
|
||||
#
|
||||
#include_content: false
|
||||
|
||||
# When a push notification is received, an unread count is also sent.
|
||||
# This number can either be calculated as the number of unread messages
|
||||
# for the user, or the number of *rooms* the user has unread messages in.
|
||||
#
|
||||
# The default value is "true", meaning push clients will see the number of
|
||||
# rooms with unread messages in them. Uncomment to instead send the number
|
||||
# of unread messages.
|
||||
#
|
||||
#group_unread_count_by_room: false
|
||||
"""
|
||||
|
||||
@@ -13,75 +13,14 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
from distutils.util import strtobool
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from synapse.api.constants import RoomCreationPreset
|
||||
from synapse.config._base import Config, ConfigError
|
||||
from synapse.types import RoomAlias, UserID
|
||||
from synapse.util.stringutils import random_string_with_symbols
|
||||
|
||||
|
||||
class AccountValidityConfig(Config):
|
||||
section = "accountvalidity"
|
||||
|
||||
def __init__(self, config, synapse_config):
|
||||
if config is None:
|
||||
return
|
||||
super().__init__()
|
||||
self.enabled = config.get("enabled", False)
|
||||
self.renew_by_email_enabled = "renew_at" in config
|
||||
|
||||
if self.enabled:
|
||||
if "period" in config:
|
||||
self.period = self.parse_duration(config["period"])
|
||||
else:
|
||||
raise ConfigError("'period' is required when using account validity")
|
||||
|
||||
if "renew_at" in config:
|
||||
self.renew_at = self.parse_duration(config["renew_at"])
|
||||
|
||||
if "renew_email_subject" in config:
|
||||
self.renew_email_subject = config["renew_email_subject"]
|
||||
else:
|
||||
self.renew_email_subject = "Renew your %(app)s account"
|
||||
|
||||
self.startup_job_max_delta = self.period * 10.0 / 100.0
|
||||
|
||||
if self.renew_by_email_enabled:
|
||||
if "public_baseurl" not in synapse_config:
|
||||
raise ConfigError("Can't send renewal emails without 'public_baseurl'")
|
||||
|
||||
template_dir = config.get("template_dir")
|
||||
|
||||
if not template_dir:
|
||||
template_dir = pkg_resources.resource_filename("synapse", "res/templates")
|
||||
|
||||
if "account_renewed_html_path" in config:
|
||||
file_path = os.path.join(template_dir, config["account_renewed_html_path"])
|
||||
|
||||
self.account_renewed_html_content = self.read_file(
|
||||
file_path, "account_validity.account_renewed_html_path"
|
||||
)
|
||||
else:
|
||||
self.account_renewed_html_content = (
|
||||
"<html><body>Your account has been successfully renewed.</body><html>"
|
||||
)
|
||||
|
||||
if "invalid_token_html_path" in config:
|
||||
file_path = os.path.join(template_dir, config["invalid_token_html_path"])
|
||||
|
||||
self.invalid_token_html_content = self.read_file(
|
||||
file_path, "account_validity.invalid_token_html_path"
|
||||
)
|
||||
else:
|
||||
self.invalid_token_html_content = (
|
||||
"<html><body>Invalid renewal token.</body><html>"
|
||||
)
|
||||
|
||||
|
||||
class RegistrationConfig(Config):
|
||||
section = "registration"
|
||||
|
||||
@@ -94,10 +33,6 @@ class RegistrationConfig(Config):
|
||||
strtobool(str(config["disable_registration"]))
|
||||
)
|
||||
|
||||
self.account_validity = AccountValidityConfig(
|
||||
config.get("account_validity") or {}, config
|
||||
)
|
||||
|
||||
self.registrations_require_3pid = config.get("registrations_require_3pid", [])
|
||||
self.allowed_local_3pids = config.get("allowed_local_3pids", [])
|
||||
self.enable_3pid_lookup = config.get("enable_3pid_lookup", True)
|
||||
@@ -211,69 +146,6 @@ class RegistrationConfig(Config):
|
||||
#
|
||||
#enable_registration: false
|
||||
|
||||
# Optional account validity configuration. This allows for accounts to be denied
|
||||
# any request after a given period.
|
||||
#
|
||||
# Once this feature is enabled, Synapse will look for registered users without an
|
||||
# expiration date at startup and will add one to every account it found using the
|
||||
# current settings at that time.
|
||||
# This means that, if a validity period is set, and Synapse is restarted (it will
|
||||
# then derive an expiration date from the current validity period), and some time
|
||||
# after that the validity period changes and Synapse is restarted, the users'
|
||||
# expiration dates won't be updated unless their account is manually renewed. This
|
||||
# date will be randomly selected within a range [now + period - d ; now + period],
|
||||
# where d is equal to 10%% of the validity period.
|
||||
#
|
||||
account_validity:
|
||||
# The account validity feature is disabled by default. Uncomment the
|
||||
# following line to enable it.
|
||||
#
|
||||
#enabled: true
|
||||
|
||||
# The period after which an account is valid after its registration. When
|
||||
# renewing the account, its validity period will be extended by this amount
|
||||
# of time. This parameter is required when using the account validity
|
||||
# feature.
|
||||
#
|
||||
#period: 6w
|
||||
|
||||
# The amount of time before an account's expiry date at which Synapse will
|
||||
# send an email to the account's email address with a renewal link. By
|
||||
# default, no such emails are sent.
|
||||
#
|
||||
# If you enable this setting, you will also need to fill out the 'email' and
|
||||
# 'public_baseurl' configuration sections.
|
||||
#
|
||||
#renew_at: 1w
|
||||
|
||||
# The subject of the email sent out with the renewal link. '%%(app)s' can be
|
||||
# used as a placeholder for the 'app_name' parameter from the 'email'
|
||||
# section.
|
||||
#
|
||||
# Note that the placeholder must be written '%%(app)s', including the
|
||||
# trailing 's'.
|
||||
#
|
||||
# If this is not set, a default value is used.
|
||||
#
|
||||
#renew_email_subject: "Renew your %%(app)s account"
|
||||
|
||||
# Directory in which Synapse will try to find templates for the HTML files to
|
||||
# serve to the user when trying to renew an account. If not set, default
|
||||
# templates from within the Synapse package will be used.
|
||||
#
|
||||
#template_dir: "res/templates"
|
||||
|
||||
# File within 'template_dir' giving the HTML to be displayed to the user after
|
||||
# they successfully renewed their account. If not set, default text is used.
|
||||
#
|
||||
#account_renewed_html_path: "account_renewed.html"
|
||||
|
||||
# File within 'template_dir' giving the HTML to be displayed when the user
|
||||
# tries to renew an account with an invalid renewal token. If not set,
|
||||
# default text is used.
|
||||
#
|
||||
#invalid_token_html_path: "invalid_token.html"
|
||||
|
||||
# Time that a user's session remains valid for, after they log in.
|
||||
#
|
||||
# Note that this is not currently compatible with guest logins.
|
||||
@@ -347,8 +219,9 @@ class RegistrationConfig(Config):
|
||||
# email will be globally disabled.
|
||||
#
|
||||
# Additionally, if `msisdn` is not set, registration and password resets via msisdn
|
||||
# will be disabled regardless. This is due to Synapse currently not supporting any
|
||||
# method of sending SMS messages on its own.
|
||||
# will be disabled regardless, and users will not be able to associate an msisdn
|
||||
# identifier to their account. This is due to Synapse currently not supporting
|
||||
# any method of sending SMS messages on its own.
|
||||
#
|
||||
# To enable using an identity server for operations regarding a particular third-party
|
||||
# identifier type, set the value to the URL of that identity server as shown in the
|
||||
|
||||
@@ -17,6 +17,9 @@ import os
|
||||
from collections import namedtuple
|
||||
from typing import Dict, List
|
||||
|
||||
from netaddr import IPSet
|
||||
|
||||
from synapse.config.server import DEFAULT_IP_RANGE_BLACKLIST
|
||||
from synapse.python_dependencies import DependencyException, check_requirements
|
||||
from synapse.util.module_loader import load_module
|
||||
|
||||
@@ -142,7 +145,7 @@ class ContentRepositoryConfig(Config):
|
||||
# them to be started.
|
||||
self.media_storage_providers = [] # type: List[tuple]
|
||||
|
||||
for provider_config in storage_providers:
|
||||
for i, provider_config in enumerate(storage_providers):
|
||||
# We special case the module "file_system" so as not to need to
|
||||
# expose FileStorageProviderBackend
|
||||
if provider_config["module"] == "file_system":
|
||||
@@ -151,7 +154,9 @@ class ContentRepositoryConfig(Config):
|
||||
".FileStorageProviderBackend"
|
||||
)
|
||||
|
||||
provider_class, parsed_config = load_module(provider_config)
|
||||
provider_class, parsed_config = load_module(
|
||||
provider_config, ("media_storage_providers", "<item %i>" % i)
|
||||
)
|
||||
|
||||
wrapper_config = MediaStorageProviderConfig(
|
||||
provider_config.get("store_local", False),
|
||||
@@ -182,9 +187,6 @@ class ContentRepositoryConfig(Config):
|
||||
"to work"
|
||||
)
|
||||
|
||||
# netaddr is a dependency for url_preview
|
||||
from netaddr import IPSet
|
||||
|
||||
self.url_preview_ip_range_blacklist = IPSet(
|
||||
config["url_preview_ip_range_blacklist"]
|
||||
)
|
||||
@@ -213,6 +215,10 @@ class ContentRepositoryConfig(Config):
|
||||
# strip final NL
|
||||
formatted_thumbnail_sizes = formatted_thumbnail_sizes[:-1]
|
||||
|
||||
ip_range_blacklist = "\n".join(
|
||||
" # - '%s'" % ip for ip in DEFAULT_IP_RANGE_BLACKLIST
|
||||
)
|
||||
|
||||
return (
|
||||
r"""
|
||||
## Media Store ##
|
||||
@@ -283,15 +289,7 @@ class ContentRepositoryConfig(Config):
|
||||
# you uncomment the following list as a starting point.
|
||||
#
|
||||
#url_preview_ip_range_blacklist:
|
||||
# - '127.0.0.0/8'
|
||||
# - '10.0.0.0/8'
|
||||
# - '172.16.0.0/12'
|
||||
# - '192.168.0.0/16'
|
||||
# - '100.64.0.0/10'
|
||||
# - '169.254.0.0/16'
|
||||
# - '::1/128'
|
||||
# - 'fe80::/64'
|
||||
# - 'fc00::/7'
|
||||
%(ip_range_blacklist)s
|
||||
|
||||
# List of IP address CIDR ranges that the URL preview spider is allowed
|
||||
# to access even if they are specified in url_preview_ip_range_blacklist.
|
||||
|
||||
@@ -180,7 +180,7 @@ class _RoomDirectoryRule:
|
||||
self._alias_regex = glob_to_regex(alias)
|
||||
self._room_id_regex = glob_to_regex(room_id)
|
||||
except Exception as e:
|
||||
raise ConfigError("Failed to parse glob into regex: %s", e)
|
||||
raise ConfigError("Failed to parse glob into regex") from e
|
||||
|
||||
def matches(self, user_id, room_id, aliases):
|
||||
"""Tests if this rule matches the given user_id, room_id and aliases.
|
||||
|
||||
@@ -90,6 +90,8 @@ class SAML2Config(Config):
|
||||
"grandfathered_mxid_source_attribute", "uid"
|
||||
)
|
||||
|
||||
self.saml2_idp_entityid = saml2_config.get("idp_entityid", None)
|
||||
|
||||
# user_mapping_provider may be None if the key is present but has no value
|
||||
ump_dict = saml2_config.get("user_mapping_provider") or {}
|
||||
|
||||
@@ -123,7 +125,7 @@ class SAML2Config(Config):
|
||||
(
|
||||
self.saml2_user_mapping_provider_class,
|
||||
self.saml2_user_mapping_provider_config,
|
||||
) = load_module(ump_dict)
|
||||
) = load_module(ump_dict, ("saml2_config", "user_mapping_provider"))
|
||||
|
||||
# Ensure loaded user mapping module has defined all necessary methods
|
||||
# Note parse_config() is already checked during the call to load_module
|
||||
@@ -256,6 +258,12 @@ class SAML2Config(Config):
|
||||
# remote:
|
||||
# - url: https://our_idp/metadata.xml
|
||||
|
||||
# Allowed clock difference in seconds between the homeserver and IdP.
|
||||
#
|
||||
# Uncomment the below to increase the accepted time difference from 0 to 3 seconds.
|
||||
#
|
||||
#accepted_time_diff: 3
|
||||
|
||||
# By default, the user has to go to our login page first. If you'd like
|
||||
# to allow IdP-initiated login, set 'allow_unsolicited: true' in a
|
||||
# 'service.sp' section:
|
||||
@@ -377,6 +385,14 @@ class SAML2Config(Config):
|
||||
# value: "staff"
|
||||
# - attribute: department
|
||||
# value: "sales"
|
||||
|
||||
# If the metadata XML contains multiple IdP entities then the `idp_entityid`
|
||||
# option must be set to the entity to redirect users to.
|
||||
#
|
||||
# Most deployments only have a single IdP entity and so should omit this
|
||||
# option.
|
||||
#
|
||||
#idp_entityid: 'https://our_idp/entityid'
|
||||
""" % {
|
||||
"config_dir_path": config_dir_path
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ from typing import Any, Dict, Iterable, List, Optional, Set
|
||||
|
||||
import attr
|
||||
import yaml
|
||||
from netaddr import IPSet
|
||||
|
||||
from synapse.api.room_versions import KNOWN_ROOM_VERSIONS
|
||||
from synapse.http.endpoint import parse_and_validate_server_name
|
||||
@@ -39,6 +40,34 @@ logger = logging.Logger(__name__)
|
||||
# in the list.
|
||||
DEFAULT_BIND_ADDRESSES = ["::", "0.0.0.0"]
|
||||
|
||||
DEFAULT_IP_RANGE_BLACKLIST = [
|
||||
# Localhost
|
||||
"127.0.0.0/8",
|
||||
# Private networks.
|
||||
"10.0.0.0/8",
|
||||
"172.16.0.0/12",
|
||||
"192.168.0.0/16",
|
||||
# Carrier grade NAT.
|
||||
"100.64.0.0/10",
|
||||
# Address registry.
|
||||
"192.0.0.0/24",
|
||||
# Link-local networks.
|
||||
"169.254.0.0/16",
|
||||
# Testing networks.
|
||||
"198.18.0.0/15",
|
||||
"192.0.2.0/24",
|
||||
"198.51.100.0/24",
|
||||
"203.0.113.0/24",
|
||||
# Multicast.
|
||||
"224.0.0.0/4",
|
||||
# Localhost
|
||||
"::1/128",
|
||||
# Link-local addresses.
|
||||
"fe80::/10",
|
||||
# Unique local addresses.
|
||||
"fc00::/7",
|
||||
]
|
||||
|
||||
DEFAULT_ROOM_VERSION = "6"
|
||||
|
||||
ROOM_COMPLEXITY_TOO_GREAT = (
|
||||
@@ -256,6 +285,38 @@ class ServerConfig(Config):
|
||||
# due to resource constraints
|
||||
self.admin_contact = config.get("admin_contact", None)
|
||||
|
||||
ip_range_blacklist = config.get(
|
||||
"ip_range_blacklist", DEFAULT_IP_RANGE_BLACKLIST
|
||||
)
|
||||
|
||||
# Attempt to create an IPSet from the given ranges
|
||||
try:
|
||||
self.ip_range_blacklist = IPSet(ip_range_blacklist)
|
||||
except Exception as e:
|
||||
raise ConfigError("Invalid range(s) provided in ip_range_blacklist.") from e
|
||||
# Always blacklist 0.0.0.0, ::
|
||||
self.ip_range_blacklist.update(["0.0.0.0", "::"])
|
||||
|
||||
try:
|
||||
self.ip_range_whitelist = IPSet(config.get("ip_range_whitelist", ()))
|
||||
except Exception as e:
|
||||
raise ConfigError("Invalid range(s) provided in ip_range_whitelist.") from e
|
||||
|
||||
# The federation_ip_range_blacklist is used for backwards-compatibility
|
||||
# and only applies to federation and identity servers. If it is not given,
|
||||
# default to ip_range_blacklist.
|
||||
federation_ip_range_blacklist = config.get(
|
||||
"federation_ip_range_blacklist", ip_range_blacklist
|
||||
)
|
||||
try:
|
||||
self.federation_ip_range_blacklist = IPSet(federation_ip_range_blacklist)
|
||||
except Exception as e:
|
||||
raise ConfigError(
|
||||
"Invalid range(s) provided in federation_ip_range_blacklist."
|
||||
) from e
|
||||
# Always blacklist 0.0.0.0, ::
|
||||
self.federation_ip_range_blacklist.update(["0.0.0.0", "::"])
|
||||
|
||||
if self.public_baseurl is not None:
|
||||
if self.public_baseurl[-1] != "/":
|
||||
self.public_baseurl += "/"
|
||||
@@ -561,6 +622,10 @@ class ServerConfig(Config):
|
||||
def generate_config_section(
|
||||
self, server_name, data_dir_path, open_private_ports, listeners, **kwargs
|
||||
):
|
||||
ip_range_blacklist = "\n".join(
|
||||
" # - '%s'" % ip for ip in DEFAULT_IP_RANGE_BLACKLIST
|
||||
)
|
||||
|
||||
_, bind_port = parse_and_validate_server_name(server_name)
|
||||
if bind_port is not None:
|
||||
unsecure_port = bind_port - 400
|
||||
@@ -752,6 +817,21 @@ class ServerConfig(Config):
|
||||
#
|
||||
#enable_search: false
|
||||
|
||||
# Prevent outgoing requests from being sent to the following blacklisted IP address
|
||||
# CIDR ranges. If this option is not specified then it defaults to private IP
|
||||
# address ranges (see the example below).
|
||||
#
|
||||
# The blacklist applies to the outbound requests for federation, identity servers,
|
||||
# push servers, and for checking key validity for third-party invite events.
|
||||
#
|
||||
# (0.0.0.0 and :: are always blacklisted, whether or not they are explicitly
|
||||
# listed here, since they correspond to unroutable addresses.)
|
||||
#
|
||||
# This option replaces federation_ip_range_blacklist in Synapse v1.25.0.
|
||||
#
|
||||
#ip_range_blacklist:
|
||||
%(ip_range_blacklist)s
|
||||
|
||||
# List of ports that Synapse should listen on, their purpose and their
|
||||
# configuration.
|
||||
#
|
||||
|
||||
@@ -33,13 +33,14 @@ class SpamCheckerConfig(Config):
|
||||
# spam checker, and thus was simply a dictionary with module
|
||||
# and config keys. Support this old behaviour by checking
|
||||
# to see if the option resolves to a dictionary
|
||||
self.spam_checkers.append(load_module(spam_checkers))
|
||||
self.spam_checkers.append(load_module(spam_checkers, ("spam_checker",)))
|
||||
elif isinstance(spam_checkers, list):
|
||||
for spam_checker in spam_checkers:
|
||||
for i, spam_checker in enumerate(spam_checkers):
|
||||
config_path = ("spam_checker", "<item %i>" % i)
|
||||
if not isinstance(spam_checker, dict):
|
||||
raise ConfigError("spam_checker syntax is incorrect")
|
||||
raise ConfigError("expected a mapping", config_path)
|
||||
|
||||
self.spam_checkers.append(load_module(spam_checker))
|
||||
self.spam_checkers.append(load_module(spam_checker, config_path))
|
||||
else:
|
||||
raise ConfigError("spam_checker syntax is incorrect")
|
||||
|
||||
|
||||
@@ -93,11 +93,8 @@ class SSOConfig(Config):
|
||||
# - https://my.custom.client/
|
||||
|
||||
# Directory in which Synapse will try to find the template files below.
|
||||
# If not set, default templates from within the Synapse package will be used.
|
||||
#
|
||||
# DO NOT UNCOMMENT THIS SETTING unless you want to customise the templates.
|
||||
# If you *do* uncomment it, you will need to make sure that all the templates
|
||||
# below are in the directory.
|
||||
# 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:
|
||||
#
|
||||
|
||||
@@ -26,7 +26,9 @@ class ThirdPartyRulesConfig(Config):
|
||||
|
||||
provider = config.get("third_party_event_rules", None)
|
||||
if provider is not None:
|
||||
self.third_party_event_rules = load_module(provider)
|
||||
self.third_party_event_rules = load_module(
|
||||
provider, ("third_party_event_rules",)
|
||||
)
|
||||
|
||||
def generate_config_section(self, **kwargs):
|
||||
return """\
|
||||
|
||||
@@ -85,6 +85,9 @@ class WorkerConfig(Config):
|
||||
# The port on the main synapse for HTTP replication endpoint
|
||||
self.worker_replication_http_port = config.get("worker_replication_http_port")
|
||||
|
||||
# The shared secret used for authentication when connecting to the main synapse.
|
||||
self.worker_replication_secret = config.get("worker_replication_secret", None)
|
||||
|
||||
self.worker_name = config.get("worker_name", self.worker_app)
|
||||
|
||||
self.worker_main_http_uri = config.get("worker_main_http_uri", None)
|
||||
@@ -185,6 +188,13 @@ class WorkerConfig(Config):
|
||||
# data). If not provided this defaults to the main process.
|
||||
#
|
||||
#run_background_tasks_on: worker1
|
||||
|
||||
# A shared secret used by the replication APIs to authenticate HTTP requests
|
||||
# from workers.
|
||||
#
|
||||
# By default this is unused and traffic is not authenticated.
|
||||
#
|
||||
#worker_replication_secret: ""
|
||||
"""
|
||||
|
||||
def read_arguments(self, args):
|
||||
|
||||
@@ -578,7 +578,7 @@ class PerspectivesKeyFetcher(BaseV2KeyFetcher):
|
||||
def __init__(self, hs):
|
||||
super().__init__(hs)
|
||||
self.clock = hs.get_clock()
|
||||
self.client = hs.get_http_client()
|
||||
self.client = hs.get_federation_http_client()
|
||||
self.key_servers = self.config.key_servers
|
||||
|
||||
async def get_keys(self, keys_to_fetch):
|
||||
@@ -748,7 +748,7 @@ class ServerKeyFetcher(BaseV2KeyFetcher):
|
||||
def __init__(self, hs):
|
||||
super().__init__(hs)
|
||||
self.clock = hs.get_clock()
|
||||
self.client = hs.get_http_client()
|
||||
self.client = hs.get_federation_http_client()
|
||||
|
||||
async def get_keys(self, keys_to_fetch):
|
||||
"""
|
||||
|
||||
@@ -15,13 +15,12 @@
|
||||
# limitations under the License.
|
||||
|
||||
import inspect
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple
|
||||
|
||||
from synapse.spam_checker_api import RegistrationBehaviour
|
||||
from synapse.types import Collection
|
||||
|
||||
MYPY = False
|
||||
if MYPY:
|
||||
if TYPE_CHECKING:
|
||||
import synapse.events
|
||||
import synapse.server
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ from synapse.federation.federation_base import FederationBase, event_from_pdu_js
|
||||
from synapse.federation.persistence import TransactionActions
|
||||
from synapse.federation.units import Edu, Transaction
|
||||
from synapse.http.endpoint import parse_server_name
|
||||
from synapse.http.servlet import assert_params_in_dict
|
||||
from synapse.logging.context import (
|
||||
make_deferred_yieldable,
|
||||
nested_logging_context,
|
||||
@@ -391,7 +392,7 @@ class FederationServer(FederationBase):
|
||||
TRANSACTION_CONCURRENCY_LIMIT,
|
||||
)
|
||||
|
||||
async def on_context_state_request(
|
||||
async def on_room_state_request(
|
||||
self, origin: str, room_id: str, event_id: str
|
||||
) -> Tuple[int, Dict[str, Any]]:
|
||||
origin_host, _ = parse_server_name(origin)
|
||||
@@ -514,11 +515,12 @@ class FederationServer(FederationBase):
|
||||
return {"event": ret_pdu.get_pdu_json(time_now)}
|
||||
|
||||
async def on_send_join_request(
|
||||
self, origin: str, content: JsonDict, room_id: str
|
||||
self, origin: str, content: JsonDict
|
||||
) -> Dict[str, Any]:
|
||||
logger.debug("on_send_join_request: content: %s", content)
|
||||
|
||||
room_version = await self.store.get_room_version(room_id)
|
||||
assert_params_in_dict(content, ["room_id"])
|
||||
room_version = await self.store.get_room_version(content["room_id"])
|
||||
pdu = event_from_pdu_json(content, room_version)
|
||||
|
||||
origin_host, _ = parse_server_name(origin)
|
||||
@@ -547,12 +549,11 @@ class FederationServer(FederationBase):
|
||||
time_now = self._clock.time_msec()
|
||||
return {"event": pdu.get_pdu_json(time_now), "room_version": room_version}
|
||||
|
||||
async def on_send_leave_request(
|
||||
self, origin: str, content: JsonDict, room_id: str
|
||||
) -> dict:
|
||||
async def on_send_leave_request(self, origin: str, content: JsonDict) -> dict:
|
||||
logger.debug("on_send_leave_request: content: %s", content)
|
||||
|
||||
room_version = await self.store.get_room_version(room_id)
|
||||
assert_params_in_dict(content, ["room_id"])
|
||||
room_version = await self.store.get_room_version(content["room_id"])
|
||||
pdu = event_from_pdu_json(content, room_version)
|
||||
|
||||
origin_host, _ = parse_server_name(origin)
|
||||
@@ -748,12 +749,8 @@ class FederationServer(FederationBase):
|
||||
)
|
||||
return ret
|
||||
|
||||
async def on_exchange_third_party_invite_request(
|
||||
self, room_id: str, event_dict: Dict
|
||||
):
|
||||
ret = await self.handler.on_exchange_third_party_invite_request(
|
||||
room_id, event_dict
|
||||
)
|
||||
async def on_exchange_third_party_invite_request(self, event_dict: Dict):
|
||||
ret = await self.handler.on_exchange_third_party_invite_request(event_dict)
|
||||
return ret
|
||||
|
||||
async def check_server_matches_acl(self, server_name: str, room_id: str):
|
||||
@@ -848,7 +845,6 @@ class FederationHandlerRegistry:
|
||||
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
self.config = hs.config
|
||||
self.http_client = hs.get_simple_http_client()
|
||||
self.clock = hs.get_clock()
|
||||
self._instance_name = hs.get_instance_name()
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ class TransportLayerClient:
|
||||
|
||||
def __init__(self, hs):
|
||||
self.server_name = hs.hostname
|
||||
self.client = hs.get_http_client()
|
||||
self.client = hs.get_federation_http_client()
|
||||
|
||||
@log_function
|
||||
def get_room_state_ids(self, destination, room_id, event_id):
|
||||
|
||||
@@ -440,13 +440,13 @@ class FederationEventServlet(BaseFederationServlet):
|
||||
|
||||
|
||||
class FederationStateV1Servlet(BaseFederationServlet):
|
||||
PATH = "/state/(?P<context>[^/]*)/?"
|
||||
PATH = "/state/(?P<room_id>[^/]*)/?"
|
||||
|
||||
# This is when someone asks for all data for a given context.
|
||||
async def on_GET(self, origin, content, query, context):
|
||||
return await self.handler.on_context_state_request(
|
||||
# This is when someone asks for all data for a given room.
|
||||
async def on_GET(self, origin, content, query, room_id):
|
||||
return await self.handler.on_room_state_request(
|
||||
origin,
|
||||
context,
|
||||
room_id,
|
||||
parse_string_from_args(query, "event_id", None, required=False),
|
||||
)
|
||||
|
||||
@@ -463,16 +463,16 @@ class FederationStateIdsServlet(BaseFederationServlet):
|
||||
|
||||
|
||||
class FederationBackfillServlet(BaseFederationServlet):
|
||||
PATH = "/backfill/(?P<context>[^/]*)/?"
|
||||
PATH = "/backfill/(?P<room_id>[^/]*)/?"
|
||||
|
||||
async def on_GET(self, origin, content, query, context):
|
||||
async def on_GET(self, origin, content, query, room_id):
|
||||
versions = [x.decode("ascii") for x in query[b"v"]]
|
||||
limit = parse_integer_from_args(query, "limit", None)
|
||||
|
||||
if not limit:
|
||||
return 400, {"error": "Did not include limit param"}
|
||||
|
||||
return await self.handler.on_backfill_request(origin, context, versions, limit)
|
||||
return await self.handler.on_backfill_request(origin, room_id, versions, limit)
|
||||
|
||||
|
||||
class FederationQueryServlet(BaseFederationServlet):
|
||||
@@ -487,9 +487,9 @@ class FederationQueryServlet(BaseFederationServlet):
|
||||
|
||||
|
||||
class FederationMakeJoinServlet(BaseFederationServlet):
|
||||
PATH = "/make_join/(?P<context>[^/]*)/(?P<user_id>[^/]*)"
|
||||
PATH = "/make_join/(?P<room_id>[^/]*)/(?P<user_id>[^/]*)"
|
||||
|
||||
async def on_GET(self, origin, _content, query, context, user_id):
|
||||
async def on_GET(self, origin, _content, query, room_id, user_id):
|
||||
"""
|
||||
Args:
|
||||
origin (unicode): The authenticated server_name of the calling server
|
||||
@@ -511,16 +511,16 @@ class FederationMakeJoinServlet(BaseFederationServlet):
|
||||
supported_versions = ["1"]
|
||||
|
||||
content = await self.handler.on_make_join_request(
|
||||
origin, context, user_id, supported_versions=supported_versions
|
||||
origin, room_id, user_id, supported_versions=supported_versions
|
||||
)
|
||||
return 200, content
|
||||
|
||||
|
||||
class FederationMakeLeaveServlet(BaseFederationServlet):
|
||||
PATH = "/make_leave/(?P<context>[^/]*)/(?P<user_id>[^/]*)"
|
||||
PATH = "/make_leave/(?P<room_id>[^/]*)/(?P<user_id>[^/]*)"
|
||||
|
||||
async def on_GET(self, origin, content, query, context, user_id):
|
||||
content = await self.handler.on_make_leave_request(origin, context, user_id)
|
||||
async def on_GET(self, origin, content, query, room_id, user_id):
|
||||
content = await self.handler.on_make_leave_request(origin, room_id, user_id)
|
||||
return 200, content
|
||||
|
||||
|
||||
@@ -528,7 +528,7 @@ class FederationV1SendLeaveServlet(BaseFederationServlet):
|
||||
PATH = "/send_leave/(?P<room_id>[^/]*)/(?P<event_id>[^/]*)"
|
||||
|
||||
async def on_PUT(self, origin, content, query, room_id, event_id):
|
||||
content = await self.handler.on_send_leave_request(origin, content, room_id)
|
||||
content = await self.handler.on_send_leave_request(origin, content)
|
||||
return 200, (200, content)
|
||||
|
||||
|
||||
@@ -538,43 +538,43 @@ class FederationV2SendLeaveServlet(BaseFederationServlet):
|
||||
PREFIX = FEDERATION_V2_PREFIX
|
||||
|
||||
async def on_PUT(self, origin, content, query, room_id, event_id):
|
||||
content = await self.handler.on_send_leave_request(origin, content, room_id)
|
||||
content = await self.handler.on_send_leave_request(origin, content)
|
||||
return 200, content
|
||||
|
||||
|
||||
class FederationEventAuthServlet(BaseFederationServlet):
|
||||
PATH = "/event_auth/(?P<context>[^/]*)/(?P<event_id>[^/]*)"
|
||||
PATH = "/event_auth/(?P<room_id>[^/]*)/(?P<event_id>[^/]*)"
|
||||
|
||||
async def on_GET(self, origin, content, query, context, event_id):
|
||||
return await self.handler.on_event_auth(origin, context, event_id)
|
||||
async def on_GET(self, origin, content, query, room_id, event_id):
|
||||
return await self.handler.on_event_auth(origin, room_id, event_id)
|
||||
|
||||
|
||||
class FederationV1SendJoinServlet(BaseFederationServlet):
|
||||
PATH = "/send_join/(?P<context>[^/]*)/(?P<event_id>[^/]*)"
|
||||
PATH = "/send_join/(?P<room_id>[^/]*)/(?P<event_id>[^/]*)"
|
||||
|
||||
async def on_PUT(self, origin, content, query, context, event_id):
|
||||
# TODO(paul): assert that context/event_id parsed from path actually
|
||||
async def on_PUT(self, origin, content, query, room_id, event_id):
|
||||
# TODO(paul): assert that room_id/event_id parsed from path actually
|
||||
# match those given in content
|
||||
content = await self.handler.on_send_join_request(origin, content, context)
|
||||
content = await self.handler.on_send_join_request(origin, content)
|
||||
return 200, (200, content)
|
||||
|
||||
|
||||
class FederationV2SendJoinServlet(BaseFederationServlet):
|
||||
PATH = "/send_join/(?P<context>[^/]*)/(?P<event_id>[^/]*)"
|
||||
PATH = "/send_join/(?P<room_id>[^/]*)/(?P<event_id>[^/]*)"
|
||||
|
||||
PREFIX = FEDERATION_V2_PREFIX
|
||||
|
||||
async def on_PUT(self, origin, content, query, context, event_id):
|
||||
# TODO(paul): assert that context/event_id parsed from path actually
|
||||
async def on_PUT(self, origin, content, query, room_id, event_id):
|
||||
# TODO(paul): assert that room_id/event_id parsed from path actually
|
||||
# match those given in content
|
||||
content = await self.handler.on_send_join_request(origin, content, context)
|
||||
content = await self.handler.on_send_join_request(origin, content)
|
||||
return 200, content
|
||||
|
||||
|
||||
class FederationV1InviteServlet(BaseFederationServlet):
|
||||
PATH = "/invite/(?P<context>[^/]*)/(?P<event_id>[^/]*)"
|
||||
PATH = "/invite/(?P<room_id>[^/]*)/(?P<event_id>[^/]*)"
|
||||
|
||||
async def on_PUT(self, origin, content, query, context, event_id):
|
||||
async def on_PUT(self, origin, content, query, room_id, event_id):
|
||||
# We don't get a room version, so we have to assume its EITHER v1 or
|
||||
# v2. This is "fine" as the only difference between V1 and V2 is the
|
||||
# state resolution algorithm, and we don't use that for processing
|
||||
@@ -589,12 +589,12 @@ class FederationV1InviteServlet(BaseFederationServlet):
|
||||
|
||||
|
||||
class FederationV2InviteServlet(BaseFederationServlet):
|
||||
PATH = "/invite/(?P<context>[^/]*)/(?P<event_id>[^/]*)"
|
||||
PATH = "/invite/(?P<room_id>[^/]*)/(?P<event_id>[^/]*)"
|
||||
|
||||
PREFIX = FEDERATION_V2_PREFIX
|
||||
|
||||
async def on_PUT(self, origin, content, query, context, event_id):
|
||||
# TODO(paul): assert that context/event_id parsed from path actually
|
||||
async def on_PUT(self, origin, content, query, room_id, event_id):
|
||||
# TODO(paul): assert that room_id/event_id parsed from path actually
|
||||
# match those given in content
|
||||
|
||||
room_version = content["room_version"]
|
||||
@@ -616,9 +616,7 @@ class FederationThirdPartyInviteExchangeServlet(BaseFederationServlet):
|
||||
PATH = "/exchange_third_party_invite/(?P<room_id>[^/]*)"
|
||||
|
||||
async def on_PUT(self, origin, content, query, room_id):
|
||||
content = await self.handler.on_exchange_third_party_invite_request(
|
||||
room_id, content
|
||||
)
|
||||
content = await self.handler.on_exchange_third_party_invite_request(content)
|
||||
return 200, content
|
||||
|
||||
|
||||
@@ -1464,7 +1462,7 @@ def register_servlets(hs, resource, authenticator, ratelimiter, servlet_groups=N
|
||||
|
||||
Args:
|
||||
hs (synapse.server.HomeServer): homeserver
|
||||
resource (TransportLayerServer): resource class to register to
|
||||
resource (JsonResource): resource class to register to
|
||||
authenticator (Authenticator): authenticator to use
|
||||
ratelimiter (util.ratelimitutils.FederationRateLimiter): ratelimiter to use
|
||||
servlet_groups (list[str], optional): List of servlet groups to register.
|
||||
|
||||
@@ -32,6 +32,10 @@ logger = logging.getLogger(__name__)
|
||||
class BaseHandler:
|
||||
"""
|
||||
Common base class for the event handlers.
|
||||
|
||||
Deprecated: new code should not use this. Instead, Handler classes should define the
|
||||
fields they actually need. The utility methods should either be factored out to
|
||||
standalone helper functions, or to different Handler classes.
|
||||
"""
|
||||
|
||||
def __init__(self, hs: "HomeServer"):
|
||||
@@ -169,7 +173,9 @@ class BaseHandler:
|
||||
# and having homeservers have their own users leave keeps more
|
||||
# of that decision-making and control local to the guest-having
|
||||
# homeserver.
|
||||
requester = synapse.types.create_requester(target_user, is_guest=True)
|
||||
requester = synapse.types.create_requester(
|
||||
target_user, is_guest=True, authenticated_entity=self.server_name
|
||||
)
|
||||
handler = self.hs.get_room_member_handler()
|
||||
await handler.update_membership(
|
||||
requester,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user