Skip to content
This repository was archived by the owner on Apr 26, 2024. It is now read-only.

Commit 5573133

Browse files
authored
Move experimental & retention config out of the server module. (#11070)
1 parent 6a67f37 commit 5573133

File tree

10 files changed

+290
-255
lines changed

10 files changed

+290
-255
lines changed

changelog.d/11070.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Create a separate module for the retention configuration.

docs/sample_config.yaml

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,48 @@ limit_remote_rooms:
472472
#
473473
#user_ips_max_age: 14d
474474

475+
# Inhibits the /requestToken endpoints from returning an error that might leak
476+
# information about whether an e-mail address is in use or not on this
477+
# homeserver.
478+
# Note that for some endpoints the error situation is the e-mail already being
479+
# used, and for others the error is entering the e-mail being unused.
480+
# If this option is enabled, instead of returning an error, these endpoints will
481+
# act as if no error happened and return a fake session ID ('sid') to clients.
482+
#
483+
#request_token_inhibit_3pid_errors: true
484+
485+
# A list of domains that the domain portion of 'next_link' parameters
486+
# must match.
487+
#
488+
# This parameter is optionally provided by clients while requesting
489+
# validation of an email or phone number, and maps to a link that
490+
# users will be automatically redirected to after validation
491+
# succeeds. Clients can make use this parameter to aid the validation
492+
# process.
493+
#
494+
# The whitelist is applied whether the homeserver or an
495+
# identity server is handling validation.
496+
#
497+
# The default value is no whitelist functionality; all domains are
498+
# allowed. Setting this value to an empty list will instead disallow
499+
# all domains.
500+
#
501+
#next_link_domain_whitelist: ["matrix.org"]
502+
503+
# Templates to use when generating email or HTML page contents.
504+
#
505+
templates:
506+
# Directory in which Synapse will try to find template files to use to generate
507+
# email or HTML page contents.
508+
# If not set, or a file is not found within the template directory, a default
509+
# template from within the Synapse package will be used.
510+
#
511+
# See https://matrix-org.github.io/synapse/latest/templates.html for more
512+
# information about using custom templates.
513+
#
514+
#custom_template_directory: /path/to/custom/templates/
515+
516+
475517
# Message retention policy at the server level.
476518
#
477519
# Room admins and mods can define a retention period for their rooms using the
@@ -541,47 +583,6 @@ retention:
541583
# - shortest_max_lifetime: 3d
542584
# interval: 1d
543585

544-
# Inhibits the /requestToken endpoints from returning an error that might leak
545-
# information about whether an e-mail address is in use or not on this
546-
# homeserver.
547-
# Note that for some endpoints the error situation is the e-mail already being
548-
# used, and for others the error is entering the e-mail being unused.
549-
# If this option is enabled, instead of returning an error, these endpoints will
550-
# act as if no error happened and return a fake session ID ('sid') to clients.
551-
#
552-
#request_token_inhibit_3pid_errors: true
553-
554-
# A list of domains that the domain portion of 'next_link' parameters
555-
# must match.
556-
#
557-
# This parameter is optionally provided by clients while requesting
558-
# validation of an email or phone number, and maps to a link that
559-
# users will be automatically redirected to after validation
560-
# succeeds. Clients can make use this parameter to aid the validation
561-
# process.
562-
#
563-
# The whitelist is applied whether the homeserver or an
564-
# identity server is handling validation.
565-
#
566-
# The default value is no whitelist functionality; all domains are
567-
# allowed. Setting this value to an empty list will instead disallow
568-
# all domains.
569-
#
570-
#next_link_domain_whitelist: ["matrix.org"]
571-
572-
# Templates to use when generating email or HTML page contents.
573-
#
574-
templates:
575-
# Directory in which Synapse will try to find template files to use to generate
576-
# email or HTML page contents.
577-
# If not set, or a file is not found within the template directory, a default
578-
# template from within the Synapse package will be used.
579-
#
580-
# See https://matrix-org.github.io/synapse/latest/templates.html for more
581-
# information about using custom templates.
582-
#
583-
#custom_template_directory: /path/to/custom/templates/
584-
585586

586587
## TLS ##
587588

synapse/config/_base.pyi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ from synapse.config import (
2626
redis,
2727
registration,
2828
repository,
29+
retention,
2930
room_directory,
3031
saml2,
3132
server,
@@ -91,6 +92,7 @@ class RootConfig:
9192
modules: modules.ModulesConfig
9293
caches: cache.CacheConfig
9394
federation: federation.FederationConfig
95+
retention: retention.RetentionConfig
9496

9597
config_classes: List = ...
9698
def __init__(self) -> None: ...

synapse/config/experimental.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ class ExperimentalConfig(Config):
2424
def read_config(self, config: JsonDict, **kwargs):
2525
experimental = config.get("experimental_features") or {}
2626

27+
# Whether to enable experimental MSC1849 (aka relations) support
28+
self.msc1849_enabled = config.get("experimental_msc1849_support_enabled", True)
29+
2730
# MSC3026 (busy presence state)
2831
self.msc3026_enabled: bool = experimental.get("msc3026_enabled", False)
2932

synapse/config/homeserver.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from .redis import RedisConfig
3939
from .registration import RegistrationConfig
4040
from .repository import ContentRepositoryConfig
41+
from .retention import RetentionConfig
4142
from .room import RoomConfig
4243
from .room_directory import RoomDirectoryConfig
4344
from .saml2 import SAML2Config
@@ -59,6 +60,7 @@ class HomeServerConfig(RootConfig):
5960
config_classes = [
6061
ModulesConfig,
6162
ServerConfig,
63+
RetentionConfig,
6264
TlsConfig,
6365
FederationConfig,
6466
CacheConfig,

synapse/config/retention.py

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
# Copyright 2021 The Matrix.org Foundation C.I.C.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import logging
16+
from typing import List, Optional
17+
18+
import attr
19+
20+
from synapse.config._base import Config, ConfigError
21+
22+
logger = logging.getLogger(__name__)
23+
24+
25+
@attr.s(slots=True, frozen=True, auto_attribs=True)
26+
class RetentionPurgeJob:
27+
"""Object describing the configuration of the manhole"""
28+
29+
interval: int
30+
shortest_max_lifetime: Optional[int]
31+
longest_max_lifetime: Optional[int]
32+
33+
34+
class RetentionConfig(Config):
35+
section = "retention"
36+
37+
def read_config(self, config, **kwargs):
38+
retention_config = config.get("retention")
39+
if retention_config is None:
40+
retention_config = {}
41+
42+
self.retention_enabled = retention_config.get("enabled", False)
43+
44+
retention_default_policy = retention_config.get("default_policy")
45+
46+
if retention_default_policy is not None:
47+
self.retention_default_min_lifetime = retention_default_policy.get(
48+
"min_lifetime"
49+
)
50+
if self.retention_default_min_lifetime is not None:
51+
self.retention_default_min_lifetime = self.parse_duration(
52+
self.retention_default_min_lifetime
53+
)
54+
55+
self.retention_default_max_lifetime = retention_default_policy.get(
56+
"max_lifetime"
57+
)
58+
if self.retention_default_max_lifetime is not None:
59+
self.retention_default_max_lifetime = self.parse_duration(
60+
self.retention_default_max_lifetime
61+
)
62+
63+
if (
64+
self.retention_default_min_lifetime is not None
65+
and self.retention_default_max_lifetime is not None
66+
and (
67+
self.retention_default_min_lifetime
68+
> self.retention_default_max_lifetime
69+
)
70+
):
71+
raise ConfigError(
72+
"The default retention policy's 'min_lifetime' can not be greater"
73+
" than its 'max_lifetime'"
74+
)
75+
else:
76+
self.retention_default_min_lifetime = None
77+
self.retention_default_max_lifetime = None
78+
79+
if self.retention_enabled:
80+
logger.info(
81+
"Message retention policies support enabled with the following default"
82+
" policy: min_lifetime = %s ; max_lifetime = %s",
83+
self.retention_default_min_lifetime,
84+
self.retention_default_max_lifetime,
85+
)
86+
87+
self.retention_allowed_lifetime_min = retention_config.get(
88+
"allowed_lifetime_min"
89+
)
90+
if self.retention_allowed_lifetime_min is not None:
91+
self.retention_allowed_lifetime_min = self.parse_duration(
92+
self.retention_allowed_lifetime_min
93+
)
94+
95+
self.retention_allowed_lifetime_max = retention_config.get(
96+
"allowed_lifetime_max"
97+
)
98+
if self.retention_allowed_lifetime_max is not None:
99+
self.retention_allowed_lifetime_max = self.parse_duration(
100+
self.retention_allowed_lifetime_max
101+
)
102+
103+
if (
104+
self.retention_allowed_lifetime_min is not None
105+
and self.retention_allowed_lifetime_max is not None
106+
and self.retention_allowed_lifetime_min
107+
> self.retention_allowed_lifetime_max
108+
):
109+
raise ConfigError(
110+
"Invalid retention policy limits: 'allowed_lifetime_min' can not be"
111+
" greater than 'allowed_lifetime_max'"
112+
)
113+
114+
self.retention_purge_jobs: List[RetentionPurgeJob] = []
115+
for purge_job_config in retention_config.get("purge_jobs", []):
116+
interval_config = purge_job_config.get("interval")
117+
118+
if interval_config is None:
119+
raise ConfigError(
120+
"A retention policy's purge jobs configuration must have the"
121+
" 'interval' key set."
122+
)
123+
124+
interval = self.parse_duration(interval_config)
125+
126+
shortest_max_lifetime = purge_job_config.get("shortest_max_lifetime")
127+
128+
if shortest_max_lifetime is not None:
129+
shortest_max_lifetime = self.parse_duration(shortest_max_lifetime)
130+
131+
longest_max_lifetime = purge_job_config.get("longest_max_lifetime")
132+
133+
if longest_max_lifetime is not None:
134+
longest_max_lifetime = self.parse_duration(longest_max_lifetime)
135+
136+
if (
137+
shortest_max_lifetime is not None
138+
and longest_max_lifetime is not None
139+
and shortest_max_lifetime > longest_max_lifetime
140+
):
141+
raise ConfigError(
142+
"A retention policy's purge jobs configuration's"
143+
" 'shortest_max_lifetime' value can not be greater than its"
144+
" 'longest_max_lifetime' value."
145+
)
146+
147+
self.retention_purge_jobs.append(
148+
RetentionPurgeJob(interval, shortest_max_lifetime, longest_max_lifetime)
149+
)
150+
151+
if not self.retention_purge_jobs:
152+
self.retention_purge_jobs = [
153+
RetentionPurgeJob(self.parse_duration("1d"), None, None)
154+
]
155+
156+
def generate_config_section(self, config_dir_path, server_name, **kwargs):
157+
return """\
158+
# Message retention policy at the server level.
159+
#
160+
# Room admins and mods can define a retention period for their rooms using the
161+
# 'm.room.retention' state event, and server admins can cap this period by setting
162+
# the 'allowed_lifetime_min' and 'allowed_lifetime_max' config options.
163+
#
164+
# If this feature is enabled, Synapse will regularly look for and purge events
165+
# which are older than the room's maximum retention period. Synapse will also
166+
# filter events received over federation so that events that should have been
167+
# purged are ignored and not stored again.
168+
#
169+
retention:
170+
# The message retention policies feature is disabled by default. Uncomment the
171+
# following line to enable it.
172+
#
173+
#enabled: true
174+
175+
# Default retention policy. If set, Synapse will apply it to rooms that lack the
176+
# 'm.room.retention' state event. Currently, the value of 'min_lifetime' doesn't
177+
# matter much because Synapse doesn't take it into account yet.
178+
#
179+
#default_policy:
180+
# min_lifetime: 1d
181+
# max_lifetime: 1y
182+
183+
# Retention policy limits. If set, and the state of a room contains a
184+
# 'm.room.retention' event in its state which contains a 'min_lifetime' or a
185+
# 'max_lifetime' that's out of these bounds, Synapse will cap the room's policy
186+
# to these limits when running purge jobs.
187+
#
188+
#allowed_lifetime_min: 1d
189+
#allowed_lifetime_max: 1y
190+
191+
# Server admins can define the settings of the background jobs purging the
192+
# events which lifetime has expired under the 'purge_jobs' section.
193+
#
194+
# If no configuration is provided, a single job will be set up to delete expired
195+
# events in every room daily.
196+
#
197+
# Each job's configuration defines which range of message lifetimes the job
198+
# takes care of. For example, if 'shortest_max_lifetime' is '2d' and
199+
# 'longest_max_lifetime' is '3d', the job will handle purging expired events in
200+
# rooms whose state defines a 'max_lifetime' that's both higher than 2 days, and
201+
# lower than or equal to 3 days. Both the minimum and the maximum value of a
202+
# range are optional, e.g. a job with no 'shortest_max_lifetime' and a
203+
# 'longest_max_lifetime' of '3d' will handle every room with a retention policy
204+
# which 'max_lifetime' is lower than or equal to three days.
205+
#
206+
# The rationale for this per-job configuration is that some rooms might have a
207+
# retention policy with a low 'max_lifetime', where history needs to be purged
208+
# of outdated messages on a more frequent basis than for the rest of the rooms
209+
# (e.g. every 12h), but not want that purge to be performed by a job that's
210+
# iterating over every room it knows, which could be heavy on the server.
211+
#
212+
# If any purge job is configured, it is strongly recommended to have at least
213+
# a single job with neither 'shortest_max_lifetime' nor 'longest_max_lifetime'
214+
# set, or one job without 'shortest_max_lifetime' and one job without
215+
# 'longest_max_lifetime' set. Otherwise some rooms might be ignored, even if
216+
# 'allowed_lifetime_min' and 'allowed_lifetime_max' are set, because capping a
217+
# room's policy to these values is done after the policies are retrieved from
218+
# Synapse's database (which is done using the range specified in a purge job's
219+
# configuration).
220+
#
221+
#purge_jobs:
222+
# - longest_max_lifetime: 3d
223+
# interval: 12h
224+
# - shortest_max_lifetime: 3d
225+
# interval: 1d
226+
"""

0 commit comments

Comments
 (0)