Add related support to 'filter_objects_by_access' and 'get_allowed_class_objects' methods
This commit is contained in:
@@ -95,11 +95,20 @@ class AccessEntryManager(models.Manager):
|
||||
|
||||
raise PermissionDenied(ugettext(u'Insufficient access.'))
|
||||
|
||||
def get_allowed_class_objects(self, permission, actor, cls):
|
||||
def get_allowed_class_objects(self, permission, actor, cls, related=None):
|
||||
logger.debug('related: %s' % related)
|
||||
|
||||
actor_type = ContentType.objects.get_for_model(actor)
|
||||
content_type = ContentType.objects.get_for_model(cls)
|
||||
|
||||
return (obj.content_object for obj in self.model.objects.filter(holder_type=actor_type, holder_id=actor.pk, content_type=content_type, permission=permission.get_stored_permission))
|
||||
if related:
|
||||
master_list = [obj.content_object for obj in self.model.objects.select_related().filter(holder_type=actor_type, holder_id=actor.pk, permission=permission.get_stored_permission)]
|
||||
logger.debug('master_list: %s' % master_list)
|
||||
# TODO: update to use Q objects and check performance diff
|
||||
# kwargs = {'%s__in' % related: master_list}
|
||||
# Q(**kwargs)
|
||||
return (obj for obj in cls.objects.all() if getattr(obj, related) in master_list)
|
||||
else:
|
||||
return (obj.content_object for obj in self.model.objects.filter(holder_type=actor_type, holder_id=actor.pk, content_type=content_type, permission=permission.get_stored_permission))
|
||||
|
||||
def get_acl_url(self, obj):
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
@@ -132,7 +141,7 @@ class AccessEntryManager(models.Manager):
|
||||
content_type = ContentType.objects.get_for_model(obj)
|
||||
return (access.permission for access in self.model.objects.filter(content_type=content_type, object_id=obj.pk, holder_type=actor_type, holder_id=actor.pk))
|
||||
|
||||
def filter_objects_by_access(self, permission, actor, object_list, exception_on_empty=False):
|
||||
def filter_objects_by_access(self, permission, actor, object_list, exception_on_empty=False, related=None):
|
||||
logger.debug('exception_on_empty: %s' % exception_on_empty)
|
||||
logger.debug('object_list: %s' % object_list)
|
||||
|
||||
@@ -150,7 +159,7 @@ class AccessEntryManager(models.Manager):
|
||||
|
||||
try:
|
||||
# Try to process as a QuerySet
|
||||
qs = object_list.filter(pk__in=[obj.pk for obj in self.get_allowed_class_objects(permission, actor, object_list[0])])
|
||||
qs = object_list.filter(pk__in=[obj.pk for obj in self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related)])
|
||||
logger.debug('qs: %s' % qs)
|
||||
|
||||
if qs.count() == 0 and exception_on_empty == True:
|
||||
@@ -158,13 +167,13 @@ class AccessEntryManager(models.Manager):
|
||||
|
||||
return qs
|
||||
except AttributeError:
|
||||
# Fallback to a list filtered list
|
||||
obj_list = list(set(object_list) & set(self.get_allowed_class_objects(permission, actor, object_list[0])))
|
||||
logger.debug('obj_list: %s' % obj_list)
|
||||
if len(obj_list) == 0 and exception_on_empty == True:
|
||||
# Fallback to a filtered list
|
||||
object_list = list(set(object_list) & set(self.get_allowed_class_objects(permission, actor, object_list[0].__class__, related)))
|
||||
logger.debug('object_list: %s' % object_list)
|
||||
if len(object_list) == 0 and exception_on_empty == True:
|
||||
raise PermissionDenied
|
||||
|
||||
return obj_list
|
||||
return object_list
|
||||
|
||||
|
||||
class DefaultAccessEntryManager(models.Manager):
|
||||
|
||||
Reference in New Issue
Block a user