From 73c9b77eaacc75449395cb69f44180e2364a3deb Mon Sep 17 00:00:00 2001
From: Julian Rother <julian@cccv.de>
Date: Thu, 9 Dec 2021 01:48:02 +0100
Subject: [PATCH] Replace CONFIG_FILENAME with CONFIG_PATH

CONFIG_FILENAME works relative to the app's instance path. While (strictly
speaking) CONFIG_FILENAME is named correctly, it is not really obvious that
it should be set to an instance-relative filename instead of a path. The
current uwsgi.ini file illustrates this problem.

Not having a way to specify an absolute config file path is a problem for
the Debian package: The actual config file /etc/uffd/uffd.cfg must be
symlinked to /usr/share/uffd/instance/config.cfg to be found. Setting
CONFIG_PATH to "/etc/uffd/uffd.cfg" simplifies this.

Since this change is part of a new major release, we can drop
CONFIG_FILENAME in favour of CONFIG_PATH.
---
 README.md                 |  5 ++++-
 debian/contrib/uffd-admin |  4 ++--
 debian/dirs               |  1 -
 debian/links              |  1 -
 uffd/__init__.py          | 25 ++++++++++++-------------
 uwsgi.ini                 |  2 +-
 6 files changed, 19 insertions(+), 19 deletions(-)

diff --git a/README.md b/README.md
index 49293d90..0ca4fec3 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,9 @@ For an example uwsgi config, see our [uswgi.ini](uwsgi.ini). You might find our
 
 ## Migration from version 1
 
+If a custom config file name was set with `CONFIG_FILENAME`, this must be replaced with `CONFIG_PATH`.
+The new variable must be set to a full path instead of a filename relative to the application's instance directory.
+
 Prior to version 2 uffd stored users, groups and mail aliases in an LDAP server.
 To migrate from version 1 to a later version, make sure to keep the v1 config file as it is with all LDAP settings.
 Running the database migrations with `flask db upgrade` automatically imports all users, groups and mail forwardings from LDAP to the database.
@@ -102,7 +105,7 @@ We ship a [pylint](https://pylint.org/) config to verify changes with.
 Uffd reads its default config from `uffd/default_config.cfg`.
 You can overwrite config variables by creating a config file in the `instance` folder.
 The file must be named `config.cfg` (Python syntax), `config.json` or `config.yml`/`config.yaml`.
-You can also set a custom file name with the environment variable `CONFIG_FILENAME`.
+You can also set a custom file path with the environment variable `CONFIG_PATH`.
 
 ## OAuth2 Single-Sign-On Provider
 
diff --git a/debian/contrib/uffd-admin b/debian/contrib/uffd-admin
index 897f6904..ffffdfa8 100755
--- a/debian/contrib/uffd-admin
+++ b/debian/contrib/uffd-admin
@@ -3,12 +3,12 @@
 set -eu
 
 export FLASK_APP=/usr/share/uffd/uffd
-export CONFIG_FILENAME=/etc/uffd/uffd.cfg
+export CONFIG_PATH=/etc/uffd/uffd.cfg
 
 if [ "$(whoami)" = "uffd" ]; then
 	flask "$@"
 elif command -v sudo > /dev/null 2>&1; then
-	exec sudo --preserve-env=FLASK_APP,CONFIG_FILENAME -u uffd flask "$@"
+	exec sudo --preserve-env=FLASK_APP,CONFIG_PATH -u uffd flask "$@"
 elif command -v runuser > /dev/null 2>&1; then
 	exec runuser --preserve-environment -u uffd -- flask "$@"
 else
diff --git a/debian/dirs b/debian/dirs
index fe0717b3..0100ce67 100644
--- a/debian/dirs
+++ b/debian/dirs
@@ -1,3 +1,2 @@
 /etc/uffd
 /var/lib/uffd
-/usr/share/uffd/uffd/instance
diff --git a/debian/links b/debian/links
index e97982ee..16c29e9e 100644
--- a/debian/links
+++ b/debian/links
@@ -1,3 +1,2 @@
-/etc/uffd/uffd.cfg /usr/share/uffd/uffd/instance/config.cfg
 /etc/uffd/uwsgi.ini /etc/uwsgi/apps-available/uffd.ini
 /etc/uwsgi/apps-available/uffd.ini /etc/uwsgi/apps-enabled/uffd.ini
diff --git a/uffd/__init__.py b/uffd/__init__.py
index c6c83c71..ae885358 100644
--- a/uffd/__init__.py
+++ b/uffd/__init__.py
@@ -22,22 +22,21 @@ from uffd.user.models import User, Group
 from uffd.role.models import Role, RoleGroup
 from uffd.mail.models import Mail
 
-def load_config_file(app, cfg_name, silent=False):
-	cfg_path = os.path.join(app.instance_path, cfg_name)
-	if not os.path.exists(cfg_path):
+def load_config_file(app, path, silent=False):
+	if not os.path.exists(path):
 		if not silent:
-			raise Exception(f"Config file {cfg_path} not found")
+			raise Exception(f"Config file {path} not found")
 		return False
 
-	if cfg_path.endswith(".json"):
-		app.config.from_json(cfg_path)
-	elif cfg_path.endswith(".yaml") or cfg_path.endswith(".yml"):
+	if path.endswith(".json"):
+		app.config.from_json(path)
+	elif path.endswith(".yaml") or path.endswith(".yml"):
 		import yaml  # pylint: disable=import-outside-toplevel disable=import-error
-		with open(cfg_path, encoding='utf-8') as ymlfile:
+		with open(path, encoding='utf-8') as ymlfile:
 			data = yaml.safe_load(ymlfile)
 		app.config.from_mapping(data)
 	else:
-		app.config.from_pyfile(cfg_path, silent=True)
+		app.config.from_pyfile(path, silent=True)
 	return True
 
 def init_config(app: Flask, test_config):
@@ -48,11 +47,11 @@ def init_config(app: Flask, test_config):
 	# load config
 	if test_config is not None:
 		app.config.from_mapping(test_config)
-	elif os.environ.get("CONFIG_FILENAME"):
-		load_config_file(app, os.environ["CONFIG_FILENAME"], silent=False)
+	elif os.environ.get('CONFIG_PATH'):
+		load_config_file(app, os.environ['CONFIG_PATH'], silent=False)
 	else:
-		for cfg_name in ["config.cfg", "config.json", "config.yml", "config.yaml"]:
-			if load_config_file(app, cfg_name, silent=True):
+		for filename in ["config.cfg", "config.json", "config.yml", "config.yaml"]:
+			if load_config_file(app, os.path.join(app.instance_path, filename), silent=True):
 				break
 	# Prior to v1.1 login required ACL_SELFSERVICE_GROUP and ACL_ACCESS_GROUP did not exist
 	app.config.setdefault('ACL_ACCESS_GROUP', app.config['ACL_SELFSERVICE_GROUP'])
diff --git a/uwsgi.ini b/uwsgi.ini
index 183b56ea..2235d830 100644
--- a/uwsgi.ini
+++ b/uwsgi.ini
@@ -11,7 +11,7 @@ vacuum = true
 env = PYTHONIOENCODING=UTF-8
 env = LANG=en_GB.utf8
 env = TZ=Europe/Berlin
-env = CONFIG_FILENAME=/etc/uffd/uffd.cfg
+env = CONFIG_PATH=/etc/uffd/uffd.cfg
 chdir = /usr/share/uffd
 module = uffd:create_app()
 
-- 
GitLab