diff --git a/awx/main/access.py b/awx/main/access.py index 231ece8042..eecaf69253 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -270,6 +270,12 @@ class UserAccess(BaseAccess): return True return False + def can_attach(self, obj, sub_obj, relationship, data, skip_sub_obj_read_check=False): + if relationship == 'roles': + role_access = RoleAccess(self.user) + return role_access.can_attach(sub_obj, obj, 'members', data, skip_sub_obj_read_check=False) + return super(UserAccess, self).can_attach(obj, sub_obj, relationship, data, skip_sub_obj_read_check=False) + class OrganizationAccess(BaseAccess): ''' diff --git a/awx/main/tests/functional/test_rbac_role.py b/awx/main/tests/functional/test_rbac_role.py new file mode 100644 index 0000000000..bb61262fd5 --- /dev/null +++ b/awx/main/tests/functional/test_rbac_role.py @@ -0,0 +1,46 @@ +import mock +import pytest + +from awx.main.access import ( + RoleAccess, + UserAccess +) + +from django.core.urlresolvers import reverse +from django.contrib.auth.models import User + + +@pytest.mark.django_db +def test_inventory_read_role_access_functional(rando, inventory, mocker, post): + inventory.read_role.members.add(rando) + role_pk = inventory.admin_role.pk + + mock_access = mocker.MagicMock(spec=RoleAccess, id=968) + with mocker.patch('awx.main.access.RoleAccess', return_value=mock_access): + response = post(url=reverse('api:user_roles_list', args=(rando.pk,)), + data={'id': role_pk}, user=rando) + mock_access.can_attach.assert_called_once_with( + inventory.admin_role, rando, 'members', {"id": role_pk}, + skip_sub_obj_read_check=False) + +@pytest.mark.django_db +def test_inventory_read_role_user_can_access(rando, inventory): + inventory.read_role.members.add(rando) + access = RoleAccess(rando) + assert not rando.can_access( + User, 'attach', rando, inventory.admin_role, 'roles', + {'id': inventory.admin_role.pk}, False) + +@pytest.mark.django_db +def test_inventory_read_role_user_access(rando, inventory): + inventory.read_role.members.add(rando) + access = UserAccess(rando) + data = {'id': inventory.admin_role.pk} + assert not access.can_attach(rando, inventory.admin_role, 'roles', data, False) + +@pytest.mark.django_db +def test_inventory_read_role_access(rando, inventory): + inventory.read_role.members.add(rando) + access = RoleAccess(rando) + assert not access.can_attach(inventory.admin_role, rando, 'members', None) +