warnings.py 4.5 KB

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