diff --git a/synapse/config/_base.py b/synapse/config/_base.py
index c629990dd4..40af1979c4 100644
--- a/synapse/config/_base.py
+++ b/synapse/config/_base.py
@@ -225,7 +225,9 @@ class Config:
return self.read_templates([filename])[0]
def read_templates(
- self, filenames: List[str], custom_template_directory: Optional[str] = None,
+ self,
+ filenames: List[str],
+ custom_template_directory: Optional[str] = None,
) -> List[jinja2.Template]:
"""Load a list of template files from disk using the given variables.
@@ -265,7 +267,10 @@ class Config:
# TODO: switch to synapse.util.templates.build_jinja_env
loader = jinja2.FileSystemLoader(search_directories)
- env = jinja2.Environment(loader=loader, autoescape=jinja2.select_autoescape(),)
+ env = jinja2.Environment(
+ loader=loader,
+ autoescape=jinja2.select_autoescape(),
+ )
# Update the environment with our custom filters
env.filters.update(
@@ -826,8 +831,7 @@ class ShardedWorkerHandlingConfig:
instances = attr.ib(type=List[str])
def should_handle(self, instance_name: str, key: str) -> bool:
- """Whether this instance is responsible for handling the given key.
- """
+ """Whether this instance is responsible for handling the given key."""
# If multiple instances are not defined we always return true
if not self.instances or len(self.instances) == 1:
return True
diff --git a/synapse/config/auth.py b/synapse/config/auth.py
index 2b3e2ce87b..7fa64b821a 100644
--- a/synapse/config/auth.py
+++ b/synapse/config/auth.py
@@ -18,8 +18,7 @@ from ._base import Config
class AuthConfig(Config):
- """Password and login configuration
- """
+ """Password and login configuration"""
section = "auth"
@@ -98,7 +97,7 @@ class AuthConfig(Config):
# session to be active.
#
# This defaults to 0, meaning the user is queried for their credentials
- # before every action, but this can be overridden to alow a single
+ # before every action, but this can be overridden to allow a single
# validation to be re-used. This weakens the protections afforded by
# the user-interactive authentication process, by allowing for multiple
# (and potentially different) operations to use the same validation session.
diff --git a/synapse/config/cas.py b/synapse/config/cas.py
index aaa7eba110..dbf5085965 100644
--- a/synapse/config/cas.py
+++ b/synapse/config/cas.py
@@ -13,7 +13,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from typing import Any, List
+
+from synapse.config.sso import SsoAttributeRequirement
+
from ._base import Config, ConfigError
+from ._util import validate_config
class CasConfig(Config):
@@ -40,12 +45,16 @@ class CasConfig(Config):
# TODO Update this to a _synapse URL.
self.cas_service_url = public_baseurl + "_matrix/client/r0/login/cas/ticket"
self.cas_displayname_attribute = cas_config.get("displayname_attribute")
- self.cas_required_attributes = cas_config.get("required_attributes") or {}
+ required_attributes = cas_config.get("required_attributes") or {}
+ self.cas_required_attributes = _parsed_required_attributes_def(
+ required_attributes
+ )
+
else:
self.cas_server_url = None
self.cas_service_url = None
self.cas_displayname_attribute = None
- self.cas_required_attributes = {}
+ self.cas_required_attributes = []
def generate_config_section(self, config_dir_path, server_name, **kwargs):
return """\
@@ -77,3 +86,22 @@ class CasConfig(Config):
# userGroup: "staff"
# department: None
"""
+
+
+# CAS uses a legacy required attributes mapping, not the one provided by
+# SsoAttributeRequirement.
+REQUIRED_ATTRIBUTES_SCHEMA = {
+ "type": "object",
+ "additionalProperties": {"anyOf": [{"type": "string"}, {"type": "null"}]},
+}
+
+
+def _parsed_required_attributes_def(
+ required_attributes: Any,
+) -> List[SsoAttributeRequirement]:
+ validate_config(
+ REQUIRED_ATTRIBUTES_SCHEMA,
+ required_attributes,
+ config_path=("cas_config", "required_attributes"),
+ )
+ return [SsoAttributeRequirement(k, v) for k, v in required_attributes.items()]
diff --git a/synapse/config/database.py b/synapse/config/database.py
index 8a18a9ca2a..e7889b9c20 100644
--- a/synapse/config/database.py
+++ b/synapse/config/database.py
@@ -207,8 +207,7 @@ class DatabaseConfig(Config):
)
def get_single_database(self) -> DatabaseConnectionConfig:
- """Returns the database if there is only one, useful for e.g. tests
- """
+ """Returns the database if there is only one, useful for e.g. tests"""
if not self.databases:
raise Exception("More than one database exists")
diff --git a/synapse/config/emailconfig.py b/synapse/config/emailconfig.py
index d0b94c456b..5431691831 100644
--- a/synapse/config/emailconfig.py
+++ b/synapse/config/emailconfig.py
@@ -289,7 +289,8 @@ class EmailConfig(Config):
self.email_notif_template_html,
self.email_notif_template_text,
) = self.read_templates(
- [notif_template_html, notif_template_text], template_dir,
+ [notif_template_html, notif_template_text],
+ template_dir,
)
self.email_notif_for_new_users = email_config.get(
@@ -311,7 +312,8 @@ class EmailConfig(Config):
self.account_validity_template_html,
self.account_validity_template_text,
) = self.read_templates(
- [expiry_template_html, expiry_template_text], template_dir,
+ [expiry_template_html, expiry_template_text],
+ template_dir,
)
subjects_config = email_config.get("subjects", {})
diff --git a/synapse/config/logger.py b/synapse/config/logger.py
index 4df3f93c1c..e56cf846f5 100644
--- a/synapse/config/logger.py
+++ b/synapse/config/logger.py
@@ -162,7 +162,10 @@ class LoggingConfig(Config):
)
logging_group.add_argument(
- "-f", "--log-file", dest="log_file", help=argparse.SUPPRESS,
+ "-f",
+ "--log-file",
+ dest="log_file",
+ help=argparse.SUPPRESS,
)
def generate_files(self, config, config_dir_path):
diff --git a/synapse/config/oidc_config.py b/synapse/config/oidc_config.py
index d081f36fa5..a27594befc 100644
--- a/synapse/config/oidc_config.py
+++ b/synapse/config/oidc_config.py
@@ -355,9 +355,10 @@ def _parse_oidc_config_dict(
ump_config.setdefault("module", DEFAULT_USER_MAPPING_PROVIDER)
ump_config.setdefault("config", {})
- (user_mapping_provider_class, user_mapping_provider_config,) = load_module(
- ump_config, config_path + ("user_mapping_provider",)
- )
+ (
+ user_mapping_provider_class,
+ user_mapping_provider_config,
+ ) = load_module(ump_config, config_path + ("user_mapping_provider",))
# Ensure loaded user mapping module has defined all necessary methods
required_methods = [
@@ -372,7 +373,11 @@ def _parse_oidc_config_dict(
if missing_methods:
raise ConfigError(
"Class %s is missing required "
- "methods: %s" % (user_mapping_provider_class, ", ".join(missing_methods),),
+ "methods: %s"
+ % (
+ user_mapping_provider_class,
+ ", ".join(missing_methods),
+ ),
config_path + ("user_mapping_provider", "module"),
)
diff --git a/synapse/config/repository.py b/synapse/config/repository.py
index ef86450ed2..45f90beabc 100644
--- a/synapse/config/repository.py
+++ b/synapse/config/repository.py
@@ -52,7 +52,7 @@ MediaStorageProviderConfig = namedtuple(
def parse_thumbnail_requirements(thumbnail_sizes):
- """ Takes a list of dictionaries with "width", "height", and "method" keys
+ """Takes a list of dictionaries with "width", "height", and "method" keys
and creates a map from image media types to the thumbnail size, thumbnailing
method, and thumbnail media type to precalculate
diff --git a/synapse/config/room_directory.py b/synapse/config/room_directory.py
index 9a3e1c3e7d..2dd719c388 100644
--- a/synapse/config/room_directory.py
+++ b/synapse/config/room_directory.py
@@ -123,7 +123,7 @@ class RoomDirectoryConfig(Config):
alias (str)
Returns:
- boolean: True if user is allowed to crate the alias
+ boolean: True if user is allowed to create the alias
"""
for rule in self._alias_creation_rules:
if rule.matches(user_id, room_id, [alias]):
diff --git a/synapse/config/saml2_config.py b/synapse/config/saml2_config.py
index 7226abd829..4b494f217f 100644
--- a/synapse/config/saml2_config.py
+++ b/synapse/config/saml2_config.py
@@ -17,8 +17,7 @@
import logging
from typing import Any, List
-import attr
-
+from synapse.config.sso import SsoAttributeRequirement
from synapse.python_dependencies import DependencyException, check_requirements
from synapse.util.module_loader import load_module, load_python_module
@@ -398,32 +397,18 @@ class SAML2Config(Config):
}
-@attr.s(frozen=True)
-class SamlAttributeRequirement:
- """Object describing a single requirement for SAML attributes."""
-
- attribute = attr.ib(type=str)
- value = attr.ib(type=str)
-
- JSON_SCHEMA = {
- "type": "object",
- "properties": {"attribute": {"type": "string"}, "value": {"type": "string"}},
- "required": ["attribute", "value"],
- }
-
-
ATTRIBUTE_REQUIREMENTS_SCHEMA = {
"type": "array",
- "items": SamlAttributeRequirement.JSON_SCHEMA,
+ "items": SsoAttributeRequirement.JSON_SCHEMA,
}
def _parse_attribute_requirements_def(
attribute_requirements: Any,
-) -> List[SamlAttributeRequirement]:
+) -> List[SsoAttributeRequirement]:
validate_config(
ATTRIBUTE_REQUIREMENTS_SCHEMA,
attribute_requirements,
- config_path=["saml2_config", "attribute_requirements"],
+ config_path=("saml2_config", "attribute_requirements"),
)
- return [SamlAttributeRequirement(**x) for x in attribute_requirements]
+ return [SsoAttributeRequirement(**x) for x in attribute_requirements]
diff --git a/synapse/config/server.py b/synapse/config/server.py
index 09f1e0b057..1b82c81db1 100644
--- a/synapse/config/server.py
+++ b/synapse/config/server.py
@@ -52,7 +52,12 @@ def _6to4(network: IPNetwork) -> IPNetwork:
hex_network = hex(network.first)[2:]
hex_network = ("0" * (8 - len(hex_network))) + hex_network
return IPNetwork(
- "2002:%s:%s::/%d" % (hex_network[:4], hex_network[4:], 16 + network.prefixlen,)
+ "2002:%s:%s::/%d"
+ % (
+ hex_network[:4],
+ hex_network[4:],
+ 16 + network.prefixlen,
+ )
)
@@ -254,7 +259,8 @@ class ServerConfig(Config):
# Whether to require sharing a room with a user to retrieve their
# profile data
self.limit_profile_requests_to_users_who_share_rooms = config.get(
- "limit_profile_requests_to_users_who_share_rooms", False,
+ "limit_profile_requests_to_users_who_share_rooms",
+ False,
)
if "restrict_public_rooms_to_local_users" in config and (
@@ -620,7 +626,9 @@ class ServerConfig(Config):
if manhole:
self.listeners.append(
ListenerConfig(
- port=manhole, bind_addresses=["127.0.0.1"], type="manhole",
+ port=manhole,
+ bind_addresses=["127.0.0.1"],
+ type="manhole",
)
)
@@ -656,7 +664,8 @@ class ServerConfig(Config):
# and letting the client know which email address is bound to an account and
# which one isn't.
self.request_token_inhibit_3pid_errors = config.get(
- "request_token_inhibit_3pid_errors", False,
+ "request_token_inhibit_3pid_errors",
+ False,
)
# List of users trialing the new experimental default push rules. This setting is
diff --git a/synapse/config/sso.py b/synapse/config/sso.py
index 19bdfd462b..243cc681e8 100644
--- a/synapse/config/sso.py
+++ b/synapse/config/sso.py
@@ -12,14 +12,30 @@
# 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 Any, Dict
+from typing import Any, Dict, Optional
+
+import attr
from ._base import Config
+@attr.s(frozen=True)
+class SsoAttributeRequirement:
+ """Object describing a single requirement for SSO attributes."""
+
+ attribute = attr.ib(type=str)
+ # If a value is not given, than the attribute must simply exist.
+ value = attr.ib(type=Optional[str])
+
+ JSON_SCHEMA = {
+ "type": "object",
+ "properties": {"attribute": {"type": "string"}, "value": {"type": "string"}},
+ "required": ["attribute", "value"],
+ }
+
+
class SSOConfig(Config):
- """SSO Configuration
- """
+ """SSO Configuration"""
section = "sso"
diff --git a/synapse/config/workers.py b/synapse/config/workers.py
index f10e33f7b8..7a0ca16da8 100644
--- a/synapse/config/workers.py
+++ b/synapse/config/workers.py
@@ -33,8 +33,7 @@ def _instance_to_list_converter(obj: Union[str, List[str]]) -> List[str]:
@attr.s
class InstanceLocationConfig:
- """The host and port to talk to an instance via HTTP replication.
- """
+ """The host and port to talk to an instance via HTTP replication."""
host = attr.ib(type=str)
port = attr.ib(type=int)
@@ -54,13 +53,19 @@ class WriterLocations:
)
typing = attr.ib(default="master", type=str)
to_device = attr.ib(
- default=["master"], type=List[str], converter=_instance_to_list_converter,
+ default=["master"],
+ type=List[str],
+ converter=_instance_to_list_converter,
)
account_data = attr.ib(
- default=["master"], type=List[str], converter=_instance_to_list_converter,
+ default=["master"],
+ type=List[str],
+ converter=_instance_to_list_converter,
)
receipts = attr.ib(
- default=["master"], type=List[str], converter=_instance_to_list_converter,
+ default=["master"],
+ type=List[str],
+ converter=_instance_to_list_converter,
)
@@ -107,7 +112,9 @@ class WorkerConfig(Config):
if manhole:
self.worker_listeners.append(
ListenerConfig(
- port=manhole, bind_addresses=["127.0.0.1"], type="manhole",
+ port=manhole,
+ bind_addresses=["127.0.0.1"],
+ type="manhole",
)
)
|