From 7c2f8881a955a509a4137119128974c4a58a9b88 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 21 Jun 2019 23:39:08 +0100 Subject: [PATCH 1/6] Ensure that all config options have sensible defaults This will enable us to skip the unintuitive behaviour where the generated config and default config are the same thing. --- synapse/config/_base.py | 10 +++++----- synapse/config/key.py | 22 +++++++++++++++++----- synapse/config/logger.py | 2 +- synapse/config/repository.py | 6 ++++-- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/synapse/config/_base.py b/synapse/config/_base.py index 21d110c82de3..20778973d503 100644 --- a/synapse/config/_base.py +++ b/synapse/config/_base.py @@ -354,8 +354,8 @@ def load_or_generate_config(cls, description, argv): config_file.write("# vim:ft=yaml\n\n") config_file.write(config_str) - config = yaml.safe_load(config_str) - obj.invoke_all("generate_files", config) + config_dict = yaml.safe_load(config_str) + obj.generate_missing_files(config_dict, config_dir_path) print( ( @@ -390,7 +390,7 @@ def load_or_generate_config(cls, description, argv): ) if generate_missing_configs: - obj.generate_missing_files(config_dict) + obj.generate_missing_files(config_dict, config_dir_path) return None obj.parse_config_dict( @@ -466,8 +466,8 @@ def parse_config_dict(self, config_dict, config_dir_path, data_dir_path): data_dir_path=data_dir_path, ) - def generate_missing_files(self, config_dict): - self.invoke_all("generate_files", config_dict) + def generate_missing_files(self, config_dict, config_dir_path): + self.invoke_all("generate_files", config_dict, config_dir_path) def find_config_files(search_paths): diff --git a/synapse/config/key.py b/synapse/config/key.py index e58638f7084d..5ec465b196f4 100644 --- a/synapse/config/key.py +++ b/synapse/config/key.py @@ -65,13 +65,18 @@ class TrustedKeyServer(object): class KeyConfig(Config): - def read_config(self, config, **kwargs): + def read_config(self, config, config_dir_path, **kwargs): # the signing key can be specified inline or in a separate file if "signing_key" in config: self.signing_key = read_signing_keys([config["signing_key"]]) else: - self.signing_key_path = config["signing_key_path"] - self.signing_key = self.read_signing_key(self.signing_key_path) + signing_key_path = config.get("signing_key_path") + if signing_key_path is None: + signing_key_path = os.path.join( + config_dir_path, config["server_name"] + ".signing.key" + ) + + self.signing_key = self.read_signing_key(signing_key_path) self.old_signing_keys = self.read_old_signing_keys( config.get("old_signing_keys", {}) @@ -237,8 +242,15 @@ def read_old_signing_keys(self, old_signing_keys): ) return keys - def generate_files(self, config): - signing_key_path = config["signing_key_path"] + def generate_files(self, config, config_dir_path): + if "signing_key" in config: + return + + signing_key_path = config.get("signing_key_path") + if signing_key_path is None: + signing_key_path = os.path.join( + config_dir_path, config["server_name"] + ".signing.key" + ) if not self.path_exists(signing_key_path): print("Generating signing key file %s" % (signing_key_path,)) diff --git a/synapse/config/logger.py b/synapse/config/logger.py index 153a13751785..3e05f49abaf7 100644 --- a/synapse/config/logger.py +++ b/synapse/config/logger.py @@ -133,7 +133,7 @@ def add_arguments(cls, parser): help="Do not redirect stdout/stderr to the log", ) - def generate_files(self, config): + def generate_files(self, config, config_dir_path): log_config = config.get("log_config") if log_config and not os.path.exists(log_config): log_file = self.abspath("homeserver.log") diff --git a/synapse/config/repository.py b/synapse/config/repository.py index 15a19e09118c..43e6c4921fa9 100644 --- a/synapse/config/repository.py +++ b/synapse/config/repository.py @@ -91,7 +91,9 @@ def read_config(self, config, **kwargs): self.max_image_pixels = self.parse_size(config.get("max_image_pixels", "32M")) self.max_spider_size = self.parse_size(config.get("max_spider_size", "10M")) - self.media_store_path = self.ensure_directory(config["media_store_path"]) + self.media_store_path = self.ensure_directory( + config.get("media_store_path", "media_store") + ) backup_media_store_path = config.get("backup_media_store_path") @@ -148,7 +150,7 @@ def read_config(self, config, **kwargs): (provider_class, parsed_config, wrapper_config) ) - self.uploads_path = self.ensure_directory(config["uploads_path"]) + self.uploads_path = self.ensure_directory(config.get("uploads_path", "uploads")) self.dynamic_thumbnails = config.get("dynamic_thumbnails", False) self.thumbnail_requirements = parse_thumbnail_requirements( config.get("thumbnail_sizes", DEFAULT_THUMBNAIL_SIZES) From 16b52642e274054a070fb494684547a77790c22b Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sat, 22 Jun 2019 00:00:20 +0100 Subject: [PATCH 2/6] Don't load the generated config as the default. It's too confusing. --- synapse/config/_base.py | 96 +++++++---------------- synapse/config/api.py | 2 +- synapse/config/appservice.py | 2 +- synapse/config/captcha.py | 2 +- synapse/config/cas.py | 2 +- synapse/config/consent_config.py | 2 +- synapse/config/database.py | 2 +- synapse/config/emailconfig.py | 2 +- synapse/config/groups.py | 2 +- synapse/config/jwt_config.py | 2 +- synapse/config/key.py | 2 +- synapse/config/logger.py | 2 +- synapse/config/metrics.py | 2 +- synapse/config/password.py | 2 +- synapse/config/password_auth_providers.py | 2 +- synapse/config/push.py | 2 +- synapse/config/ratelimiting.py | 2 +- synapse/config/registration.py | 2 +- synapse/config/repository.py | 2 +- synapse/config/room_directory.py | 2 +- synapse/config/saml2_config.py | 2 +- synapse/config/server.py | 2 +- synapse/config/server_notices_config.py | 2 +- synapse/config/spam_checker.py | 2 +- synapse/config/stats.py | 2 +- synapse/config/third_party_event_rules.py | 2 +- synapse/config/tls.py | 4 +- synapse/config/user_directory.py | 2 +- synapse/config/voip.py | 2 +- 29 files changed, 60 insertions(+), 94 deletions(-) diff --git a/synapse/config/_base.py b/synapse/config/_base.py index 20778973d503..8757416a6056 100644 --- a/synapse/config/_base.py +++ b/synapse/config/_base.py @@ -136,11 +136,6 @@ def read_file(cls, file_path, config_name): with open(file_path) as file_stream: return file_stream.read() - @staticmethod - def read_config_file(file_path): - with open(file_path) as file_stream: - return yaml.safe_load(file_stream) - def invoke_all(self, name, *args, **kargs): results = [] for cls in type(self).mro(): @@ -158,9 +153,8 @@ def generate_config( ): """Build a default configuration file - This is used both when the user explicitly asks us to generate a config file - (eg with --generate_config), and before loading the config at runtime (to give - a base which the config files override) + This is used when the user explicitly asks us to generate a config file + (eg with --generate_config). Args: config_dir_path (str): The path where the config files are kept. Used to @@ -182,10 +176,10 @@ def generate_config( Returns: str: the yaml config file """ - default_config = "\n\n".join( + return "\n\n".join( dedent(conf) for conf in self.invoke_all( - "default_config", + "generate_config_section", config_dir_path=config_dir_path, data_dir_path=data_dir_path, server_name=server_name, @@ -194,8 +188,6 @@ def generate_config( ) ) - return default_config - @classmethod def load_config(cls, description, argv): """Parse the commandline and config files @@ -240,9 +232,7 @@ def load_config(cls, description, argv): config_dir_path = os.path.abspath(config_dir_path) data_dir_path = os.getcwd() - config_dict = obj.read_config_files( - config_files, config_dir_path=config_dir_path, data_dir_path=data_dir_path - ) + config_dict = read_config_files(config_files) obj.parse_config_dict( config_dict, config_dir_path=config_dir_path, data_dir_path=data_dir_path ) @@ -385,10 +375,7 @@ def load_or_generate_config(cls, description, argv): obj.invoke_all("add_arguments", parser) args = parser.parse_args(remaining_args) - config_dict = obj.read_config_files( - config_files, config_dir_path=config_dir_path, data_dir_path=data_dir_path - ) - + config_dict = read_config_files(config_files) if generate_missing_configs: obj.generate_missing_files(config_dict, config_dir_path) return None @@ -400,53 +387,6 @@ def load_or_generate_config(cls, description, argv): return obj - def read_config_files(self, config_files, config_dir_path, data_dir_path): - """Read the config files into a dict - - Args: - config_files (iterable[str]): A list of the config files to read - - config_dir_path (str): The path where the config files are kept. Used to - create filenames for things like the log config and the signing key. - - data_dir_path (str): The path where the data files are kept. Used to create - filenames for things like the database and media store. - - Returns: dict - """ - # first we read the config files into a dict - specified_config = {} - for config_file in config_files: - yaml_config = self.read_config_file(config_file) - specified_config.update(yaml_config) - - # not all of the options have sensible defaults in code, so we now need to - # generate a default config file suitable for the specified server name... - if "server_name" not in specified_config: - raise ConfigError(MISSING_SERVER_NAME) - server_name = specified_config["server_name"] - config_string = self.generate_config( - config_dir_path=config_dir_path, - data_dir_path=data_dir_path, - server_name=server_name, - generate_secrets=False, - ) - - # ... and read it into a base config dict ... - config = yaml.safe_load(config_string) - - # ... and finally, overlay it with the actual configuration. - config.pop("log_config") - config.update(specified_config) - - if "report_stats" not in config: - raise ConfigError( - MISSING_REPORT_STATS_CONFIG_INSTRUCTIONS - + "\n" - + MISSING_REPORT_STATS_SPIEL - ) - return config - def parse_config_dict(self, config_dict, config_dir_path, data_dir_path): """Read the information from the config dict into this Config object. @@ -470,6 +410,30 @@ def generate_missing_files(self, config_dict, config_dir_path): self.invoke_all("generate_files", config_dict, config_dir_path) +def read_config_files(config_files): + """Read the config files into a dict + + Args: + config_files (iterable[str]): A list of the config files to read + + Returns: dict + """ + specified_config = {} + for config_file in config_files: + with open(config_file) as file_stream: + yaml_config = yaml.safe_load(file_stream) + specified_config.update(yaml_config) + + if "server_name" not in specified_config: + raise ConfigError(MISSING_SERVER_NAME) + + if "report_stats" not in specified_config: + raise ConfigError( + MISSING_REPORT_STATS_CONFIG_INSTRUCTIONS + "\n" + MISSING_REPORT_STATS_SPIEL + ) + return specified_config + + def find_config_files(search_paths): """Finds config files using a list of search paths. If a path is a file then that file path is added to the list. If a search path is a directory diff --git a/synapse/config/api.py b/synapse/config/api.py index d9eff9ae1f24..dddea79a8afd 100644 --- a/synapse/config/api.py +++ b/synapse/config/api.py @@ -30,7 +30,7 @@ def read_config(self, config, **kwargs): ], ) - def default_config(cls, **kwargs): + def generate_config_section(cls, **kwargs): return """\ ## API Configuration ## diff --git a/synapse/config/appservice.py b/synapse/config/appservice.py index b74cebfca906..8387ff6805c0 100644 --- a/synapse/config/appservice.py +++ b/synapse/config/appservice.py @@ -34,7 +34,7 @@ def read_config(self, config, **kwargs): self.notify_appservices = config.get("notify_appservices", True) self.track_appservice_user_ips = config.get("track_appservice_user_ips", False) - def default_config(cls, **kwargs): + def generate_config_section(cls, **kwargs): return """\ # A list of application service config files to use # diff --git a/synapse/config/captcha.py b/synapse/config/captcha.py index a08b08570bce..8dac8152cf12 100644 --- a/synapse/config/captcha.py +++ b/synapse/config/captcha.py @@ -28,7 +28,7 @@ def read_config(self, config, **kwargs): "https://www.recaptcha.net/recaptcha/api/siteverify", ) - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ ## Captcha ## # See docs/CAPTCHA_SETUP for full details of configuring this. diff --git a/synapse/config/cas.py b/synapse/config/cas.py index a5f04499559e..ebe34d933bfa 100644 --- a/synapse/config/cas.py +++ b/synapse/config/cas.py @@ -35,7 +35,7 @@ def read_config(self, config, **kwargs): self.cas_service_url = None self.cas_required_attributes = {} - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """ # Enable CAS for registration and login. # diff --git a/synapse/config/consent_config.py b/synapse/config/consent_config.py index 6fd4931681c0..94916f3a496a 100644 --- a/synapse/config/consent_config.py +++ b/synapse/config/consent_config.py @@ -111,5 +111,5 @@ def read_config(self, config, **kwargs): "policy_name", "Privacy Policy" ) - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return DEFAULT_CONFIG diff --git a/synapse/config/database.py b/synapse/config/database.py index c8963e276a3a..bcb2089dd727 100644 --- a/synapse/config/database.py +++ b/synapse/config/database.py @@ -38,7 +38,7 @@ def read_config(self, config, **kwargs): self.set_databasepath(config.get("database_path")) - def default_config(self, data_dir_path, **kwargs): + def generate_config_section(self, data_dir_path, **kwargs): database_path = os.path.join(data_dir_path, "homeserver.db") return ( """\ diff --git a/synapse/config/emailconfig.py b/synapse/config/emailconfig.py index 07df7b7173c1..cf39936da70e 100644 --- a/synapse/config/emailconfig.py +++ b/synapse/config/emailconfig.py @@ -214,7 +214,7 @@ def read_config(self, config, **kwargs): if not os.path.isfile(p): raise ConfigError("Unable to find email template file %s" % (p,)) - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """ # Enable sending emails for password resets, notification events or # account expiry notices diff --git a/synapse/config/groups.py b/synapse/config/groups.py index d11f4d3b960c..2a522b5f44a1 100644 --- a/synapse/config/groups.py +++ b/synapse/config/groups.py @@ -21,7 +21,7 @@ def read_config(self, config, **kwargs): self.enable_group_creation = config.get("enable_group_creation", False) self.group_creation_prefix = config.get("group_creation_prefix", "") - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ # Uncomment to allow non-server-admin users to create groups on this server # diff --git a/synapse/config/jwt_config.py b/synapse/config/jwt_config.py index a2c97dea954d..36d87cef03c6 100644 --- a/synapse/config/jwt_config.py +++ b/synapse/config/jwt_config.py @@ -41,7 +41,7 @@ def read_config(self, config, **kwargs): self.jwt_secret = None self.jwt_algorithm = None - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ # The JWT needs to contain a globally unique "sub" (subject) claim. # diff --git a/synapse/config/key.py b/synapse/config/key.py index 5ec465b196f4..8fc74f9cdf45 100644 --- a/synapse/config/key.py +++ b/synapse/config/key.py @@ -122,7 +122,7 @@ def read_config(self, config, config_dir_path, **kwargs): # falsification of values self.form_secret = config.get("form_secret", None) - def default_config( + def generate_config_section( self, config_dir_path, server_name, generate_secrets=False, **kwargs ): base_key_name = os.path.join(config_dir_path, server_name) diff --git a/synapse/config/logger.py b/synapse/config/logger.py index 3e05f49abaf7..931aec41c09c 100644 --- a/synapse/config/logger.py +++ b/synapse/config/logger.py @@ -80,7 +80,7 @@ def read_config(self, config, **kwargs): self.log_config = self.abspath(config.get("log_config")) self.log_file = self.abspath(config.get("log_file")) - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): log_config = os.path.join(config_dir_path, server_name + ".log.config") return ( """\ diff --git a/synapse/config/metrics.py b/synapse/config/metrics.py index 6af82e1329fa..3698441963b1 100644 --- a/synapse/config/metrics.py +++ b/synapse/config/metrics.py @@ -40,7 +40,7 @@ def read_config(self, config, **kwargs): "sentry.dsn field is required when sentry integration is enabled" ) - def default_config(self, report_stats=None, **kwargs): + def generate_config_section(self, report_stats=None, **kwargs): res = """\ ## Metrics ### diff --git a/synapse/config/password.py b/synapse/config/password.py index 300b67f23624..598f84fc0c84 100644 --- a/synapse/config/password.py +++ b/synapse/config/password.py @@ -28,7 +28,7 @@ def read_config(self, config, **kwargs): self.password_enabled = password_config.get("enabled", True) self.password_pepper = password_config.get("pepper", "") - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """\ password_config: # Uncomment to disable password login diff --git a/synapse/config/password_auth_providers.py b/synapse/config/password_auth_providers.py index 8ffefd263905..788c39c9fbaf 100644 --- a/synapse/config/password_auth_providers.py +++ b/synapse/config/password_auth_providers.py @@ -46,7 +46,7 @@ def read_config(self, config, **kwargs): self.password_providers.append((provider_class, provider_config)) - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ #password_providers: # - module: "ldap_auth_provider.LdapAuthProvider" diff --git a/synapse/config/push.py b/synapse/config/push.py index 99d15e4461ee..1b932722a548 100644 --- a/synapse/config/push.py +++ b/synapse/config/push.py @@ -42,7 +42,7 @@ def read_config(self, config, **kwargs): ) self.push_include_content = not redact_content - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """ # Clients requesting push notifications can either have the body of # the message sent in the notification poke along with other details diff --git a/synapse/config/ratelimiting.py b/synapse/config/ratelimiting.py index b03047f2b508..8c587f3fd2f8 100644 --- a/synapse/config/ratelimiting.py +++ b/synapse/config/ratelimiting.py @@ -80,7 +80,7 @@ def read_config(self, config, **kwargs): "federation_rr_transactions_per_room_per_second", 50 ) - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ ## Ratelimiting ## diff --git a/synapse/config/registration.py b/synapse/config/registration.py index 6d8a2df29b6b..4a59e6ec90f6 100644 --- a/synapse/config/registration.py +++ b/synapse/config/registration.py @@ -85,7 +85,7 @@ def read_config(self, config, **kwargs): "disable_msisdn_registration", False ) - def default_config(self, generate_secrets=False, **kwargs): + def generate_config_section(self, generate_secrets=False, **kwargs): if generate_secrets: registration_shared_secret = 'registration_shared_secret: "%s"' % ( random_string_with_symbols(50), diff --git a/synapse/config/repository.py b/synapse/config/repository.py index 43e6c4921fa9..80a628d9b0cb 100644 --- a/synapse/config/repository.py +++ b/synapse/config/repository.py @@ -190,7 +190,7 @@ def read_config(self, config, **kwargs): self.url_preview_url_blacklist = config.get("url_preview_url_blacklist", ()) - def default_config(self, data_dir_path, **kwargs): + def generate_config_section(self, data_dir_path, **kwargs): media_store = os.path.join(data_dir_path, "media_store") uploads_path = os.path.join(data_dir_path, "uploads") diff --git a/synapse/config/room_directory.py b/synapse/config/room_directory.py index 24223db7a158..a92693017be9 100644 --- a/synapse/config/room_directory.py +++ b/synapse/config/room_directory.py @@ -46,7 +46,7 @@ def read_config(self, config, **kwargs): _RoomDirectoryRule("room_list_publication_rules", {"action": "allow"}) ] - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """ # Uncomment to disable searching the public room list. When disabled # blocks searching local and remote room lists for local and remote diff --git a/synapse/config/saml2_config.py b/synapse/config/saml2_config.py index d86cf0e6eebc..872a1ba934bb 100644 --- a/synapse/config/saml2_config.py +++ b/synapse/config/saml2_config.py @@ -61,7 +61,7 @@ def _default_saml_config_dict(self): }, } - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """\ # Enable SAML2 for registration and login. Uses pysaml2. # diff --git a/synapse/config/server.py b/synapse/config/server.py index 1e58b2e91b8b..2f5d1a6ae3ef 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -307,7 +307,7 @@ def read_config(self, config, **kwargs): def has_tls_listener(self): return any(l["tls"] for l in self.listeners) - def default_config(self, server_name, data_dir_path, **kwargs): + def generate_config_section(self, server_name, data_dir_path, **kwargs): _, bind_port = parse_and_validate_server_name(server_name) if bind_port is not None: unsecure_port = bind_port - 400 diff --git a/synapse/config/server_notices_config.py b/synapse/config/server_notices_config.py index 05110c17a6c1..eaac3d73bc7a 100644 --- a/synapse/config/server_notices_config.py +++ b/synapse/config/server_notices_config.py @@ -78,5 +78,5 @@ def read_config(self, config, **kwargs): # todo: i18n self.server_notices_room_name = c.get("room_name", "Server Notices") - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return DEFAULT_CONFIG diff --git a/synapse/config/spam_checker.py b/synapse/config/spam_checker.py index 1968003cb3c2..e40797ab50f9 100644 --- a/synapse/config/spam_checker.py +++ b/synapse/config/spam_checker.py @@ -26,7 +26,7 @@ def read_config(self, config, **kwargs): if provider is not None: self.spam_checker = load_module(provider) - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ #spam_checker: # module: "my_custom_project.SuperSpamChecker" diff --git a/synapse/config/stats.py b/synapse/config/stats.py index 73a87c73f278..b518a3ed9cb3 100644 --- a/synapse/config/stats.py +++ b/synapse/config/stats.py @@ -42,7 +42,7 @@ def read_config(self, config, **kwargs): / 1000 ) - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """ # Local statistics collection. Used in populating the room directory. # diff --git a/synapse/config/third_party_event_rules.py b/synapse/config/third_party_event_rules.py index 1bedd607b612..b3431441b9b7 100644 --- a/synapse/config/third_party_event_rules.py +++ b/synapse/config/third_party_event_rules.py @@ -26,7 +26,7 @@ def read_config(self, config, **kwargs): if provider is not None: self.third_party_event_rules = load_module(provider) - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ # Server admins can define a Python module that implements extra rules for # allowing or denying incoming events. In order to work, this module needs to diff --git a/synapse/config/tls.py b/synapse/config/tls.py index 9a66e8cc4bf0..8fcf80141863 100644 --- a/synapse/config/tls.py +++ b/synapse/config/tls.py @@ -217,7 +217,9 @@ def read_certificate_from_disk(self, require_cert_and_key): if sha256_fingerprint not in sha256_fingerprints: self.tls_fingerprints.append({"sha256": sha256_fingerprint}) - def default_config(self, config_dir_path, server_name, data_dir_path, **kwargs): + def generate_config_section( + self, config_dir_path, server_name, data_dir_path, **kwargs + ): base_key_name = os.path.join(config_dir_path, server_name) tls_certificate_path = base_key_name + ".tls.crt" diff --git a/synapse/config/user_directory.py b/synapse/config/user_directory.py index 0665dc3fcffd..f6313e17d432 100644 --- a/synapse/config/user_directory.py +++ b/synapse/config/user_directory.py @@ -33,7 +33,7 @@ def read_config(self, config, **kwargs): "search_all_users", False ) - def default_config(self, config_dir_path, server_name, **kwargs): + def generate_config_section(self, config_dir_path, server_name, **kwargs): return """ # User Directory configuration # diff --git a/synapse/config/voip.py b/synapse/config/voip.py index 01e0cb2e287a..2ca0e1cf70d1 100644 --- a/synapse/config/voip.py +++ b/synapse/config/voip.py @@ -26,7 +26,7 @@ def read_config(self, config, **kwargs): ) self.turn_allow_guests = config.get("turn_allow_guests", True) - def default_config(self, **kwargs): + def generate_config_section(self, **kwargs): return """\ ## TURN ## From c7832945498b45f0ae2a0b3c00c2e08254aed4e0 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sat, 22 Jun 2019 00:15:01 +0100 Subject: [PATCH 3/6] changelog --- changelog.d/5523.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5523.bugfix diff --git a/changelog.d/5523.bugfix b/changelog.d/5523.bugfix new file mode 100644 index 000000000000..26acd367a850 --- /dev/null +++ b/changelog.d/5523.bugfix @@ -0,0 +1 @@ +Fix a regression where homeservers on private IP addresses were incorrectly blacklisted. \ No newline at end of file From 6a92b06cbb4677a38bf3f5bb3bb22dfbd93ea088 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 21 Jun 2019 10:53:49 +0100 Subject: [PATCH 4/6] Add --data-directory commandline argument We don't necessarily want to put the data in the cwd. --- synapse/config/_base.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/synapse/config/_base.py b/synapse/config/_base.py index 8757416a6056..8654b0f4a15f 100644 --- a/synapse/config/_base.py +++ b/synapse/config/_base.py @@ -290,6 +290,15 @@ def load_or_generate_config(cls, description, argv): " config file." ), ) + generate_group.add_argument( + "--data-directory", + metavar="DIRECTORY", + help=( + "Specify where data such as the media store and database file should be" + " stored. Defaults to the current working directory." + ), + ) + config_args, remaining_args = config_parser.parse_known_args(argv) config_files = find_config_files(search_paths=config_args.config_path) @@ -323,6 +332,12 @@ def load_or_generate_config(cls, description, argv): if not cls.path_exists(config_path): print("Generating config file %s" % (config_path,)) + if config_args.data_directory: + data_dir_path = config_args.data_directory + else: + data_dir_path = os.getcwd() + data_dir_path = os.path.abspath(data_dir_path) + server_name = config_args.server_name if not server_name: raise ConfigError( From 3f8a252dd86fecff6cdda58043aaba7b79436e01 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Fri, 21 Jun 2019 13:46:39 +0100 Subject: [PATCH 5/6] Add "--open-private-ports" cmdline option This is helpful when generating a config file for running synapse under docker. --- docs/sample_config.yaml | 2 +- synapse/config/_base.py | 14 ++++++++++++++ synapse/config/server.py | 17 ++++++++++++----- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/docs/sample_config.yaml b/docs/sample_config.yaml index bb07b02f4ed5..522ec7e8ffd4 100644 --- a/docs/sample_config.yaml +++ b/docs/sample_config.yaml @@ -209,7 +209,7 @@ listeners: - names: [client, federation] compress: false - # example additonal_resources: + # example additional_resources: # #additional_resources: # "/_matrix/my/custom/endpoint": diff --git a/synapse/config/_base.py b/synapse/config/_base.py index 8654b0f4a15f..965478d8d59e 100644 --- a/synapse/config/_base.py +++ b/synapse/config/_base.py @@ -150,6 +150,7 @@ def generate_config( server_name, generate_secrets=False, report_stats=None, + open_private_ports=False, ): """Build a default configuration file @@ -173,6 +174,9 @@ def generate_config( report_stats (bool|None): Initial setting for the report_stats setting. If None, report_stats will be left unset. + open_private_ports (bool): True to leave private ports (such as the non-TLS + HTTP listener) open to the internet. + Returns: str: the yaml config file """ @@ -185,6 +189,7 @@ def generate_config( server_name=server_name, generate_secrets=generate_secrets, report_stats=report_stats, + open_private_ports=open_private_ports, ) ) @@ -298,6 +303,14 @@ def load_or_generate_config(cls, description, argv): " stored. Defaults to the current working directory." ), ) + generate_group.add_argument( + "--open-private-ports", + action="store_true", + help=( + "Leave private ports (such as the non-TLS HTTP listener) open to the" + " internet. Do not use this unless you know what you are doing." + ), + ) config_args, remaining_args = config_parser.parse_known_args(argv) @@ -351,6 +364,7 @@ def load_or_generate_config(cls, description, argv): server_name=server_name, report_stats=(config_args.report_stats == "yes"), generate_secrets=True, + open_private_ports=config_args.open_private_ports, ) if not cls.path_exists(config_dir_path): diff --git a/synapse/config/server.py b/synapse/config/server.py index 2f5d1a6ae3ef..c1b2ccfe450a 100644 --- a/synapse/config/server.py +++ b/synapse/config/server.py @@ -307,7 +307,9 @@ def read_config(self, config, **kwargs): def has_tls_listener(self): return any(l["tls"] for l in self.listeners) - def generate_config_section(self, server_name, data_dir_path, **kwargs): + def generate_config_section( + self, server_name, data_dir_path, open_private_ports, **kwargs + ): _, bind_port = parse_and_validate_server_name(server_name) if bind_port is not None: unsecure_port = bind_port - 400 @@ -320,6 +322,13 @@ def generate_config_section(self, server_name, data_dir_path, **kwargs): # Bring DEFAULT_ROOM_VERSION into the local-scope for use in the # default config string default_room_version = DEFAULT_ROOM_VERSION + + unsecure_http_binding = "port: %i\n tls: false" % (unsecure_port,) + if not open_private_ports: + unsecure_http_binding += ( + "\n bind_addresses: ['::1', '127.0.0.1']" + ) + return ( """\ ## Server ## @@ -511,9 +520,7 @@ def generate_config_section(self, server_name, data_dir_path, **kwargs): # If you plan to use a reverse proxy, please see # https://github.com/matrix-org/synapse/blob/master/docs/reverse_proxy.rst. # - - port: %(unsecure_port)s - tls: false - bind_addresses: ['::1', '127.0.0.1'] + - %(unsecure_http_binding)s type: http x_forwarded: true @@ -521,7 +528,7 @@ def generate_config_section(self, server_name, data_dir_path, **kwargs): - names: [client, federation] compress: false - # example additonal_resources: + # example additional_resources: # #additional_resources: # "/_matrix/my/custom/endpoint": From e6b2ccbb516a65e8c45ba70a54e0d14afee8704d Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Sat, 22 Jun 2019 00:27:57 +0100 Subject: [PATCH 6/6] changelog --- changelog.d/5524.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5524.feature diff --git a/changelog.d/5524.feature b/changelog.d/5524.feature new file mode 100644 index 000000000000..6ba211c3cc03 --- /dev/null +++ b/changelog.d/5524.feature @@ -0,0 +1 @@ +Add --data-dir and --open-private-ports options. \ No newline at end of file