From 7aabd7a1cc5247ecf091158d65464a70687c51c3 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 02:20:27 -0400 Subject: [PATCH 01/13] Add 'get_classes' function to acls.api, add function docstrings --- apps/acls/api.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/apps/acls/api.py b/apps/acls/api.py index 8dc3f2d931..2b72ef6b11 100644 --- a/apps/acls/api.py +++ b/apps/acls/api.py @@ -1,13 +1,30 @@ +from __future__ import absolute_import + from django.contrib.contenttypes.models import ContentType +from .classes import AccessObjectClass + _class_permissions = {} def class_permissions(cls, permission_list): + """ + Associate a permissions list to a class + """ stored_permissions = _class_permissions.setdefault(cls, []) stored_permissions.extend(permission_list) def get_class_permissions_for(obj): + """ + Return a list of permissions associated with a content type + """ content_type = ContentType.objects.get_for_model(obj) return _class_permissions.get(content_type.model_class(), []) + + +def get_classes(): + """ + Return a list of encapsulated classes that have been registered + """ + return [AccessObjectClass.encapsulate(cls) for cls in _class_permissions.keys()] From 6e24b56e0ef27ec7b6cdc8dd53a8a13e59d14901 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 02:21:01 -0400 Subject: [PATCH 02/13] Add missing capfirst import --- apps/acls/classes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/acls/classes.py b/apps/acls/classes.py index bcca9a6971..8e8397dfa5 100644 --- a/apps/acls/classes.py +++ b/apps/acls/classes.py @@ -5,6 +5,7 @@ import types from django.db import models from django.contrib.contenttypes.models import ContentType from django.db.models.base import ModelBase +from django.template.defaultfilters import capfirst from common.models import AnonymousUserSingleton From 78c99c77008bfd77dfeef236a6ae03dd27d7203c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 02:21:17 -0400 Subject: [PATCH 03/13] Add tags and smartlinks icon mappings --- apps/acls/literals.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/acls/literals.py b/apps/acls/literals.py index 50c6626b8e..03b9587342 100644 --- a/apps/acls/literals.py +++ b/apps/acls/literals.py @@ -1,8 +1,11 @@ +# Content type <-> fam fam icon mapping CONTENT_TYPE_ICON_MAP = { 'auth.user': 'user', 'auth.group': 'group', 'documents.document': 'page', 'permissions.role': 'medal_gold_1', 'folders.folder': 'folder', + 'taggit.tag': 'tag_blue', + 'linking.smartlink': 'page_link', } From 071da1433060c6bb11f4b50cfba5043ac953e1e2 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 02:22:04 -0400 Subject: [PATCH 04/13] Remove moved method and unused import --- apps/acls/models.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/acls/models.py b/apps/acls/models.py index 7aa847a88d..656994d780 100644 --- a/apps/acls/models.py +++ b/apps/acls/models.py @@ -11,7 +11,6 @@ from django.core.exceptions import PermissionDenied from django.core.urlresolvers import reverse from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import get_object_or_404 -from django.template.defaultfilters import capfirst from permissions.models import StoredPermission @@ -24,7 +23,6 @@ class AccessEntry(models.Model): ''' Model that hold the permission, object, actor relationship ''' - permission = models.ForeignKey(StoredPermission, verbose_name=_(u'permission')) holder_type = models.ForeignKey( @@ -63,11 +61,6 @@ class DefaultAccessEntry(models.Model): Model that holds the permission, class, actor relationship, that will be added upon the creation of an instance of said class ''' - - @classmethod - def get_classes(cls): - return [AccessObjectClass.encapsulate(cls) for cls in _class_permissions.keys()] - permission = models.ForeignKey(StoredPermission, verbose_name=_(u'permission')) holder_type = models.ForeignKey( From a2e00b77768e1bdf1bc92e4bce0ec11c13b8820a Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 02:22:25 -0400 Subject: [PATCH 05/13] Use content type model name and not name when mapping content types to icons --- apps/acls/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/acls/widgets.py b/apps/acls/widgets.py index 8a410fd171..3c13fce54b 100644 --- a/apps/acls/widgets.py +++ b/apps/acls/widgets.py @@ -14,7 +14,7 @@ from .literals import CONTENT_TYPE_ICON_MAP def content_type_icon(content_type): - return mark_safe(u'' % CONTENT_TYPE_ICON_MAP.get('%s.%s' % (content_type.app_label, content_type.name), 'help')) + return mark_safe(u'' % CONTENT_TYPE_ICON_MAP.get('%s.%s' % (content_type.app_label, content_type.model), 'help')) def object_w_content_type_icon(obj): From 014ca49a7c5f65c3fe1aad768d6bb3d1f4f6fc2c Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 02:23:01 -0400 Subject: [PATCH 06/13] Call the correct function to get list of registered classes for acl --- apps/acls/views.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/acls/views.py b/apps/acls/views.py index f0332fe33e..da813f3e6f 100644 --- a/apps/acls/views.py +++ b/apps/acls/views.py @@ -29,7 +29,7 @@ from .classes import (AccessHolder, AccessObject, AccessObjectClass, ClassAccessHolder) from .widgets import object_w_content_type_icon from .forms import HolderSelectionForm -from .api import get_class_permissions_for +from .api import get_class_permissions_for, get_classes logger = logging.getLogger(__name__) @@ -85,9 +85,9 @@ def acl_detail(request, access_object_gid, holder_object_gid): def acl_detail_for(request, actor, obj, navigation_object=None): try: - Permission.objects.check_permissions(request.user, [ACLS_VIEW_ACL, ACLS_EDIT_ACL]) + Permission.objects.check_permissions(request.user, [ACLS_VIEW_ACL]) except PermissionDenied: - AccessEntry.objects.check_accesses([ACLS_VIEW_ACL, ACLS_EDIT_ACL], actor, obj) + AccessEntry.objects.check_accesses([ACLS_VIEW_ACL], actor, obj) permission_list = get_class_permissions_for(obj) @@ -371,11 +371,11 @@ def acl_new_holder_for(request, obj, extra_context=None, navigation_object=None) # Setup views def acl_setup_valid_classes(request): - Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL, ACLS_CLASS_EDIT_ACL]) - logger.debug('DefaultAccessEntry.get_classes(): %s' % DefaultAccessEntry.get_classes()) + Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL]) + logger.debug('DefaultAccessEntry.get_classes(): %s' % get_classes()) context = { - 'object_list': DefaultAccessEntry.get_classes(), + 'object_list': get_classes(), 'title': _(u'classes'), 'extra_columns': [ {'name': _(u'class'), 'attribute': encapsulate(lambda x: object_w_content_type_icon(x.source_object))}, From 4aad4efad371f1e5039b53b7875eb7cf708c082e Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 04:46:46 -0400 Subject: [PATCH 07/13] Navigation feedback improvements for a few apps --- apps/acls/__init__.py | 13 ++++++------- apps/acls/urls.py | 2 +- apps/documents/__init__.py | 2 +- apps/linking/__init__.py | 2 +- apps/permissions/__init__.py | 2 +- apps/tags/__init__.py | 2 +- apps/user_management/__init__.py | 4 ++-- 7 files changed, 13 insertions(+), 14 deletions(-) diff --git a/apps/acls/__init__.py b/apps/acls/__init__.py index eae1816727..c6dd477306 100644 --- a/apps/acls/__init__.py +++ b/apps/acls/__init__.py @@ -11,14 +11,14 @@ from .permissions import (ACLS_EDIT_ACL, ACLS_VIEW_ACL, acl_list = {'text': _(u'ACLs'), 'view': 'acl_list', 'famfam': 'lock', 'permissions': [ACLS_VIEW_ACL]} -acl_detail = {'text': _(u'details'), 'view': 'acl_detail', 'args': ['access_object.gid', 'object.gid'], 'famfam': 'lock', 'permissions': [ACLS_VIEW_ACL]} +acl_detail = {'text': _(u'details'), 'view': 'acl_detail', 'args': ['access_object.gid', 'object.gid'], 'famfam': 'key_go', 'permissions': [ACLS_VIEW_ACL]} acl_grant = {'text': _(u'grant'), 'view': 'acl_multiple_grant', 'famfam': 'key_add', 'permissions': [ACLS_EDIT_ACL]} acl_revoke = {'text': _(u'revoke'), 'view': 'acl_multiple_revoke', 'famfam': 'key_delete', 'permissions': [ACLS_EDIT_ACL]} acl_setup_valid_classes = {'text': _(u'Default ACLs'), 'view': 'acl_setup_valid_classes', 'icon': 'lock.png', 'permissions': [ACLS_CLASS_VIEW_ACL]} acl_class_list = {'text': _(u'List of classes'), 'view': 'acl_setup_valid_classes', 'famfam': 'package', 'permissions': [ACLS_CLASS_VIEW_ACL]} -acl_class_acl_list = {'text': _(u'ACLs for class'), 'view': 'acl_class_acl_list', 'args': 'object.gid', 'famfam': 'lock', 'permissions': [ACLS_CLASS_VIEW_ACL]} -acl_class_acl_detail = {'text': _(u'edit'), 'view': 'acls_class_acl_detail', 'args': ['access_object_class.gid', 'object.gid'], 'famfam': 'lock', 'permissions': [ACLS_CLASS_VIEW_ACL]} +acl_class_acl_list = {'text': _(u'ACLs for class'), 'view': 'acl_class_acl_list', 'args': 'object.gid', 'famfam': 'lock_go', 'permissions': [ACLS_CLASS_VIEW_ACL]} +acl_class_acl_detail = {'text': _(u'details'), 'view': 'acl_class_acl_detail', 'args': ['access_object_class.gid', 'object.gid'], 'famfam': 'key_go', 'permissions': [ACLS_CLASS_VIEW_ACL]} acl_class_new_holder_for = {'text': _(u'New holder'), 'view': 'acl_class_new_holder_for', 'args': 'object.gid', 'famfam': 'user', 'permissions': [ACLS_CLASS_EDIT_ACL]} acl_class_grant = {'text': _(u'grant'), 'view': 'acl_class_multiple_grant', 'famfam': 'key_add', 'permissions': [ACLS_CLASS_EDIT_ACL]} acl_class_revoke = {'text': _(u'revoke'), 'view': 'acl_class_multiple_revoke', 'famfam': 'key_delete', 'permissions': [ACLS_CLASS_EDIT_ACL]} @@ -27,10 +27,9 @@ register_links(AccessHolder, [acl_detail]) register_multi_item_links(['acl_detail'], [acl_grant, acl_revoke]) register_setup(acl_setup_valid_classes) -register_links(['acl_setup_valid_classes', 'acl_class_acl_list', 'acl_class_new_holder_for', 'acl_class_acl_detail'], [acl_class_list], menu_name='sidebar') +register_links(['acl_setup_valid_classes', 'acl_class_acl_list', 'acl_class_new_holder_for', 'acl_class_acl_detail'], [acl_class_list], menu_name='secondary_menu') register_links(ClassAccessHolder, [acl_class_acl_detail]) -register_links(AccessObjectClass, [acl_class_acl_list]) -register_links(AccessObjectClass, [acl_class_new_holder_for]) -register_multi_item_links(['acls_class_acl_detail'], [acl_class_grant, acl_class_revoke]) +register_links(AccessObjectClass, [acl_class_acl_list, acl_class_new_holder_for]) +register_multi_item_links(['acl_class_acl_detail'], [acl_class_grant, acl_class_revoke]) diff --git a/apps/acls/urls.py b/apps/acls/urls.py index 1ef00855a7..ff1e9dd4b3 100644 --- a/apps/acls/urls.py +++ b/apps/acls/urls.py @@ -9,7 +9,7 @@ urlpatterns = patterns('acls.views', url(r'^multiple/revoke/$', 'acl_revoke', (), 'acl_multiple_revoke'), url(r'^class/$', 'acl_setup_valid_classes', (), 'acl_setup_valid_classes'), - url(r'^class/details/(?P[.\w]+)/holder/(?P[.\w]+)/$', 'acls_class_acl_detail', (), 'acls_class_acl_detail'), + url(r'^class/details/(?P[.\w]+)/holder/(?P[.\w]+)/$', 'acl_class_acl_detail', (), 'acl_class_acl_detail'), url(r'^class/list_for/(?P[.\w]+)/$', 'acl_class_acl_list', (), 'acl_class_acl_list'), url(r'^class/holder/new/(?P[.\w]+)/$', 'acl_class_new_holder_for', (), 'acl_class_new_holder_for'), diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index 45fd4c5ad7..1d052cfa24 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -129,7 +129,7 @@ register_links(['setup_document_type_metadata', 'document_type_filename_delete', register_links(['document_type_filename_create', 'document_type_filename_list', 'document_type_filename_edit', 'document_type_filename_delete'], [document_type_filename_create], menu_name='sidebar') # Register document links -register_links(Document, [document_edit, document_print, document_delete, document_download, document_find_duplicates, document_clear_transformations, document_create_siblings]) +register_links(Document, [document_view_simple, document_edit, document_print, document_delete, document_download, document_find_duplicates, document_clear_transformations, document_create_siblings]) register_multi_item_links(['document_find_duplicates', 'folder_view', 'index_instance_list', 'document_type_document_list', 'search', 'results', 'document_group_view', 'document_list', 'document_list_recent'], [document_multiple_clear_transformations, document_multiple_delete, document_multiple_download]) # Document Version links diff --git a/apps/linking/__init__.py b/apps/linking/__init__.py index 0354346f7e..cb1c98cbff 100644 --- a/apps/linking/__init__.py +++ b/apps/linking/__init__.py @@ -36,7 +36,7 @@ register_links(['smart_link_acl_list', 'smart_link_new_holder'], [smart_link_new 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, smart_link_acl_list]) -register_links([SmartLink, 'smart_link_list', 'smart_link_create'], [smart_link_list, smart_link_create], menu_name='sidebar') +register_links([SmartLink, 'smart_link_list', 'smart_link_create'], [smart_link_list, smart_link_create], menu_name='secondary_menu') register_links(SmartLinkCondition, [smart_link_condition_edit, smart_link_condition_delete]) 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') diff --git a/apps/permissions/__init__.py b/apps/permissions/__init__.py index 77f5c6119e..6eb0d68be5 100644 --- a/apps/permissions/__init__.py +++ b/apps/permissions/__init__.py @@ -25,7 +25,7 @@ permission_grant = {'text': _(u'grant'), 'view': 'permission_multiple_grant', 'f permission_revoke = {'text': _(u'revoke'), 'view': 'permission_multiple_revoke', 'famfam': 'key_delete', 'permissions': [PERMISSION_PERMISSION_REVOKE]} register_links(Role, [role_edit, role_delete, role_permissions, role_members]) -register_links(['role_members', 'role_list', 'role_view', 'role_create', 'role_edit', 'role_permissions', 'role_delete'], [role_list, role_create], menu_name='sidebar') +register_links(['role_members', 'role_list', 'role_view', 'role_create', 'role_edit', 'role_permissions', 'role_delete'], [role_list, role_create], menu_name='secondary_menu') register_multi_item_links(['role_permissions'], [permission_grant, permission_revoke]) permission_views = ['role_list', 'role_create', 'role_edit', 'role_members', 'role_permissions', 'role_delete'] diff --git a/apps/tags/__init__.py b/apps/tags/__init__.py index 8cfeacf58b..79a04dbd03 100644 --- a/apps/tags/__init__.py +++ b/apps/tags/__init__.py @@ -59,7 +59,7 @@ register_top_menu('tags', link={'text': _(u'tags'), 'view': 'tag_list', 'famfam' register_links(['tag_acl_list', 'tag_new_holder'], [tag_new_holder], menu_name='sidebar') register_links(Document, [tag_document_list], menu_name='form_header') -register_links(['document_tags', 'tag_add_attach', 'tag_remove', 'tag_multiple_remove'], [tag_attach], menu_name='sidebar') +register_links(['document_tags', 'tag_remove', 'tag_multiple_remove', 'tag_attach'], [tag_attach], menu_name='sidebar') register_multi_item_links(['document_tags'], [tag_document_remove_multiple]) class_permissions(Document, [ diff --git a/apps/user_management/__init__.py b/apps/user_management/__init__.py index 133f60df71..fb751fb6c2 100644 --- a/apps/user_management/__init__.py +++ b/apps/user_management/__init__.py @@ -28,11 +28,11 @@ group_multiple_delete = {u'text': _('delete'), 'view': 'group_multiple_delete', group_members = {'text': _(u'members'), 'view': 'group_members', 'args': 'object.id', 'famfam': 'group_link', 'permissions': [PERMISSION_GROUP_EDIT]} register_links(User, [user_edit, user_set_password, user_delete]) -register_links(['user_multiple_set_password', 'user_set_password', 'user_multiple_delete', 'user_delete', 'user_edit', 'user_list', 'user_add'], [user_list, user_add], menu_name=u'sidebar') +register_links(['user_multiple_set_password', 'user_set_password', 'user_multiple_delete', 'user_delete', 'user_edit', 'user_list', 'user_add'], [user_list, user_add], menu_name=u'secondary_menu') register_multi_item_links(['user_list'], [user_multiple_set_password, user_multiple_delete]) register_links(Group, [group_edit, group_members, group_delete]) -register_links(['group_multiple_delete', 'group_delete', 'group_edit', 'group_list', 'group_add', 'group_members'], [group_list, group_add], menu_name=u'sidebar') +register_links(['group_multiple_delete', 'group_delete', 'group_edit', 'group_list', 'group_add', 'group_members'], [group_list, group_add], menu_name=u'secondary_menu') register_multi_item_links(['group_list'], [group_multiple_delete]) user_management_views = [ From 77400fc42fe55c6da3f02b2ab70667aeee7fef30 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 04:47:41 -0400 Subject: [PATCH 08/13] Make api module not dependant on any other --- apps/acls/api.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/acls/api.py b/apps/acls/api.py index 2b72ef6b11..bfcdcf1e7b 100644 --- a/apps/acls/api.py +++ b/apps/acls/api.py @@ -2,8 +2,6 @@ from __future__ import absolute_import from django.contrib.contenttypes.models import ContentType -from .classes import AccessObjectClass - _class_permissions = {} @@ -27,4 +25,4 @@ def get_classes(): """ Return a list of encapsulated classes that have been registered """ - return [AccessObjectClass.encapsulate(cls) for cls in _class_permissions.keys()] + return _class_permissions.keys() From a7f1e081c1d45bf8ac9fa028d8fe4cd48d02db81 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 04:48:17 -0400 Subject: [PATCH 09/13] Refactor the EncapsulatedObject class 'encapsulate' method --- apps/acls/classes.py | 68 +++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/apps/acls/classes.py b/apps/acls/classes.py index 8e8397dfa5..016a4ca797 100644 --- a/apps/acls/classes.py +++ b/apps/acls/classes.py @@ -1,3 +1,5 @@ +from __future__ import absolute_import + import logging import sys import types @@ -16,6 +18,13 @@ _cache = {} class EncapsulatedObject(object): source_object_name = u'source_object' + + @classmethod + def object_key(cls, app_label=None, model=None, pk=None): + if pk: + return '%s.%s.%s.%s' % (cls.__name__, app_label, model, pk) + else: + return '%s.%s.%s' % (cls.__name__, app_label, model) @classmethod def add_to_class(cls, name, value): @@ -28,34 +37,21 @@ class EncapsulatedObject(object): def set_source_object_name(cls, new_name): cls.source_object_name = new_name + #@classmethod + #def encapsulate_list(cls, source_object=None, app_label=None, model=None, pk=None): + + @classmethod - def encapsulate(cls, source_object=None, app_label=None, model=None, pk=None): - if source_object: - source_object = AnonymousUserSingleton.objects.passthru_check(source_object) - content_type = ContentType.objects.get_for_model(source_object) - elif app_label and model: - try: - content_type = ContentType.objects.get(app_label=app_label, model=model) - source_object_model_class = content_type.model_class() - if pk: - source_object = content_type.get_object_for_this_type(pk=pk) - else: - source_object = source_object_model_class - except ContentType.DoesNotExist: - #cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) - #raise cls.DoesNotExist("%s matching query does not exist." % ContentType._meta.object_name) - raise ObjectDoesNotExist("%s matching query does not exist." % ContentType._meta.object_name) - except source_object_model_class.DoesNotExist: - #cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) - #raise cls.DoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name) - raise ObjectDoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name) + def encapsulate(cls, source_object): + source_object = AnonymousUserSingleton.objects.passthru_check(source_object) + content_type = ContentType.objects.get_for_model(source_object) if hasattr(source_object, 'pk'): # Object - object_key = '%s.%s.%s.%s' % (cls.__name__, content_type.app_label, content_type.model, source_object.pk) + object_key = cls.object_key(content_type.app_label, content_type.model, source_object.pk) else: # Class - object_key = '%s.%s.%s' % (cls.__name__, content_type.app_label, content_type.model) + object_key = cls.object_key(content_type.app_label, content_type.model) try: return _cache[object_key] @@ -69,19 +65,34 @@ class EncapsulatedObject(object): elements = gid.split('.') if len(elements) == 3: app_label, model, pk = elements[0], elements[1], elements[2] - object_key = '%s.%s.%s.%s' % (cls.__name__, app_label, model, pk) elif len(elements) == 2: app_label, model = elements[0], elements[1] pk = None - object_key = '%s.%s.%s' % (cls.__name__, app_label, model) + + object_key = cls.object_key(*elements) try: return _cache[object_key] except KeyError: - if pk: - return cls.encapsulate(app_label=app_label, model=model, pk=pk) + try: + content_type = ContentType.objects.get(app_label=app_label, model=model) + except ContentType.DoesNotExist: + #cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) + #raise cls.DoesNotExist("%s matching query does not exist." % ContentType._meta.object_name) + raise ObjectDoesNotExist("%s matching query does not exist." % ContentType._meta.object_name) else: - return cls.encapsulate(app_label=app_label, model=model) + source_object_model_class = content_type.model_class() + if pk: + try: + source_object = content_type.get_object_for_this_type(pk=pk) + except source_object_model_class.DoesNotExist: + #cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), cls.__name__)) + #raise cls.DoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name) + raise ObjectDoesNotExist("%s matching query does not exist." % source_object_model_class._meta.object_name) + else: + source_object = source_object_model_class + + return cls.encapsulate(source_object) def __init__(self, source_object): self.content_type = ContentType.objects.get_for_model(source_object) @@ -112,9 +123,6 @@ class EncapsulatedObject(object): def source_object(self): return getattr(self, self.__class__.source_object_name, None) - def get_class_permissions(self): - return _class_permissions.get(self.content_type.model_class(), []) - class AccessHolder(EncapsulatedObject): source_object_name = u'holder_object' From af962f599882fc98c681c8ea76a6449ffffdb637 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 04:49:10 -0400 Subject: [PATCH 10/13] Add content type icon mapping for anonymous user --- apps/acls/literals.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/acls/literals.py b/apps/acls/literals.py index 03b9587342..5d86e0a013 100644 --- a/apps/acls/literals.py +++ b/apps/acls/literals.py @@ -8,4 +8,5 @@ CONTENT_TYPE_ICON_MAP = { 'folders.folder': 'folder', 'taggit.tag': 'tag_blue', 'linking.smartlink': 'page_link', + 'common.anonymoususersingleton': 'user', } From 86147c234b4b0955d648d6bf62ff0c9585cee293 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 04:49:52 -0400 Subject: [PATCH 11/13] Add 'get_classes' to the DefaultAccessEntry class --- apps/acls/models.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/acls/models.py b/apps/acls/models.py index 656994d780..865e44e567 100644 --- a/apps/acls/models.py +++ b/apps/acls/models.py @@ -15,6 +15,8 @@ from django.shortcuts import get_object_or_404 from permissions.models import StoredPermission from .managers import AccessEntryManager, DefaultAccessEntryManager +from .classes import AccessObjectClass +from .api import get_classes logger = logging.getLogger(__name__) @@ -61,6 +63,10 @@ class DefaultAccessEntry(models.Model): Model that holds the permission, class, actor relationship, that will be added upon the creation of an instance of said class ''' + @classmethod + def get_classes(cls): + return [AccessObjectClass.encapsulate(cls) for cls in get_classes()] + permission = models.ForeignKey(StoredPermission, verbose_name=_(u'permission')) holder_type = models.ForeignKey( From 5230b9ca5368fc939a522856cb58874a2e9c41f3 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 04:51:01 -0400 Subject: [PATCH 12/13] Improve permission granting and revoking messages, improve navigation feedback --- apps/acls/views.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/acls/views.py b/apps/acls/views.py index da813f3e6f..375ab37b6e 100644 --- a/apps/acls/views.py +++ b/apps/acls/views.py @@ -110,7 +110,6 @@ def acl_detail_for(request, actor, obj, navigation_object=None): 'attribute': encapsulate(lambda permission: two_state_template(AccessEntry.objects.has_access(permission, actor, obj))) }, ], - #'hide_link': True, 'hide_object': True, } }, @@ -187,7 +186,7 @@ def acl_grant(request): for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): - title_suffix.append(_(u' and ').join([u'"%s"' % unicode(p) for p in ps])) + title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' to %s') % requester) @@ -281,7 +280,7 @@ def acl_revoke(request): for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): - title_suffix.append(_(u' and ').join([u'"%s"' % unicode(p) for p in ps])) + title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' from %s') % requester) @@ -372,10 +371,10 @@ def acl_new_holder_for(request, obj, extra_context=None, navigation_object=None) # Setup views def acl_setup_valid_classes(request): Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL]) - logger.debug('DefaultAccessEntry.get_classes(): %s' % get_classes()) + logger.debug('DefaultAccessEntry.get_classes(): %s' % DefaultAccessEntry.get_classes()) context = { - 'object_list': get_classes(), + 'object_list': DefaultAccessEntry.get_classes(), 'title': _(u'classes'), 'extra_columns': [ {'name': _(u'class'), 'attribute': encapsulate(lambda x: object_w_content_type_icon(x.source_object))}, @@ -388,7 +387,7 @@ def acl_setup_valid_classes(request): def acl_class_acl_list(request, access_object_class_gid): - Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL, ACLS_CLASS_EDIT_ACL]) + Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL]) access_object_class = AccessObjectClass.get(gid=access_object_class_gid) context = { @@ -400,21 +399,23 @@ def acl_class_acl_list(request, access_object_class_gid): ], 'hide_object': True, 'access_object_class': access_object_class, + 'object': access_object_class, } return render_to_response('generic_list.html', context, context_instance=RequestContext(request)) -def acls_class_acl_detail(request, access_object_class_gid, holder_object_gid): - Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL, ACLS_CLASS_EDIT_ACL]) +def acl_class_acl_detail(request, access_object_class_gid, holder_object_gid): + Permission.objects.check_permissions(request.user, [ACLS_CLASS_VIEW_ACL]) try: actor = AccessHolder.get(gid=holder_object_gid) access_object_class = AccessObjectClass.get(gid=access_object_class_gid) except ObjectDoesNotExist: raise Http404 - permission_list = list(access_object_class.get_class_permissions()) + #permission_list = list(access_object_class.get_class_permissions()) + permission_list = get_class_permissions_for(access_object_class.content_type.model_class()) #TODO : get all globally assigned permission, new function get_permissions_for_holder (roles aware) subtemplates_list = [ { @@ -462,7 +463,7 @@ def acl_class_new_holder_for(request, access_object_class_gid): try: access_holder = ClassAccessHolder.get(form.cleaned_data['holder_gid']) - return HttpResponseRedirect(reverse('acls_class_acl_detail', args=[access_object_class.gid, access_holder.gid])) + return HttpResponseRedirect(reverse('acl_class_acl_detail', args=[access_object_class.gid, access_holder.gid])) except ObjectDoesNotExist: raise Http404 else: @@ -512,7 +513,7 @@ def acl_class_multiple_grant(request): for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): - title_suffix.append(_(u' and ').join([u'"%s"' % unicode(p) for p in ps])) + title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' to %s') % requester) @@ -592,7 +593,7 @@ def acl_class_multiple_revoke(request): for requester, obj_ps in items.items(): for obj, ps in obj_ps.items(): - title_suffix.append(_(u' and ').join([u'"%s"' % unicode(p) for p in ps])) + title_suffix.append(_(u', ').join([u'"%s"' % unicode(p) for p in ps])) title_suffix.append(_(u' for %s') % obj) title_suffix.append(_(u' from %s') % requester) From 239d59ca0cb6a66c5fdcf20ccc46933795b22a00 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 9 Jan 2012 04:56:32 -0400 Subject: [PATCH 13/13] Remove decrepated context arguments --- apps/linking/views.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/linking/views.py b/apps/linking/views.py index 7aacd67a66..5f72d8f393 100644 --- a/apps/linking/views.py +++ b/apps/linking/views.py @@ -359,8 +359,6 @@ def smart_link_new_holder(request, smart_link_pk): smart_link, extra_context={ 'smart_link': smart_link, - 'submit_label': _(u'Select'), - 'submit_icon_famfam': 'tick', 'object': smart_link, }, navigation_object=u'smart_link',