mirror of
https://github.com/ansible/awx.git
synced 2026-03-02 01:08:48 -03:30
Simplify RBAC get_roles_on_resource method (#14710)
* Simplify RBAC get_roles_on_resource method * Fix bug * Fix query type bug
This commit is contained in:
@@ -99,7 +99,7 @@ from awx.main.models import (
|
|||||||
CLOUD_INVENTORY_SOURCES,
|
CLOUD_INVENTORY_SOURCES,
|
||||||
)
|
)
|
||||||
from awx.main.models.base import VERBOSITY_CHOICES, NEW_JOB_TYPE_CHOICES
|
from awx.main.models.base import VERBOSITY_CHOICES, NEW_JOB_TYPE_CHOICES
|
||||||
from awx.main.models.rbac import get_roles_on_resource, role_summary_fields_generator
|
from awx.main.models.rbac import role_summary_fields_generator, RoleAncestorEntry
|
||||||
from awx.main.fields import ImplicitRoleField
|
from awx.main.fields import ImplicitRoleField
|
||||||
from awx.main.utils import (
|
from awx.main.utils import (
|
||||||
get_type_for_model,
|
get_type_for_model,
|
||||||
@@ -2757,6 +2757,17 @@ class ResourceAccessListElementSerializer(UserSerializer):
|
|||||||
if 'summary_fields' not in ret:
|
if 'summary_fields' not in ret:
|
||||||
ret['summary_fields'] = {}
|
ret['summary_fields'] = {}
|
||||||
|
|
||||||
|
team_content_type = ContentType.objects.get_for_model(Team)
|
||||||
|
content_type = ContentType.objects.get_for_model(obj)
|
||||||
|
|
||||||
|
def get_roles_on_resource(parent_role):
|
||||||
|
"Returns a string list of the roles a parent_role has for current obj."
|
||||||
|
return list(
|
||||||
|
RoleAncestorEntry.objects.filter(ancestor=parent_role, content_type_id=content_type.id, object_id=obj.id)
|
||||||
|
.values_list('role_field', flat=True)
|
||||||
|
.distinct()
|
||||||
|
)
|
||||||
|
|
||||||
def format_role_perm(role):
|
def format_role_perm(role):
|
||||||
role_dict = {'id': role.id, 'name': role.name, 'description': role.description}
|
role_dict = {'id': role.id, 'name': role.name, 'description': role.description}
|
||||||
try:
|
try:
|
||||||
@@ -2772,7 +2783,7 @@ class ResourceAccessListElementSerializer(UserSerializer):
|
|||||||
else:
|
else:
|
||||||
# Singleton roles should not be managed from this view, as per copy/edit rework spec
|
# Singleton roles should not be managed from this view, as per copy/edit rework spec
|
||||||
role_dict['user_capabilities'] = {'unattach': False}
|
role_dict['user_capabilities'] = {'unattach': False}
|
||||||
return {'role': role_dict, 'descendant_roles': get_roles_on_resource(obj, role)}
|
return {'role': role_dict, 'descendant_roles': get_roles_on_resource(role)}
|
||||||
|
|
||||||
def format_team_role_perm(naive_team_role, permissive_role_ids):
|
def format_team_role_perm(naive_team_role, permissive_role_ids):
|
||||||
ret = []
|
ret = []
|
||||||
@@ -2798,12 +2809,9 @@ class ResourceAccessListElementSerializer(UserSerializer):
|
|||||||
else:
|
else:
|
||||||
# Singleton roles should not be managed from this view, as per copy/edit rework spec
|
# Singleton roles should not be managed from this view, as per copy/edit rework spec
|
||||||
role_dict['user_capabilities'] = {'unattach': False}
|
role_dict['user_capabilities'] = {'unattach': False}
|
||||||
ret.append({'role': role_dict, 'descendant_roles': get_roles_on_resource(obj, team_role)})
|
ret.append({'role': role_dict, 'descendant_roles': get_roles_on_resource(team_role)})
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
team_content_type = ContentType.objects.get_for_model(Team)
|
|
||||||
content_type = ContentType.objects.get_for_model(obj)
|
|
||||||
|
|
||||||
direct_permissive_role_ids = Role.objects.filter(content_type=content_type, object_id=obj.id).values_list('id', flat=True)
|
direct_permissive_role_ids = Role.objects.filter(content_type=content_type, object_id=obj.id).values_list('id', flat=True)
|
||||||
all_permissive_role_ids = Role.objects.filter(content_type=content_type, object_id=obj.id).values_list('ancestors__id', flat=True)
|
all_permissive_role_ids = Role.objects.filter(content_type=content_type, object_id=obj.id).values_list('ancestors__id', flat=True)
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ from django.contrib.auth.models import User # noqa
|
|||||||
__all__ = [
|
__all__ = [
|
||||||
'Role',
|
'Role',
|
||||||
'batch_role_ancestor_rebuilding',
|
'batch_role_ancestor_rebuilding',
|
||||||
'get_roles_on_resource',
|
|
||||||
'ROLE_SINGLETON_SYSTEM_ADMINISTRATOR',
|
'ROLE_SINGLETON_SYSTEM_ADMINISTRATOR',
|
||||||
'ROLE_SINGLETON_SYSTEM_AUDITOR',
|
'ROLE_SINGLETON_SYSTEM_AUDITOR',
|
||||||
'role_summary_fields_generator',
|
'role_summary_fields_generator',
|
||||||
@@ -460,31 +459,6 @@ class RoleAncestorEntry(models.Model):
|
|||||||
object_id = models.PositiveIntegerField(null=False)
|
object_id = models.PositiveIntegerField(null=False)
|
||||||
|
|
||||||
|
|
||||||
def get_roles_on_resource(resource, accessor):
|
|
||||||
"""
|
|
||||||
Returns a string list of the roles a accessor has for a given resource.
|
|
||||||
An accessor can be either a User, Role, or an arbitrary resource that
|
|
||||||
contains one or more Roles associated with it.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if type(accessor) == User:
|
|
||||||
roles = accessor.roles.all()
|
|
||||||
elif type(accessor) == Role:
|
|
||||||
roles = [accessor]
|
|
||||||
else:
|
|
||||||
accessor_type = ContentType.objects.get_for_model(accessor)
|
|
||||||
roles = Role.objects.filter(content_type__pk=accessor_type.id, object_id=accessor.id)
|
|
||||||
|
|
||||||
return [
|
|
||||||
role_field
|
|
||||||
for role_field in RoleAncestorEntry.objects.filter(
|
|
||||||
ancestor__in=roles, content_type_id=ContentType.objects.get_for_model(resource).id, object_id=resource.id
|
|
||||||
)
|
|
||||||
.values_list('role_field', flat=True)
|
|
||||||
.distinct()
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
def role_summary_fields_generator(content_object, role_field):
|
def role_summary_fields_generator(content_object, role_field):
|
||||||
global role_descriptions
|
global role_descriptions
|
||||||
global role_names
|
global role_names
|
||||||
|
|||||||
@@ -95,13 +95,6 @@ The `singleton` class method is a helper method on the `Role` model that helps i
|
|||||||
You may use the `user in some_role` syntax to check and see if the specified
|
You may use the `user in some_role` syntax to check and see if the specified
|
||||||
user is a member of the given role, **or** a member of any ancestor role.
|
user is a member of the given role, **or** a member of any ancestor role.
|
||||||
|
|
||||||
#### `get_roles_on_resource(resource, accessor)`
|
|
||||||
|
|
||||||
This is a static method (not bound to a class) that will efficiently return the names
|
|
||||||
of all roles that the `accessor` (a user or a team) has on a particular resource.
|
|
||||||
The resource is a python object for something like an organization, credential, or job template.
|
|
||||||
Return value is a list of strings like `["admin_role", "execute_role"]`.
|
|
||||||
|
|
||||||
### Fields
|
### Fields
|
||||||
|
|
||||||
#### `ImplicitRoleField`
|
#### `ImplicitRoleField`
|
||||||
|
|||||||
Reference in New Issue
Block a user