Skip to content

Commit

Permalink
add more test coverage
Browse files Browse the repository at this point in the history
Signed-off-by: Seth Foster <[email protected]>
  • Loading branch information
fosterseth committed Aug 21, 2024
1 parent 93a50b2 commit 980d442
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 5 deletions.
11 changes: 11 additions & 0 deletions awx/main/models/organization.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from django.utils.timezone import now as tz_now
from django.utils.translation import gettext_lazy as _

# DRF
from rest_framework.serializers import ValidationError as DRFValidationError

# django-ansible-base
from ansible_base.resource_registry.fields import AnsibleResourceField

Expand Down Expand Up @@ -123,6 +126,10 @@ def get_absolute_url(self, request=None):
def _get_related_jobs(self):
return UnifiedJob.objects.non_polymorphic().filter(organization=self)

def validate_role_assignment(self, actor, role_definition):
if role_definition.name in ['Organization Admin', 'Organization Member']:
raise DRFValidationError({'detail': _(f"Assignment must use the Controller {role_definition.name} role.")})


class OrganizationGalaxyCredentialMembership(models.Model):
organization = models.ForeignKey('Organization', on_delete=models.CASCADE)
Expand Down Expand Up @@ -166,6 +173,10 @@ class Meta:
def get_absolute_url(self, request=None):
return reverse('api:team_detail', kwargs={'pk': self.pk}, request=request)

def validate_role_assignment(self, actor, role_definition):
if role_definition.name in ['Team Admin', 'Team Member']:
raise DRFValidationError({'detail': _(f"Assignment must use the Controller {role_definition.name} role.")})


class Profile(CreatedModifiedModel):
"""
Expand Down
70 changes: 67 additions & 3 deletions awx/main/tests/functional/dab_rbac/test_dab_rbac_api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from unittest import mock

from django.contrib.contenttypes.models import ContentType
from django.urls import reverse as django_reverse
Expand Down Expand Up @@ -150,7 +151,70 @@ def test_assign_credential_to_user_of_another_org(setup_managed_roles, credentia
@pytest.mark.django_db
@override_settings(ALLOW_LOCAL_RESOURCE_MANAGEMENT=False)
def test_team_member_role_not_assignable(team, rando, post, admin_user, setup_managed_roles):
member_rd = RoleDefinition.objects.get(name='Organization Member')
with mock.patch('awx.main.models.organization.Organization.validate_role_assignment') as mock_validate:
member_rd = RoleDefinition.objects.get(name='Organization Member')
url = django_reverse('roleuserassignment-list')
r = post(url, data={'object_id': team.id, 'role_definition': member_rd.id, 'user': rando.id}, user=admin_user, expect=400)
assert 'Not managed locally' in str(r.data)


@pytest.mark.django_db
def test_adding_user_to_org_member_role(setup_managed_roles, organization, admin, bob, post, get):
'''
Adding user to organization member role via the legacy RBAC endpoints
should give them access to the organization detail
'''
url_org_detail = reverse('api:organization_detail', kwargs={'pk': organization.id})
get(url_org_detail, user=bob, expect=403)

role = organization.member_role
url = reverse('api:role_users_list', kwargs={'pk': role.id})
post(url, data={'id': bob.id}, user=admin, expect=204)

get(url_org_detail, user=bob, expect=200)


@pytest.mark.django_db
@pytest.mark.parametrize('actor', ['user', 'team'])
@pytest.mark.parametrize('role_name', ['Organization Admin', 'Organization Member', 'Team Admin', 'Team Member'])
def test_prevent_adding_actor_to_platform_roles(setup_managed_roles, role_name, actor, organization, team, admin, bob, post):
'''
Prevent user or team from being added to platform-level roles
'''
rd = RoleDefinition.objects.get(name=role_name)
endpoint = 'roleuserassignment-list' if actor == 'user' else 'roleteamassignment-list'
url = django_reverse(endpoint)
object_id = team.id if 'Team' in role_name else organization.id
data = {'object_id': object_id, 'role_definition': rd.id}
actor_id = bob.id if actor == 'user' else team.id
data[actor] = actor_id
r = post(url, data=data, user=admin, expect=400)
assert f'Assignment must use the Controller {role_name} role' in str(r.data)


@pytest.mark.django_db
@pytest.mark.parametrize('role_name', ['Controller Team Admin', 'Controller Team Member'])
def test_adding_user_to_controller_team_roles(setup_managed_roles, role_name, team, admin, bob, post, get):
'''
Allow user to be added to Controller Team Admin or Controller Team Member
'''
rd = RoleDefinition.objects.get(name=role_name)
url = django_reverse('roleuserassignment-list')
r = post(url, data={'object_id': team.id, 'role_definition': member_rd.id, 'user': rando.id}, user=admin_user, expect=400)
assert 'Not managed locally' in str(r.data)
post(url, data={'object_id': team.id, 'role_definition': rd.id, 'user': bob.id}, user=admin, expect=201)

url = reverse('api:team_detail', kwargs={'pk': team.id})
get(url, user=bob, expect=200)


@pytest.mark.django_db
@pytest.mark.parametrize('role_name', ['Controller Organization Admin', 'Controller Organization Member'])
def test_adding_user_to_controller_organization_roles(setup_managed_roles, role_name, organization, admin, bob, post, get):
'''
Allow user to be added to Controller Organization Admin or Controller Organization Member
'''
rd = RoleDefinition.objects.get(name=role_name)
url = django_reverse('roleuserassignment-list')
post(url, data={'object_id': organization.id, 'role_definition': rd.id, 'user': bob.id}, user=admin, expect=201)

url = reverse('api:organization_detail', kwargs={'pk': organization.id})
get(url, user=bob, expect=200)
4 changes: 2 additions & 2 deletions awx/main/tests/functional/dab_rbac/test_managed_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ def test_controller_specific_roles_have_correct_permissions(setup_managed_roles)
@pytest.mark.django_db
@pytest.mark.parametrize('resource_name', ['Team', 'Organization'])
@pytest.mark.parametrize('action', ['Member', 'Admin'])
def test_old_RBAC_uses_controller_specific_roles(setup_managed_roles, resource_name, action, team, bob, organization):
def test_legacy_RBAC_uses_controller_specific_roles(setup_managed_roles, resource_name, action, team, bob, organization):
'''
Assignment to old RBAC roles should use controller specific role definitions
Assignment to legacy RBAC roles should use controller specific role definitions
e.g. Controller Team Admin, Controller Team Member, Controller Organization Member, Controller Organization Admin
'''
if resource_name == 'Team':
Expand Down

0 comments on commit 980d442

Please sign in to comment.