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

Stop conflating generated config and default config #5523

Merged
merged 3 commits into from
Jun 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5523.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a regression where homeservers on private IP addresses were incorrectly blacklisted.
106 changes: 35 additions & 71 deletions synapse/config/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand All @@ -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
Expand All @@ -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,
Expand All @@ -194,8 +188,6 @@ def generate_config(
)
)

return default_config

@classmethod
def load_config(cls, description, argv):
"""Parse the commandline and config files
Expand Down Expand Up @@ -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
)
Expand Down Expand Up @@ -354,8 +344,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(
(
Expand Down Expand Up @@ -385,12 +375,9 @@ 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)
obj.generate_missing_files(config_dict, config_dir_path)
return None

obj.parse_config_dict(
Expand All @@ -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.

Expand All @@ -466,8 +406,32 @@ 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 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):
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def read_config(self, config, **kwargs):
],
)

def default_config(cls, **kwargs):
def generate_config_section(cls, **kwargs):
return """\
## API Configuration ##

Expand Down
2 changes: 1 addition & 1 deletion synapse/config/appservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/captcha.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/cas.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
#
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/consent_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion synapse/config/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
"""\
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/emailconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
#
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/jwt_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
#
Expand Down
24 changes: 18 additions & 6 deletions synapse/config/key.py
Original file line number Diff line number Diff line change
Expand Up @@ -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", {})
Expand Down Expand Up @@ -117,7 +122,7 @@ def read_config(self, config, **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)
Expand Down Expand Up @@ -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,))
Expand Down
4 changes: 2 additions & 2 deletions synapse/config/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
"""\
Expand Down Expand Up @@ -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")
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ###

Expand Down
2 changes: 1 addition & 1 deletion synapse/config/password.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/password_auth_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion synapse/config/ratelimiting.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ##

Expand Down
2 changes: 1 addition & 1 deletion synapse/config/registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
Loading