diff options
author | Jorik Schellekens <joriks@matrix.org> | 2019-08-23 16:33:47 +0100 |
---|---|---|
committer | Jorik Schellekens <joriks@matrix.org> | 2019-08-28 15:59:54 +0100 |
commit | d63a58462f4c0e6b0d7a8f34390b8bed63fe2b08 (patch) | |
tree | a5a51845467e187ae0e87bc8c871b70cd8f14f4d | |
parent | We're not using these (diff) | |
download | synapse-d63a58462f4c0e6b0d7a8f34390b8bed63fe2b08.tar.xz |
Make the model stateless.
-rw-r--r-- | synapse_topology/model/__init__.py | 136 | ||||
-rw-r--r-- | synapse_topology/model/constants.py | 5 | ||||
-rw-r--r-- | synapse_topology/model/errors.py | 7 | ||||
-rw-r--r-- | synapse_topology/model/util.py | 9 | ||||
-rw-r--r-- | synapse_topology/server/error_handlers.py | 6 |
5 files changed, 83 insertions, 80 deletions
diff --git a/synapse_topology/model/__init__.py b/synapse_topology/model/__init__.py index 3e3e2de3d2..eb91917935 100644 --- a/synapse_topology/model/__init__.py +++ b/synapse_topology/model/__init__.py @@ -1,7 +1,7 @@ import yaml import subprocess -from os.path import abspath, join +from os.path import abspath, join, exists, isdir from synapse.config.homeserver import HomeServerConfig @@ -12,83 +12,81 @@ from .constants import ( DATA_SUBDIR, SERVER_NAME, ) -from .errors import BasConfigInUseError, BaseConfigNotFoundError, ConfigNotFoundError +from .errors import BaseConfigInUseError, ConfigNotFoundError, ServernameNotSetError from .config import create_config +from .util import is_subpath +from synapse.config import find_config_files, read_config_files -def set_config_dir(conf_dir): - global config_dir - global data_dir - config_dir = abspath(conf_dir) - data_dir = abspath(join(config_dir, "./data")) +class Model: + """ + The Model brokers modification of the config file and signing keys in the config + directory. + """ + + def __init__(self, config_dir): + self.config_dir = abspath(config_dir) + self.data_dir = abspath(join(self.config_dir, DATA_SUBDIR)) + if not isdir(self.config_dir) or not isdir(self.data_dir): + raise FileNotFoundError() -def get_config_dir(): - return config_dir + def get_config(self, config_path): + """ + Retrieves a config from the config directory. Any path can be provided + but it must be a subdirectory of self.config_dir + Args: + config_path (str): path to the config -def get_data_dir(): - return data_dir + Returns: + dict: the yaml parse of the config file + """ + conf_path = abspath(join(self.config_dir, config_path)) + if not is_subpath(config_dir, conf_path): + raise FileNotFoundError() -def get_config(): - conf_path = join(config_dir, BASE_CONFIG) - try: with open(conf_path, "r") as f: return yaml.safe_load(f) - except FileNotFoundError: - raise BaseConfigNotFoundError() - - -def set_config(config): - if config_in_use(): - raise BasConfigInUseError() - for conf_name, conf in create_config(config_dir, data_dir, config).items(): - with open(abspath(join(get_config_dir(), conf_name)), "w") as f: - f.write(conf) - - -def config_in_use(): - """ - Checks if we set whether the config is in use. If it was set up by the system - but synapse wasn't launched yet we will have set this to False. However if - it's not present we assume someone else has set up synapse before so we assume - the config is in use. - """ - try: - return get_config().get(CONFIG_LOCK, True) - except FileNotFoundError: - return False - - -def generate_base_config(server_name, report_stats): - if config_in_use(): - raise BasConfigInUseError() - - conf = HomeServerConfig().generate_config( - config_dir, - join(config_dir, DATA_SUBDIR), - server_name, - generate_secrets=True, - report_stats=report_stats, - ) - - with open(join(config_dir, BASE_CONFIG), "w") as f: - f.write(conf) - f.write(CONFIG_LOCK_DATA) - - -def get_server_name(): - config = get_config() - if config: - return config.get(SERVER_NAME) - - -def get_secret_key(): - config = get_config() - server_name = config.get(SERVER_NAME) - signing_key_path = join(config_dir, server_name + ".signing.key") - subprocess.run(["generate_signing_key.py", "-o", signing_key_path]) - with open(signing_key_path, "r") as f: - return f.read() + def write_config(self, config): + """ + Given a config generates a templated config from synapse and writes it + out to the config dir. It will raise an exception if the config in + the config directory is in use. + + Args: + config (dict): The configuration to template out. + """ + if self.config_in_use(): + raise BaseConfigInUseError() + + for conf_name, conf in create_config( + self.config_dir, self.data_dir, config + ).items(): + with open(abspath(join(self.config_dir, conf_name)), "w") as f: + f.write(conf) + + def config_in_use(self): + """ + Checks if we set whether the config is in use. If it was set up by the system + but synapse wasn't launched yet we will have set this to False. However if + it's not present we assume someone else has set up synapse before so we assume + the config is in use. + """ + try: + return read_config_files(find_config_files(self.config_dir)).get( + CONFIG_LOCK, True + ) + except FileNotFoundError: + return False + + def generate_secret_key(self, server_name): + if self.config_in_use(): + raise BaseConfigInUseError() + + signing_key_path = join(self.config_dir, server_name + ".signing.key") + subprocess.run(["generate_signing_key.py", "-o", signing_key_path]) + with open(signing_key_path, "r") as f: + return f.read() diff --git a/synapse_topology/model/constants.py b/synapse_topology/model/constants.py index a3b4d2240b..f847083db6 100644 --- a/synapse_topology/model/constants.py +++ b/synapse_topology/model/constants.py @@ -1,7 +1,4 @@ # Paths -BASE_CONFIG = "homeserver.yaml" -# TODO: fill in further configs -CONFIGS = [BASE_CONFIG, "user.yaml", "optimizations.yaml", "something.yaml"] DATA_SUBDIR = "data" # Config options @@ -17,7 +14,7 @@ CONFIG_LOCK_DATA = """ # Specifies whether synapse has been started with this config. # If set to True the setup util will not go through the initialization # phase which sets the server name and server keys. -{}: False +{}: {{}} """.format( diff --git a/synapse_topology/model/errors.py b/synapse_topology/model/errors.py index 4a36752d95..cbe9c5d819 100644 --- a/synapse_topology/model/errors.py +++ b/synapse_topology/model/errors.py @@ -9,10 +9,9 @@ class ConfigNotFoundError(FileNotFoundError): return self.config_name -class BaseConfigNotFoundError(ConfigNotFoundError): - def __init__(self): - super().__init__(BASE_CONFIG) +class ServernameNotSetError(Exception): + pass -class BasConfigInUseError(Exception): +class BaseConfigInUseError(Exception): pass diff --git a/synapse_topology/model/util.py b/synapse_topology/model/util.py new file mode 100644 index 0000000000..aad2de4efe --- /dev/null +++ b/synapse_topology/model/util.py @@ -0,0 +1,9 @@ +from os.path import realpath, pardir, sep, relpath + + +def is_subpath(superpath, subpath): + subpath = realpath(subpath) + superpath = realpath(superpath) + relative = relpath(subpath, superpath) + return not relative.startswith(pardir + sep) + diff --git a/synapse_topology/server/error_handlers.py b/synapse_topology/server/error_handlers.py index 22825159d0..f43083322d 100644 --- a/synapse_topology/server/error_handlers.py +++ b/synapse_topology/server/error_handlers.py @@ -2,8 +2,8 @@ from jsonschema import ValidationError from simplejson.errors import JSONDecodeError from synapse_topology.model.errors import ( BasConfigInUseError, - BaseConfigNotFoundError, ConfigNotFoundError, + ServernameNotSetError, ) from . import app @@ -22,8 +22,8 @@ def json_decode_error(request, failure): return "Invalid post json" -@app.handle_errors(BaseConfigNotFoundError) -def base_config_not_found(request, failure): +@app.handle_errors(ServernameNotSetError) +def not_initialised(request, failure): request.setResponseCode(500) return "Config file not setup, please initialise it using the /servername endpoint" |