moderation.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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 require_target_type, return_boolean
  9. from misago.acl.models import Role
  10. from misago.core import forms
  11. from misago.users.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_ban_users = forms.YesNoSwitch(label=_("Can ban users"))
  19. max_ban_length = forms.IntegerField(
  20. label=_("Max length, in days, of imposed ban"),
  21. help_text=_("Enter zero to let moderators impose permanent bans."),
  22. min_value=0,
  23. initial=0)
  24. can_lift_bans = forms.YesNoSwitch(label=_("Can lift bans"))
  25. max_lifted_ban_length = forms.IntegerField(
  26. label=_("Max length, in days, of lifted ban"),
  27. help_text=_("Enter zero to let moderators lift permanent bans."),
  28. min_value=0,
  29. initial=0)
  30. def change_permissions_form(role):
  31. if isinstance(role, Role) and role.special_role != 'anonymous':
  32. return PermissionsForm
  33. else:
  34. return None
  35. """
  36. ACL Builder
  37. """
  38. def build_acl(acl, roles, key_name):
  39. new_acl = {
  40. 'can_rename_users': 0,
  41. 'can_ban_users': 0,
  42. 'max_ban_length': 2,
  43. 'can_lift_bans': 0,
  44. 'max_lifted_ban_length': 2,
  45. }
  46. new_acl.update(acl)
  47. return algebra.sum_acls(
  48. new_acl, roles=roles, key=key_name,
  49. can_rename_users=algebra.greater,
  50. can_ban_users=algebra.greater,
  51. max_ban_length=algebra.greater_or_zero,
  52. can_lift_bans=algebra.greater,
  53. max_lifted_ban_length=algebra.greater_or_zero
  54. )
  55. """
  56. ACL's for targets
  57. """
  58. @require_target_type(get_user_model())
  59. def add_acl_to_target(user, acl, target):
  60. target.acl_['can_rename'] = can_rename_user(user, target)
  61. target.acl_['can_ban'] = can_ban_user(user, target)
  62. target.acl_['max_ban_length'] = user.acl['max_ban_length']
  63. target.acl_['can_lift_ban'] = can_lift_ban(user, target)
  64. for permission in ('can_rename', 'can_ban'):
  65. if target.acl_[permission]:
  66. target.acl_['can_moderate'] = True
  67. break
  68. """
  69. ACL tests
  70. """
  71. def allow_rename_user(user, target):
  72. if not user.acl['can_rename_users']:
  73. raise PermissionDenied(_("You can't rename users."))
  74. if not user.is_superuser and (target.is_staff or target.is_superuser):
  75. raise PermissionDenied(_("You can't rename administrators."))
  76. can_rename_user = return_boolean(allow_rename_user)
  77. def allow_ban_user(user, target):
  78. if not user.acl['can_ban_users']:
  79. raise PermissionDenied(_("You can't ban users."))
  80. if target.is_staff or target.is_superuser:
  81. raise PermissionDenied(_("You can't ban administrators."))
  82. can_ban_user = return_boolean(allow_ban_user)
  83. def allow_lift_ban(user, target):
  84. if not user.acl['can_lift_bans']:
  85. raise PermissionDenied(_("You can't lift bans."))
  86. ban = get_user_ban(target)
  87. if not ban:
  88. raise PermissionDenied(_("This user is not banned."))
  89. if user.acl['max_lifted_ban_length']:
  90. expiration_limit = timedelta(days=user.acl['max_lifted_ban_length'])
  91. lift_cutoff = (timezone.now() + expiration_limit).date()
  92. if not ban.valid_until:
  93. raise PermissionDenied(_("You can't lift permanent bans."))
  94. elif ban.valid_until > lift_cutoff:
  95. message = _("You can't lift bans that "
  96. "expire after %(expiration)s.")
  97. message = message % {'expiration': format_date(lift_cutoff)}
  98. raise PermissionDenied(message)
  99. can_lift_ban = return_boolean(allow_lift_ban)