diff --git a/ansible_base/lib/utils/requests.py b/ansible_base/lib/utils/requests.py index 42e3432c6..36470ddf0 100644 --- a/ansible_base/lib/utils/requests.py +++ b/ansible_base/lib/utils/requests.py @@ -2,6 +2,7 @@ from typing import Optional from crum import get_current_request +from django.conf import LazySettings, settings from django.http import HttpRequest from ansible_base.jwt_consumer.common.util import validate_x_trusted_proxy_header @@ -24,7 +25,7 @@ def split_header(value: str) -> list[str]: return values -def get_remote_hosts(request: HttpRequest, get_first_only: bool = False) -> list[str]: +def get_remote_hosts(request: HttpRequest, get_first_only: bool = False, settings_module: LazySettings = settings) -> list[str]: ''' Get all IPs from the allowed headers NOTE: this function does not unique the hosts to preserve the order of hosts found in the variables @@ -34,7 +35,7 @@ def get_remote_hosts(request: HttpRequest, get_first_only: bool = False) -> list if not request or not hasattr(request, 'META'): return remote_hosts - headers = get_setting('REMOTE_HOST_HEADERS', ['REMOTE_ADDR', 'REMOTE_HOST']) + headers = get_setting('REMOTE_HOST_HEADERS', ['REMOTE_ADDR', 'REMOTE_HOST'], settings_module=settings_module) for header in headers: for value in split_header(request.META.get(header, '')): diff --git a/ansible_base/lib/utils/settings.py b/ansible_base/lib/utils/settings.py index e71bd96ee..9a3e44a93 100644 --- a/ansible_base/lib/utils/settings.py +++ b/ansible_base/lib/utils/settings.py @@ -2,7 +2,7 @@ import logging from typing import Any -from django.conf import settings +from django.conf import LazySettings, settings from django.utils.translation import gettext_lazy as _ from ansible_base.lib.utils.validation import to_python_boolean @@ -14,9 +14,9 @@ class SettingNotSetException(Exception): pass -def get_setting(name: str, default: Any = None, log_exception: bool = True) -> Any: +def get_setting(name: str, default: Any = None, log_exception: bool = True, settings_module: LazySettings = settings) -> Any: try: - the_function = get_function_from_setting('ANSIBLE_BASE_SETTINGS_FUNCTION') + the_function = get_function_from_setting('ANSIBLE_BASE_SETTINGS_FUNCTION', settings_module=settings_module) if the_function: setting = the_function(name) return setting @@ -32,11 +32,11 @@ def get_setting(name: str, default: Any = None, log_exception: bool = True) -> A ) ) - return getattr(settings, name, default) + return getattr(settings_module, name, default) -def get_function_from_setting(setting_name: str) -> Any: - setting = getattr(settings, setting_name, None) +def get_function_from_setting(setting_name: str, settings_module: LazySettings = settings) -> Any: + setting = getattr(settings_module, setting_name, None) if not setting: return None diff --git a/ansible_base/rbac/policies.py b/ansible_base/rbac/policies.py index 6163e62f4..e3590588e 100644 --- a/ansible_base/rbac/policies.py +++ b/ansible_base/rbac/policies.py @@ -1,5 +1,5 @@ from django.apps import apps -from django.conf import settings +from django.conf import LazySettings, settings from django.db.models import Model from django.db.models.query import QuerySet from django.utils.translation import gettext_lazy as _ @@ -12,12 +12,12 @@ from ansible_base.rbac.validators import permissions_allowed_for_role -def visible_users(request_user, queryset=None, always_show_superusers=True, always_show_self=True) -> QuerySet: +def visible_users(request_user, queryset=None, always_show_superusers=True, always_show_self=True, settings_module: LazySettings = settings) -> QuerySet: """Gives a queryset of users that another user should be able to view""" user_cls = permission_registry.user_model org_cls = apps.get_model(settings.ANSIBLE_BASE_ORGANIZATION_MODEL) - if can_view_all_users(request_user): + if can_view_all_users(request_user, settings_module=settings_module): if queryset is not None: return queryset else: @@ -38,22 +38,22 @@ def visible_users(request_user, queryset=None, always_show_superusers=True, alwa return queryset.distinct() -def can_view_all_users(request_user): +def can_view_all_users(request_user, settings_module: LazySettings = settings): org_cls = apps.get_model(settings.ANSIBLE_BASE_ORGANIZATION_MODEL) return has_super_permission(request_user, 'view') or ( - get_setting('ORG_ADMINS_CAN_SEE_ALL_USERS', False) and org_cls.access_ids_qs(request_user, 'change').exists() + get_setting('ORG_ADMINS_CAN_SEE_ALL_USERS', False, settings_module=settings_module) and org_cls.access_ids_qs(request_user, 'change').exists() ) -def can_change_user(request_user, target_user) -> bool: +def can_change_user(request_user, target_user, settings_module: LazySettings = settings) -> bool: """Tells if the request user can modify details of the target user""" if request_user.is_superuser: return True elif target_user.is_superuser: return False # target is a superuser and request user is not - if not get_setting('MANAGE_ORGANIZATION_AUTH', False): + if not get_setting('MANAGE_ORGANIZATION_AUTH', False, settings_module=settings_module): return False # All users can change their own password and other details diff --git a/test_app/tests/lib/utils/test_settings.py b/test_app/tests/lib/utils/test_settings.py index fd7d2826b..30fc4cf41 100644 --- a/test_app/tests/lib/utils/test_settings.py +++ b/test_app/tests/lib/utils/test_settings.py @@ -1,3 +1,4 @@ +from types import SimpleNamespace from unittest import mock import pytest @@ -50,6 +51,11 @@ def test_settings_from_function(setting_name, default, expected_value): assert value == expected_value +def test_get_setting_custom_module(): + fake_settings = SimpleNamespace(FOO_SETTING_TEST='fooz') + assert get_setting('FOO_SETTING_TEST', settings_module=fake_settings) == 'fooz' + + @pytest.mark.parametrize( "setting_value,expected_value,expected_log_output", [