diff --git a/awx/main/migrations/_dab_rbac.py b/awx/main/migrations/_dab_rbac.py index 1263414f0214..00e3ec62d910 100644 --- a/awx/main/migrations/_dab_rbac.py +++ b/awx/main/migrations/_dab_rbac.py @@ -277,6 +277,7 @@ def setup_managed_role_definitions(apps, schema_editor): to_create = { 'object_admin': '{cls.__name__} Admin', 'org_admin': 'Organization Admin', + 'org_audit': 'Organization Audit', 'org_children': 'Organization {cls.__name__} Admin', 'special': '{cls.__name__} {action}', } @@ -327,7 +328,8 @@ def setup_managed_role_definitions(apps, schema_editor): if 'special' in to_create: special_perms = [] for perm in object_perms: - if perm.codename.split('_')[0] not in ('add', 'change', 'delete', 'view'): + # Organization auditor is handled separately + if perm.codename.split('_')[0] not in ('add', 'change', 'delete', 'view', 'audit'): special_perms.append(perm) for perm in special_perms: action = perm.codename.split('_')[0] @@ -353,6 +355,19 @@ def setup_managed_role_definitions(apps, schema_editor): ) ) + if 'org_audit' in to_create: + audit_permissions = [perm for perm in org_perms if perm.codename.startswith('view_')] + audit_permissions.append(Permission.objects.get(codename='audit_organization')) + managed_role_definitions.append( + get_or_create_managed( + to_create['org_audit'].format(cls=Organization), + 'Has permission to view all objects inside of a single organization', + org_ct, + audit_permissions, + RoleDefinition, + ) + ) + unexpected_role_definitions = RoleDefinition.objects.filter(managed=True).exclude(pk__in=[rd.pk for rd in managed_role_definitions]) for role_definition in unexpected_role_definitions: logger.info(f'Deleting old managed role definition {role_definition.name}, pk={role_definition.pk}') diff --git a/awx/main/models/rbac.py b/awx/main/models/rbac.py index ffed4f68247c..c93792d23a21 100644 --- a/awx/main/models/rbac.py +++ b/awx/main/models/rbac.py @@ -602,8 +602,9 @@ def get_role_from_object_role(object_role): elif rd.name.endswith(' Admin'): # cases like "project-admin" role_name = 'admin_role' + elif rd.name == 'Organization Audit': + role_name = 'auditor_role' else: - print(rd.name) model_name, role_name = rd.name.split() role_name = role_name.lower() role_name += '_role' diff --git a/awx/main/tests/functional/dab_rbac/test_access_regressions.py b/awx/main/tests/functional/dab_rbac/test_access_regressions.py index 21b5560dceed..abd334269709 100644 --- a/awx/main/tests/functional/dab_rbac/test_access_regressions.py +++ b/awx/main/tests/functional/dab_rbac/test_access_regressions.py @@ -21,3 +21,21 @@ def test_notification_template_object_role_change(rando, notification_template, rd.give_permission(rando, notification_template) access = NotificationTemplateAccess(rando) assert access.can_change(notification_template, {'name': 'new name'}) + + +@pytest.mark.django_db +def test_organization_auditor_role(rando, setup_managed_roles, organization, inventory, project, jt_linked): + obj_list = (inventory, project, jt_linked) + for obj in obj_list: + assert obj.organization == organization, obj # sanity + + assert [rando.has_obj_perm(obj, 'view') for obj in obj_list] == [False for i in range(3)], obj_list + + rd = RoleDefinition.objects.get(name='Organization Audit') + rd.give_permission(rando, organization) + + codename_set = set(rd.permissions.values_list('codename', flat=True)) + assert not ({'view_inventory', 'view_jobtemplate', 'audit_organization'} - codename_set) # sanity + + assert [obj in type(obj).access_qs(rando) for obj in obj_list] == [True for i in range(3)], obj_list + assert [rando.has_obj_perm(obj, 'view') for obj in obj_list] == [True for i in range(3)], obj_list diff --git a/awx/main/tests/functional/dab_rbac/test_translation_layer.py b/awx/main/tests/functional/dab_rbac/test_translation_layer.py index e5487975be4a..60328204979e 100644 --- a/awx/main/tests/functional/dab_rbac/test_translation_layer.py +++ b/awx/main/tests/functional/dab_rbac/test_translation_layer.py @@ -35,7 +35,6 @@ def test_round_trip_roles(organization, rando, role_name, setup_managed_roles): """ getattr(organization, role_name).members.add(rando) assignment = RoleUserAssignment.objects.get(user=rando) - print(assignment.role_definition.name) old_role = get_role_from_object_role(assignment.object_role) assert old_role.id == getattr(organization, role_name).id