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 return res
class ScheduleSerializer(BaseSerializer): class ScheduleSerializer(BaseSerializer):
show_capabilities = ['edit', 'delete']
class Meta: class Meta:
model = Schedule model = Schedule

View File

@@ -222,8 +222,8 @@ class BaseAccess(object):
def get_user_capabilities(self, obj, method_list): def get_user_capabilities(self, obj, method_list):
user_capabilities = {} user_capabilities = {}
# Custom ordering to loop through methods so we can reuse earlier calcs
for display_method in ['edit', 'delete', 'start', 'schedule', 'copy', 'adhoc']: 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: if display_method not in method_list:
continue continue
@@ -233,54 +233,38 @@ class BaseAccess(object):
continue continue
# Aliases for going form UI language to API language # Aliases for going form UI language to API language
# speedups in certain cases by deferring to earlier property
if display_method == 'edit': if display_method == 'edit':
method = 'change' method = 'change'
elif display_method == 'copy': elif display_method == 'copy':
method = 'add' 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': elif display_method == 'adhoc':
method = 'run_ad_hoc_commands' method = 'run_ad_hoc_commands'
else: else:
method = display_method 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 # Preprocessing before the access method is called
data = None 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): if isinstance(obj, JobTemplate):
data = {'reference_obj': obj} data = {'reference_obj': obj}
elif method == 'add':
data = {}
# try: # Compute permission
access_method = getattr(access_instance, "can_%s" % method) access_method = getattr(self, "can_%s" % method)
if method in ['change']: # 3 args 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 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 elif method in ['add']: # 2 args with data
user_capabilities[display_method] = access_method(data) user_capabilities[display_method] = access_method(data)
# except Exception as exc:
# user_capabilities[display_method] = False
# print(exc)
return user_capabilities return user_capabilities
@@ -603,6 +587,12 @@ class GroupAccess(BaseAccess):
"active_jobs": active_jobs}) "active_jobs": active_jobs})
return True 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): class InventorySourceAccess(BaseAccess):
''' '''
I can see inventory sources whenever I can see their group or inventory. 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. 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 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 # if reference_obj is provided, determine if it can be coppied
reference_obj = data.pop('reference_obj', None) 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] page_ids = [obj.id for obj in page]
id_lists = {} id_lists = {}
for obj in page:
obj.capabilities_cache = {}
for role_type in role_types: for role_type in role_types:
# Role name translation to UI names for methods # Role name translation to UI names for methods
display_method = role_type display_method = role_type
@@ -423,14 +426,15 @@ def cache_list_capabilities(page, role_types, model, user):
display_method = 'edit' display_method = 'edit'
elif role_type in ['execute', 'update']: elif role_type in ['execute', 'update']:
display_method = 'start' display_method = 'start'
# Query for union of page objects & role accessible_objects # Query for union of page objects & role accessible_objects
id_lists[display_method] = model.accessible_objects( ids_with_role = set(model.accessible_objects(
user, '%s_role' % role_type).filter(pk__in=page_ids).values_list('pk', flat=True) user, '%s_role' % role_type).filter(pk__in=page_ids).values_list('pk', flat=True))
# Save data item-by-item
for obj in page: # Save data item-by-item
obj.capabilities_cache = {display_method: False for display_method in id_lists.keys()} for obj in page:
for display_method, id_list in id_lists.iteritems(): obj.capabilities_cache[display_method] = False
if obj.pk in id_list: if obj.pk in ids_with_role:
obj.capabilities_cache[display_method] = True obj.capabilities_cache[display_method] = True