summaryrefslogtreecommitdiff
path: root/synapse/config
diff options
context:
space:
mode:
Diffstat (limited to 'synapse/config')
-rw-r--r--synapse/config/_base.py64
-rw-r--r--synapse/config/account_validity.py2
-rw-r--r--synapse/config/cas.py2
-rw-r--r--synapse/config/emailconfig.py9
-rw-r--r--synapse/config/key.py6
-rw-r--r--synapse/config/oidc.py2
-rw-r--r--synapse/config/registration.py7
-rw-r--r--synapse/config/repository.py2
-rw-r--r--synapse/config/saml2.py2
-rw-r--r--synapse/config/server.py104
-rw-r--r--synapse/config/server_notices.py4
-rw-r--r--synapse/config/sso.py6
-rw-r--r--synapse/config/tls.py9
13 files changed, 89 insertions, 130 deletions
diff --git a/synapse/config/_base.py b/synapse/config/_base.py
index d974a1a2..7c4428a1 100644
--- a/synapse/config/_base.py
+++ b/synapse/config/_base.py
@@ -118,21 +118,6 @@ class Config:
"synapse", "res/templates"
)
- def __getattr__(self, item: str) -> Any:
- """
- Try and fetch a configuration option that does not exist on this class.
-
- This is so that existing configs that rely on `self.value`, where value
- is actually from a different config section, continue to work.
- """
- if item in ["generate_config_section", "read_config"]:
- raise AttributeError(item)
-
- if self.root is None:
- raise AttributeError(item)
- else:
- return self.root._get_unclassed_config(self.section, item)
-
@staticmethod
def parse_size(value):
if isinstance(value, int):
@@ -289,7 +274,9 @@ class Config:
env.filters.update(
{
"format_ts": _format_ts_filter,
- "mxc_to_http": _create_mxc_to_http_filter(self.public_baseurl),
+ "mxc_to_http": _create_mxc_to_http_filter(
+ self.root.server.public_baseurl
+ ),
}
)
@@ -311,8 +298,6 @@ class RootConfig:
config_classes = []
def __init__(self):
- self._configs = OrderedDict()
-
for config_class in self.config_classes:
if config_class.section is None:
raise ValueError("%r requires a section name" % (config_class,))
@@ -321,42 +306,7 @@ class RootConfig:
conf = config_class(self)
except Exception as e:
raise Exception("Failed making %s: %r" % (config_class.section, e))
- self._configs[config_class.section] = conf
-
- def __getattr__(self, item: str) -> Any:
- """
- Redirect lookups on this object either to config objects, or values on
- config objects, so that `config.tls.blah` works, as well as legacy uses
- of things like `config.server_name`. It will first look up the config
- section name, and then values on those config classes.
- """
- if item in self._configs.keys():
- return self._configs[item]
-
- return self._get_unclassed_config(None, item)
-
- def _get_unclassed_config(self, asking_section: Optional[str], item: str):
- """
- Fetch a config value from one of the instantiated config classes that
- has not been fetched directly.
-
- Args:
- asking_section: If this check is coming from a Config child, which
- one? This section will not be asked if it has the value.
- item: The configuration value key.
-
- Raises:
- AttributeError if no config classes have the config key. The body
- will contain what sections were checked.
- """
- for key, val in self._configs.items():
- if key == asking_section:
- continue
-
- if item in dir(val):
- return getattr(val, item)
-
- raise AttributeError(item, "not found in %s" % (list(self._configs.keys()),))
+ setattr(self, config_class.section, conf)
def invoke_all(self, func_name: str, *args, **kwargs) -> MutableMapping[str, Any]:
"""
@@ -373,9 +323,11 @@ class RootConfig:
"""
res = OrderedDict()
- for name, config in self._configs.items():
+ for config_class in self.config_classes:
+ config = getattr(self, config_class.section)
+
if hasattr(config, func_name):
- res[name] = getattr(config, func_name)(*args, **kwargs)
+ res[config_class.section] = getattr(config, func_name)(*args, **kwargs)
return res
diff --git a/synapse/config/account_validity.py b/synapse/config/account_validity.py
index ffaffc49..b56c2a24 100644
--- a/synapse/config/account_validity.py
+++ b/synapse/config/account_validity.py
@@ -76,7 +76,7 @@ class AccountValidityConfig(Config):
)
if self.account_validity_renew_by_email_enabled:
- if not self.public_baseurl:
+ if not self.root.server.public_baseurl:
raise ConfigError("Can't send renewal emails without 'public_baseurl'")
# Load account validity templates.
diff --git a/synapse/config/cas.py b/synapse/config/cas.py
index 901f4123..9b58ecf3 100644
--- a/synapse/config/cas.py
+++ b/synapse/config/cas.py
@@ -37,7 +37,7 @@ class CasConfig(Config):
# The public baseurl is required because it is used by the redirect
# template.
- public_baseurl = self.public_baseurl
+ public_baseurl = self.root.server.public_baseurl
if not public_baseurl:
raise ConfigError("cas_config requires a public_baseurl to be set")
diff --git a/synapse/config/emailconfig.py b/synapse/config/emailconfig.py
index 936abe61..8ff59aa2 100644
--- a/synapse/config/emailconfig.py
+++ b/synapse/config/emailconfig.py
@@ -19,7 +19,6 @@ import email.utils
import logging
import os
from enum import Enum
-from typing import Optional
import attr
@@ -135,7 +134,7 @@ class EmailConfig(Config):
# msisdn is currently always remote while Synapse does not support any method of
# sending SMS messages
ThreepidBehaviour.REMOTE
- if self.account_threepid_delegate_email
+ if self.root.registration.account_threepid_delegate_email
else ThreepidBehaviour.LOCAL
)
# Prior to Synapse v1.4.0, there was another option that defined whether Synapse would
@@ -144,7 +143,7 @@ class EmailConfig(Config):
# identity server in the process.
self.using_identity_server_from_trusted_list = False
if (
- not self.account_threepid_delegate_email
+ not self.root.registration.account_threepid_delegate_email
and config.get("trust_identity_server_for_password_resets", False) is True
):
# Use the first entry in self.trusted_third_party_id_servers instead
@@ -156,7 +155,7 @@ class EmailConfig(Config):
# trusted_third_party_id_servers does not contain a scheme whereas
# account_threepid_delegate_email is expected to. Presume https
- self.account_threepid_delegate_email: Optional[str] = (
+ self.root.registration.account_threepid_delegate_email = (
"https://" + first_trusted_identity_server
)
self.using_identity_server_from_trusted_list = True
@@ -335,7 +334,7 @@ class EmailConfig(Config):
"client_base_url", email_config.get("riot_base_url", None)
)
- if self.account_validity_renew_by_email_enabled:
+ if self.root.account_validity.account_validity_renew_by_email_enabled:
expiry_template_html = email_config.get(
"expiry_template_html", "notice_expiry.html"
)
diff --git a/synapse/config/key.py b/synapse/config/key.py
index 94a90630..015dbb8a 100644
--- a/synapse/config/key.py
+++ b/synapse/config/key.py
@@ -145,11 +145,13 @@ class KeyConfig(Config):
# list of TrustedKeyServer objects
self.key_servers = list(
- _parse_key_servers(key_servers, self.federation_verify_certificates)
+ _parse_key_servers(
+ key_servers, self.root.tls.federation_verify_certificates
+ )
)
self.macaroon_secret_key = config.get(
- "macaroon_secret_key", self.registration_shared_secret
+ "macaroon_secret_key", self.root.registration.registration_shared_secret
)
if not self.macaroon_secret_key:
diff --git a/synapse/config/oidc.py b/synapse/config/oidc.py
index 7e67fbad..10f57963 100644
--- a/synapse/config/oidc.py
+++ b/synapse/config/oidc.py
@@ -58,7 +58,7 @@ class OIDCConfig(Config):
"Multiple OIDC providers have the idp_id %r." % idp_id
)
- public_baseurl = self.public_baseurl
+ public_baseurl = self.root.server.public_baseurl
if public_baseurl is None:
raise ConfigError("oidc_config requires a public_baseurl to be set")
self.oidc_callback_url = public_baseurl + "_synapse/client/oidc/callback"
diff --git a/synapse/config/registration.py b/synapse/config/registration.py
index 7cffdacf..a3d2a38c 100644
--- a/synapse/config/registration.py
+++ b/synapse/config/registration.py
@@ -45,7 +45,10 @@ class RegistrationConfig(Config):
account_threepid_delegates = config.get("account_threepid_delegates") or {}
self.account_threepid_delegate_email = account_threepid_delegates.get("email")
self.account_threepid_delegate_msisdn = account_threepid_delegates.get("msisdn")
- if self.account_threepid_delegate_msisdn and not self.public_baseurl:
+ if (
+ self.account_threepid_delegate_msisdn
+ and not self.root.server.public_baseurl
+ ):
raise ConfigError(
"The configuration option `public_baseurl` is required if "
"`account_threepid_delegate.msisdn` is set, such that "
@@ -85,7 +88,7 @@ class RegistrationConfig(Config):
if mxid_localpart:
# Convert the localpart to a full mxid.
self.auto_join_user_id = UserID(
- mxid_localpart, self.server_name
+ mxid_localpart, self.root.server.server_name
).to_string()
if self.autocreate_auto_join_rooms:
diff --git a/synapse/config/repository.py b/synapse/config/repository.py
index 7481f3bf..69906a98 100644
--- a/synapse/config/repository.py
+++ b/synapse/config/repository.py
@@ -94,7 +94,7 @@ class ContentRepositoryConfig(Config):
# Only enable the media repo if either the media repo is enabled or the
# current worker app is the media repo.
if (
- self.enable_media_repo is False
+ self.root.server.enable_media_repo is False
and config.get("worker_app") != "synapse.app.media_repository"
):
self.can_load_media_repo = False
diff --git a/synapse/config/saml2.py b/synapse/config/saml2.py
index 05e98362..9c51b6a2 100644
--- a/synapse/config/saml2.py
+++ b/synapse/config/saml2.py
@@ -199,7 +199,7 @@ class SAML2Config(Config):
"""
import saml2
- public_baseurl = self.public_baseurl
+ public_baseurl = self.root.server.public_baseurl
if public_baseurl is None:
raise ConfigError("saml2_config requires a public_baseurl to be set")
diff --git a/synapse/config/server.py b/synapse/config/server.py
index ad8715da..818b8063 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -1,6 +1,4 @@
-# Copyright 2014-2016 OpenMarket Ltd
-# Copyright 2017-2018 New Vector Ltd
-# Copyright 2019 The Matrix.org Foundation C.I.C.
+# Copyright 2014-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.
@@ -19,7 +17,7 @@ import logging
import os.path
import re
from textwrap import indent
-from typing import Any, Dict, Iterable, List, Optional, Set, Tuple
+from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, Union
import attr
import yaml
@@ -184,49 +182,74 @@ KNOWN_RESOURCES = {
@attr.s(frozen=True)
class HttpResourceConfig:
- names = attr.ib(
- type=List[str],
+ names: List[str] = attr.ib(
factory=list,
validator=attr.validators.deep_iterable(attr.validators.in_(KNOWN_RESOURCES)), # type: ignore
)
- compress = attr.ib(
- type=bool,
+ compress: bool = attr.ib(
default=False,
validator=attr.validators.optional(attr.validators.instance_of(bool)), # type: ignore[arg-type]
)
-@attr.s(frozen=True)
+@attr.s(slots=True, frozen=True, auto_attribs=True)
class HttpListenerConfig:
"""Object describing the http-specific parts of the config of a listener"""
- x_forwarded = attr.ib(type=bool, default=False)
- resources = attr.ib(type=List[HttpResourceConfig], factory=list)
- additional_resources = attr.ib(type=Dict[str, dict], factory=dict)
- tag = attr.ib(type=str, default=None)
+ x_forwarded: bool = False
+ resources: List[HttpResourceConfig] = attr.ib(factory=list)
+ additional_resources: Dict[str, dict] = attr.ib(factory=dict)
+ tag: Optional[str] = None
-@attr.s(frozen=True)
+@attr.s(slots=True, frozen=True, auto_attribs=True)
class ListenerConfig:
"""Object describing the configuration of a single listener."""
- port = attr.ib(type=int, validator=attr.validators.instance_of(int))
- bind_addresses = attr.ib(type=List[str])
- type = attr.ib(type=str, validator=attr.validators.in_(KNOWN_LISTENER_TYPES))
- tls = attr.ib(type=bool, default=False)
+ port: int = attr.ib(validator=attr.validators.instance_of(int))
+ bind_addresses: List[str]
+ type: str = attr.ib(validator=attr.validators.in_(KNOWN_LISTENER_TYPES))
+ tls: bool = False
# http_options is only populated if type=http
- http_options = attr.ib(type=Optional[HttpListenerConfig], default=None)
+ http_options: Optional[HttpListenerConfig] = None
-@attr.s(frozen=True)
+@attr.s(slots=True, frozen=True, auto_attribs=True)
class ManholeConfig:
"""Object describing the configuration of the manhole"""
- username = attr.ib(type=str, validator=attr.validators.instance_of(str))
- password = attr.ib(type=str, validator=attr.validators.instance_of(str))
- priv_key = attr.ib(type=Optional[Key])
- pub_key = attr.ib(type=Optional[Key])
+ username: str = attr.ib(validator=attr.validators.instance_of(str))
+ password: str = attr.ib(validator=attr.validators.instance_of(str))
+ priv_key: Optional[Key]
+ pub_key: Optional[Key]
+
+
+@attr.s(slots=True, frozen=True, auto_attribs=True)
+class RetentionConfig:
+ """Object describing the configuration of the manhole"""
+
+ interval: int
+ shortest_max_lifetime: Optional[int]
+ longest_max_lifetime: Optional[int]
+
+
+@attr.s(frozen=True)
+class LimitRemoteRoomsConfig:
+ enabled: bool = attr.ib(validator=attr.validators.instance_of(bool), default=False)
+ complexity: Union[float, int] = attr.ib(
+ validator=attr.validators.instance_of(
+ (float, int) # type: ignore[arg-type] # noqa
+ ),
+ default=1.0,
+ )
+ complexity_error: str = attr.ib(
+ validator=attr.validators.instance_of(str),
+ default=ROOM_COMPLEXITY_TOO_GREAT,
+ )
+ admins_can_join: bool = attr.ib(
+ validator=attr.validators.instance_of(bool), default=False
+ )
class ServerConfig(Config):
@@ -519,7 +542,7 @@ class ServerConfig(Config):
" greater than 'allowed_lifetime_max'"
)
- self.retention_purge_jobs: List[Dict[str, Optional[int]]] = []
+ self.retention_purge_jobs: List[RetentionConfig] = []
for purge_job_config in retention_config.get("purge_jobs", []):
interval_config = purge_job_config.get("interval")
@@ -553,20 +576,12 @@ class ServerConfig(Config):
)
self.retention_purge_jobs.append(
- {
- "interval": interval,
- "shortest_max_lifetime": shortest_max_lifetime,
- "longest_max_lifetime": longest_max_lifetime,
- }
+ RetentionConfig(interval, shortest_max_lifetime, longest_max_lifetime)
)
if not self.retention_purge_jobs:
self.retention_purge_jobs = [
- {
- "interval": self.parse_duration("1d"),
- "shortest_max_lifetime": None,
- "longest_max_lifetime": None,
- }
+ RetentionConfig(self.parse_duration("1d"), None, None)
]
self.listeners = [parse_listener_def(x) for x in config.get("listeners", [])]
@@ -591,25 +606,6 @@ class ServerConfig(Config):
self.gc_thresholds = read_gc_thresholds(config.get("gc_thresholds", None))
self.gc_seconds = self.read_gc_intervals(config.get("gc_min_interval", None))
- @attr.s
- class LimitRemoteRoomsConfig:
- enabled = attr.ib(
- validator=attr.validators.instance_of(bool), default=False
- )
- complexity = attr.ib(
- validator=attr.validators.instance_of(
- (float, int) # type: ignore[arg-type] # noqa
- ),
- default=1.0,
- )
- complexity_error = attr.ib(
- validator=attr.validators.instance_of(str),
- default=ROOM_COMPLEXITY_TOO_GREAT,
- )
- admins_can_join = attr.ib(
- validator=attr.validators.instance_of(bool), default=False
- )
-
self.limit_remote_rooms = LimitRemoteRoomsConfig(
**(config.get("limit_remote_rooms") or {})
)
diff --git a/synapse/config/server_notices.py b/synapse/config/server_notices.py
index 48bf3241..bde4e879 100644
--- a/synapse/config/server_notices.py
+++ b/synapse/config/server_notices.py
@@ -73,7 +73,9 @@ class ServerNoticesConfig(Config):
return
mxid_localpart = c["system_mxid_localpart"]
- self.server_notices_mxid = UserID(mxid_localpart, self.server_name).to_string()
+ self.server_notices_mxid = UserID(
+ mxid_localpart, self.root.server.server_name
+ ).to_string()
self.server_notices_mxid_display_name = c.get("system_mxid_display_name", None)
self.server_notices_mxid_avatar_url = c.get("system_mxid_avatar_url", None)
# todo: i18n
diff --git a/synapse/config/sso.py b/synapse/config/sso.py
index 524a7ff3..11a9b76a 100644
--- a/synapse/config/sso.py
+++ b/synapse/config/sso.py
@@ -103,8 +103,10 @@ class SSOConfig(Config):
# the client's.
# public_baseurl is an optional setting, so we only add the fallback's URL to the
# list if it's provided (because we can't figure out what that URL is otherwise).
- if self.public_baseurl:
- login_fallback_url = self.public_baseurl + "_matrix/static/client/login"
+ if self.root.server.public_baseurl:
+ login_fallback_url = (
+ self.root.server.public_baseurl + "_matrix/static/client/login"
+ )
self.sso_client_whitelist.append(login_fallback_url)
def generate_config_section(self, **kwargs):
diff --git a/synapse/config/tls.py b/synapse/config/tls.py
index 5679f05e..6227434b 100644
--- a/synapse/config/tls.py
+++ b/synapse/config/tls.py
@@ -172,9 +172,12 @@ class TlsConfig(Config):
)
# YYYYMMDDhhmmssZ -- in UTC
- expires_on = datetime.strptime(
- tls_certificate.get_notAfter().decode("ascii"), "%Y%m%d%H%M%SZ"
- )
+ expiry_data = tls_certificate.get_notAfter()
+ if expiry_data is None:
+ raise ValueError(
+ "TLS Certificate has no expiry date, and this is not permitted"
+ )
+ expires_on = datetime.strptime(expiry_data.decode("ascii"), "%Y%m%d%H%M%SZ")
now = datetime.utcnow()
days_remaining = (expires_on - now).days
return days_remaining