/cms/admin/permissionadmin.py

https://github.com/daonb/django-cms · Python · 148 lines · 125 code · 6 blank · 17 comment · 1 complexity · fb1003c3357e19d6ded1f5634fd047c3 MD5 · raw file

  1. from django.conf import settings
  2. from cms.admin.forms import GlobalPagePermissionAdminForm, \
  3. PagePermissionInlineAdminForm
  4. from cms.admin.models import BaseInlineFormSetWithQuerySet
  5. from cms.exceptions import NoPermissionsException
  6. from cms.models import Page, PagePermission, GlobalPagePermission, PageUser
  7. from cms.utils.permissions import get_user_permission_level
  8. from copy import deepcopy
  9. from django.contrib import admin
  10. from django.template.defaultfilters import title
  11. from django.utils.translation import ugettext as _
  12. PAGE_ADMIN_INLINES = []
  13. ################################################################################
  14. # Permissions
  15. ################################################################################
  16. class PagePermissionInlineAdmin(admin.TabularInline):
  17. model = PagePermission
  18. # use special form, so we can override of user and group field
  19. form = PagePermissionInlineAdminForm
  20. # use special formset, so we can use queryset defined here
  21. formset = BaseInlineFormSetWithQuerySet
  22. classes = ['collapse', 'collapsed']
  23. def __init__(self, *args, **kwargs):
  24. super(PagePermissionInlineAdmin, self).__init__(*args, **kwargs)
  25. def queryset(self, request):
  26. """Queryset change, so user with global change permissions can see
  27. all permissions. Otherwise can user see only permissions for
  28. peoples which are under him (he can't see his permissions, because
  29. this will lead to violation, when he can add more power to itself)
  30. """
  31. # can see only permissions for users which are under him in tree
  32. qs = PagePermission.objects.subordinate_to_user(request.user)
  33. return qs
  34. def get_fieldsets(self, request, obj=None):
  35. """Request formset with given obj.
  36. """
  37. if self.declared_fieldsets:
  38. return self.declared_fieldsets
  39. form = self.get_formset(request, obj).form
  40. return [(None, {'fields': form.base_fields.keys()})]
  41. def get_formset(self, request, obj=None, **kwargs):
  42. """Some fields may be excluded here. User can change only
  43. permissions which are available for him. E.g. if user does not haves
  44. can_publish flag, he can't change assign can_publish permissions.
  45. Seems django doesn't cares about queryset defined here - its
  46. probably a bug, so monkey patching again.. Assign use_queryset
  47. attribute to FormSet, our overiden formset knows how to handle this,
  48. @see BaseInlineFormSetWithQuerySet for more details.
  49. """
  50. if obj:
  51. self.exclude = []
  52. if not obj.has_add_permission(request):
  53. self.exclude.append('can_add')
  54. if not obj.has_delete_permission(request):
  55. self.exclude.append('can_delete')
  56. if not obj.has_publish_permission(request):
  57. self.exclude.append('can_publish')
  58. if not obj.has_advanced_settings_permission(request):
  59. self.exclude.append('can_change_advanced_settings')
  60. if not obj.has_move_page_permission(request):
  61. self.exclude.append('can_move_page')
  62. if not settings.CMS_MODERATOR or not obj.has_moderate_permission(request):
  63. self.exclude.append('can_moderate')
  64. FormSet = super(PagePermissionInlineAdmin, self).get_formset(request, obj=None, **kwargs)
  65. # asign queryset
  66. FormSet.use_queryset = self.queryset(request)
  67. return FormSet
  68. if settings.CMS_PERMISSION:
  69. PAGE_ADMIN_INLINES.append(PagePermissionInlineAdmin)
  70. class GlobalPagePermissionAdmin(admin.ModelAdmin):
  71. list_display = ['user', 'group', 'can_change', 'can_delete', 'can_publish', 'can_change_permissions']
  72. list_filter = ['user', 'group', 'can_change', 'can_delete', 'can_publish', 'can_change_permissions']
  73. form = GlobalPagePermissionAdminForm
  74. search_fields = ('user__username', 'user__firstname', 'user__lastname', 'group__name')
  75. exclude = []
  76. list_display.append('can_change_advanced_settings')
  77. list_filter.append('can_change_advanced_settings')
  78. if settings.CMS_MODERATOR:
  79. list_display.append('can_moderate')
  80. list_filter.append('can_moderate')
  81. else:
  82. exclude.append('can_moderate')
  83. if settings.CMS_PERMISSION:
  84. admin.site.register(GlobalPagePermission, GlobalPagePermissionAdmin)
  85. class GenericCmsPermissionAdmin(object):
  86. def update_permission_fieldsets(self, request, obj=None):
  87. """Nobody can grant more than he haves, so check for user
  88. permissions to Page and User model and render fieldset depending on
  89. them.
  90. """
  91. fieldsets = deepcopy(self.fieldsets)
  92. models = (
  93. (Page, _('Page permissions')),
  94. (PageUser, _('User & Group permissions')),
  95. (PagePermission, _('Page permissions management')),
  96. )
  97. i = 0
  98. for model, title in models:
  99. opts, fields = model._meta, []
  100. name = model.__name__.lower()
  101. for t in ('add', 'change', 'delete'):
  102. fn = getattr(opts, 'get_%s_permission' % t)
  103. if request.user.has_perm(opts.app_label + '.' + fn()):
  104. fields.append('can_%s_%s' % (t, name))
  105. if fields:
  106. fieldsets.insert(2 + i, (title, {'fields': (fields,)}))
  107. i += 1
  108. return fieldsets
  109. def _has_change_permissions_permission(self, request):
  110. """User is able to add/change objects only if he haves can change
  111. permission on some page.
  112. """
  113. try:
  114. user_level = get_user_permission_level(request.user)
  115. except NoPermissionsException:
  116. return False
  117. return True
  118. def has_add_permission(self, request):
  119. return self._has_change_permissions_permission(request) and \
  120. super(self.__class__, self).has_add_permission(request)
  121. def has_change_permission(self, request, obj=None):
  122. return self._has_change_permissions_permission(request) and \
  123. super(self.__class__, self).has_change_permission(request, obj)