1
0
mirror of https://github.com/ansible/awx.git synced 2024-11-02 18:21:12 +03:00

JT OPTIONS based on RBAC, refactoring toward combinational prefetching

This commit is contained in:
AlanCoding 2016-09-02 17:07:42 -04:00
parent 0406431337
commit 1ca7ce1bd4
3 changed files with 36 additions and 39 deletions

View File

@ -2544,6 +2544,7 @@ class LabelSerializer(BaseSerializer):
return res
class ScheduleSerializer(BaseSerializer):
show_capabilities = ['edit', 'delete']
class Meta:
model = Schedule

View File

@ -222,8 +222,8 @@ class BaseAccess(object):
def get_user_capabilities(self, obj, method_list):
user_capabilities = {}
# Custom ordering to loop through methods so we can reuse earlier calcs
for display_method in ['edit', 'delete', 'start', 'schedule', 'copy', 'adhoc']:
# Custom ordering of methods used so we can reuse earlier calcs
if display_method not in method_list:
continue
@ -233,54 +233,38 @@ class BaseAccess(object):
continue
# Aliases for going form UI language to API language
# speedups in certain cases by deferring to earlier property
if display_method == 'edit':
method = 'change'
elif display_method == 'copy':
method = 'add'
elif display_method == 'schedule' and 'edit' in user_capabilities:
user_capabilities['schedule'] = user_capabilities['edit']
continue
elif display_method == 'delete' and not isinstance(obj, (User, UnifiedJob)):
user_capabilities['delete'] = user_capabilities['edit']
continue
elif display_method == 'adhoc':
method = 'run_ad_hoc_commands'
else:
method = display_method
# Shortcuts in certain cases by deferring to earlier property
if display_method == 'schedule' and 'edit' in user_capabilities:
user_capabilities['schedule'] = user_capabilities['edit']
continue
elif display_method == 'delete' and not isinstance(obj, (User, UnifiedJob)):
user_capabilities['delete'] = user_capabilities['edit']
continue
# Preprocessing before the access method is called
data = None
if method == 'add':
data = {}
access_instance = self
obj_check = obj
if isinstance(obj, (Group, Host)):
if method == 'start':
if obj.inventory_source:
obj_check = obj.inventory_source
else:
user_capabilities[method] = False
continue
else:
obj_check = obj.inventory
access_class = access_registry.get(type(obj_check), [])[0]
access_instance = access_class(self.user)
if isinstance(obj, JobTemplate):
data = {'reference_obj': obj}
elif method == 'add':
data = {}
# try:
access_method = getattr(access_instance, "can_%s" % method)
# Compute permission
access_method = getattr(self, "can_%s" % method)
if method in ['change']: # 3 args
user_capabilities[display_method] = access_method(obj_check, data)
user_capabilities[display_method] = access_method(obj, data)
elif method in ['delete', 'start', 'run_ad_hoc_commands']: # 2 args
user_capabilities[display_method] = access_method(obj_check)
user_capabilities[display_method] = access_method(obj)
elif method in ['add']: # 2 args with data
user_capabilities[display_method] = access_method(data)
# except Exception as exc:
# user_capabilities[display_method] = False
# print(exc)
return user_capabilities
@ -603,6 +587,12 @@ class GroupAccess(BaseAccess):
"active_jobs": active_jobs})
return True
def can_start(self, obj):
# Used as another alias to inventory_source start access
if obj and obj.inventory_source:
return self.user.can_access(InventorySource, 'start', obj.inventory_source)
return False
class InventorySourceAccess(BaseAccess):
'''
I can see inventory sources whenever I can see their group or inventory.
@ -938,7 +928,9 @@ class JobTemplateAccess(BaseAccess):
Users who are able to create deploy jobs can also run normal and check (dry run) jobs.
'''
if not data: # So the browseable API will work
return True
return (
Project.accessible_objects(self.user, 'use_role').exists() or
Inventory.accessible_objects(self.user, 'use_role').exists())
# if reference_obj is provided, determine if it can be coppied
reference_obj = data.pop('reference_obj', None)

View File

@ -416,6 +416,9 @@ def cache_list_capabilities(page, role_types, model, user):
'''
page_ids = [obj.id for obj in page]
id_lists = {}
for obj in page:
obj.capabilities_cache = {}
for role_type in role_types:
# Role name translation to UI names for methods
display_method = role_type
@ -423,14 +426,15 @@ def cache_list_capabilities(page, role_types, model, user):
display_method = 'edit'
elif role_type in ['execute', 'update']:
display_method = 'start'
# Query for union of page objects & role accessible_objects
id_lists[display_method] = model.accessible_objects(
user, '%s_role' % role_type).filter(pk__in=page_ids).values_list('pk', flat=True)
# Save data item-by-item
for obj in page:
obj.capabilities_cache = {display_method: False for display_method in id_lists.keys()}
for display_method, id_list in id_lists.iteritems():
if obj.pk in id_list:
ids_with_role = set(model.accessible_objects(
user, '%s_role' % role_type).filter(pk__in=page_ids).values_list('pk', flat=True))
# Save data item-by-item
for obj in page:
obj.capabilities_cache[display_method] = False
if obj.pk in ids_with_role:
obj.capabilities_cache[display_method] = True