permsadmin.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. from django.contrib import messages
  2. from django.shortcuts import redirect
  3. from django.utils.translation import gettext_lazy as _
  4. from ...acl.cache import clear_acl_cache
  5. from ...acl.forms import get_permissions_forms
  6. from ...acl.models import Role
  7. from ...acl.views import RoleAdmin, RolesList
  8. from ...admin.views import generic
  9. from ..forms import (
  10. CategoryRoleForm,
  11. CategoryRolesACLFormFactory,
  12. RoleCategoryACLFormFactory,
  13. )
  14. from ..models import Category, CategoryRole, RoleCategoryACL
  15. from .categoriesadmin import CategoriesList, CategoryAdmin
  16. class CategoryRoleAdmin(generic.AdminBaseMixin):
  17. root_link = "misago:admin:permissions:categories:index"
  18. model = CategoryRole
  19. templates_dir = "misago/admin/categoryroles"
  20. message_404 = _("Requested role does not exist.")
  21. class CategoryRolesList(CategoryRoleAdmin, generic.ListView):
  22. ordering = (("name", None),)
  23. class RoleFormMixin:
  24. def real_dispatch(self, request, target):
  25. form = CategoryRoleForm(instance=target)
  26. perms_forms = get_permissions_forms(target)
  27. if request.method == "POST":
  28. perms_forms = get_permissions_forms(target, request.POST)
  29. valid_forms = 0
  30. for permissions_form in perms_forms:
  31. if permissions_form.is_valid():
  32. valid_forms += 1
  33. form = CategoryRoleForm(request.POST, instance=target)
  34. if form.is_valid():
  35. if len(perms_forms) == valid_forms:
  36. new_permissions = {}
  37. for permissions_form in perms_forms:
  38. cleaned_data = permissions_form.cleaned_data
  39. new_permissions[permissions_form.prefix] = cleaned_data
  40. form.instance.permissions = new_permissions
  41. form.instance.save()
  42. messages.success(
  43. request, self.message_submit % {"name": target.name}
  44. )
  45. if "stay" in request.POST:
  46. return redirect(request.path)
  47. return redirect(self.root_link)
  48. form.add_error(None, _("Form contains errors."))
  49. return self.render(
  50. request, {"form": form, "target": target, "perms_forms": perms_forms}
  51. )
  52. class NewCategoryRole(RoleFormMixin, CategoryRoleAdmin, generic.ModelFormView):
  53. message_submit = _('New role "%(name)s" has been saved.')
  54. class EditCategoryRole(RoleFormMixin, CategoryRoleAdmin, generic.ModelFormView):
  55. message_submit = _('Role "%(name)s" has been changed.')
  56. class DeleteCategoryRole(CategoryRoleAdmin, generic.ButtonView):
  57. def check_permissions(self, request, target):
  58. if target.special_role:
  59. message = _('Role "%(name)s" is special role and can\'t be deleted.')
  60. return message % {"name": target.name}
  61. def button_action(self, request, target):
  62. target.delete()
  63. message = _('Role "%(name)s" has been deleted.')
  64. messages.success(request, message % {"name": target.name})
  65. class CategoryPermissions(CategoryAdmin, generic.ModelFormView):
  66. templates_dir = "misago/admin/categoryroles"
  67. template = "categoryroles.html"
  68. def real_dispatch(self, request, target):
  69. category_roles = CategoryRole.objects.order_by("name")
  70. assigned_roles = {}
  71. for acl in target.category_role_set.select_related("category_role"):
  72. assigned_roles[acl.role_id] = acl.category_role
  73. forms = []
  74. forms_are_valid = True
  75. for role in Role.objects.order_by("name"):
  76. FormType = CategoryRolesACLFormFactory(
  77. role, category_roles, assigned_roles.get(role.pk)
  78. )
  79. if request.method == "POST":
  80. forms.append(FormType(request.POST, prefix=role.pk))
  81. if not forms[-1].is_valid():
  82. forms_are_valid = False
  83. else:
  84. forms.append(FormType(prefix=role.pk))
  85. if request.method == "POST" and forms_are_valid:
  86. target.category_role_set.all().delete()
  87. new_permissions = []
  88. for form in forms:
  89. if form.cleaned_data["category_role"]:
  90. new_permissions.append(
  91. RoleCategoryACL(
  92. role=form.role,
  93. category=target,
  94. category_role=form.cleaned_data["category_role"],
  95. )
  96. )
  97. if new_permissions:
  98. RoleCategoryACL.objects.bulk_create(new_permissions)
  99. clear_acl_cache()
  100. message = _("Category %(name)s permissions have been changed.")
  101. messages.success(request, message % {"name": target.name})
  102. if "stay" in request.POST:
  103. return redirect(request.path)
  104. return redirect(self.root_link)
  105. return self.render(request, {"forms": forms, "target": target})
  106. CategoriesList.add_item_action(
  107. name=_("Category permissions"),
  108. icon="fa fa-adjust",
  109. link="misago:admin:categories:nodes:permissions",
  110. style="success",
  111. )
  112. class RoleCategoriesACL(RoleAdmin, generic.ModelFormView):
  113. templates_dir = "misago/admin/categoryroles"
  114. template = "rolecategories.html"
  115. def real_dispatch(self, request, target):
  116. categories = Category.objects.all_categories()
  117. roles = CategoryRole.objects.order_by("name")
  118. if not categories:
  119. messages.info(request, _("No categories exist."))
  120. return redirect(self.root_link)
  121. choices = {}
  122. for choice in target.categories_acls.select_related("category_role"):
  123. choices[choice.category_id] = choice.category_role
  124. forms = []
  125. forms_are_valid = True
  126. for category in categories:
  127. category.level_range = range(category.level - 1)
  128. FormType = RoleCategoryACLFormFactory(
  129. category, roles, choices.get(category.pk)
  130. )
  131. if request.method == "POST":
  132. forms.append(FormType(request.POST, prefix=category.pk))
  133. if not forms[-1].is_valid():
  134. forms_are_valid = False
  135. else:
  136. forms.append(FormType(prefix=category.pk))
  137. if request.method == "POST" and forms_are_valid:
  138. target.categories_acls.all().delete()
  139. new_permissions = []
  140. for form in forms:
  141. if form.cleaned_data["role"]:
  142. new_permissions.append(
  143. RoleCategoryACL(
  144. role=target,
  145. category=form.category,
  146. category_role=form.cleaned_data["role"],
  147. )
  148. )
  149. if new_permissions:
  150. RoleCategoryACL.objects.bulk_create(new_permissions)
  151. clear_acl_cache()
  152. message = _("Category permissions for role %(name)s have been changed.")
  153. messages.success(request, message % {"name": target.name})
  154. if "stay" in request.POST:
  155. return redirect(request.path)
  156. return redirect(self.root_link)
  157. return self.render(request, {"forms": forms, "target": target})
  158. RolesList.add_item_action(
  159. name=_("Categories permissions"),
  160. icon="fa fa-comments-o",
  161. link="misago:admin:permissions:users:categories",
  162. style="success",
  163. )