warnings.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. from django.contrib.auth import get_user_model
  2. from django.core.exceptions import PermissionDenied
  3. from django.utils.translation import ugettext_lazy as _
  4. from misago.acl import algebra
  5. from misago.acl.decorators import return_boolean
  6. from misago.acl.models import Role
  7. from misago.core import forms
  8. from ..models import UserWarning
  9. from .decorators import authenticated_only
  10. """
  11. Admin Permissions Form
  12. """
  13. NO_OWNED_ALL = ((0, _("No")), (1, _("Owned")), (2, _("All")))
  14. class LimitedPermissionsForm(forms.Form):
  15. legend = _("Warnings")
  16. can_see_other_users_warnings = forms.YesNoSwitch(
  17. label=_("Can see other users warnings"))
  18. class PermissionsForm(LimitedPermissionsForm):
  19. can_warn_users = forms.YesNoSwitch(label=_("Can warn users"))
  20. can_be_warned = forms.YesNoSwitch(label=_("Can be warned"), initial=False)
  21. can_cancel_warnings = forms.TypedChoiceField(
  22. label=_("Can cancel warnings"),
  23. coerce=int,
  24. choices=NO_OWNED_ALL,
  25. initial=0)
  26. can_delete_warnings = forms.TypedChoiceField(
  27. label=_("Can delete warnings"),
  28. coerce=int,
  29. choices=NO_OWNED_ALL,
  30. initial=0)
  31. def change_permissions_form(role):
  32. if isinstance(role, Role):
  33. if role.special_role == 'anonymous':
  34. return LimitedPermissionsForm
  35. else:
  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_see_other_users_warnings': 0,
  45. 'can_warn_users': 0,
  46. 'can_cancel_warnings': 0,
  47. 'can_delete_warnings': 0,
  48. 'can_be_warned': 1,
  49. }
  50. new_acl.update(acl)
  51. return algebra.sum_acls(new_acl, roles=roles, key=key_name,
  52. can_see_other_users_warnings=algebra.greater,
  53. can_warn_users=algebra.greater,
  54. can_cancel_warnings=algebra.greater,
  55. can_delete_warnings=algebra.greater,
  56. can_be_warned=algebra.lower
  57. )
  58. """
  59. ACL's for targets
  60. """
  61. def add_acl_to_user(user, target):
  62. target_acl = target.acl_
  63. target_acl['can_see_warnings'] = can_see_warnings(user, target)
  64. target_acl['can_warn'] = can_warn_user(user, target)
  65. target_acl['can_cancel_warnings'] = False
  66. target_acl['can_delete_warnings'] = False
  67. if target_acl['can_warn']:
  68. target_acl['can_moderate'] = True
  69. def add_acl_to_warning(user, target):
  70. target.acl['can_cancel'] = can_cancel_warning(user, target)
  71. target.acl['can_delete'] = can_delete_warning(user, target)
  72. can_moderate = target.acl['can_cancel'] or target.acl['can_delete']
  73. target.acl['can_moderate'] = can_moderate
  74. def register_with(registry):
  75. registry.acl_annotator(get_user_model(), add_acl_to_user)
  76. registry.acl_annotator(UserWarning, add_acl_to_warning)
  77. """
  78. ACL tests
  79. """
  80. def allow_see_warnings(user, target):
  81. if user.is_authenticated() and user.pk == target.pk:
  82. return None
  83. if not user.acl['can_see_other_users_warnings']:
  84. raise PermissionDenied(_("You can't see other users warnings."))
  85. can_see_warnings = return_boolean(allow_see_warnings)
  86. @authenticated_only
  87. def allow_warn_user(user, target):
  88. if not user.acl['can_warn_users']:
  89. raise PermissionDenied(_("You can't warn users."))
  90. if not user.is_superuser and (target.is_staff or target.is_superuser):
  91. raise PermissionDenied(_("You can't warn administrators."))
  92. if not target.acl['can_be_warned']:
  93. message = _("%(user)s can't be warned.")
  94. raise PermissionDenied(message % {'user': target.username})
  95. can_warn_user = return_boolean(allow_warn_user)
  96. @authenticated_only
  97. def allow_cancel_warning(user, target):
  98. if user.is_anonymous() or not user.acl['can_cancel_warnings']:
  99. raise PermissionDenied(_("You can't cancel warnings."))
  100. if user.acl['can_cancel_warnings'] == 1:
  101. if target.giver_id != user.pk:
  102. message = _("You can't cancel warnings issued by other users.")
  103. raise PermissionDenied(message)
  104. if target.is_canceled:
  105. raise PermissionDenied(_("This warning is already canceled."))
  106. can_cancel_warning = return_boolean(allow_cancel_warning)
  107. @authenticated_only
  108. def allow_delete_warning(user, target):
  109. if user.is_anonymous() or not user.acl['can_delete_warnings']:
  110. raise PermissionDenied(_("You can't delete warnings."))
  111. if user.acl['can_delete_warnings'] == 1:
  112. if target.giver_id != user.pk:
  113. message = _("You can't delete warnings issued by other users.")
  114. raise PermissionDenied(message)
  115. can_delete_warning = return_boolean(allow_delete_warning)