Merge branch 'feature/comment_permissions' into development
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):
|
||||
|
||||
@@ -8,20 +8,19 @@ from django.contrib.contenttypes import generic
|
||||
from navigation.api import register_links, register_model_list_columns
|
||||
from permissions.models import PermissionNamespace, Permission
|
||||
from common.utils import encapsulate
|
||||
|
||||
from acls.api import class_permissions
|
||||
from documents.models import Document
|
||||
|
||||
if 'django.contrib.comments' not in settings.INSTALLED_APPS:
|
||||
raise Exception('This app depends on the django.contrib.comments app.')
|
||||
|
||||
from .permissions import (PERMISSION_COMMENT_CREATE,
|
||||
PERMISSION_COMMENT_DELETE, PERMISSION_COMMENT_EDIT,
|
||||
PERMISSION_COMMENT_VIEW)
|
||||
PERMISSION_COMMENT_DELETE, PERMISSION_COMMENT_VIEW)
|
||||
|
||||
comment_delete = {'text': _('delete'), 'view': 'comment_delete', 'args': 'object.pk', 'famfam': 'comment_delete', 'permissions': [PERMISSION_COMMENT_DELETE]}
|
||||
comment_multiple_delete = {'text': _('delete'), 'view': 'comment_multiple_delete', 'args': 'object.pk', 'famfam': 'comments_delete', 'permissions': [PERMISSION_COMMENT_DELETE]}
|
||||
comment_add = {'text': _('add comment'), 'view': 'comment_add', 'args': 'object.pk', 'famfam': 'comment_add', 'permissions': [PERMISSION_COMMENT_CREATE]}
|
||||
comments_for_object = {'text': _('comments'), 'view': 'comments_for_object', 'args': 'object.pk', 'famfam': 'comments', 'permissions': [PERMISSION_COMMENT_VIEW], 'children_view_regex': ['comment']}
|
||||
comments_for_document = {'text': _('comments'), 'view': 'comments_for_document', 'args': 'object.pk', 'famfam': 'comments', 'permissions': [PERMISSION_COMMENT_VIEW], 'children_view_regex': ['comment']}
|
||||
|
||||
register_model_list_columns(Comment, [
|
||||
{
|
||||
@@ -38,9 +37,9 @@ register_model_list_columns(Comment, [
|
||||
}
|
||||
])
|
||||
|
||||
register_links(['comments_for_object', 'comment_add', 'comment_delete', 'comment_multiple_delete'], [comment_add], menu_name='sidebar')
|
||||
register_links(['comments_for_document', 'comment_add', 'comment_delete', 'comment_multiple_delete'], [comment_add], menu_name='sidebar')
|
||||
register_links(Comment, [comment_delete])
|
||||
register_links(Document, [comments_for_object], menu_name='form_header')
|
||||
register_links(Document, [comments_for_document], menu_name='form_header')
|
||||
|
||||
Document.add_to_class(
|
||||
'comments',
|
||||
@@ -50,3 +49,9 @@ Document.add_to_class(
|
||||
object_id_field='object_pk'
|
||||
)
|
||||
)
|
||||
|
||||
class_permissions(Document, [
|
||||
PERMISSION_COMMENT_CREATE,
|
||||
PERMISSION_COMMENT_DELETE,
|
||||
PERMISSION_COMMENT_VIEW
|
||||
])
|
||||
|
||||
@@ -8,5 +8,4 @@ comments_namespace = PermissionNamespace('comments', _(u'Comments'))
|
||||
|
||||
PERMISSION_COMMENT_CREATE = Permission.objects.register(comments_namespace, 'comment_create', _(u'Create new comments'))
|
||||
PERMISSION_COMMENT_DELETE = Permission.objects.register(comments_namespace, 'comment_delete', _(u'Delete comments'))
|
||||
PERMISSION_COMMENT_EDIT = Permission.objects.register(comments_namespace, 'comment_edit', _(u'Edit comments'))
|
||||
PERMISSION_COMMENT_VIEW = Permission.objects.register(comments_namespace, 'comment_view', _(u'View comments'))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
|
||||
urlpatterns = patterns('document_comments.views',
|
||||
url(r'^(?P<comment_id>\d+)/delete/$', 'comment_delete', (), 'comment_delete'),
|
||||
url(r'^multiple/delete/$', 'comment_multiple_delete', (), 'comment_multiple_delete'),
|
||||
url(r'^add_to_document/(?P<document_id>\d+)/$', 'comment_add', (), 'comment_add'),
|
||||
url(r'^for/object/(?P<document_id>\d+)/$', 'comments_for_object', (), 'comments_for_object'),
|
||||
url(r'^comment/(?P<comment_id>\d+)/delete/$', 'comment_delete', (), 'comment_delete'),
|
||||
url(r'^comment/multiple/delete/$', 'comment_multiple_delete', (), 'comment_multiple_delete'),
|
||||
url(r'^(?P<document_id>\d+)/comment/add/$', 'comment_add', (), 'comment_add'),
|
||||
url(r'^(?P<document_id>\d+)/comment/list/$', 'comments_for_document', (), 'comments_for_document'),
|
||||
)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.comments.models import Comment
|
||||
from . import comment_delete
|
||||
|
||||
|
||||
def get_comments_subtemplate(obj):
|
||||
"""
|
||||
Return all the settings to render a subtemplate containing an
|
||||
object's comments
|
||||
"""
|
||||
return {
|
||||
'name': 'generic_list_subtemplate.html',
|
||||
'context': {
|
||||
'title': _(u'comments'),
|
||||
'object_list': Comment.objects.for_model(obj).order_by('-submit_date'),
|
||||
'hide_link': True,
|
||||
'hide_object': True,
|
||||
'navigation_object_links': [comment_delete],
|
||||
'scrollable_content': True,
|
||||
'scrollable_content_height': '200px',
|
||||
}
|
||||
}
|
||||
@@ -8,27 +8,33 @@ from django.template import RequestContext
|
||||
from django.contrib import messages
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
from acls.models import AccessEntry
|
||||
from permissions.models import Permission
|
||||
from documents.models import Document
|
||||
|
||||
from .permissions import (PERMISSION_COMMENT_CREATE,
|
||||
PERMISSION_COMMENT_DELETE, PERMISSION_COMMENT_EDIT,
|
||||
PERMISSION_COMMENT_VIEW)
|
||||
PERMISSION_COMMENT_DELETE, PERMISSION_COMMENT_VIEW)
|
||||
from .forms import CommentForm
|
||||
|
||||
|
||||
def comment_delete(request, comment_id=None, comment_id_list=None):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_DELETE])
|
||||
post_action_redirect = None
|
||||
|
||||
if comment_id:
|
||||
comments = [get_object_or_404(Comment, pk=comment_id)]
|
||||
elif comment_id_list:
|
||||
comments = [get_object_or_404(Comment, pk=comment_id) for comment_id in comment_id_list.split(',')]
|
||||
else:
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_DELETE])
|
||||
except PermissionDenied:
|
||||
comments = AccessEntry.objects.filter_objects_by_access(PERMISSION_COMMENT_DELETE, request.user, comments, related='content_object')
|
||||
|
||||
if not comments:
|
||||
messages.error(request, _(u'Must provide at least one comment.'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
|
||||
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
|
||||
|
||||
previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/')))
|
||||
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
|
||||
@@ -69,9 +75,13 @@ def comment_multiple_delete(request):
|
||||
|
||||
|
||||
def comment_add(request, document_id):
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_CREATE])
|
||||
|
||||
document = get_object_or_404(Document, pk=document_id)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_CREATE])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_COMMENT_CREATE, request.user, document)
|
||||
|
||||
post_action_redirect = None
|
||||
|
||||
next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', '/')))
|
||||
@@ -99,16 +109,20 @@ def comment_add(request, document_id):
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
|
||||
def comments_for_object(request, document_id):
|
||||
def comments_for_document(request, document_id):
|
||||
'''
|
||||
Show a list of all the comments related to the passed object
|
||||
'''
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_VIEW])
|
||||
|
||||
document = get_object_or_404(Document, pk=document_id)
|
||||
|
||||
try:
|
||||
Permission.objects.check_permissions(request.user, [PERMISSION_COMMENT_VIEW])
|
||||
except PermissionDenied:
|
||||
AccessEntry.objects.check_access(PERMISSION_COMMENT_VIEW, request.user, document)
|
||||
|
||||
return render_to_response('generic_list.html', {
|
||||
'object': document,
|
||||
'access_object': document,
|
||||
'title': _(u'comments: %s') % document,
|
||||
'object_list': Comment.objects.for_model(document).order_by('-submit_date'),
|
||||
'hide_link': True,
|
||||
|
||||
Reference in New Issue
Block a user