mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
[2.6] Remove controller specific role definitions (#7002)
Remove Controller specific roles Removes - Controller Organization Admin - Controller Organization Member - Controller Team Admin - Controller Team Member - Controller System Auditor Going forward the platform role definitions will be used, e.g. Organization Member The migration will take care of any assignments with those controller specific roles and use the platform roles instead. Signed-off-by: Seth Foster <fosterbseth@gmail.com>
This commit is contained in:
parent
534549139c
commit
c2c0f2b828
@ -849,7 +849,7 @@ class ResourceAccessList(ParentMixin, ListAPIView):
|
|||||||
if settings.ANSIBLE_BASE_ROLE_SYSTEM_ACTIVATED:
|
if settings.ANSIBLE_BASE_ROLE_SYSTEM_ACTIVATED:
|
||||||
ancestors = set(RoleEvaluation.objects.filter(content_type_id=content_type.id, object_id=obj.id).values_list('role_id', flat=True))
|
ancestors = set(RoleEvaluation.objects.filter(content_type_id=content_type.id, object_id=obj.id).values_list('role_id', flat=True))
|
||||||
qs = User.objects.filter(has_roles__in=ancestors) | User.objects.filter(is_superuser=True)
|
qs = User.objects.filter(has_roles__in=ancestors) | User.objects.filter(is_superuser=True)
|
||||||
auditor_role = RoleDefinition.objects.filter(name="Controller System Auditor").first()
|
auditor_role = RoleDefinition.objects.filter(name="Platform Auditor").first()
|
||||||
if auditor_role:
|
if auditor_role:
|
||||||
qs |= User.objects.filter(role_assignments__role_definition=auditor_role)
|
qs |= User.objects.filter(role_assignments__role_definition=auditor_role)
|
||||||
return qs.distinct()
|
return qs.distinct()
|
||||||
|
|||||||
@ -3083,7 +3083,7 @@ class ResourceAccessListElementSerializer(UserSerializer):
|
|||||||
{
|
{
|
||||||
"role": {
|
"role": {
|
||||||
"id": None,
|
"id": None,
|
||||||
"name": _("Controller System Auditor"),
|
"name": _("Platform Auditor"),
|
||||||
"description": _("Can view all aspects of the system"),
|
"description": _("Can view all aspects of the system"),
|
||||||
"user_capabilities": {"unattach": False},
|
"user_capabilities": {"unattach": False},
|
||||||
},
|
},
|
||||||
|
|||||||
102
awx/main/migrations/0202_convert_controller_role_definitions.py
Normal file
102
awx/main/migrations/0202_convert_controller_role_definitions.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
# Generated by Django migration for converting Controller role definitions
|
||||||
|
|
||||||
|
from ansible_base.rbac.migrations._utils import give_permissions
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
def convert_controller_role_definitions(apps, schema_editor):
|
||||||
|
"""
|
||||||
|
Convert Controller role definitions to regular role definitions:
|
||||||
|
- Controller Organization Admin -> Organization Admin
|
||||||
|
- Controller Organization Member -> Organization Member
|
||||||
|
- Controller Team Admin -> Team Admin
|
||||||
|
- Controller Team Member -> Team Member
|
||||||
|
- Controller System Auditor -> Platform Auditor
|
||||||
|
|
||||||
|
Then delete the old Controller role definitions.
|
||||||
|
"""
|
||||||
|
RoleDefinition = apps.get_model('dab_rbac', 'RoleDefinition')
|
||||||
|
RoleUserAssignment = apps.get_model('dab_rbac', 'RoleUserAssignment')
|
||||||
|
RoleTeamAssignment = apps.get_model('dab_rbac', 'RoleTeamAssignment')
|
||||||
|
Permission = apps.get_model('dab_rbac', 'DABPermission')
|
||||||
|
|
||||||
|
# Mapping of old Controller role names to new role names
|
||||||
|
role_mappings = {
|
||||||
|
'Controller Organization Admin': 'Organization Admin',
|
||||||
|
'Controller Organization Member': 'Organization Member',
|
||||||
|
'Controller Team Admin': 'Team Admin',
|
||||||
|
'Controller Team Member': 'Team Member',
|
||||||
|
}
|
||||||
|
|
||||||
|
for old_name, new_name in role_mappings.items():
|
||||||
|
# Find the old Controller role definition
|
||||||
|
old_role = RoleDefinition.objects.filter(name=old_name).first()
|
||||||
|
if not old_role:
|
||||||
|
continue # Skip if the old role doesn't exist
|
||||||
|
|
||||||
|
# Find the new role definition
|
||||||
|
new_role = RoleDefinition.objects.get(name=new_name)
|
||||||
|
|
||||||
|
# Collect all the assignments that need to be migrated
|
||||||
|
# Group by object (content_type + object_id) to batch the give_permissions calls
|
||||||
|
assignments_by_object = {}
|
||||||
|
|
||||||
|
# Get user assignments
|
||||||
|
user_assignments = RoleUserAssignment.objects.filter(role_definition=old_role).select_related('object_role')
|
||||||
|
for assignment in user_assignments:
|
||||||
|
key = (assignment.object_role.content_type_id, assignment.object_role.object_id)
|
||||||
|
if key not in assignments_by_object:
|
||||||
|
assignments_by_object[key] = {'users': [], 'teams': []}
|
||||||
|
assignments_by_object[key]['users'].append(assignment.user)
|
||||||
|
|
||||||
|
# Get team assignments
|
||||||
|
team_assignments = RoleTeamAssignment.objects.filter(role_definition=old_role).select_related('object_role')
|
||||||
|
for assignment in team_assignments:
|
||||||
|
key = (assignment.object_role.content_type_id, assignment.object_role.object_id)
|
||||||
|
if key not in assignments_by_object:
|
||||||
|
assignments_by_object[key] = {'users': [], 'teams': []}
|
||||||
|
assignments_by_object[key]['teams'].append(assignment.team.id)
|
||||||
|
|
||||||
|
# Use give_permissions to create new assignments with the new role definition
|
||||||
|
for (content_type_id, object_id), data in assignments_by_object.items():
|
||||||
|
if data['users'] or data['teams']:
|
||||||
|
give_permissions(
|
||||||
|
apps,
|
||||||
|
new_role,
|
||||||
|
users=data['users'],
|
||||||
|
teams=data['teams'],
|
||||||
|
object_id=object_id,
|
||||||
|
content_type_id=content_type_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delete the old role definition (this will cascade to delete old assignments and ObjectRoles)
|
||||||
|
old_role.delete()
|
||||||
|
|
||||||
|
# Create or get Platform Auditor
|
||||||
|
auditor_rd, created = RoleDefinition.objects.get_or_create(
|
||||||
|
name='Platform Auditor',
|
||||||
|
defaults={'description': 'Migrated singleton role giving read permission to everything', 'managed': True},
|
||||||
|
)
|
||||||
|
if created:
|
||||||
|
auditor_rd.permissions.add(*list(Permission.objects.filter(codename__startswith='view')))
|
||||||
|
|
||||||
|
old_rd = RoleDefinition.objects.filter(name='Controller System Auditor').first()
|
||||||
|
if old_rd:
|
||||||
|
for assignment in RoleUserAssignment.objects.filter(role_definition=old_rd):
|
||||||
|
RoleUserAssignment.objects.create(
|
||||||
|
user=assignment.user,
|
||||||
|
role_definition=auditor_rd,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delete the Controller System Auditor role
|
||||||
|
RoleDefinition.objects.filter(name='Controller System Auditor').delete()
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('main', '0201_create_managed_creds'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(convert_controller_role_definitions),
|
||||||
|
]
|
||||||
@ -167,7 +167,7 @@ def migrate_to_new_rbac(apps, schema_editor):
|
|||||||
perm.delete()
|
perm.delete()
|
||||||
|
|
||||||
managed_definitions = dict()
|
managed_definitions = dict()
|
||||||
for role_definition in RoleDefinition.objects.filter(managed=True).exclude(name__in=(settings.ANSIBLE_BASE_JWT_MANAGED_ROLES)):
|
for role_definition in RoleDefinition.objects.filter(managed=True):
|
||||||
permissions = frozenset(role_definition.permissions.values_list('id', flat=True))
|
permissions = frozenset(role_definition.permissions.values_list('id', flat=True))
|
||||||
managed_definitions[permissions] = role_definition
|
managed_definitions[permissions] = role_definition
|
||||||
|
|
||||||
@ -239,11 +239,14 @@ def migrate_to_new_rbac(apps, schema_editor):
|
|||||||
|
|
||||||
# Create new replacement system auditor role
|
# Create new replacement system auditor role
|
||||||
new_system_auditor, created = RoleDefinition.objects.get_or_create(
|
new_system_auditor, created = RoleDefinition.objects.get_or_create(
|
||||||
name='Controller System Auditor',
|
name='Platform Auditor',
|
||||||
defaults={'description': 'Migrated singleton role giving read permission to everything', 'managed': True},
|
defaults={'description': 'Migrated singleton role giving read permission to everything', 'managed': True},
|
||||||
)
|
)
|
||||||
new_system_auditor.permissions.add(*list(Permission.objects.filter(codename__startswith='view')))
|
new_system_auditor.permissions.add(*list(Permission.objects.filter(codename__startswith='view')))
|
||||||
|
|
||||||
|
if created:
|
||||||
|
logger.info(f'Created RoleDefinition {new_system_auditor.name} pk={new_system_auditor.pk} with {new_system_auditor.permissions.count()} permissions')
|
||||||
|
|
||||||
# migrate is_system_auditor flag, because it is no longer handled by a system role
|
# migrate is_system_auditor flag, because it is no longer handled by a system role
|
||||||
old_system_auditor = Role.objects.filter(singleton_name='system_auditor').first()
|
old_system_auditor = Role.objects.filter(singleton_name='system_auditor').first()
|
||||||
if old_system_auditor:
|
if old_system_auditor:
|
||||||
@ -272,7 +275,7 @@ def get_or_create_managed(name, description, ct, permissions, RoleDefinition):
|
|||||||
|
|
||||||
def setup_managed_role_definitions(apps, schema_editor):
|
def setup_managed_role_definitions(apps, schema_editor):
|
||||||
"""
|
"""
|
||||||
Idepotent method to create or sync the managed role definitions
|
Idempotent method to create or sync the managed role definitions
|
||||||
"""
|
"""
|
||||||
to_create = {
|
to_create = {
|
||||||
'object_admin': '{cls.__name__} Admin',
|
'object_admin': '{cls.__name__} Admin',
|
||||||
@ -309,16 +312,6 @@ def setup_managed_role_definitions(apps, schema_editor):
|
|||||||
to_create['object_admin'].format(cls=cls), f'Has all permissions to a single {cls._meta.verbose_name}', ct, indiv_perms, RoleDefinition
|
to_create['object_admin'].format(cls=cls), f'Has all permissions to a single {cls._meta.verbose_name}', ct, indiv_perms, RoleDefinition
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if cls_name == 'team':
|
|
||||||
managed_role_definitions.append(
|
|
||||||
get_or_create_managed(
|
|
||||||
'Controller Team Admin',
|
|
||||||
f'Has all permissions to a single {cls._meta.verbose_name}',
|
|
||||||
ct,
|
|
||||||
indiv_perms,
|
|
||||||
RoleDefinition,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if 'org_children' in to_create and (cls_name not in ('organization', 'instancegroup', 'team')):
|
if 'org_children' in to_create and (cls_name not in ('organization', 'instancegroup', 'team')):
|
||||||
org_child_perms = object_perms.copy()
|
org_child_perms = object_perms.copy()
|
||||||
@ -359,18 +352,6 @@ def setup_managed_role_definitions(apps, schema_editor):
|
|||||||
RoleDefinition,
|
RoleDefinition,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if action == 'member' and cls_name in ('organization', 'team'):
|
|
||||||
suffix = to_create['special'].format(cls=cls, action=action.title())
|
|
||||||
rd_name = f'Controller {suffix}'
|
|
||||||
managed_role_definitions.append(
|
|
||||||
get_or_create_managed(
|
|
||||||
rd_name,
|
|
||||||
f'Has {action} permissions to a single {cls._meta.verbose_name}',
|
|
||||||
ct,
|
|
||||||
perm_list,
|
|
||||||
RoleDefinition,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if 'org_admin' in to_create:
|
if 'org_admin' in to_create:
|
||||||
managed_role_definitions.append(
|
managed_role_definitions.append(
|
||||||
@ -382,15 +363,6 @@ def setup_managed_role_definitions(apps, schema_editor):
|
|||||||
RoleDefinition,
|
RoleDefinition,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
managed_role_definitions.append(
|
|
||||||
get_or_create_managed(
|
|
||||||
'Controller Organization Admin',
|
|
||||||
'Has all permissions to a single organization and all objects inside of it',
|
|
||||||
org_ct,
|
|
||||||
org_perms,
|
|
||||||
RoleDefinition,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Special "organization action" roles
|
# Special "organization action" roles
|
||||||
audit_permissions = [perm for perm in org_perms if perm.codename.startswith('view_')]
|
audit_permissions = [perm for perm in org_perms if perm.codename.startswith('view_')]
|
||||||
|
|||||||
@ -203,7 +203,7 @@ User.add_to_class('created', created)
|
|||||||
|
|
||||||
def get_system_auditor_role():
|
def get_system_auditor_role():
|
||||||
rd, created = RoleDefinition.objects.get_or_create(
|
rd, created = RoleDefinition.objects.get_or_create(
|
||||||
name='Controller System Auditor', defaults={'description': 'Migrated singleton role giving read permission to everything'}
|
name='Platform Auditor', defaults={'description': 'Migrated singleton role giving read permission to everything'}
|
||||||
)
|
)
|
||||||
if created:
|
if created:
|
||||||
rd.permissions.add(*list(permission_registry.permission_qs.filter(codename__startswith='view')))
|
rd.permissions.add(*list(permission_registry.permission_qs.filter(codename__startswith='view')))
|
||||||
|
|||||||
@ -559,24 +559,12 @@ def get_role_definition(role):
|
|||||||
f = obj._meta.get_field(role.role_field)
|
f = obj._meta.get_field(role.role_field)
|
||||||
action_name = f.name.rsplit("_", 1)[0]
|
action_name = f.name.rsplit("_", 1)[0]
|
||||||
model_print = type(obj).__name__
|
model_print = type(obj).__name__
|
||||||
|
rd_name = f'{model_print} {action_name.title()} Compat'
|
||||||
perm_list = get_role_codenames(role)
|
perm_list = get_role_codenames(role)
|
||||||
defaults = {
|
defaults = {
|
||||||
'content_type_id': role.content_type_id,
|
'content_type_id': role.content_type_id,
|
||||||
'description': f'Has {action_name.title()} permission to {model_print} for backwards API compatibility',
|
'description': f'Has {action_name.title()} permission to {model_print} for backwards API compatibility',
|
||||||
}
|
}
|
||||||
# use Controller-specific role definitions for Team/Organization and member/admin
|
|
||||||
# instead of platform role definitions
|
|
||||||
# these should exist in the system already, so just do a lookup by role definition name
|
|
||||||
if model_print in ['Team', 'Organization'] and action_name in ['member', 'admin']:
|
|
||||||
rd_name = f'Controller {model_print} {action_name.title()}'
|
|
||||||
rd = RoleDefinition.objects.filter(name=rd_name).first()
|
|
||||||
if rd:
|
|
||||||
return rd
|
|
||||||
else:
|
|
||||||
return RoleDefinition.objects.create_from_permissions(permissions=perm_list, name=rd_name, managed=True, **defaults)
|
|
||||||
|
|
||||||
else:
|
|
||||||
rd_name = f'{model_print} {action_name.title()} Compat'
|
|
||||||
|
|
||||||
with impersonate(None):
|
with impersonate(None):
|
||||||
try:
|
try:
|
||||||
@ -600,12 +588,6 @@ def get_role_from_object_role(object_role):
|
|||||||
model_name, role_name, _ = rd.name.split()
|
model_name, role_name, _ = rd.name.split()
|
||||||
role_name = role_name.lower()
|
role_name = role_name.lower()
|
||||||
role_name += '_role'
|
role_name += '_role'
|
||||||
elif rd.name.startswith('Controller') and rd.name.endswith(' Admin'):
|
|
||||||
# Controller Organization Admin and Controller Team Admin
|
|
||||||
role_name = 'admin_role'
|
|
||||||
elif rd.name.startswith('Controller') and rd.name.endswith(' Member'):
|
|
||||||
# Controller Organization Member and Controller Team Member
|
|
||||||
role_name = 'member_role'
|
|
||||||
elif rd.name.endswith(' Admin') and rd.name.count(' ') == 2:
|
elif rd.name.endswith(' Admin') and rd.name.count(' ') == 2:
|
||||||
# cases like "Organization Project Admin"
|
# cases like "Organization Project Admin"
|
||||||
model_name, target_model_name, role_name = rd.name.split()
|
model_name, target_model_name, role_name = rd.name.split()
|
||||||
@ -737,7 +719,6 @@ def sync_parents_to_new_rbac(instance, action, model, pk_set, reverse, **kwargs)
|
|||||||
|
|
||||||
ROLE_DEFINITION_TO_ROLE_FIELD = {
|
ROLE_DEFINITION_TO_ROLE_FIELD = {
|
||||||
'Organization Member': 'member_role',
|
'Organization Member': 'member_role',
|
||||||
'Controller Organization Member': 'member_role',
|
|
||||||
'WorkflowJobTemplate Admin': 'admin_role',
|
'WorkflowJobTemplate Admin': 'admin_role',
|
||||||
'Organization WorkflowJobTemplate Admin': 'workflow_admin_role',
|
'Organization WorkflowJobTemplate Admin': 'workflow_admin_role',
|
||||||
'WorkflowJobTemplate Execute': 'execute_role',
|
'WorkflowJobTemplate Execute': 'execute_role',
|
||||||
@ -762,11 +743,8 @@ ROLE_DEFINITION_TO_ROLE_FIELD = {
|
|||||||
'Organization Credential Admin': 'credential_admin_role',
|
'Organization Credential Admin': 'credential_admin_role',
|
||||||
'Credential Use': 'use_role',
|
'Credential Use': 'use_role',
|
||||||
'Team Admin': 'admin_role',
|
'Team Admin': 'admin_role',
|
||||||
'Controller Team Admin': 'admin_role',
|
|
||||||
'Team Member': 'member_role',
|
'Team Member': 'member_role',
|
||||||
'Controller Team Member': 'member_role',
|
|
||||||
'Organization Admin': 'admin_role',
|
'Organization Admin': 'admin_role',
|
||||||
'Controller Organization Admin': 'admin_role',
|
|
||||||
'Organization Audit': 'auditor_role',
|
'Organization Audit': 'auditor_role',
|
||||||
'Organization Execute': 'execute_role',
|
'Organization Execute': 'execute_role',
|
||||||
'Organization Approval': 'approval_role',
|
'Organization Approval': 'approval_role',
|
||||||
|
|||||||
@ -146,14 +146,6 @@ def test_assign_credential_to_user_of_another_org(setup_managed_roles, credentia
|
|||||||
post(url=url, data={"user": org_admin.id, "role_definition": rd.id, "object_id": credential.id}, user=admin_user, expect=201)
|
post(url=url, data={"user": org_admin.id, "role_definition": rd.id, "object_id": credential.id}, user=admin_user, expect=201)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
def test_team_member_role_not_assignable(team, rando, post, admin_user, setup_managed_roles):
|
|
||||||
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
|
@pytest.mark.django_db
|
||||||
def test_adding_user_to_org_member_role(setup_managed_roles, organization, admin, bob, post, get):
|
def test_adding_user_to_org_member_role(setup_managed_roles, organization, admin, bob, post, get):
|
||||||
'''
|
'''
|
||||||
@ -173,10 +165,16 @@ def test_adding_user_to_org_member_role(setup_managed_roles, organization, admin
|
|||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@pytest.mark.parametrize('actor', ['user', 'team'])
|
@pytest.mark.parametrize('actor', ['user', 'team'])
|
||||||
@pytest.mark.parametrize('role_name', ['Organization Admin', 'Organization Member', 'Team Admin', 'Team Member'])
|
@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):
|
def test_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
|
Allow user or team to be added to platform-level roles
|
||||||
|
Exceptions:
|
||||||
|
- Team cannot be added to Organization Member or Admin role
|
||||||
'''
|
'''
|
||||||
|
if actor == 'team' and 'Organization' in role_name:
|
||||||
|
expect = 400
|
||||||
|
else:
|
||||||
|
expect = 201
|
||||||
rd = RoleDefinition.objects.get(name=role_name)
|
rd = RoleDefinition.objects.get(name=role_name)
|
||||||
endpoint = 'roleuserassignment-list' if actor == 'user' else 'roleteamassignment-list'
|
endpoint = 'roleuserassignment-list' if actor == 'user' else 'roleteamassignment-list'
|
||||||
url = django_reverse(endpoint)
|
url = django_reverse(endpoint)
|
||||||
@ -184,37 +182,6 @@ def test_prevent_adding_actor_to_platform_roles(setup_managed_roles, role_name,
|
|||||||
data = {'object_id': object_id, 'role_definition': rd.id}
|
data = {'object_id': object_id, 'role_definition': rd.id}
|
||||||
actor_id = bob.id if actor == 'user' else team.id
|
actor_id = bob.id if actor == 'user' else team.id
|
||||||
data[actor] = actor_id
|
data[actor] = actor_id
|
||||||
r = post(url, data=data, user=admin, expect=400)
|
r = post(url, data=data, user=admin, expect=expect)
|
||||||
assert 'Not managed locally' in str(r.data)
|
if expect == 400:
|
||||||
|
assert 'Assigning organization member permission to teams is not allowed' 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
|
|
||||||
'''
|
|
||||||
url_detail = reverse('api:team_detail', kwargs={'pk': team.id})
|
|
||||||
get(url_detail, user=bob, expect=403)
|
|
||||||
|
|
||||||
rd = RoleDefinition.objects.get(name=role_name)
|
|
||||||
url = django_reverse('roleuserassignment-list')
|
|
||||||
post(url, data={'object_id': team.id, 'role_definition': rd.id, 'user': bob.id}, user=admin, expect=201)
|
|
||||||
|
|
||||||
get(url_detail, 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
|
|
||||||
'''
|
|
||||||
url_detail = reverse('api:organization_detail', kwargs={'pk': organization.id})
|
|
||||||
get(url_detail, user=bob, expect=403)
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
get(url, user=bob, expect=200)
|
|
||||||
|
|||||||
@ -31,32 +31,18 @@ def test_org_child_add_permission(setup_managed_roles):
|
|||||||
assert not DABPermission.objects.filter(codename='add_jobtemplate').exists()
|
assert not DABPermission.objects.filter(codename='add_jobtemplate').exists()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
def test_controller_specific_roles_have_correct_permissions(setup_managed_roles):
|
|
||||||
'''
|
|
||||||
Controller specific roles should have the same permissions as the platform roles
|
|
||||||
e.g. Controller Team Admin should have same permission set as Team Admin
|
|
||||||
'''
|
|
||||||
for rd_name in ['Controller Team Admin', 'Controller Team Member', 'Controller Organization Member', 'Controller Organization Admin']:
|
|
||||||
rd = RoleDefinition.objects.get(name=rd_name)
|
|
||||||
rd_platform = RoleDefinition.objects.get(name=rd_name.split('Controller ')[1])
|
|
||||||
assert set(rd.permissions.all()) == set(rd_platform.permissions.all())
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@pytest.mark.parametrize('resource_name', ['Team', 'Organization'])
|
@pytest.mark.parametrize('resource_name', ['Team', 'Organization'])
|
||||||
@pytest.mark.parametrize('action', ['Member', 'Admin'])
|
@pytest.mark.parametrize('action', ['Member', 'Admin'])
|
||||||
def test_legacy_RBAC_uses_controller_specific_roles(setup_managed_roles, resource_name, action, team, bob, organization):
|
def test_legacy_RBAC_uses_platform_roles(setup_managed_roles, resource_name, action, team, bob, organization):
|
||||||
'''
|
'''
|
||||||
Assignment to legacy RBAC roles should use controller specific role definitions
|
Assignment to legacy RBAC roles should use platform role definitions
|
||||||
e.g. Controller Team Admin, Controller Team Member, Controller Organization Member, Controller Organization Admin
|
e.g. Team Admin, Team Member, Organization Member, Organization Admin
|
||||||
'''
|
'''
|
||||||
resource = team if resource_name == 'Team' else organization
|
resource = team if resource_name == 'Team' else organization
|
||||||
if action == 'Member':
|
if action == 'Member':
|
||||||
resource.member_role.members.add(bob)
|
resource.member_role.members.add(bob)
|
||||||
else:
|
else:
|
||||||
resource.admin_role.members.add(bob)
|
resource.admin_role.members.add(bob)
|
||||||
rd = RoleDefinition.objects.get(name=f'Controller {resource_name} {action}')
|
rd = RoleDefinition.objects.get(name=f'{resource_name} {action}')
|
||||||
rd_platform = RoleDefinition.objects.get(name=f'{resource_name} {action}')
|
|
||||||
assert RoleUserAssignment.objects.filter(role_definition=rd, user=bob, object_id=resource.id).exists()
|
assert RoleUserAssignment.objects.filter(role_definition=rd, user=bob, object_id=resource.id).exists()
|
||||||
assert not RoleUserAssignment.objects.filter(role_definition=rd_platform, user=bob, object_id=resource.id).exists()
|
|
||||||
|
|||||||
@ -208,19 +208,19 @@ def test_user_auditor_rel(organization, rando, setup_managed_roles):
|
|||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@pytest.mark.parametrize('resource_name', ['Organization', 'Team'])
|
@pytest.mark.parametrize('resource_name', ['Organization', 'Team'])
|
||||||
@pytest.mark.parametrize('role_name', ['Member', 'Admin'])
|
@pytest.mark.parametrize('role_name', ['Member', 'Admin'])
|
||||||
def test_mapping_from_controller_role_definitions_to_roles(organization, team, rando, role_name, resource_name, setup_managed_roles):
|
def test_mapping_from_role_definitions_to_roles(organization, team, rando, role_name, resource_name, setup_managed_roles):
|
||||||
"""
|
"""
|
||||||
ensure mappings for controller roles are correct
|
ensure mappings for platform roles are correct
|
||||||
e.g.
|
e.g.
|
||||||
Controller Organization Member > organization.member_role
|
Organization Member > organization.member_role
|
||||||
Controller Organization Admin > organization.admin_role
|
Organization Admin > organization.admin_role
|
||||||
Controller Team Member > team.member_role
|
Team Member > team.member_role
|
||||||
Controller Team Admin > team.admin_role
|
Team Admin > team.admin_role
|
||||||
"""
|
"""
|
||||||
resource = organization if resource_name == 'Organization' else team
|
resource = organization if resource_name == 'Organization' else team
|
||||||
old_role_name = f"{role_name.lower()}_role"
|
old_role_name = f"{role_name.lower()}_role"
|
||||||
getattr(resource, old_role_name).members.add(rando)
|
getattr(resource, old_role_name).members.add(rando)
|
||||||
assignment = RoleUserAssignment.objects.get(user=rando)
|
assignment = RoleUserAssignment.objects.get(user=rando)
|
||||||
assert assignment.role_definition.name == f'Controller {resource_name} {role_name}'
|
assert assignment.role_definition.name == f'{resource_name} {role_name}'
|
||||||
old_role = get_role_from_object_role(assignment.object_role)
|
old_role = get_role_from_object_role(assignment.object_role)
|
||||||
assert old_role.id == getattr(resource, old_role_name).id
|
assert old_role.id == getattr(resource, old_role_name).id
|
||||||
|
|||||||
@ -35,21 +35,21 @@ class TestNewToOld:
|
|||||||
|
|
||||||
def test_new_to_old_rbac_team_member_addition(self, admin, post, team, bob, setup_managed_roles):
|
def test_new_to_old_rbac_team_member_addition(self, admin, post, team, bob, setup_managed_roles):
|
||||||
'''
|
'''
|
||||||
Assign user to Controller Team Member role definition, should be added to team.member_role.members
|
Assign user to Team Member role definition, should be added to team.member_role.members
|
||||||
'''
|
'''
|
||||||
rd = RoleDefinition.objects.get(name='Controller Team Member')
|
rd = RoleDefinition.objects.get(name='Team Member')
|
||||||
|
|
||||||
url = get_relative_url('roleuserassignment-list')
|
url = get_relative_url('roleuserassignment-list')
|
||||||
post(url, user=admin, data={'role_definition': rd.id, 'user': bob.id, 'object_id': team.id}, expect=201)
|
post(url, user=admin, data={'role_definition': rd.id, 'user': bob.id, 'object_id': team.id}, expect=201)
|
||||||
assert bob in team.member_role.members.all()
|
assert bob in team.member_role.members.all()
|
||||||
|
|
||||||
def test_new_to_old_rbac_team_member_removal(self, admin, delete, team, bob):
|
def test_new_to_old_rbac_team_member_removal(self, admin, delete, team, bob, setup_managed_roles):
|
||||||
'''
|
'''
|
||||||
Remove user from Controller Team Member role definition, should be deleted from team.member_role.members
|
Remove user from Team Member role definition, should be deleted from team.member_role.members
|
||||||
'''
|
'''
|
||||||
team.member_role.members.add(bob)
|
team.member_role.members.add(bob)
|
||||||
|
|
||||||
rd = RoleDefinition.objects.get(name='Controller Team Member')
|
rd = RoleDefinition.objects.get(name='Team Member')
|
||||||
user_assignment = RoleUserAssignment.objects.get(user=bob, role_definition=rd, object_id=team.id)
|
user_assignment = RoleUserAssignment.objects.get(user=bob, role_definition=rd, object_id=team.id)
|
||||||
|
|
||||||
url = get_relative_url('roleuserassignment-detail', kwargs={'pk': user_assignment.id})
|
url = get_relative_url('roleuserassignment-detail', kwargs={'pk': user_assignment.id})
|
||||||
|
|||||||
@ -90,8 +90,8 @@ class TestMigrationSmoke:
|
|||||||
|
|
||||||
RoleUserAssignment = new_state.apps.get_model('dab_rbac', 'RoleUserAssignment')
|
RoleUserAssignment = new_state.apps.get_model('dab_rbac', 'RoleUserAssignment')
|
||||||
assert RoleUserAssignment.objects.filter(user=user.id, object_id=org.id).exists()
|
assert RoleUserAssignment.objects.filter(user=user.id, object_id=org.id).exists()
|
||||||
assert RoleUserAssignment.objects.filter(user=user.id, role_definition__name='Controller Organization Member', object_id=org.id).exists()
|
assert RoleUserAssignment.objects.filter(user=user.id, role_definition__name='Organization Member', object_id=org.id).exists()
|
||||||
assert RoleUserAssignment.objects.filter(user=user.id, role_definition__name='Controller Team Member', object_id=team.id).exists()
|
assert RoleUserAssignment.objects.filter(user=user.id, role_definition__name='Team Member', object_id=team.id).exists()
|
||||||
|
|
||||||
# Regression testing for bug that comes from current vs past models mismatch
|
# Regression testing for bug that comes from current vs past models mismatch
|
||||||
RoleDefinition = new_state.apps.get_model('dab_rbac', 'RoleDefinition')
|
RoleDefinition = new_state.apps.get_model('dab_rbac', 'RoleDefinition')
|
||||||
|
|||||||
@ -683,7 +683,7 @@ AWX_AUTO_DEPROVISION_INSTANCES = False
|
|||||||
|
|
||||||
|
|
||||||
# If True, allow users to be assigned to roles that were created via JWT
|
# If True, allow users to be assigned to roles that were created via JWT
|
||||||
ALLOW_LOCAL_ASSIGNING_JWT_ROLES = False
|
ALLOW_LOCAL_ASSIGNING_JWT_ROLES = True
|
||||||
|
|
||||||
# Enable Pendo on the UI, possible values are 'off', 'anonymous', and 'detailed'
|
# Enable Pendo on the UI, possible values are 'off', 'anonymous', and 'detailed'
|
||||||
# Note: This setting may be overridden by database settings.
|
# Note: This setting may be overridden by database settings.
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user