mirror of
https://github.com/ansible/awx.git
synced 2024-10-31 23:51:09 +03:00
Merge pull request #3160 from wwitzel3/api_3.0.1
do not allow membership changes to User.admin_role
This commit is contained in:
commit
27470b0648
@ -1208,7 +1208,12 @@ class UserRolesList(SubListCreateAttachDetachAPIView):
|
||||
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if sub_id == self.request.user.admin_role.pk:
|
||||
raise PermissionDenied('You may not remove your own admin_role.')
|
||||
raise PermissionDenied('You may not perform any action with your own admin_role.')
|
||||
|
||||
role = get_object_or_400(Role, pk=sub_id)
|
||||
user_content_type = ContentType.objects.get_for_model(User)
|
||||
if role.content_type == user_content_type:
|
||||
raise PermissionDenied('You may not change the membership of a users admin_role')
|
||||
|
||||
return super(UserRolesList, self).post(request, *args, **kwargs)
|
||||
|
||||
@ -3648,6 +3653,15 @@ class RoleUsersList(SubListCreateAttachDetachAPIView):
|
||||
if not sub_id:
|
||||
data = dict(msg="User 'id' field is missing.")
|
||||
return Response(data, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
role = self.get_parent_object()
|
||||
if role == self.request.user.admin_role:
|
||||
raise PermissionDenied('You may not perform any action with your own admin_role.')
|
||||
|
||||
user_content_type = ContentType.objects.get_for_model(User)
|
||||
if role.content_type == user_content_type:
|
||||
raise PermissionDenied('You may not change the membership of a users admin_role')
|
||||
|
||||
return super(RoleUsersList, self).post(request, *args, **kwargs)
|
||||
|
||||
|
||||
|
100
awx/main/tests/unit/api/test_roles.py
Normal file
100
awx/main/tests/unit/api/test_roles.py
Normal file
@ -0,0 +1,100 @@
|
||||
import mock
|
||||
from mock import PropertyMock
|
||||
|
||||
import pytest
|
||||
|
||||
from rest_framework.test import APIRequestFactory
|
||||
from rest_framework.test import force_authenticate
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from awx.api.views import (
|
||||
RoleUsersList,
|
||||
UserRolesList,
|
||||
TeamRolesList,
|
||||
)
|
||||
|
||||
from awx.main.models import (
|
||||
User,
|
||||
Role,
|
||||
)
|
||||
|
||||
@pytest.mark.parametrize("pk, err", [
|
||||
(111, "not change the membership"),
|
||||
(1, "may not perform"),
|
||||
])
|
||||
def test_user_roles_list_user_admin_role(pk, err):
|
||||
with mock.patch('awx.api.views.get_object_or_400') as role_get, \
|
||||
mock.patch('awx.api.views.ContentType.objects.get_for_model') as ct_get:
|
||||
|
||||
role_mock = mock.MagicMock(spec=Role, id=1, pk=1)
|
||||
content_type_mock = mock.MagicMock(spec=ContentType)
|
||||
role_mock.content_type = content_type_mock
|
||||
role_get.return_value = role_mock
|
||||
ct_get.return_value = content_type_mock
|
||||
|
||||
with mock.patch('awx.api.views.User.admin_role', new_callable=PropertyMock, return_value=role_mock):
|
||||
factory = APIRequestFactory()
|
||||
view = UserRolesList.as_view()
|
||||
|
||||
user = User(username="root", is_superuser=True)
|
||||
|
||||
request = factory.post("/user/1/roles", {'id':pk}, format="json")
|
||||
force_authenticate(request, user)
|
||||
|
||||
response = view(request)
|
||||
response.render()
|
||||
|
||||
assert response.status_code == 403
|
||||
assert err in response.content
|
||||
|
||||
@pytest.mark.parametrize("admin_role, err", [
|
||||
(True, "may not perform"),
|
||||
(False, "not change the membership"),
|
||||
])
|
||||
def test_role_users_list_other_user_admin_role(admin_role, err):
|
||||
with mock.patch('awx.api.views.RoleUsersList.get_parent_object') as role_get, \
|
||||
mock.patch('awx.api.views.ContentType.objects.get_for_model') as ct_get:
|
||||
|
||||
role_mock = mock.MagicMock(spec=Role, id=1)
|
||||
content_type_mock = mock.MagicMock(spec=ContentType)
|
||||
role_mock.content_type = content_type_mock
|
||||
role_get.return_value = role_mock
|
||||
ct_get.return_value = content_type_mock
|
||||
|
||||
user_admin_role = role_mock if admin_role else None
|
||||
with mock.patch('awx.api.views.User.admin_role', new_callable=PropertyMock, return_value=user_admin_role):
|
||||
factory = APIRequestFactory()
|
||||
view = RoleUsersList.as_view()
|
||||
|
||||
user = User(username="root", is_superuser=True, pk=1, id=1)
|
||||
request = factory.post("/role/1/users", {'id':1}, format="json")
|
||||
force_authenticate(request, user)
|
||||
|
||||
response = view(request)
|
||||
response.render()
|
||||
|
||||
assert response.status_code == 403
|
||||
assert err in response.content
|
||||
|
||||
def test_team_roles_list_post_org_roles():
|
||||
with mock.patch('awx.api.views.get_object_or_400') as role_get, \
|
||||
mock.patch('awx.api.views.ContentType.objects.get_for_model') as ct_get:
|
||||
|
||||
role_mock = mock.MagicMock(spec=Role)
|
||||
content_type_mock = mock.MagicMock(spec=ContentType)
|
||||
role_mock.content_type = content_type_mock
|
||||
role_get.return_value = role_mock
|
||||
ct_get.return_value = content_type_mock
|
||||
|
||||
factory = APIRequestFactory()
|
||||
view = TeamRolesList.as_view()
|
||||
|
||||
request = factory.post("/team/1/roles", {'id':1}, format="json")
|
||||
force_authenticate(request, User(username="root", is_superuser=True))
|
||||
|
||||
response = view(request)
|
||||
response.render()
|
||||
|
||||
assert response.status_code == 400
|
||||
assert 'cannot assign' in response.content
|
@ -1,22 +1,11 @@
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from rest_framework.test import APIRequestFactory
|
||||
from rest_framework.test import force_authenticate
|
||||
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from awx.api.views import (
|
||||
ApiV1RootView,
|
||||
TeamRolesList,
|
||||
JobTemplateLabelList,
|
||||
)
|
||||
|
||||
from awx.main.models import (
|
||||
User,
|
||||
Role,
|
||||
)
|
||||
|
||||
@pytest.fixture
|
||||
def mock_response_new(mocker):
|
||||
m = mocker.patch('awx.api.views.Response.__new__')
|
||||
@ -68,30 +57,6 @@ class TestJobTemplateLabelList:
|
||||
with mock.patch('awx.api.generics.DeleteLastUnattachLabelMixin.unattach') as mixin_unattach:
|
||||
view = JobTemplateLabelList()
|
||||
mock_request = mock.MagicMock()
|
||||
|
||||
|
||||
super(JobTemplateLabelList, view).unattach(mock_request, None, None)
|
||||
assert mixin_unattach.called_with(mock_request, None, None)
|
||||
|
||||
@pytest.mark.parametrize("url", ["/team/1/roles", "/role/1/teams"])
|
||||
def test_team_roles_list_post_org_roles(url):
|
||||
with mock.patch('awx.api.views.get_object_or_400') as mock_get_obj, \
|
||||
mock.patch('awx.api.views.ContentType.objects.get_for_model') as ct_get:
|
||||
|
||||
role_mock = mock.MagicMock(spec=Role)
|
||||
content_type_mock = mock.MagicMock(spec=ContentType)
|
||||
role_mock.content_type = content_type_mock
|
||||
mock_get_obj.return_value = role_mock
|
||||
ct_get.return_value = content_type_mock
|
||||
|
||||
factory = APIRequestFactory()
|
||||
view = TeamRolesList.as_view()
|
||||
|
||||
request = factory.post(url, {'id':1}, format="json")
|
||||
force_authenticate(request, User(username="root", is_superuser=True))
|
||||
|
||||
response = view(request)
|
||||
response.render()
|
||||
|
||||
assert response.status_code == 400
|
||||
assert 'cannot assign' in response.content
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user