def _object_permissions_get(self, group): """ Construct a list of object permissions for hosts for this group. """ # Process object permission flags def _process_flags(flags): ret_flags = {} for k,v in flags.iteritems(): if not k in ret_flags: ret_flags[k] = v return ret_flags # Construct the object permissions ret = {} for obj_details in ACLObjects.get_values(): obj_type = obj_details['type'] obj_key = '%s_id' % obj_type # Get an instance of the ACL class acl_def = ACLObjects.get_values(obj_type)[0] acl_mod = importlib.import_module(acl_def['acl_mod']) acl_class = getattr(acl_mod, acl_def['acl_cls']) # Get the object details acl_obj = list(acl_class.objects.filter(owner=group['uuid']).values()) for acl in acl_obj: acl['object_id'] = acl[obj_key] del acl[obj_key] # Create the object permissions for this type ret[obj_type] = { 'ids': {}, 'details': acl_obj } # Set the object IDs for acl in acl_obj: obj_id = acl['object_id'] if not obj_id in ret[obj_type]['ids']: ret[obj_type]['ids'][obj_id] = [] ret[obj_type]['ids'][obj_id].append(acl['acl_id']) # Return the constructed object permissions return ret
def get(self, obj_type, obj_id=None, cache=True, values={}, filters={}): """ Retrieve details for an API object. @param obj_type: The type of object to retrieve @type obj_type: str @param obj_id: The ID of the object to retrieve @type obj_id: str @param cache: Enable or disable retrieval from the database cache table @type cache: bool @param values: Extra parameters to pass to the values QuerySet method @type values: dict @param filters: Extra filter parameters @type filters: dict """ # If the ACL object exists if len(ACLObjects.get_values(obj_type)) > 0: self.log.info('Retrieving database object: type=%s, id=%s, cache=%s' % (obj_type, repr(obj_id), repr(cache))) # If retrieving from the database cache table and caching not explicitly disabled if cache and not (self.conf.server.caching == False): # Look for object details in the cache cached_obj = self.cache.get_object(obj_type, obj_id, filters=filters) # If cached data found if cached_obj: self.log.info('Cached data found for object: type=%s, id=%s' % (obj_type, repr(obj_id))) return cached_obj # No cached data found, retrieve directly from the object model return self._get_from_model(obj_type, obj_id, values=values, filters=filters) # If querying directly from the database else: return self._get_from_model(obj_type, obj_id, values=values, filters=filters) # Invalid ACL object type else: self.log.error('Failed to retrieve object <%s> of type <%s>, object type not found' % (obj_id, obj_type)) # Return an empty result return None
def save_object(self, obj_type, obj_id, values={}): """ Save cache data for an object in the database. """ # If the ACL object exists if len(ACLObjects.get_values(obj_type)) > 0: try: # If supplied, values argument must be a dictionary if values and not isinstance(values, dict): self.log.error('Failed to cache object <%s> of type <%s>, values keyword must contain a dictionary' % (obj_id, obj_type)) return False # Get the ACL object definition acl_object = ACLObjects.get(type=obj_type) # Get an instance of the object class obj_mod = importlib.import_module(getattr(acl_object, 'obj_mod')) obj_class = getattr(obj_mod, getattr(acl_object, 'obj_cls')) obj_key = getattr(acl_object, 'obj_key') # Create the object filter obj_filter = {} obj_filter[obj_key] = obj_id # Define the cache object filter cache_filter = { 'object_type': obj_type, 'object_id': obj_id } # If the object doesn't exist anymore if not obj_class.objects.filter(**obj_filter).count(): # If an expired cache entry exists if DBClusterCache.objects.filter(**cache_filter).count(): self.log.info('Base object <%s> of type <%s> no longer exists, flushing cached entry' % (obj_id, obj_type)) # Flush the old cache entry DBClusterCache.objects.filter(**cache_filter).delete() # Expired cache object cleared return True # Get the object details obj_details = base64.encodestring(json.dumps(list(obj_class.objects.filter(**obj_filter).values(**values))[0], cls=DjangoJSONEncoder)) obj_size = sys.getsizeof(obj_details) obj_hash = hashlib.md5(obj_details).hexdigest() # If the object already has a cache entry if DBClusterCache.objects.filter(**cache_filter).count(): # Get the current cache entry cache_row = list(DBClusterCache.objects.filter(**cache_filter).values())[0] # If the cached data hasn't changed if cache_row['object_hash'] == obj_hash: return self.log.info('Cached data unchanged for object <%s> of type <%s>' % (obj_id, obj_type)) # Update the cached data DBClusterCache.objects.filter(**cache_filter).update(object_data=obj_details, object_size=obj_size) # Create a new cache entry else: # Create the cache entry DBClusterCache( object_type = acl_object, object_id = obj_id, object_data = obj_details, object_hash = obj_hash, object_size = obj_size ).save() # Object successfull cached self.log.info('Cached data for object <%s> of type <%s>: bytes_cached=%s, hash=%s' % (obj_id, obj_type, str(obj_size), obj_hash)) # Critical error when caching object except Exception as e: self.log.exception('Failed to cache object <%s> of type <%s>: %s' % (obj_id, obj_type, str(e))) # ACL object does not exist else: self.log.error('Cannot cache object <%s> of type <%s>, ACL object type not found' % (obj_id, obj_type))
def object_permissions_set(self, permissions): """ Set object permissions for this group. """ # Get a list of object types and details obj_types = [] obj_details = [] for obj in ACLObjects.get_values(): obj_types.append(obj['type']) obj_details.append(obj) # Process each object type in the request for obj_type in obj_types: if obj_type in permissions: # Get the details for this ACL object type obj_def = ACLObjects.get_values(obj_type)[0] # Get an instance of the ACL class acl_mod = importlib.import_module(obj_def['acl_mod']) acl_class = getattr(acl_mod, obj_def['acl_cls']) acl_key = obj_def['acl_key'] # Process each object for obj_id, obj_acls in permissions[obj_type].iteritems(): # Get an instance of the object class obj_mod = importlib.import_module(obj_def['obj_mod']) obj_class = getattr(obj_mod, obj_def['obj_cls']) obj_key = obj_def['obj_key'] # Object filter obj_filter = {} obj_filter[obj_key] = obj_id # Process each ACL definition for acl_id, acl_val in obj_acls.iteritems(): # Define the filter dictionairy filter = {} filter['owner'] = self.uuid filter['acl'] = acl_id filter[acl_key] = obj_id # Revoke the permission if acl_val == 'remove': acl_class.objects.filter(**filter).delete() # Modify the permission else: # If creating a new ACL entry if not acl_class.objects.filter(**filter).count(): # Model fields fields = {} fields['acl'] = DBGatewayACLKeys.objects.get(uuid=acl_id) fields['owner'] = self fields[obj_type] = obj_class.objects.get(**obj_filter) fields['allowed'] = acl_val # Create a new ACL entry acl_class(**fields).save() # If updating an existing ACL entry else: obj = acl_class.objects.get(**filter) obj.allowed = acl_val obj.save()