moderation.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  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.template.defaultfilters import date as format_date
  6. from django.utils import timezone
  7. from django.utils.translation import ugettext_lazy as _
  8. from misago.acl import algebra
  9. from misago.acl.decorators import return_boolean
  10. from misago.acl.models import Role
  11. from misago.core.forms import YesNoSwitch
  12. from misago.users.bans import get_user_ban
  13. __all__ = [
  14. 'allow_rename_user',
  15. 'can_rename_user',
  16. 'allow_moderate_avatar',
  17. 'can_moderate_avatar',
  18. 'allow_moderate_signature',
  19. 'can_moderate_signature',
  20. 'allow_ban_user',
  21. 'can_ban_user',
  22. 'allow_lift_ban',
  23. 'can_lift_ban',
  24. ]
  25. """
  26. Admin Permissions Form
  27. """
  28. class PermissionsForm(forms.Form):
  29. legend = _("Users moderation")
  30. can_rename_users = YesNoSwitch(label=_("Can rename users"))
  31. can_moderate_avatars = YesNoSwitch(label=_("Can moderate avatars"))
  32. can_moderate_signatures = YesNoSwitch(label=_("Can moderate signatures"))
  33. can_ban_users = YesNoSwitch(label=_("Can ban users"))
  34. max_ban_length = forms.IntegerField(
  35. label=_("Max length, in days, of imposed ban"),
  36. help_text=_("Enter zero to let moderators impose permanent bans."),
  37. min_value=0,
  38. initial=0,
  39. )
  40. can_lift_bans = YesNoSwitch(label=_("Can lift bans"))
  41. max_lifted_ban_length = forms.IntegerField(
  42. label=_("Max length, in days, of lifted ban"),
  43. help_text=_("Enter zero to let moderators lift permanent bans."),
  44. min_value=0,
  45. initial=0,
  46. )
  47. def change_permissions_form(role):
  48. if isinstance(role, Role) and role.special_role != 'anonymous':
  49. return PermissionsForm
  50. else:
  51. return None
  52. """
  53. ACL Builder
  54. """
  55. def build_acl(acl, roles, key_name):
  56. new_acl = {
  57. 'can_rename_users': 0,
  58. 'can_moderate_avatars': 0,
  59. 'can_moderate_signatures': 0,
  60. 'can_ban_users': 0,
  61. 'max_ban_length': 2,
  62. 'can_lift_bans': 0,
  63. 'max_lifted_ban_length': 2,
  64. }
  65. new_acl.update(acl)
  66. return algebra.sum_acls(
  67. new_acl,
  68. roles=roles,
  69. key=key_name,
  70. can_rename_users=algebra.greater,
  71. can_moderate_avatars=algebra.greater,
  72. can_moderate_signatures=algebra.greater,
  73. can_ban_users=algebra.greater,
  74. max_ban_length=algebra.greater_or_zero,
  75. can_lift_bans=algebra.greater,
  76. max_lifted_ban_length=algebra.greater_or_zero,
  77. )
  78. """
  79. ACL's for targets
  80. """
  81. def add_acl_to_user(user, target):
  82. target.acl['can_rename'] = can_rename_user(user, target)
  83. target.acl['can_moderate_avatar'] = can_moderate_avatar(user, target)
  84. target.acl['can_moderate_signature'] = can_moderate_signature(user, target)
  85. target.acl['can_ban'] = can_ban_user(user, target)
  86. target.acl['max_ban_length'] = user.acl_cache['max_ban_length']
  87. target.acl['can_lift_ban'] = can_lift_ban(user, target)
  88. mod_permissions = [
  89. 'can_rename',
  90. 'can_moderate_avatar',
  91. 'can_moderate_signature',
  92. 'can_ban',
  93. ]
  94. for permission in mod_permissions:
  95. if target.acl[permission]:
  96. target.acl['can_moderate'] = True
  97. break
  98. def register_with(registry):
  99. registry.acl_annotator(get_user_model(), add_acl_to_user)
  100. """
  101. ACL tests
  102. """
  103. def allow_rename_user(user, target):
  104. if not user.acl_cache['can_rename_users']:
  105. raise PermissionDenied(_("You can't rename users."))
  106. if not user.is_superuser and (target.is_staff or target.is_superuser):
  107. raise PermissionDenied(_("You can't rename administrators."))
  108. can_rename_user = return_boolean(allow_rename_user)
  109. def allow_moderate_avatar(user, target):
  110. if not user.acl_cache['can_moderate_avatars']:
  111. raise PermissionDenied(_("You can't moderate avatars."))
  112. if not user.is_superuser and (target.is_staff or target.is_superuser):
  113. raise PermissionDenied(_("You can't moderate administrators avatars."))
  114. can_moderate_avatar = return_boolean(allow_moderate_avatar)
  115. def allow_moderate_signature(user, target):
  116. if not user.acl_cache['can_moderate_signatures']:
  117. raise PermissionDenied(_("You can't moderate signatures."))
  118. if not user.is_superuser and (target.is_staff or target.is_superuser):
  119. message = _("You can't moderate administrators signatures.")
  120. raise PermissionDenied(message)
  121. can_moderate_signature = return_boolean(allow_moderate_signature)
  122. def allow_ban_user(user, target):
  123. if not user.acl_cache['can_ban_users']:
  124. raise PermissionDenied(_("You can't ban users."))
  125. if target.is_staff or target.is_superuser:
  126. raise PermissionDenied(_("You can't ban administrators."))
  127. can_ban_user = return_boolean(allow_ban_user)
  128. def allow_lift_ban(user, target):
  129. if not user.acl_cache['can_lift_bans']:
  130. raise PermissionDenied(_("You can't lift bans."))
  131. ban = get_user_ban(target)
  132. if not ban:
  133. raise PermissionDenied(_("This user is not banned."))
  134. if user.acl_cache['max_lifted_ban_length']:
  135. expiration_limit = timedelta(days=user.acl_cache['max_lifted_ban_length'])
  136. lift_cutoff = (timezone.now() + expiration_limit).date()
  137. if not ban.valid_until:
  138. raise PermissionDenied(_("You can't lift permanent bans."))
  139. elif ban.valid_until > lift_cutoff:
  140. message = _("You can't lift bans that expire after %(expiration)s.")
  141. raise PermissionDenied(message % {'expiration': format_date(lift_cutoff)})
  142. can_lift_ban = return_boolean(allow_lift_ban)