delete.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. from datetime import timedelta
  2. from django import forms
  3. from django.contrib.auth import get_user_model
  4. from django.core.exceptions import PermissionDenied
  5. from django.utils import timezone
  6. from django.utils.translation import gettext_lazy as _
  7. from django.utils.translation import ngettext
  8. from misago.acl import algebra
  9. from misago.acl.decorators import return_boolean
  10. from misago.acl.models import Role
  11. from misago.conf import settings
  12. __all__ = [
  13. "allow_delete_user",
  14. "can_delete_user",
  15. "allow_delete_own_account",
  16. "can_delete_own_account",
  17. ]
  18. class PermissionsForm(forms.Form):
  19. legend = _("Deleting users")
  20. can_delete_users_newer_than = forms.IntegerField(
  21. label=_("Maximum age of deleted account (in days)"),
  22. help_text=_("Enter zero to disable this check."),
  23. min_value=0,
  24. initial=0,
  25. )
  26. can_delete_users_with_less_posts_than = forms.IntegerField(
  27. label=_("Maximum number of posts on deleted account"),
  28. help_text=_("Enter zero to disable this check."),
  29. min_value=0,
  30. initial=0,
  31. )
  32. def change_permissions_form(role):
  33. if isinstance(role, Role) and role.special_role != "anonymous":
  34. return PermissionsForm
  35. else:
  36. return None
  37. def build_acl(acl, roles, key_name):
  38. new_acl = {
  39. "can_delete_users_newer_than": 0,
  40. "can_delete_users_with_less_posts_than": 0,
  41. }
  42. new_acl.update(acl)
  43. return algebra.sum_acls(
  44. new_acl,
  45. roles=roles,
  46. key=key_name,
  47. can_delete_users_newer_than=algebra.greater,
  48. can_delete_users_with_less_posts_than=algebra.greater,
  49. )
  50. def add_acl_to_user(user_acl, target):
  51. target.acl["can_delete"] = can_delete_user(user_acl, target)
  52. if target.acl["can_delete"]:
  53. target.acl["can_moderate"] = True
  54. def register_with(registry):
  55. registry.acl_annotator(get_user_model(), add_acl_to_user)
  56. def allow_delete_user(user_acl, target):
  57. newer_than = user_acl["can_delete_users_newer_than"]
  58. less_posts_than = user_acl["can_delete_users_with_less_posts_than"]
  59. if not newer_than and not less_posts_than:
  60. raise PermissionDenied(_("You can't delete users."))
  61. if user_acl["user_id"] == target.id:
  62. raise PermissionDenied(_("You can't delete your account."))
  63. if target.is_staff or target.is_superuser:
  64. raise PermissionDenied(_("You can't delete administrators."))
  65. if newer_than:
  66. if target.joined_on < timezone.now() - timedelta(days=newer_than):
  67. message = ngettext(
  68. "You can't delete users that are members for more than %(days)s day.",
  69. "You can't delete users that are members for more than %(days)s days.",
  70. newer_than,
  71. )
  72. raise PermissionDenied(message % {"days": newer_than})
  73. if less_posts_than:
  74. if target.posts > less_posts_than:
  75. message = ngettext(
  76. "You can't delete users that made more than %(posts)s post.",
  77. "You can't delete users that made more than %(posts)s posts.",
  78. less_posts_than,
  79. )
  80. raise PermissionDenied(message % {"posts": less_posts_than})
  81. can_delete_user = return_boolean(allow_delete_user)
  82. def allow_delete_own_account(user, target):
  83. if not settings.MISAGO_ENABLE_DELETE_OWN_ACCOUNT and not user.is_deleting_account:
  84. raise PermissionDenied(_("You can't delete your account."))
  85. if user.id != target.id:
  86. raise PermissionDenied(_("You can't delete other users accounts."))
  87. if user.is_staff or user.is_superuser:
  88. raise PermissionDenied(
  89. _("You can't delete your account because you are an administrator.")
  90. )
  91. can_delete_own_account = return_boolean(allow_delete_own_account)