From 52a0fa91f0419b843e1a11ad80a3cc916c0838d9 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 26 Mar 2021 19:31:43 +0000 Subject: [PATCH 1/5] Replace `room_invite_state_types` with `room_prejoin_state` `room_invite_state_types` was inconvenient as a configuration setting, because anyone that ever set it would not receive any new types that were added to the defaults. Here, we deprecate the old setting, and replace it with a couple of new settings under `room_prejoin_state`. --- changelog.d/9700.feature | 1 + docker/conf/homeserver.yaml | 8 --- docs/code_style.md | 3 + docs/sample_config.yaml | 33 ++++++--- synapse/config/api.py | 138 +++++++++++++++++++++++++++++------- synapse/handlers/message.py | 2 +- tests/utils.py | 1 - 7 files changed, 144 insertions(+), 42 deletions(-) create mode 100644 changelog.d/9700.feature diff --git a/changelog.d/9700.feature b/changelog.d/9700.feature new file mode 100644 index 000000000000..037de8367f93 --- /dev/null +++ b/changelog.d/9700.feature @@ -0,0 +1 @@ +Replace the `room_invite_state_types` configuration setting with `room_prejoin_state`. diff --git a/docker/conf/homeserver.yaml b/docker/conf/homeserver.yaml index 0dea62a87d5f..a792899540ee 100644 --- a/docker/conf/homeserver.yaml +++ b/docker/conf/homeserver.yaml @@ -173,18 +173,10 @@ report_stats: False ## API Configuration ## -room_invite_state_types: - - "m.room.join_rules" - - "m.room.canonical_alias" - - "m.room.avatar" - - "m.room.name" - {% if SYNAPSE_APPSERVICES %} app_service_config_files: {% for appservice in SYNAPSE_APPSERVICES %} - "{{ appservice }}" {% endfor %} -{% else %} -app_service_config_files: [] {% endif %} macaroon_secret_key: "{{ SYNAPSE_MACAROON_SECRET_KEY }}" diff --git a/docs/code_style.md b/docs/code_style.md index 190f8ab2de88..28fb7277c41b 100644 --- a/docs/code_style.md +++ b/docs/code_style.md @@ -128,6 +128,9 @@ Some guidelines follow: will be if no sub-options are enabled). - Lines should be wrapped at 80 characters. - Use two-space indents. +- `true` and `false` are spelt thus (as opposed to `True`, etc.) +- Use single quotes (`'`) rather than double-quotes (`"`) or backticks + (`` ` ``) to refer to configuration options. Example: diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml index 07a928224d8d..468b3369bcae 100644 --- a/docs/sample_config.yaml +++ b/docs/sample_config.yaml @@ -1451,14 +1451,31 @@ metrics_flags: ## API Configuration ## -# A list of event types that will be included in the room_invite_state -# -#room_invite_state_types: -# - "m.room.join_rules" -# - "m.room.canonical_alias" -# - "m.room.avatar" -# - "m.room.encryption" -# - "m.room.name" +# Controls for the state that is shared with users who receive an invite +# to a room +# +room_prejoin_state: + # By default, the following state event types are shared with users who + # receive invites to the room: + # + # - m.room.join_rules + # - m.room.canonical_alias + # - m.room.avatar + # - m.room.encryption + # - m.room.name + # + # Uncomment the following to disable these defaults (so that only the event + # types listed in 'additional_event_types' are shared). Defaults to 'false'. + # + #disable_default_event_types: true + + # Additional state event types to share with users when they are invited + # to a room. + # + # By default, this list is empty (so only the default event types are shared) + # + #additional_event_types: + # - org.example.custom.event.type # A list of application service config files to use diff --git a/synapse/config/api.py b/synapse/config/api.py index 74cd53a8ed34..93cc9fb44803 100644 --- a/synapse/config/api.py +++ b/synapse/config/api.py @@ -1,4 +1,4 @@ -# Copyright 2015, 2016 OpenMarket Ltd +# Copyright 2015-2021 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. @@ -12,38 +12,128 @@ # See the License for the specific language governing permissions and # limitations under the License. +import logging +from typing import Iterable + from synapse.api.constants import EventTypes +from synapse.config._base import Config, ConfigError +from synapse.config._util import validate_config +from synapse.types import JsonDict -from ._base import Config +logger = logging.getLogger(__name__) class ApiConfig(Config): section = "api" - def read_config(self, config, **kwargs): - self.room_invite_state_types = config.get( - "room_invite_state_types", - [ - EventTypes.JoinRules, - EventTypes.CanonicalAlias, - EventTypes.RoomAvatar, - EventTypes.RoomEncryption, - EventTypes.Name, - ], + def read_config(self, config: JsonDict, **kwargs): + validate_config(_MAIN_SCHEMA, config, ()) + self.room_prejoin_state = list(_get_prejoin_state_types(config)) + + def generate_config_section(cls, **kwargs) -> str: + formatted_default_state_types = "\n".join( + " # - %s" % (t,) for t in _DEFAULT_PREJOIN_STATE_TYPES ) - def generate_config_section(cls, **kwargs): return """\ ## API Configuration ## - - # A list of event types that will be included in the room_invite_state + + # Controls for the state that is shared with users who receive an invite + # to a room # - #room_invite_state_types: - # - "{JoinRules}" - # - "{CanonicalAlias}" - # - "{RoomAvatar}" - # - "{RoomEncryption}" - # - "{Name}" - """.format( - **vars(EventTypes) - ) + room_prejoin_state: + # By default, the following state event types are shared with users who + # receive invites to the room: + # +%(formatted_default_state_types)s + # + # Uncomment the following to disable these defaults (so that only the event + # types listed in 'additional_event_types' are shared). Defaults to 'false'. + # + #disable_default_event_types: true + + # Additional state event types to share with users when they are invited + # to a room. + # + # By default, this list is empty (so only the default event types are shared) + # + #additional_event_types: + # - org.example.custom.event.type + """ % { + "formatted_default_state_types": formatted_default_state_types + } + + +def _get_prejoin_state_types(config: JsonDict) -> Iterable[str]: + """Get the event types to include in the prejoin state + + Parsees the config and returns an iterable of the event types to be included. + """ + room_prejoin_state_config = config.get("room_prejoin_state") or {} + + # backwards-compatibility support for room_invite_state_types + if "room_invite_state_types" in config: + # if both "room_invite_state_types" and "room_prejoin_state" are set, then + # we don't really know what to do. + if room_prejoin_state_config: + raise ConfigError( + "Can't specify both 'room_invite_state_types' and 'room_prejoin_state' " + "in config" + ) + + logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING) + + yield from config["room_invite_state_types"] + return + + if not room_prejoin_state_config.get("disable_default_event_types"): + yield from _DEFAULT_PREJOIN_STATE_TYPES + + yield from room_prejoin_state_config.get("additional_event_types", []) + + +_ROOM_INVITE_STATE_TYPES_WARNING = """\ +WARNING: The 'room_invite_state_types' configuration setting is now deprecated, +and replaced with 'room_prejoin_state'. New features may not work correctly +unless room_invite_state_types is removed. See the sample configuration file for +details of 'room_prejoin_state'. +-------------------------------------------------------------------------------- +""" + +_DEFAULT_PREJOIN_STATE_TYPES = [ + EventTypes.JoinRules, + EventTypes.CanonicalAlias, + EventTypes.RoomAvatar, + EventTypes.RoomEncryption, + EventTypes.Name, +] + + +# room_prejoin_state can either be None (as it is in the default config), or +# an object containing other config settings +_ROOM_PREJOIN_STATE_CONFIG_SCHEMA = { + "oneOf": [ + { + "type": "object", + "properties": { + "disable_default_event_types": {"type": "boolean"}, + "additional_event_types": { + "type": "array", + "items": {"type": "string"}, + }, + }, + }, + {"type": "null"}, + ] +} + +# the legacy room_invite_state_types setting +_ROOM_INVITE_STATE_TYPES_SCHEMA = {"type": "array", "items": {"type": "string"}} + +_MAIN_SCHEMA = { + "type": "object", + "properties": { + "room_prejoin_state": _ROOM_PREJOIN_STATE_CONFIG_SCHEMA, + "room_invite_state_types": _ROOM_INVITE_STATE_TYPES_SCHEMA, + }, +} diff --git a/synapse/handlers/message.py b/synapse/handlers/message.py index 1b7c065b34e1..6069968f7f34 100644 --- a/synapse/handlers/message.py +++ b/synapse/handlers/message.py @@ -385,7 +385,7 @@ def __init__(self, hs: "HomeServer"): self._events_shard_config = self.config.worker.events_shard_config self._instance_name = hs.get_instance_name() - self.room_invite_state_types = self.hs.config.room_invite_state_types + self.room_invite_state_types = self.hs.config.api.room_prejoin_state self.membership_types_to_include_profile_data_in = ( {Membership.JOIN, Membership.INVITE} diff --git a/tests/utils.py b/tests/utils.py index be80b1376089..a141ee64966f 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -122,7 +122,6 @@ def default_config(name, parse=False): "enable_registration_captcha": False, "macaroon_secret_key": "not even a little secret", "trusted_third_party_id_servers": [], - "room_invite_state_types": [], "password_providers": [], "worker_replication_url": "", "worker_app": None, From 186f819254e839b5d4be4eed294ec3de5dc62a73 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 29 Mar 2021 12:13:49 +0100 Subject: [PATCH 2/5] Fix lint --- synapse/config/api.py | 4 ++-- synapse/storage/databases/main/events_worker.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/synapse/config/api.py b/synapse/config/api.py index 93cc9fb44803..6aa39a9e3f26 100644 --- a/synapse/config/api.py +++ b/synapse/config/api.py @@ -37,7 +37,7 @@ def generate_config_section(cls, **kwargs) -> str: return """\ ## API Configuration ## - + # Controls for the state that is shared with users who receive an invite # to a room # @@ -51,7 +51,7 @@ def generate_config_section(cls, **kwargs) -> str: # types listed in 'additional_event_types' are shared). Defaults to 'false'. # #disable_default_event_types: true - + # Additional state event types to share with users when they are invited # to a room. # diff --git a/synapse/storage/databases/main/events_worker.py b/synapse/storage/databases/main/events_worker.py index 952d4969b220..c00780969f6e 100644 --- a/synapse/storage/databases/main/events_worker.py +++ b/synapse/storage/databases/main/events_worker.py @@ -16,7 +16,7 @@ import logging import threading from collections import namedtuple -from typing import Dict, Iterable, List, Optional, Tuple, overload +from typing import Container, Dict, Iterable, List, Optional, Tuple, overload from constantly import NamedConstant, Names from typing_extensions import Literal @@ -544,7 +544,7 @@ def _get_events_from_cache(self, events, allow_rejected, update_metrics=True): async def get_stripped_room_state_from_event_context( self, context: EventContext, - state_types_to_include: List[EventTypes], + state_types_to_include: Container[str], membership_user_id: Optional[str] = None, ) -> List[JsonDict]: """ From 2c6dd9d2c782a70db0deca8bcb1459867513d72e Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 29 Mar 2021 12:24:43 +0100 Subject: [PATCH 3/5] make _get_prejoin_state_types a method --- synapse/config/api.py | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/synapse/config/api.py b/synapse/config/api.py index 6aa39a9e3f26..6a65b323ca08 100644 --- a/synapse/config/api.py +++ b/synapse/config/api.py @@ -28,7 +28,7 @@ class ApiConfig(Config): def read_config(self, config: JsonDict, **kwargs): validate_config(_MAIN_SCHEMA, config, ()) - self.room_prejoin_state = list(_get_prejoin_state_types(config)) + self.room_prejoin_state = list(self._get_prejoin_state_types(config)) def generate_config_section(cls, **kwargs) -> str: formatted_default_state_types = "\n".join( @@ -63,33 +63,32 @@ def generate_config_section(cls, **kwargs) -> str: "formatted_default_state_types": formatted_default_state_types } + def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]: + """Get the event types to include in the prejoin state -def _get_prejoin_state_types(config: JsonDict) -> Iterable[str]: - """Get the event types to include in the prejoin state + Parsees the config and returns an iterable of the event types to be included. + """ + room_prejoin_state_config = config.get("room_prejoin_state") or {} - Parsees the config and returns an iterable of the event types to be included. - """ - room_prejoin_state_config = config.get("room_prejoin_state") or {} + # backwards-compatibility support for room_invite_state_types + if "room_invite_state_types" in config: + # if both "room_invite_state_types" and "room_prejoin_state" are set, then + # we don't really know what to do. + if room_prejoin_state_config: + raise ConfigError( + "Can't specify both 'room_invite_state_types' and 'room_prejoin_state' " + "in config" + ) - # backwards-compatibility support for room_invite_state_types - if "room_invite_state_types" in config: - # if both "room_invite_state_types" and "room_prejoin_state" are set, then - # we don't really know what to do. - if room_prejoin_state_config: - raise ConfigError( - "Can't specify both 'room_invite_state_types' and 'room_prejoin_state' " - "in config" - ) + logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING) - logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING) + yield from config["room_invite_state_types"] + return - yield from config["room_invite_state_types"] - return + if not room_prejoin_state_config.get("disable_default_event_types"): + yield from _DEFAULT_PREJOIN_STATE_TYPES - if not room_prejoin_state_config.get("disable_default_event_types"): - yield from _DEFAULT_PREJOIN_STATE_TYPES - - yield from room_prejoin_state_config.get("additional_event_types", []) + yield from room_prejoin_state_config.get("additional_event_types", []) _ROOM_INVITE_STATE_TYPES_WARNING = """\ From 4e1f79675871f61b208514c03f36ec5db04cfbc5 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Mon, 29 Mar 2021 18:34:24 +0100 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Andrew Morgan <1342360+anoadragon453@users.noreply.github.com> --- synapse/config/api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/synapse/config/api.py b/synapse/config/api.py index 6a65b323ca08..91387a7f0ec8 100644 --- a/synapse/config/api.py +++ b/synapse/config/api.py @@ -55,7 +55,7 @@ def generate_config_section(cls, **kwargs) -> str: # Additional state event types to share with users when they are invited # to a room. # - # By default, this list is empty (so only the default event types are shared) + # By default, this list is empty (so only the default event types are shared). # #additional_event_types: # - org.example.custom.event.type @@ -66,7 +66,7 @@ def generate_config_section(cls, **kwargs) -> str: def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]: """Get the event types to include in the prejoin state - Parsees the config and returns an iterable of the event types to be included. + Parses the config and returns an iterable of the event types to be included. """ room_prejoin_state_config = config.get("room_prejoin_state") or {} @@ -94,7 +94,7 @@ def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]: _ROOM_INVITE_STATE_TYPES_WARNING = """\ WARNING: The 'room_invite_state_types' configuration setting is now deprecated, and replaced with 'room_prejoin_state'. New features may not work correctly -unless room_invite_state_types is removed. See the sample configuration file for +unless 'room_invite_state_types' is removed. See the sample configuration file for details of 'room_prejoin_state'. -------------------------------------------------------------------------------- """ From 7c5024b8f27c71f456132663898296d39e8abded Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 30 Mar 2021 11:17:01 +0100 Subject: [PATCH 5/5] update sample config --- docs/sample_config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml index 468b3369bcae..8c952a7b06fe 100644 --- a/docs/sample_config.yaml +++ b/docs/sample_config.yaml @@ -1472,7 +1472,7 @@ room_prejoin_state: # Additional state event types to share with users when they are invited # to a room. # - # By default, this list is empty (so only the default event types are shared) + # By default, this list is empty (so only the default event types are shared). # #additional_event_types: # - org.example.custom.event.type