diff --git a/authentik/lib/config.py b/authentik/lib/config.py index e3b00a7e1..8656756f3 100644 --- a/authentik/lib/config.py +++ b/authentik/lib/config.py @@ -62,7 +62,7 @@ class ConfigLoader: output.update(kwargs) print(dumps(output)) - def update(self, root, updatee): + def update(self, root: dict[str, Any], updatee: dict[str, Any]) -> dict[str, Any]: """Recursively update dictionary""" for key, value in updatee.items(): if isinstance(value, Mapping): @@ -73,7 +73,7 @@ class ConfigLoader: root[key] = value return root - def parse_uri(self, value): + def parse_uri(self, value: str) -> str: """Parse string values which start with a URI""" url = urlparse(value) if url.scheme == "env": @@ -99,7 +99,10 @@ class ConfigLoader: raise ImproperlyConfigured from exc except PermissionError as exc: self._log( - "warning", "Permission denied while reading file", path=path, error=exc + "warning", + "Permission denied while reading file", + path=path, + error=str(exc), ) def update_from_dict(self, update: dict): diff --git a/authentik/lib/tests/test_config.py b/authentik/lib/tests/test_config.py new file mode 100644 index 000000000..30c00932e --- /dev/null +++ b/authentik/lib/tests/test_config.py @@ -0,0 +1,61 @@ +"""Test config loader""" +from os import chmod, environ, unlink, write +from tempfile import mkstemp + +from django.conf import ImproperlyConfigured +from django.test import TestCase + +from authentik.lib.config import ENV_PREFIX, ConfigLoader + + +class TestConfig(TestCase): + """Test config loader""" + + def test_env(self): + """Test simple instance""" + config = ConfigLoader() + environ[ENV_PREFIX + "_test__test"] = "bar" + config.update_from_env() + self.assertEqual(config.y("test.test"), "bar") + + def test_patch(self): + """Test patch decorator""" + config = ConfigLoader() + config.y_set("foo.bar", "bar") + self.assertEqual(config.y("foo.bar"), "bar") + with config.patch("foo.bar", "baz"): + self.assertEqual(config.y("foo.bar"), "baz") + self.assertEqual(config.y("foo.bar"), "bar") + + def test_uri_env(self): + """Test URI parsing (environment)""" + config = ConfigLoader() + environ["foo"] = "bar" + self.assertEqual(config.parse_uri("env://foo"), "bar") + self.assertEqual(config.parse_uri("env://fo?bar"), "bar") + + def test_uri_file(self): + """Test URI parsing (file load)""" + config = ConfigLoader() + file, file_name = mkstemp() + write(file, "foo".encode()) + _, file2_name = mkstemp() + chmod(file2_name, 0o000) # Remove all permissions so we can't read the file + self.assertEqual(config.parse_uri(f"file://{file_name}"), "foo") + self.assertEqual(config.parse_uri(f"file://{file2_name}?def"), "def") + unlink(file_name) + unlink(file2_name) + + def test_file_update(self): + """Test update_from_file""" + config = ConfigLoader() + file, file_name = mkstemp() + write(file, "{".encode()) + file2, file2_name = mkstemp() + write(file2, "{".encode()) + chmod(file2_name, 0o000) # Remove all permissions so we can't read the file + with self.assertRaises(ImproperlyConfigured): + config.update_from_file(file_name) + config.update_from_file(file2_name) + unlink(file_name) + unlink(file2_name)