diff --git a/awx/api/views.py b/awx/api/views.py index ab44697843..25c75ae2a2 100644 --- a/awx/api/views.py +++ b/awx/api/views.py @@ -875,6 +875,13 @@ class TeamRolesList(SubListCreateAttachDetachAPIView): if not sub_id: data = dict(msg="Role 'id' field is missing.") return Response(data, status=status.HTTP_400_BAD_REQUEST) + + role = Role.objects.get(pk=sub_id) + content_type = ContentType.objects.get_for_model(Organization) + if role.content_type == content_type: + data = dict(msg="You cannot assign an Organization role as a child role for a Team.") + return Response(data, status=status.HTTP_400_BAD_REQUEST) + return super(TeamRolesList, self).post(request, *args, **kwargs) class TeamObjectRolesList(SubListAPIView): @@ -3715,6 +3722,11 @@ class RoleTeamsList(ListAPIView): return Response(data, status=status.HTTP_400_BAD_REQUEST) role = Role.objects.get(pk=self.kwargs['pk']) + content_type = ContentType.objects.get_for_model(Organization) + if role.content_type == content_type: + data = dict(msg="You cannot assign an Organization role as a child role for a Team.") + return Response(data, status=status.HTTP_400_BAD_REQUEST) + team = Team.objects.get(pk=sub_id) action = 'attach' if request.data.get('disassociate', None): diff --git a/awx/main/tests/unit/api/test_views.py b/awx/main/tests/unit/api/test_views.py index 0200518078..27442286c6 100644 --- a/awx/main/tests/unit/api/test_views.py +++ b/awx/main/tests/unit/api/test_views.py @@ -1,9 +1,20 @@ +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, ) +from awx.main.models import ( + User, + Role, +) @pytest.fixture def mock_response_new(mocker): @@ -11,7 +22,6 @@ def mock_response_new(mocker): m.return_value = m return m - class TestApiV1RootView: def test_get_endpoints(self, mocker, mock_response_new): endpoints = [ @@ -52,3 +62,25 @@ class TestApiV1RootView: for endpoint in endpoints: assert endpoint in data_arg +@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.Role.objects.get') 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(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