PageRenderTime 67ms CodeModel.GetById 43ms RepoModel.GetById 0ms app.codeStats 1ms

/cms/admin/permissionadmin.py

https://github.com/conrado/django-cms
Python | 181 lines | 138 code | 9 blank | 34 comment | 4 complexity | 67eca20033d5a6d500e0c7897d8018a7 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. from copy import deepcopy
  3. from cms.admin.forms import GlobalPagePermissionAdminForm, PagePermissionInlineAdminForm, ViewRestrictionInlineAdminForm
  4. from cms.exceptions import NoPermissionsException
  5. from cms.models import Page, PagePermission, GlobalPagePermission, PageUser
  6. from cms.utils.conf import get_cms_setting
  7. from cms.utils.helpers import classproperty
  8. from cms.utils.permissions import get_user_permission_level
  9. from django.contrib import admin
  10. from django.contrib.auth.models import User
  11. from django.utils.translation import ugettext as _
  12. PERMISSION_ADMIN_INLINES = []
  13. class TabularInline(admin.TabularInline):
  14. pass
  15. class PagePermissionInlineAdmin(TabularInline):
  16. model = PagePermission
  17. # use special form, so we can override of user and group field
  18. form = PagePermissionInlineAdminForm
  19. classes = ['collapse', 'collapsed']
  20. exclude = ['can_view']
  21. extra = 0 # edit page load time boost
  22. @classproperty
  23. def raw_id_fields(cls):
  24. # Dynamically set raw_id_fields based on settings
  25. threshold = get_cms_setting('RAW_ID_USERS')
  26. if threshold and User.objects.count() > threshold:
  27. return ['user']
  28. return []
  29. def queryset(self, request):
  30. """
  31. Queryset change, so user with global change permissions can see
  32. all permissions. Otherwise can user see only permissions for
  33. peoples which are under him (he can't see his permissions, because
  34. this will lead to violation, when he can add more power to itself)
  35. """
  36. # can see only permissions for users which are under him in tree
  37. ### here a exception can be thrown
  38. try:
  39. qs = PagePermission.objects.subordinate_to_user(request.user)
  40. return qs.filter(can_view=False)
  41. except NoPermissionsException:
  42. return self.objects.get_empty_query_set()
  43. def get_formset(self, request, obj=None, **kwargs):
  44. """
  45. Some fields may be excluded here. User can change only
  46. permissions which are available for him. E.g. if user does not haves
  47. can_publish flag, he can't change assign can_publish permissions.
  48. """
  49. exclude = self.exclude or []
  50. if obj:
  51. if not obj.has_add_permission(request):
  52. exclude.append('can_add')
  53. if not obj.has_delete_permission(request):
  54. exclude.append('can_delete')
  55. if not obj.has_publish_permission(request):
  56. exclude.append('can_publish')
  57. if not obj.has_advanced_settings_permission(request):
  58. exclude.append('can_change_advanced_settings')
  59. if not obj.has_move_page_permission(request):
  60. exclude.append('can_move_page')
  61. formset_cls = super(PagePermissionInlineAdmin, self
  62. ).get_formset(request, obj=None, exclude=exclude, *kwargs)
  63. qs = self.queryset(request)
  64. if obj is not None:
  65. qs = qs.filter(page=obj)
  66. formset_cls._queryset = qs
  67. return formset_cls
  68. class ViewRestrictionInlineAdmin(PagePermissionInlineAdmin):
  69. extra = 0 # edit page load time boost
  70. form = ViewRestrictionInlineAdminForm
  71. verbose_name = _("View restriction")
  72. verbose_name_plural = _("View restrictions")
  73. exclude = [
  74. 'can_add', 'can_change', 'can_delete', 'can_view',
  75. 'can_publish', 'can_change_advanced_settings', 'can_move_page',
  76. 'can_change_permissions'
  77. ]
  78. def get_formset(self, request, obj=None, **kwargs):
  79. """
  80. Some fields may be excluded here. User can change only permissions
  81. which are available for him. E.g. if user does not haves can_publish
  82. flag, he can't change assign can_publish permissions.
  83. """
  84. formset_cls = super(PagePermissionInlineAdmin, self).get_formset(request, obj, **kwargs)
  85. qs = self.queryset(request)
  86. if obj is not None:
  87. qs = qs.filter(page=obj)
  88. formset_cls._queryset = qs
  89. return formset_cls
  90. def queryset(self, request):
  91. """
  92. Returns a QuerySet of all model instances that can be edited by the
  93. admin site. This is used by changelist_view.
  94. """
  95. qs = PagePermission.objects.subordinate_to_user(request.user)
  96. return qs.filter(can_view=True)
  97. class GlobalPagePermissionAdmin(admin.ModelAdmin):
  98. list_display = ['user', 'group', 'can_change', 'can_delete', 'can_publish', 'can_change_permissions']
  99. list_filter = ['user', 'group', 'can_change', 'can_delete', 'can_publish', 'can_change_permissions']
  100. form = GlobalPagePermissionAdminForm
  101. search_fields = ('user__username', 'user__first_name', 'user__last_name', 'group__name')
  102. exclude = []
  103. list_display.append('can_change_advanced_settings')
  104. list_filter.append('can_change_advanced_settings')
  105. class GenericCmsPermissionAdmin(object):
  106. """
  107. Custom mixin for permission-enabled admin interfaces.
  108. """
  109. def update_permission_fieldsets(self, request, obj=None):
  110. """
  111. Nobody can grant more than he haves, so check for user permissions
  112. to Page and User model and render fieldset depending on them.
  113. """
  114. fieldsets = deepcopy(self.fieldsets)
  115. perm_models = (
  116. (Page, _('Page permissions')),
  117. (PageUser, _('User & Group permissions')),
  118. (PagePermission, _('Page permissions management')),
  119. )
  120. for i, perm_model in enumerate(perm_models):
  121. model, title = perm_model
  122. opts, fields = model._meta, []
  123. name = model.__name__.lower()
  124. for t in ('add', 'change', 'delete'):
  125. fn = getattr(opts, 'get_%s_permission' % t)
  126. if request.user.has_perm(opts.app_label + '.' + fn()):
  127. fields.append('can_%s_%s' % (t, name))
  128. if fields:
  129. fieldsets.insert(2 + i, (title, {'fields': (fields,)}))
  130. return fieldsets
  131. def _has_change_permissions_permission(self, request):
  132. """
  133. User is able to add/change objects only if he haves can change
  134. permission on some page.
  135. """
  136. try:
  137. user_level = get_user_permission_level(request.user)
  138. except NoPermissionsException:
  139. return False
  140. return True
  141. def has_add_permission(self, request):
  142. return self._has_change_permissions_permission(request) and \
  143. super(self.__class__, self).has_add_permission(request)
  144. def has_change_permission(self, request, obj=None):
  145. return self._has_change_permissions_permission(request) and \
  146. super(self.__class__, self).has_change_permission(request, obj)
  147. if get_cms_setting('PERMISSION'):
  148. admin.site.register(GlobalPagePermission, GlobalPagePermissionAdmin)
  149. PERMISSION_ADMIN_INLINES.extend([
  150. ViewRestrictionInlineAdmin,
  151. PagePermissionInlineAdmin,
  152. ])