From 3c7fd98b40695ecc7eefdaee1c53ebf1642e19c2 Mon Sep 17 00:00:00 2001 From: babolivier Date: Fri, 18 Jun 2021 11:16:12 +0000 Subject: deploy: 1b3e398bea8129fa7ae6fe28fd3a395fcd427ad9 --- develop/print.html | 254 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 233 insertions(+), 21 deletions(-) (limited to 'develop/print.html') diff --git a/develop/print.html b/develop/print.html index 7f600f3308..be5abf152d 100644 --- a/develop/print.html +++ b/develop/print.html @@ -101,7 +101,7 @@ @@ -1448,6 +1448,15 @@ for example:

dpkg -i matrix-synapse-py3_1.3.0+stretch1_amd64.deb

+

Upgrading to v1.37.0

+

Deprecation of the current spam checker interface

+

The current spam checker interface is deprecated in favour of a new generic modules system. +Authors of spam checker modules can refer to this documentation <https://matrix-org.github.io/synapse/develop/modules.html#porting-an-existing-module-that-uses-the-old-interface>_ +to update their modules. Synapse administrators can refer to this documentation <https://matrix-org.github.io/synapse/develop/modules.html#using-modules>_ +to update their configuration once the modules they are using have been updated.

+

We plan to remove support for the current spam checker interface in August 2021.

+

More module interfaces will be ported over to this new generic system in future versions +of Synapse.

Upgrading to v1.34.0

room_invite_state_types configuration setting

The room_invite_state_types configuration setting has been deprecated and @@ -2735,6 +2744,22 @@ a fresh config using Synapse by following the instructions in # # [1] https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html + +## Modules ## + +# Server admins can expand Synapse's functionality with external modules. +# +# See https://matrix-org.github.io/synapse/develop/modules.html for more +# documentation on how to configure or create custom modules for Synapse. +# +modules: + # - module: my_super_module.MySuperClass + # config: + # do_thing: true + # - module: my_other_super_module.SomeClass + # config: {} + + ## Server ## # The public-facing domain of the server @@ -5195,19 +5220,6 @@ push: #group_unread_count_by_room: false -# Spam checkers are third-party modules that can block specific actions -# of local users, such as creating rooms and registering undesirable -# usernames, as well as remote users by redacting incoming events. -# -spam_checker: - #- module: "my_custom_project.SuperSpamChecker" - # config: - # example_option: 'things' - #- module: "some_other_project.BadEventStopper" - # config: - # example_stop_events_from: ['@bad:example.com'] - - ## Rooms ## # Controls whether locally-created rooms should be end-to-end encrypted by @@ -7172,7 +7184,207 @@ space, it will start writing new data into where the purged data was.

operating system, the server admin needs to run VACUUM FULL; (or VACUUM; for SQLite databases) on Synapse's database (see the related PostgreSQL documentation).

-

Handling spam in Synapse

+

Modules

+

Synapse supports extending its functionality by configuring external modules.

+

Using modules

+

To use a module on Synapse, add it to the modules section of the configuration file:

+
modules:
+  - module: my_super_module.MySuperClass
+    config:
+      do_thing: true
+  - module: my_other_super_module.SomeClass
+    config: {}
+
+

Each module is defined by a path to a Python class as well as a configuration. This +information for a given module should be available in the module's own documentation.

+

Note: When using third-party modules, you effectively allow someone else to run +custom code on your Synapse homeserver. Server admins are encouraged to verify the +provenance of the modules they use on their homeserver and make sure the modules aren't +running malicious code on their instance.

+

Also note that we are currently in the process of migrating module interfaces to this +system. While some interfaces might be compatible with it, others still require +configuring modules in another part of Synapse's configuration file. Currently, only the +spam checker interface is compatible with this new system.

+

Writing a module

+

A module is a Python class that uses Synapse's module API to interact with the +homeserver. It can register callbacks that Synapse will call on specific operations, as +well as web resources to attach to Synapse's web server.

+

When instantiated, a module is given its parsed configuration as well as an instance of +the synapse.module_api.ModuleApi class. The configuration is a dictionary, and is +either the output of the module's parse_config static method (see below), or the +configuration associated with the module in Synapse's configuration file.

+

See the documentation for the ModuleApi class +here.

+

Handling the module's configuration

+

A module can implement the following static method:

+
@staticmethod
+def parse_config(config: dict) -> dict
+
+

This method is given a dictionary resulting from parsing the YAML configuration for the +module. It may modify it (for example by parsing durations expressed as strings (e.g. +"5d") into milliseconds, etc.), and return the modified dictionary. It may also verify +that the configuration is correct, and raise an instance of +synapse.module_api.errors.ConfigError if not.

+

Registering a web resource

+

Modules can register web resources onto Synapse's web server using the following module +API method:

+
def ModuleApi.register_web_resource(path: str, resource: IResource)
+
+

The path is the full absolute path to register the resource at. For example, if you +register a resource for the path /_synapse/client/my_super_module/say_hello, Synapse +will serve it at http(s)://[HS_URL]/_synapse/client/my_super_module/say_hello. Note +that Synapse does not allow registering resources for several sub-paths in the /_matrix +namespace (such as anything under /_matrix/client for example). It is strongly +recommended that modules register their web resources under the /_synapse/client +namespace.

+

The provided resource is a Python class that implements Twisted's IResource +interface (such as Resource).

+

Only one resource can be registered for a given path. If several modules attempt to +register a resource for the same path, the module that appears first in Synapse's +configuration file takes priority.

+

Modules must register their web resources in their __init__ method.

+

Registering a callback

+

Modules can use Synapse's module API to register callbacks. Callbacks are functions that +Synapse will call when performing specific actions. Callbacks must be asynchronous, and +are split in categories. A single module may implement callbacks from multiple categories, +and is under no obligation to implement all callbacks from the categories it registers +callbacks for.

+

Spam checker callbacks

+

To register one of the callbacks described in this section, a module needs to use the +module API's register_spam_checker_callbacks method. The callback functions are passed +to register_spam_checker_callbacks as keyword arguments, with the callback name as the +argument name and the function as its value. This is demonstrated in the example below.

+

The available spam checker callbacks are:

+
def check_event_for_spam(event: "synapse.events.EventBase") -> Union[bool, str]
+
+

Called when receiving an event from a client or via federation. The module can return +either a bool to indicate whether the event must be rejected because of spam, or a str +to indicate the event must be rejected because of spam and to give a rejection reason to +forward to clients.

+
def user_may_invite(inviter: str, invitee: str, room_id: str) -> bool
+
+

Called when processing an invitation. The module must return a bool indicating whether +the inviter can invite the invitee to the given room. Both inviter and invitee are +represented by their Matrix user ID (i.e. @alice:example.com).

+
def user_may_create_room(user: str) -> bool
+
+

Called when processing a room creation request. The module must return a bool indicating +whether the given user (represented by their Matrix user ID) is allowed to create a room.

+
def user_may_create_room_alias(user: str, room_alias: "synapse.types.RoomAlias") -> bool
+
+

Called when trying to associate an alias with an existing room. The module must return a +bool indicating whether the given user (represented by their Matrix user ID) is allowed +to set the given alias.

+
def user_may_publish_room(user: str, room_id: str) -> bool
+
+

Called when trying to publish a room to the homeserver's public rooms directory. The +module must return a bool indicating whether the given user (represented by their +Matrix user ID) is allowed to publish the given room.

+
def check_username_for_spam(user_profile: Dict[str, str]) -> bool
+
+

Called when computing search results in the user directory. The module must return a +bool indicating whether the given user profile can appear in search results. The profile +is represented as a dictionary with the following keys:

+ +

The module is given a copy of the original dictionary, so modifying it from within the +module cannot modify a user's profile when included in user directory search results.

+
def check_registration_for_spam(
+    email_threepid: Optional[dict],
+    username: Optional[str],
+    request_info: Collection[Tuple[str, str]],
+    auth_provider_id: Optional[str] = None,
+) -> "synapse.spam_checker_api.RegistrationBehaviour"
+
+

Called when registering a new user. The module must return a RegistrationBehaviour +indicating whether the registration can go through or must be denied, or whether the user +may be allowed to register but will be shadow banned.

+

The arguments passed to this callback are:

+ +
def check_media_file_for_spam(
+    file_wrapper: "synapse.rest.media.v1.media_storage.ReadableFileWrapper",
+    file_info: "synapse.rest.media.v1._base.FileInfo"
+) -> bool
+
+

Called when storing a local or remote file. The module must return a boolean indicating +whether the given file can be stored in the homeserver's media store.

+

Porting an existing module that uses the old interface

+

In order to port a module that uses Synapse's old module interface, its author needs to:

+ +

Additionally, if the module is packaged with an additional web resource, the module +should register this resource in its __init__ method using the register_web_resource +method from the ModuleApi class (see this section for +more info).

+

The module's author should also update any example in the module's configuration to only +use the new modules section in Synapse's configuration file (see this section +for more info).

+

Example

+

The example below is a module that implements the spam checker callback +user_may_create_room to deny room creation to user @evilguy:example.com, and registers +a web resource to the path /_synapse/client/demo/hello that returns a JSON object.

+
import json
+
+from twisted.web.resource import Resource
+from twisted.web.server import Request
+
+from synapse.module_api import ModuleApi
+
+
+class DemoResource(Resource):
+    def __init__(self, config):
+        super(DemoResource, self).__init__()
+        self.config = config
+
+    def render_GET(self, request: Request):
+        name = request.args.get(b"name")[0]
+        request.setHeader(b"Content-Type", b"application/json")
+        return json.dumps({"hello": name})
+
+
+class DemoModule:
+    def __init__(self, config: dict, api: ModuleApi):
+        self.config = config
+        self.api = api
+
+        self.api.register_web_resource(
+            path="/_synapse/client/demo/hello",
+            resource=DemoResource(self.config),
+        )
+
+        self.api.register_spam_checker_callbacks(
+            user_may_create_room=self.user_may_create_room,
+        )
+
+    @staticmethod
+    def parse_config(config):
+        return config
+
+    async def user_may_create_room(self, user: str) -> bool:
+        if user == "@evilguy:example.com":
+            return False
+
+        return True
+
+

Note: this page of the Synapse documentation is now deprecated. For up to date +documentation on setting up or writing a spam checker module, please see +this page.

+

Handling spam in Synapse

Synapse has support to customize spam checking behavior. It can plug into a variety of events and affect how they are presented to users on your homeserver.

The spam checking behavior is implemented as a Python class, which must be @@ -7203,7 +7415,7 @@ call back into the homeserver internals.

Additionally, a parse_config method is mandatory and receives the plugin config dictionary. After parsing, It must return an object which will be passed to __init__ later.

-

Example

+

Example

from synapse.spam_checker_api import RegistrationBehaviour
 
 class ExampleSpamChecker:
@@ -7258,7 +7470,7 @@ custom logic, e.g. my_module.ExampleSpamChecker.

config is a dictionary that gets passed to the spam checker class.

-

Example

+

Example

This section might look like:

spam_checker:
   - module: my_module.ExampleSpamChecker
@@ -7335,7 +7547,7 @@ user should receive presence information for all known users.

{"@bob:example.com", "@charlie:somewhere.org"} is returned, this signifies that Alice should receive presence updates sent by Bob and Charlie, regardless of whether these users share a room.

-

Example

+

Example

Below is an example implementation of a presence router class.

from typing import Dict, Iterable, Set, Union
 from synapse.events.presence_router import PresenceRouter
@@ -9307,7 +9519,7 @@ that were not kicked.
 the old room to the new.
 
  • new_room_id - A string representing the room ID of the new room.
  • -

    Example

    +

    Example

    Request:

    POST /_synapse/admin/v1/shutdown_room/!somebadroom%3Aexample.com
     
    @@ -11971,7 +12183,7 @@ connection errors.

    received for each stream so that on reconneciton it can start streaming from the correct place. Note: not all RDATA have valid tokens due to batching. See RdataCommand for more details.

    -

    Example

    +

    Example

    An example iteraction is shown below. Each line is prefixed with '>' or '<' to indicate which side is sending, these are not included on the wire:

    @@ -12216,7 +12428,7 @@ graph), and one where we remove redundant links (the transitive reduction of the links graph) e.g. if we have chains C3 -> C2 -> C1 then the link C3 -> C1 would not be stored. Synapse uses the former implementations so that it doesn't need to recurse to test reachability between chains.

    -

    Example

    +

    Example

    An example auth graph would look like the following, where chains have been formed based on type/state_key and are denoted by colour and are labelled with (chain ID, sequence number). Links are denoted by the arrows (links in grey -- cgit 1.5.1