Example #1
0
 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
Example #2
0
 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
Example #3
0
 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))
Example #4
0
 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()
Example #5
0
 def _get_from_model(self, obj_type, obj_id, values={}, filters={}):
     """
     Retrieve object details directly from the model.
     
     @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 values:   Extra parameters to pass to the values QuerySet method
     @type  values:   dict
     @param filters:  Extra filter parameters
     @type  filters:  dict
     """
     self.log.info('Retrieving object data from model: type=%s, id=%s' % (obj_type, repr(obj_id)))
     
     # Get the ACL object definition
     acl_object  = ACLObjects.get(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  = {}
     
     # If retrieving a single object
     if obj_id:
         obj_filter[obj_key] = obj_id
     
     # Create the query object
     query_obj = obj_class.objects
     
     # If an object filter is defined
     if obj_filter:
         self.log.info('Applying object filters: %s' % json.dumps(obj_filter))
         query_obj = query_obj.filter(**obj_filter)
         
     # If a values filter is defined
     if filters:
         self.log.info('Applying value filters: %s' % json.dumps(filters))
         query_obj = query_obj.filter(**filters)
     
     # If no filters were defined
     if not obj_filter and not filters:
         self.log.info('No filters defined, retrieving all objects')
         query_obj = query_obj.all()
     
     # Log the constructed query object
     self.log.info('Constructed object query: %s' % str(query_obj))
     
     # Attempt to retrieve the object
     obj_details = list(query_obj.values())
     
     # Log the retrieved details
     log_data = json.dumps(obj_details, cls=DjangoJSONEncoder)
     self.log.info('Retrieved object details: length=%s, data=%s' % (len(log_data), (log_data[:75] + '...') if len(log_data) > 75 else log_data))
     
     # If the object doesn't exist
     if len(obj_details) == 0:
         return None
     
     # Return the object details
     if not obj_id:
         return obj_details
     return obj_details[0]