Add folder level access control

This commit is contained in:
Roberto Rosario
2011-12-17 19:44:04 -04:00
parent 84410ac98e
commit 8baa84f96b
3 changed files with 123 additions and 27 deletions

View File

@@ -4,23 +4,40 @@ from navigation.api import register_links, register_top_menu, \
register_multi_item_links, register_sidebar_template
from documents.models import Document
from documents.literals import PERMISSION_DOCUMENT_VIEW
from permissions.models import PermissionNamespace, Permission
from acls.models import class_permissions
from folders.models import Folder
folder_list = {'text': _(u'folder list'), 'view': 'folder_list', 'famfam': 'folder_user'}
folder_create = {'text': _('create folder'), 'view': 'folder_create', 'famfam': 'folder_add'}
folder_edit = {'text': _('edit'), 'view': 'folder_edit', 'args': 'object.pk', 'famfam': 'folder_edit'}
folder_delete = {'text': _('delete'), 'view': 'folder_delete', 'args': 'object.pk', 'famfam': 'folder_delete'}
folder_document_multiple_remove = {'text': _('remove from folder'), 'view': 'folder_document_multiple_remove', 'args': 'object.pk', 'famfam': 'delete'}
folder_view = {'text': _(u'folder documents'), 'view': 'folder_view', 'args': 'object.pk', 'famfam': 'folder_go'}
folder_add_document = {'text': _('add to a folder'), 'view': 'folder_add_document', 'args': 'object.pk', 'famfam': 'add'}
folder_namespace = PermissionNamespace('folders', _(u'Folders'))
PERMISSION_FOLDER_LIST = Permission.objects.register(folder_namespace, 'folder_list', _(u'View all folders'))
PERMISSION_FOLDER_CREATE = Permission.objects.register(folder_namespace, 'folder_create', _(u'Create new folders'))
PERMISSION_FOLDER_EDIT = Permission.objects.register(folder_namespace, 'folder_edit', _(u'Edit new folders'))
PERMISSION_FOLDER_DELETE = Permission.objects.register(folder_namespace, 'folder_delete', _(u'Delete new folders'))
PERMISSION_FOLDER_REMOVE_DOCUMENT = Permission.objects.register(folder_namespace, 'folder_remove_document', _(u'Remove documents from folders'))
PERMISSION_FOLDER_VIEW = Permission.objects.register(folder_namespace, 'folder_view', _(u'View existing folders'))
PERMISSION_FOLDER_ADD_DOCUMENT = Permission.objects.register(folder_namespace, 'folder_add_document', _(u'Add documents to existing folders'))
folder_list = {'text': _(u'folder list'), 'view': 'folder_list', 'famfam': 'folder_user', 'permissions': [PERMISSION_FOLDER_LIST]}
folder_create = {'text': _('create folder'), 'view': 'folder_create', 'famfam': 'folder_add', 'permissions': [PERMISSION_FOLDER_CREATE]}
folder_edit = {'text': _('edit'), 'view': 'folder_edit', 'args': 'object.pk', 'famfam': 'folder_edit', 'permissions': [PERMISSION_FOLDER_EDIT]}
folder_delete = {'text': _('delete'), 'view': 'folder_delete', 'args': 'object.pk', 'famfam': 'folder_delete', 'permissions': [PERMISSION_FOLDER_DELETE]}
folder_document_multiple_remove = {'text': _('remove from folder'), 'view': 'folder_document_multiple_remove', 'args': 'object.pk', 'famfam': 'delete', 'permissions': [PERMISSION_FOLDER_REMOVE_DOCUMENT]}
folder_view = {'text': _(u'folder documents'), 'view': 'folder_view', 'args': 'object.pk', 'famfam': 'folder_go', 'permissions': [PERMISSION_FOLDER_VIEW]}
folder_add_document = {'text': _('add to a folder'), 'view': 'folder_add_document', 'args': 'object.pk', 'famfam': 'add', 'permissions': [PERMISSION_FOLDER_ADD_DOCUMENT]}
document_folder_list = {'text': _(u'folders'), 'view': 'document_folder_list', 'args': 'object.pk', 'famfam': 'folder_user', 'permissions': [PERMISSION_DOCUMENT_VIEW], 'children_view_regex': [r'folder']}
folder_acl_list = {'text': _(u'ACLs'), 'view': 'folder_acl_list', 'args': 'object.pk', 'famfam': 'lock'}#, 'permissions': [ACLS_VIEW_ACL]}
folder_new_holder = {'text': _(u'New holder'), 'view': 'folder_new_holder', 'args': 'object.pk', 'famfam': 'user'}#, 'permissions': [ACLS_VIEW_ACL]}
register_multi_item_links(['folder_view'], [folder_document_multiple_remove])
register_links(Folder, [folder_view, folder_edit, folder_delete])
register_links(Folder, [folder_view, folder_edit, folder_delete, folder_acl_list])
register_links(['folder_edit', 'folder_delete', 'folder_list', 'folder_create', 'folder_view', 'folder_document_multiple_remove'], [folder_list, folder_create], menu_name='secondary_menu')
register_links(['folder_acl_list'], [folder_new_holder], menu_name='sidebar')
register_links(['folder_edit', 'folder_delete', 'folder_list', 'folder_create', 'folder_view', 'folder_document_multiple_remove', 'folder_acl_list', 'folder_new_holder'], [folder_list, folder_create], menu_name='secondary_menu')
register_top_menu(name='folders', link={'text': _('folders'), 'famfam': 'folder_user', 'view': 'folder_list'}, children_views=['folder_list', 'folder_create', 'folder_edit', 'folder_delete', 'folder_view', 'folder_document_multiple_remove'])
@@ -29,3 +46,15 @@ register_links(Document, [document_folder_list], menu_name='form_header')
register_sidebar_template(['folder_list'], 'folders_help.html')
register_links(['document_folder_list', 'folder_add_document'], [folder_add_document], menu_name="sidebar")
class_permissions(Folder, [
PERMISSION_FOLDER_LIST,
PERMISSION_FOLDER_EDIT,
PERMISSION_FOLDER_DELETE,
PERMISSION_FOLDER_VIEW,
])
class_permissions(Document, [
PERMISSION_FOLDER_ADD_DOCUMENT,
PERMISSION_FOLDER_REMOVE_DOCUMENT,
])

View File

@@ -9,7 +9,10 @@ urlpatterns = patterns('folders.views',
url(r'^(?P<folder_id>\d+)/$', 'folder_view', (), 'folder_view'),
url(r'^(?P<folder_id>\d+)/remove/document/multiple/$', 'folder_document_multiple_remove', (), 'folder_document_multiple_remove'),
url(r'^document/(?P<document_id>\d+)/folder/add/sidebar/$', 'folder_add_document_sidebar', (), 'folder_add_document_sidebar'),
#url(r'^document/(?P<document_id>\d+)/folder/add/sidebar/$', 'folder_add_document_sidebar', (), 'folder_add_document_sidebar'),
url(r'^document/(?P<document_id>\d+)/folder/add/$', 'folder_add_document', (), 'folder_add_document'),
url(r'^document/(?P<document_id>\d+)/folder/list/$', 'document_folder_list', (), 'document_folder_list'),
url(r'^(?P<folder_pk>\d+)/acl/list/$', 'folder_acl_list', (), 'folder_acl_list'),
url(r'^(?P<folder_pk>\d+)/acl/holder/new/$', 'folder_new_holder', (), 'folder_new_holder'),
)

View File

@@ -11,9 +11,15 @@ from documents.literals import PERMISSION_DOCUMENT_VIEW
from documents.models import Document
from permissions.models import Permission
from common.utils import encapsulate
from acls.models import AccessEntry, PermissionDenied
from acls.views import acl_list_for, acl_new_holder_for
from folders.models import Folder, FolderDocument
from folders.forms import FolderForm, AddDocumentForm
from folders import (PERMISSION_FOLDER_LIST, PERMISSION_FOLDER_CREATE,
PERMISSION_FOLDER_EDIT, PERMISSION_FOLDER_DELETE,
PERMISSION_FOLDER_REMOVE_DOCUMENT, PERMISSION_FOLDER_VIEW,
PERMISSION_FOLDER_ADD_DOCUMENT)
def folder_list(request, queryset=None, extra_context=None):
@@ -27,16 +33,27 @@ def folder_list(request, queryset=None, extra_context=None):
}
if extra_context:
context.update(extra_context)
queryset = queryset if not (queryset is None) else Folder.objects.all()
try:
Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_VIEW])
except PermissionDenied:
pass
#class_objects = AccessEntry.objects.get_allowed_class_objects(PERMISSION_FOLDER_VIEW, request.user, Folder)
#queryset = list(set(queryset) & set(class_objects))
context['object_list'] = queryset
return object_list(
request,
queryset=queryset if not (queryset is None) else Folder.objects.filter(user=request.user),
template_name='generic_list.html',
extra_context=context,
return render_to_response('generic_list.html',
context,
context_instance=RequestContext(request)
)
def folder_create(request):
Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_CREATE])
if request.method == 'POST':
form = FolderForm(request.POST)
if form.is_valid():
@@ -59,8 +76,10 @@ def folder_create(request):
def folder_edit(request, folder_id):
folder = get_object_or_404(Folder, pk=folder_id)
if not request.user.is_staff and not request.user.is_superuser and not request.user == folder.user:
raise PermissionDenied
try:
Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_EDIT])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_FOLDER_EDIT, request.user, folder)
if request.method == 'POST':
form = FolderForm(request.POST)
@@ -87,8 +106,10 @@ def folder_edit(request, folder_id):
def folder_delete(request, folder_id):
folder = get_object_or_404(Folder, pk=folder_id)
if not request.user.is_staff and not request.user.is_superuser and not request.user == folder.user:
raise PermissionDenied
try:
Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_DELETE])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_FOLDER_DELETE, request.user, folder)
post_action_redirect = reverse('folder_list')
@@ -122,8 +143,10 @@ def folder_delete(request, folder_id):
def folder_view(request, folder_id):
folder = get_object_or_404(Folder, pk=folder_id)
if not request.user.is_staff and not request.user.is_superuser and not request.user == folder.user:
raise PermissionDenied
try:
Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_VIEW])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_FOLDER_VIEW, request.user, folder)
return render_to_response('generic_list.html', {
'object_list': [fd.document for fd in folder.folderdocument_set.all()],
@@ -134,7 +157,7 @@ def folder_view(request, folder_id):
'object_name': _(u'folder'),
}, context_instance=RequestContext(request))
'''
def folder_add_document_sidebar(request, document_id):
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
document = get_object_or_404(Document, pk=document_id)
@@ -166,13 +189,16 @@ def folder_add_document_sidebar(request, document_id):
'document': document, 'folder': folder})
return HttpResponseRedirect(previous)
'''
def folder_add_document(request, document_id):
# TODO: merge with folder_add_document_sidebar
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
document = get_object_or_404(Document, pk=document_id)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_ADD_DOCUMENT])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_FOLDER_ADD_DOCUMENT, request.user, document)
next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/')))#reverse('document_tags', args=[document.pk]))))
if request.method == 'POST':
@@ -213,12 +239,16 @@ def folder_add_document(request, document_id):
def document_folder_list(request, document_id):
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
document = get_object_or_404(Document, pk=document_id)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_DOCUMENT_VIEW])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_DOCUMENT_VIEW, request.user, document)
return folder_list(
request,
queryset=Folder.objects.filter(user=request.user).filter(folderdocument__document=document),
queryset=Folder.objects.filter(folderdocument__document=document),
extra_context={
'title': _(u'folders containing: %s') % document,
'object': document,
@@ -239,6 +269,15 @@ def folder_document_remove(request, folder_id, document_id=None, document_id_lis
messages.error(request, _(u'Must provide at least one folder document.'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
try:
Permission.objects.check_permissions(request.user, [PERMISSION_FOLDER_REMOVE_DOCUMENT])
except PermissionDenied:
for document in folder_documents:
try:
AccessEntry.objects.check_access(PERMISSION_FOLDER_REMOVE_DOCUMENT, request.user, document)
except PermissionDenied:
folder_documents.remove(document)
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', '/')))
@@ -274,3 +313,28 @@ def folder_document_remove(request, folder_id, document_id=None, document_id_lis
def folder_document_multiple_remove(request, folder_id):
return folder_document_remove(request, folder_id, document_id_list=request.GET.get('id_list', []))
def folder_acl_list(request, folder_pk):
folder = get_object_or_404(Folder, pk=folder_pk)
return acl_list_for(
request,
folder,
extra_context={
'object': folder,
}
)
def folder_new_holder(request, folder_pk):
folder = get_object_or_404(Folder, pk=folder_pk)
return acl_new_holder_for(
request,
folder,
extra_context={
'folder': folder,
'submit_label': _(u'Select'),
'submit_icon_famfam': 'tick',
'object': folder,
}
)