Skip to content

Commit 7d62a63

Browse files
AAP-35609 Allow for ServiceTokenAuth in IsSuperUserOrAuditor
1 parent ed23011 commit 7d62a63

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

ansible_base/lib/utils/views/permissions.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from rest_framework.permissions import SAFE_METHODS, BasePermission
22

3+
from ansible_base.lib.utils.models import is_system_user
34
from ansible_base.lib.utils.settings import get_setting
45

56
oauth2_provider_installed = "ansible_base.oauth2_provider" in get_setting("INSTALLED_APPS", [])
@@ -21,12 +22,21 @@ def try_add_oauth2_scope_permission(permission_classes: list):
2122
return permission_classes
2223

2324

25+
def check_service_token_auth(request, view):
26+
if is_system_user(request.user) and getattr(view, 'allow_service_token', False) is True and request.auth == 'ServiceTokenAuthentication':
27+
return True
28+
return False
29+
30+
2431
class IsSuperuser(BasePermission):
2532
"""
2633
Allows access only to superusers.
2734
"""
2835

2936
def has_permission(self, request, view):
37+
if check_service_token_auth(request, view):
38+
return True
39+
3040
return bool(request.user and request.user.is_authenticated and request.user.is_superuser)
3141

3242

@@ -37,6 +47,8 @@ class IsSuperuserOrAuditor(BasePermission):
3747
"""
3848

3949
def has_permission(self, request, view):
50+
if check_service_token_auth(request, view):
51+
return True
4052
if not (request.user and request.user.is_authenticated):
4153
return False
4254
if request.user.is_superuser:

test_app/tests/lib/utils/test_views.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,3 +141,106 @@ def test_ansible_base_view_filter_backends_custom_settings():
141141
importlib.reload(ansible_base.lib.utils.views.django_app_api)
142142
assert len(AuthenticatorViewSet.filter_backends) == len(settings.REST_FRAMEWORK['DEFAULT_FILTER_BACKENDS'])
143143
override_settings(ANSIBLE_BASE_CUSTOM_VIEW_FILTERS=settings.ANSIBLE_BASE_ALL_REST_FILTERS)
144+
145+
146+
@pytest.mark.parametrize(
147+
"user_type,allow_service_token,request_auth,expected_result",
148+
[
149+
# Change only the auth_request
150+
(None, None, None, False),
151+
(None, None, 'junk', False),
152+
(None, None, 'ServiceTokenAuthentication', False),
153+
# Try view attr False with different auth_requests
154+
(None, False, None, False),
155+
(None, False, 'junk', False),
156+
(None, False, 'ServiceTokenAuthentication', False),
157+
# Try view attr True with different auth_requests
158+
(None, True, None, False),
159+
(None, True, 'junk', False),
160+
(None, True, 'ServiceTokenAuthentication', False),
161+
# Try a real non-system user with different settings
162+
('random', None, None, False),
163+
('random', None, 'junk', False),
164+
('random', None, 'ServiceTokenAuthentication', False),
165+
('random', False, None, False),
166+
('random', False, 'junk', False),
167+
('random', False, 'ServiceTokenAuthentication', False),
168+
('random', True, None, False),
169+
('random', True, 'junk', False),
170+
('random', True, 'ServiceTokenAuthentication', False),
171+
# Try the system user with different settings
172+
('system', None, None, False),
173+
('system', None, 'junk', False),
174+
('system', None, 'ServiceTokenAuthentication', False),
175+
('system', False, None, False),
176+
('system', False, 'junk', False),
177+
('system', False, 'ServiceTokenAuthentication', False),
178+
('system', True, None, False),
179+
('system', True, 'junk', False),
180+
('system', True, 'ServiceTokenAuthentication', True),
181+
],
182+
)
183+
def test_check_service_token_auth(user_type, allow_service_token, request_auth, expected_result, system_user, random_user):
184+
from ansible_base.lib.utils.views.permissions import check_service_token_auth
185+
186+
request = mock.Mock()
187+
view = mock.Mock()
188+
189+
if user_type is None:
190+
request.user = user_type
191+
elif user_type == 'random':
192+
request.user = random_user
193+
elif user_type == 'system':
194+
request.user = system_user
195+
196+
if allow_service_token is not None:
197+
view.allow_service_token = allow_service_token
198+
request.auth = request_auth
199+
200+
assert check_service_token_auth(request, view) == expected_result
201+
202+
203+
@pytest.mark.parametrize(
204+
"check_service_token_auth_return,user_is_superuser,expected_result",
205+
[
206+
(True, False, True),
207+
(False, False, False),
208+
(False, False, False),
209+
(False, True, True),
210+
(True, None, True),
211+
(False, None, False),
212+
],
213+
)
214+
def test_is_superuser_has_permission(check_service_token_auth_return, user_is_superuser, expected_result, random_user):
215+
from ansible_base.lib.utils.views.permissions import IsSuperuser
216+
217+
perm_class = IsSuperuser()
218+
219+
request = mock.Mock()
220+
if user_is_superuser is None:
221+
request.user = None
222+
else:
223+
random_user.is_superuser = user_is_superuser
224+
random_user.save()
225+
request.user = random_user
226+
with mock.patch('ansible_base.lib.utils.views.permissions.check_service_token_auth', return_value=check_service_token_auth_return):
227+
assert perm_class.has_permission(request, None) == expected_result
228+
229+
230+
@pytest.mark.parametrize(
231+
"check_service_token_auth_return,expected_result",
232+
[
233+
(True, True),
234+
(False, False),
235+
],
236+
)
237+
def test_is_superuser_or_auditor_has_permission_with_check_service_token_auth(check_service_token_auth_return, expected_result):
238+
from ansible_base.lib.utils.views.permissions import IsSuperuserOrAuditor
239+
240+
perm_class = IsSuperuserOrAuditor()
241+
242+
request = mock.Mock()
243+
# Because there is no user the function will return False if the check_service_token_auth does not response with True
244+
request.user = None
245+
with mock.patch('ansible_base.lib.utils.views.permissions.check_service_token_auth', return_value=check_service_token_auth_return):
246+
assert perm_class.has_permission(request, None) == expected_result

0 commit comments

Comments
 (0)