diff --git a/apps/linking/__init__.py b/apps/linking/__init__.py index f64337045e..63895ab171 100644 --- a/apps/linking/__init__.py +++ b/apps/linking/__init__.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + from django.utils.translation import ugettext_lazy as _ from navigation.api import register_links, register_sidebar_template @@ -5,8 +7,10 @@ from permissions.models import PermissionNamespace, Permission from project_setup.api import register_setup from documents.literals import PERMISSION_DOCUMENT_VIEW from documents.models import Document +from acls.models import class_permissions +from acls import ACLS_EDIT_ACL, ACLS_VIEW_ACL -from linking.models import SmartLink, SmartLinkCondition +from .models import SmartLink, SmartLinkCondition linking_namespace = PermissionNamespace('linking', _(u'Smart links')) @@ -29,12 +33,26 @@ smart_link_condition_create = {'text': _(u'create condition'), 'view': 'smart_li smart_link_condition_edit = {'text': _(u'edit'), 'view': 'smart_link_condition_edit', 'args': 'condition.pk', 'famfam': 'cog_edit', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]} smart_link_condition_delete = {'text': _(u'delete'), 'view': 'smart_link_condition_delete', 'args': 'condition.pk', 'famfam': 'cog_delete', 'permissions': [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]} +smart_link_acl_list = {'text': _(u'ACLs'), 'view': 'smart_link_acl_list', 'args': 'smart_link.pk', 'famfam': 'lock', 'permissions': [ACLS_VIEW_ACL]} +smart_link_new_holder = {'text': _(u'New holder'), 'view': 'smart_link_new_holder', 'args': 'smart_link.pk', 'famfam': 'user', 'permissions': [ACLS_VIEW_ACL]} + +register_links(['smart_link_acl_list', 'smart_link_new_holder'], [smart_link_new_holder], menu_name='sidebar') + register_links(Document, [smart_link_instances_for_document], menu_name='form_header') -register_links(SmartLink, [smart_link_edit, smart_link_delete, smart_link_condition_list]) +register_links(SmartLink, [smart_link_edit, smart_link_delete, smart_link_condition_list, smart_link_acl_list]) +register_links([SmartLink, 'smart_link_list', 'smart_link_create'], [smart_link_list, smart_link_create], menu_name='sidebar') + register_links(SmartLinkCondition, [smart_link_condition_edit, smart_link_condition_delete]) -register_links(['smart_link_list', 'smart_link_create', 'smart_link_edit', 'smart_link_delete', 'smart_link_condition_list', 'smart_link_condition_create', 'smart_link_condition_edit', 'smart_link_condition_delete'], [smart_link_list, smart_link_create], menu_name='sidebar') register_links(['smart_link_condition_list', 'smart_link_condition_create', 'smart_link_condition_edit', 'smart_link_condition_delete'], [smart_link_condition_create], menu_name='sidebar') register_setup(smart_link_setup) register_sidebar_template(['smart_link_list'], 'smart_links_help.html') + +class_permissions(SmartLink, [ + PERMISSION_SMART_LINK_VIEW, + PERMISSION_SMART_LINK_DELETE, + PERMISSION_SMART_LINK_EDIT, + ACLS_EDIT_ACL, + ACLS_VIEW_ACL +]) diff --git a/apps/linking/admin.py b/apps/linking/admin.py index 045244bc5a..84f13692f5 100644 --- a/apps/linking/admin.py +++ b/apps/linking/admin.py @@ -1,6 +1,8 @@ +from __future__ import absolute_import + from django.contrib import admin -from linking.models import SmartLink, SmartLinkCondition +from .models import SmartLink, SmartLinkCondition class SmartLinkConditionInline(admin.StackedInline): diff --git a/apps/linking/forms.py b/apps/linking/forms.py index 1e90e16c8a..5cdb6be1f9 100644 --- a/apps/linking/forms.py +++ b/apps/linking/forms.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + from django import forms from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext @@ -9,7 +11,7 @@ from django.conf import settings from documents.widgets import document_html_widget from tags.widgets import get_tags_inline_widget -from linking.models import SmartLink, SmartLinkCondition +from .models import SmartLink, SmartLinkCondition class SmartLinkForm(forms.ModelForm): diff --git a/apps/linking/managers.py b/apps/linking/managers.py index 050ddffea2..bb6dcba1c5 100644 --- a/apps/linking/managers.py +++ b/apps/linking/managers.py @@ -1,10 +1,12 @@ +from __future__ import absolute_import + from django.db import models from django.db.models import Q from metadata.classes import MetadataObject from documents.models import Document -from linking.literals import INCLUSION_AND, INCLUSION_OR +from .literals import INCLUSION_AND, INCLUSION_OR class SmartLinkManager(models.Manager): diff --git a/apps/linking/models.py b/apps/linking/models.py index ccc04f5537..18b145b936 100644 --- a/apps/linking/models.py +++ b/apps/linking/models.py @@ -1,8 +1,10 @@ +from __future__ import absolute_import + from django.db import models from django.utils.translation import ugettext_lazy as _ -from linking.managers import SmartLinkManager -from linking.literals import OPERATOR_CHOICES, INCLUSION_AND, \ +from .managers import SmartLinkManager +from .literals import OPERATOR_CHOICES, INCLUSION_AND, \ INCLUSION_CHOICES diff --git a/apps/linking/tests.py b/apps/linking/tests.py deleted file mode 100644 index 2247054b35..0000000000 --- a/apps/linking/tests.py +++ /dev/null @@ -1,23 +0,0 @@ -""" -This file demonstrates two different styles of tests (one doctest and one -unittest). These will both pass when you run "manage.py test". - -Replace these with more appropriate tests for your application. -""" - -from django.test import TestCase - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.failUnlessEqual(1 + 1, 2) - -__test__ = {"doctest": """ -Another way to test that 1 + 1 is equal to 2. - ->>> 1 + 1 == 2 -True -"""} - diff --git a/apps/linking/urls.py b/apps/linking/urls.py index 080a180b2b..e13bc00441 100644 --- a/apps/linking/urls.py +++ b/apps/linking/urls.py @@ -14,4 +14,7 @@ urlpatterns = patterns('linking.views', url(r'^setup/(?P\d+)/condition/create/$', 'smart_link_condition_create', (), 'smart_link_condition_create'), url(r'^setup/smart_link/condition/(?P\d+)/edit/$', 'smart_link_condition_edit', (), 'smart_link_condition_edit'), url(r'^setup/smart_link/condition/(?P\d+)/delete/$', 'smart_link_condition_delete', (), 'smart_link_condition_delete'), + + url(r'^(?P\d+)/acl/list/$', 'smart_link_acl_list', (), 'smart_link_acl_list'), + url(r'^(?P\d+)/acl/holder/new/$', 'smart_link_new_holder', (), 'smart_link_new_holder'), ) diff --git a/apps/linking/views.py b/apps/linking/views.py index 559f4dcea7..2e5d72a626 100644 --- a/apps/linking/views.py +++ b/apps/linking/views.py @@ -1,3 +1,6 @@ +from __future__ import absolute_import +import logging + from django.utils.translation import ugettext_lazy as _ from django.contrib import messages from django.http import HttpResponseRedirect @@ -7,24 +10,27 @@ from django.template import RequestContext from common.utils import generate_choices_w_labels, encapsulate from common.widgets import two_state_template - from documents.models import Document from documents.views import document_list - +from documents.literals import PERMISSION_DOCUMENT_VIEW from permissions.models import Permission +from acls.views import acl_new_holder_for, acl_list_for, acl_detail_for +from acls.models import AccessEntry, PermissionDenied -from linking.models import SmartLink, SmartLinkCondition -from linking.conf.settings import SHOW_EMPTY_SMART_LINKS -from linking.forms import (SmartLinkInstanceForm, SmartLinkForm, +from .models import SmartLink, SmartLinkCondition +from .conf.settings import SHOW_EMPTY_SMART_LINKS +from .forms import (SmartLinkInstanceForm, SmartLinkForm, SmartLinkConditionForm) -from linking import smart_link_instance_view_link -from linking import (PERMISSION_SMART_LINK_VIEW, +from . import smart_link_instance_view_link +from . import (PERMISSION_SMART_LINK_VIEW, PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_DELETE, PERMISSION_SMART_LINK_EDIT) +logger = logging.getLogger(__name__) + def smart_link_action(request): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) + #Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) action = request.GET.get('action', None) @@ -36,10 +42,14 @@ def smart_link_action(request): def smart_link_instance_view(request, document_id, smart_link_pk): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) - document = get_object_or_404(Document, pk=document_id) smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) + + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) + except PermissionDenied: + AccessEntry.objects.check_access(PERMISSION_SMART_LINK_VIEW, request.user, smart_link) + object_list, errors = SmartLink.objects.get_smart_link_instances_for(document, smart_link) return document_list( @@ -55,8 +65,6 @@ def smart_link_instance_view(request, document_id, smart_link_pk): def smart_link_instances_for_document(request, document_id): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) - subtemplates_list = [] document = get_object_or_404(Document, pk=document_id) smart_link_instances, errors = SmartLink.objects.get_smart_link_instances_for(document) @@ -69,6 +77,17 @@ def smart_link_instances_for_document(request, document_id): #dictionary smart_link_instances = dict([(group, data) for group, data in smart_link_instances.items() if data['documents']]) + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) + except PermissionDenied: + smart_link_instances_keys_filtered = AccessEntry.objects.filter_objects_by_access(PERMISSION_SMART_LINK_VIEW, request.user, smart_link_instances.keys()) + # Remove smart link instances not found in the new filtered key list + for key, value in smart_link_instances.items(): + if key not in smart_link_instances_keys_filtered: + smart_link_instances.pop(key) + + value['documents'] = AccessEntry.objects.filter_objects_by_access(PERMISSION_DOCUMENT_VIEW, request.user, value['documents']) + if smart_link_instances: subtemplates_list = [{ 'name': 'generic_form_subtemplate.html', @@ -99,11 +118,17 @@ def smart_link_instances_for_document(request, document_id): def smart_link_list(request): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE]) + qs = SmartLink.objects.all() + + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_VIEW]) + except PermissionDenied: + qs = AccessEntry.objects.filter_objects_by_access(PERMISSION_SMART_LINK_VIEW, request.user, qs) + return render_to_response('generic_list.html', { 'title': _(u'smart links'), - 'object_list': SmartLink.objects.all(), + 'object_list': qs, 'extra_columns': [ {'name': _(u'dynamic title'), 'attribute': 'dynamic_title'}, {'name': _(u'enabled'), 'attribute': encapsulate(lambda x: two_state_template(x.enabled))}, @@ -133,10 +158,13 @@ def smart_link_create(request): def smart_link_edit(request, smart_link_pk): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_EDIT]) - smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_EDIT]) + except PermissionDenied: + AccessEntry.objects.check_access(PERMISSION_SMART_LINK_EDIT, request.user, smart_link) + if request.method == 'POST': form = SmartLinkForm(request.POST, instance=smart_link) if form.is_valid(): @@ -155,10 +183,13 @@ def smart_link_edit(request, smart_link_pk): def smart_link_delete(request, smart_link_pk): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_DELETE]) - smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_DELETE]) + except PermissionDenied: + AccessEntry.objects.check_access(PERMISSION_SMART_LINK_DELETE, request.user, smart_link) + next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -185,10 +216,13 @@ def smart_link_delete(request, smart_link_pk): def smart_link_condition_list(request, smart_link_pk): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) - smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) + except PermissionDenied: + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link) + return render_to_response('generic_list.html', { 'title': _(u'conditions for smart link: %s') % smart_link, 'object_list': smart_link.smartlinkcondition_set.all(), @@ -203,10 +237,13 @@ def smart_link_condition_list(request, smart_link_pk): def smart_link_condition_create(request, smart_link_pk): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) - smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) + except PermissionDenied: + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link) + if request.method == 'POST': form = SmartLinkConditionForm(request.POST) if form.is_valid(): @@ -227,10 +264,13 @@ def smart_link_condition_create(request, smart_link_pk): def smart_link_condition_edit(request, smart_link_condition_pk): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) - smart_link_condition = get_object_or_404(SmartLinkCondition, pk=smart_link_condition_pk) + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) + except PermissionDenied: + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link_condition.smart_link) + next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -261,10 +301,13 @@ def smart_link_condition_edit(request, smart_link_condition_pk): def smart_link_condition_delete(request, smart_link_condition_pk): - Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) - smart_link_condition = get_object_or_404(SmartLinkCondition, pk=smart_link_condition_pk) + try: + Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT]) + except PermissionDenied: + AccessEntry.objects.check_accesses([PERMISSION_SMART_LINK_CREATE, PERMISSION_SMART_LINK_EDIT], request.user, smart_link_condition.smart_link) + next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', '/'))) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) @@ -292,3 +335,32 @@ def smart_link_condition_delete(request, smart_link_condition_pk): 'previous': previous, 'form_icon': u'cog_delete.png', }, context_instance=RequestContext(request)) + + +def smart_link_acl_list(request, smart_link_pk): + smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) + logger.debug('smart_link: %s' % smart_link) + + return acl_list_for( + request, + smart_link, + extra_context={ + 'object': smart_link, + 'smart_link': smart_link, + } + ) + + +def smart_link_new_holder(request, smart_link_pk): + smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) + return acl_new_holder_for( + request, + smart_link, + extra_context={ + 'smart_link': smart_link, + 'submit_label': _(u'Select'), + 'submit_icon_famfam': 'tick', + 'object': smart_link, + }, + navigation_object=u'smart_link', + )