Skip to content

Commit

Permalink
Keep key format for CKAN___ env vars if they are declared
Browse files Browse the repository at this point in the history
If a config key is declared in the CKAN config declaration, the key is
not further processed. This allows to keep eg upper case setttings like
SECRET_KEY, WTF_CSRF_ENABLED etc:

    CKAN___SECRET_KEY=xxx -> config["SECRET_KEY"] = 'xxx'
    CKAN___WTF_CSRF_ENABLED=True -> config["WTF_CSRF_ENABLED"] = True
  • Loading branch information
amercader committed Oct 6, 2023
1 parent 0e2992b commit 6b89fb0
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 9 deletions.
41 changes: 33 additions & 8 deletions ckanext/envvars/plugin.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,46 @@
import logging
import os

import ckan.plugins as plugins
import ckantoolkit as toolkit

if toolkit.check_ckan_version(min_version='2.10'):
from ckan.common import config_declaration
else:
config_declaration = None


log = logging.getLogger(__name__)


class EnvvarsPlugin(plugins.SingletonPlugin):
plugins.implements(plugins.IConfigurer)

@staticmethod
def _envvar_to_ini(key):
# This is only used on CKAN>=2.10
declared_keys = None

def _envvar_to_ini(self, key):
'''Transforms an env var formatted key to ini formatting.'''

def _format_key(key):
# Set it to lowercase
key = key.lower()
# Replace dunders with dots
key = key.replace('__', '.')

return key

# If the key starts with 'CKAN___' (3 underscores).
if key.startswith('CKAN___'):
key = key[7:]
# Set it to lowercase
key = key.lower()
# Replace dunders with dots
key = key.replace('__', '.')

if self.declared_keys:
# If the key is defined as present in the env var, leave as is
# (eg uppercase)
if key not in self.declared_keys:
key = _format_key(key)
else:
key = _format_key(key)

return key

Expand All @@ -31,13 +52,17 @@ def update_config(self, config):
ckan_vars = ((k, v) for k, v in os.environ.items()
if k.startswith('CKAN'))

if config_declaration:
self.declared_keys = [str(k) for k in config_declaration.iter_options()]
else:
self.declared_keys = None

# transform vars into ini settings format
ckan_vars = ((self._envvar_to_ini(k), v) for k, v in ckan_vars)

# override config settings with new values
config.update(dict(ckan_vars))

# CKAN >=2.10 normalizes config values
if toolkit.check_ckan_version(min_version='2.10'):
from ckan.common import config_declaration
if config_declaration:
config_declaration.normalize(config)
37 changes: 36 additions & 1 deletion ckanext/envvars/tests/test_base_envvars.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,24 @@ def test_envvartoini_expected_output(self):
]

for envkey, inikey in envvar_to_ini_examples:
assert EnvvarsPlugin._envvar_to_ini(envkey) == inikey
assert EnvvarsPlugin()._envvar_to_ini(envkey) == inikey

@pytest.mark.skipif(tk.check_ckan_version(max_version='2.10'), reason="This does not apply to CKAN<2.10")
def test_envvartoini_expected_output_declared_option(self):
'''
EnvvarsPlugin._envvar_to_ini returns expected transformation of env
var formated keys
'''

envvar_to_ini_examples = [
('CKAN___SECRET_KEY', 'SECRET_KEY'),
('CKAN___REMEMBER_COOKIE_DURATION', 'REMEMBER_COOKIE_DURATION'),
('CKAN___WTF_CSRF_ENABLED', 'WTF_CSRF_ENABLED'),
('CKAN___NOT_DECLARED', 'not_declared'),
]

for envkey, inikey in envvar_to_ini_examples:
assert EnvvarsPlugin()._envvar_to_ini(envkey) == inikey

class TestEnvVarsConfig(object):

Expand Down Expand Up @@ -71,6 +87,25 @@ def test_envvars_values_in_config(self):

self._teardown_env_vars(envvar_to_ini_examples)

@pytest.mark.skipif(tk.check_ckan_version(max_version='2.10'), reason="This does not apply to CKAN<2.10")
def test_envvars_values_in_config(self):

envvar_to_ini_examples = [
('CKAN___SECRET_KEY', 'super_secret'),
('CKAN___REMEMBER_COOKIE_DURATION', '1000'),
('CKAN___WTF_CSRF_ENABLED', 'True'),
('CKAN___NOT_DECLARED', 'test'),
]

self._setup_env_vars(envvar_to_ini_examples)

assert tk.config['SECRET_KEY'] == 'super_secret'
assert tk.config['REMEMBER_COOKIE_DURATION'] == 1000
assert tk.config['WTF_CSRF_ENABLED'] == True
assert tk.config['not_declared'] == 'test'

self._teardown_env_vars(envvar_to_ini_examples)


class TestCkanCoreEnvVarsConfig(object):

Expand Down

0 comments on commit 6b89fb0

Please sign in to comment.