put variable data permission in its own class

This commit is contained in:
AlanCoding
2019-05-08 13:43:13 -04:00
parent 70972f7ea1
commit 231abf865b
3 changed files with 30 additions and 9 deletions

View File

@@ -15,7 +15,7 @@ from awx.main.utils import get_object_or_400
logger = logging.getLogger('awx.api.permissions') logger = logging.getLogger('awx.api.permissions')
__all__ = ['ModelAccessPermission', 'JobTemplateCallbackPermission', __all__ = ['ModelAccessPermission', 'JobTemplateCallbackPermission', 'VariableDataPermission',
'TaskPermission', 'ProjectUpdatePermission', 'InventoryInventorySourcesUpdatePermission', 'TaskPermission', 'ProjectUpdatePermission', 'InventoryInventorySourcesUpdatePermission',
'UserPermission', 'IsSuperUser', 'InstanceGroupTowerPermission',] 'UserPermission', 'IsSuperUser', 'InstanceGroupTowerPermission',]
@@ -74,12 +74,8 @@ class ModelAccessPermission(permissions.BasePermission):
# FIXME: For some reason this needs to return True # FIXME: For some reason this needs to return True
# because it is first called with obj=None? # because it is first called with obj=None?
return True return True
if getattr(view, 'is_variable_data', False): return check_user_access(request.user, view.model, 'change', obj,
return check_user_access(request.user, view.model, 'change', obj, request.data)
dict(variables=request.data))
else:
return check_user_access(request.user, view.model, 'change', obj,
request.data)
def check_patch_permissions(self, request, view, obj=None): def check_patch_permissions(self, request, view, obj=None):
return self.check_put_permissions(request, view, obj) return self.check_put_permissions(request, view, obj)
@@ -163,6 +159,15 @@ class JobTemplateCallbackPermission(ModelAccessPermission):
return True return True
class VariableDataPermission(ModelAccessPermission):
def check_put_permissions(self, request, view, obj=None):
if not obj:
return True
return check_user_access(request.user, view.model, 'change', obj,
dict(variables=request.data))
class TaskPermission(ModelAccessPermission): class TaskPermission(ModelAccessPermission):
''' '''
Permission checks used for API callbacks from running a task. Permission checks used for API callbacks from running a task.

View File

@@ -92,7 +92,7 @@ from awx.main.redact import UriCleaner
from awx.api.permissions import ( from awx.api.permissions import (
JobTemplateCallbackPermission, TaskPermission, ProjectUpdatePermission, JobTemplateCallbackPermission, TaskPermission, ProjectUpdatePermission,
InventoryInventorySourcesUpdatePermission, UserPermission, InventoryInventorySourcesUpdatePermission, UserPermission,
InstanceGroupTowerPermission, InstanceGroupTowerPermission, VariableDataPermission
) )
from awx.api import renderers from awx.api import renderers
from awx.api import serializers from awx.api import serializers
@@ -1948,7 +1948,7 @@ class BaseVariableData(RetrieveUpdateAPIView):
parser_classes = api_settings.DEFAULT_PARSER_CLASSES + [YAMLParser] parser_classes = api_settings.DEFAULT_PARSER_CLASSES + [YAMLParser]
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES + [YAMLRenderer] renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES + [YAMLRenderer]
is_variable_data = True # Special flag for permissions check. permission_classes = (VariableDataPermission,)
class InventoryVariableData(BaseVariableData): class InventoryVariableData(BaseVariableData):

View File

@@ -425,6 +425,22 @@ def test_inventory_source_vars_prohibition(post, inventory, admin_user):
assert 'FOOBAR' in r.data['source_vars'][0] assert 'FOOBAR' in r.data['source_vars'][0]
@pytest.mark.django_db
@pytest.mark.parametrize('role,expect', [
('admin_role', 200),
('use_role', 403),
('adhoc_role', 403),
('read_role', 403)
])
def test_action_view_permissions(patch, put, get, inventory, rando, role, expect):
getattr(inventory, role).members.add(rando)
url = reverse('api:inventory_variable_data', kwargs={'pk': inventory.pk})
# read_role and all other roles should be able to view
get(url=url, user=rando, expect=200)
patch(url=url, data={"host_filter": "bar"}, user=rando, expect=expect)
put(url=url, data={"fooooo": "bar"}, user=rando, expect=expect)
@pytest.mark.django_db @pytest.mark.django_db
class TestInventorySourceCredential: class TestInventorySourceCredential:
def test_need_cloud_credential(self, inventory, admin_user, post): def test_need_cloud_credential(self, inventory, admin_user, post):