diff --git a/connect/eaas/core/constants.py b/connect/eaas/core/constants.py index a61b4f8..b60ff88 100644 --- a/connect/eaas/core/constants.py +++ b/connect/eaas/core/constants.py @@ -11,6 +11,7 @@ DEVOPS_PAGES_ATTR_NAME = '_eaas_devops_pages' PROXIED_CONNECT_API_ATTR_NAME = '_eaas_proxied_connect_api' CUSTOMER_PAGES_ATTR_NAME = '_eaas_customer_pages' +DJANGO_SECRET_KEY_VAR_ATTR_NAME = '_eaas_django_secret_key_var' PROXIED_CONNECT_API_ENDPOINTS_MAX_ALLOWED_NUMBER = 100 diff --git a/connect/eaas/core/decorators.py b/connect/eaas/core/decorators.py index 4ba3922..3fbd964 100644 --- a/connect/eaas/core/decorators.py +++ b/connect/eaas/core/decorators.py @@ -10,6 +10,7 @@ ANVIL_KEY_VAR_ATTR_NAME, CUSTOMER_PAGES_ATTR_NAME, DEVOPS_PAGES_ATTR_NAME, + DJANGO_SECRET_KEY_VAR_ATTR_NAME, EVENT_INFO_ATTR_NAME, MODULE_PAGES_ATTR_NAME, PROXIED_CONNECT_API_ATTR_NAME, @@ -625,6 +626,20 @@ def wrapper(cls): return wrapper +def django_secret_key_variable(name): + def wrapper(cls): + setattr(cls, DJANGO_SECRET_KEY_VAR_ATTR_NAME, name) + variables = [] + if not hasattr(cls, VARIABLES_INFO_ATTR_NAME): + setattr(cls, VARIABLES_INFO_ATTR_NAME, variables) + else: + variables = getattr(cls, VARIABLES_INFO_ATTR_NAME) + if len(list(filter(lambda x: x['name'] == name, variables))) == 0: + variables.append({'name': name, 'initial_value': 'changeme!', 'secure': True}) + return cls + return wrapper + + router = InferringRouter() web_app = cbv """ diff --git a/connect/eaas/core/extension.py b/connect/eaas/core/extension.py index a88600a..99ba095 100644 --- a/connect/eaas/core/extension.py +++ b/connect/eaas/core/extension.py @@ -15,6 +15,7 @@ ANVIL_CALLABLE_ATTR_NAME, ANVIL_KEY_VAR_ATTR_NAME, CUSTOMER_PAGES_ATTR_NAME, + DJANGO_SECRET_KEY_VAR_ATTR_NAME, DEVOPS_PAGES_ATTR_NAME, EVENT_INFO_ATTR_NAME, MODULE_PAGES_ATTR_NAME, @@ -80,6 +81,14 @@ def get_variables(cls) -> dict: """ return getattr(cls, VARIABLES_INFO_ATTR_NAME, []) + @classmethod + def get_django_secret_key_variable(cls) -> str: + """ + Returns the name of the environment variable that + stores the Anvil Server Uplink key. + """ + return getattr(cls, DJANGO_SECRET_KEY_VAR_ATTR_NAME, None) + class InstallationAdminClientMixin: def get_installation_admin_client(self, installation_id): @@ -284,7 +293,7 @@ def get_anvil_key_variable(cls) -> str: Returns the name of the environment variable that stores the Anvil Server Uplink key. """ - return getattr(cls, ANVIL_KEY_VAR_ATTR_NAME, []) + return getattr(cls, ANVIL_KEY_VAR_ATTR_NAME, None) @classmethod def get_anvil_callables(cls): diff --git a/poetry.lock b/poetry.lock index 00c6bff..8aa7640 100644 --- a/poetry.lock +++ b/poetry.lock @@ -231,13 +231,13 @@ files = [ [[package]] name = "click" -version = "8.1.5" +version = "8.1.6" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" files = [ - {file = "click-8.1.5-py3-none-any.whl", hash = "sha256:e576aa487d679441d7d30abb87e1b43d24fc53bffb8758443b1a9e1cee504548"}, - {file = "click-8.1.5.tar.gz", hash = "sha256:4be4b1af8d665c6d942909916d31a213a106800c47d0eeba73d34da3cbc11367"}, + {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, + {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, ] [package.dependencies] @@ -1402,24 +1402,6 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] -[[package]] -name = "pytest-django" -version = "4.5.2" -description = "A Django plugin for pytest." -optional = false -python-versions = ">=3.5" -files = [ - {file = "pytest-django-4.5.2.tar.gz", hash = "sha256:d9076f759bb7c36939dbdd5ae6633c18edfc2902d1a69fdbefd2426b970ce6c2"}, - {file = "pytest_django-4.5.2-py3-none-any.whl", hash = "sha256:c60834861933773109334fe5a53e83d1ef4828f2203a1d6a0fa9972f4f75ab3e"}, -] - -[package.dependencies] -pytest = ">=5.4.0" - -[package.extras] -docs = ["sphinx", "sphinx-rtd-theme"] -testing = ["Django", "django-configurations (>=2.0)"] - [[package]] name = "pytest-httpx" version = "0.22.0" @@ -1870,13 +1852,13 @@ files = [ [[package]] name = "types-pyyaml" -version = "6.0.12.10" +version = "6.0.12.11" description = "Typing stubs for PyYAML" optional = false python-versions = "*" files = [ - {file = "types-PyYAML-6.0.12.10.tar.gz", hash = "sha256:ebab3d0700b946553724ae6ca636ea932c1b0868701d4af121630e78d695fc97"}, - {file = "types_PyYAML-6.0.12.10-py3-none-any.whl", hash = "sha256:662fa444963eff9b68120d70cda1af5a5f2aa57900003c2006d7626450eaae5f"}, + {file = "types-PyYAML-6.0.12.11.tar.gz", hash = "sha256:7d340b19ca28cddfdba438ee638cd4084bde213e501a3978738543e27094775b"}, + {file = "types_PyYAML-6.0.12.11-py3-none-any.whl", hash = "sha256:a461508f3096d1d5810ec5ab95d7eeecb651f3a15b71959999988942063bf01d"}, ] [[package]] @@ -1984,4 +1966,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">=3.8,<4" -content-hash = "351f8a3cd51470a5e99345d56a082b9a5026ce684fb89ecfbb0e617fbf8d6d3f" +content-hash = "763891ab972496f4eb868ee5ab7d50bb40ba409d0e087316f1172a7ac37b817b" diff --git a/pyproject.toml b/pyproject.toml index bd69eeb..6ac9dac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,8 +55,6 @@ responses = ">=0.14.0,<1" pytest-httpx = ">=0.20" Faker = "^14.2.0" flake8-isort = "^6.0.0" -django = ">=4.2,<5" -pytest-django = "^4.5.2" django-rql = "^4.4.0" [tool.poetry.group.docs.dependencies] diff --git a/tests/connect/eaas/core/deployment/test_utils.py b/tests/connect/eaas/core/deployment/test_utils.py index b25f734..d9d5783 100644 --- a/tests/connect/eaas/core/deployment/test_utils.py +++ b/tests/connect/eaas/core/deployment/test_utils.py @@ -71,7 +71,6 @@ def test_extract_arguments_ok(mocker): } -@pytest.mark.django_db def test_extract_arguments_ok_with_overview(mocker): tempdir_mock = mocker.MagicMock() tempdir_mock.__enter__.return_value = '/tmp' @@ -96,7 +95,6 @@ def test_extract_arguments_ok_with_overview(mocker): assert deploy_args['overview'] is not None -@pytest.mark.django_db def test_extract_arguments_ok_with_non_existing_overview(mocker): tempdir_mock = mocker.MagicMock() tempdir_mock.__enter__.return_value = '/tmp' @@ -124,7 +122,6 @@ def test_extract_arguments_ok_with_non_existing_overview(mocker): assert deploy_args['overview'] is None -@pytest.mark.django_db def test_extract_arguments_clone_error(mocker): tempdir_mock = mocker.MagicMock() tempdir_mock.__enter__.return_value = '/tmp' diff --git a/tests/connect/eaas/core/test_extension.py b/tests/connect/eaas/core/test_extension.py index a42e352..45bc152 100644 --- a/tests/connect/eaas/core/test_extension.py +++ b/tests/connect/eaas/core/test_extension.py @@ -13,6 +13,7 @@ anvil_key_variable, customer_pages, devops_pages, + django_secret_key_variable, event, guest, manual_transformation, @@ -836,3 +837,68 @@ def transform_row(self, row): assert installation_admin_client.endpoint == extension_client.endpoint assert installation_admin_client.default_headers == extension_client.default_headers assert installation_admin_client.logger == extension_client.logger + + +@pytest.mark.parametrize( + 'app_base_class', + ( + AnvilApplicationBase, + EventsApplicationBase, + TransformationsApplicationBase, + WebApplicationBase, + ), +) +def test_get_django_secret_key_variable(app_base_class): + + @django_secret_key_variable('DJANGO_SECRET_KEY') + class MyApp(app_base_class): + pass + + assert MyApp.get_django_secret_key_variable() == 'DJANGO_SECRET_KEY' + assert MyApp.get_variables()[0] == { + 'name': 'DJANGO_SECRET_KEY', + 'initial_value': 'changeme!', + 'secure': True, + } + + +@pytest.mark.parametrize( + 'vars', + ( + [ + { + 'name': 'VAR', + 'initial_value': 'VALUE', + }, + ], + [ + { + 'name': 'DJANGO_SECRET_KEY', + 'initial_value': 'changeme!', + 'secure': True, + }, + ], + ), +) +@pytest.mark.parametrize( + 'app_base_class', + ( + AnvilApplicationBase, + EventsApplicationBase, + TransformationsApplicationBase, + WebApplicationBase, + ), +) +def test_get_django_secret_key_variable_with_variables(app_base_class, vars): + + @django_secret_key_variable('DJANGO_SECRET_KEY') + @variables(vars) + class MyApp(app_base_class): + pass + + assert MyApp.get_django_secret_key_variable() == 'DJANGO_SECRET_KEY' + assert { + 'name': 'DJANGO_SECRET_KEY', + 'initial_value': 'changeme!', + 'secure': True, + } in MyApp.get_variables()