moderation.py 5.3 KB

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