moderation.py 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. from django.contrib import messages
  2. from django.contrib.auth import get_user_model
  3. from django.db import IntegrityError, transaction
  4. from django.shortcuts import redirect, render
  5. from django.utils.translation import ugettext as _
  6. from misago.acl import add_acl
  7. from misago.core.decorators import require_POST
  8. from misago.core.shortcuts import get_object_or_404, validate_slug
  9. from misago.markup import Editor
  10. from misago.users.avatars.dynamic import set_avatar as set_dynamic_avatar
  11. from misago.users.bans import get_user_ban
  12. from misago.users.decorators import deny_guests
  13. from misago.users.forms.rename import ChangeUsernameForm
  14. from misago.users.forms.modusers import (BanForm, ModerateAvatarForm,
  15. ModerateSignatureForm)
  16. from misago.users.models import Ban
  17. from misago.users.permissions.moderation import (allow_rename_user,
  18. allow_moderate_avatar,
  19. allow_moderate_signature,
  20. allow_ban_user,
  21. allow_lift_ban)
  22. from misago.users.permissions.delete import allow_delete_user
  23. from misago.users.signatures import set_user_signature
  24. from misago.users.sites import user_profile
  25. def user_moderation_view(required_permission=None):
  26. def wrap(f):
  27. @deny_guests
  28. @transaction.atomic
  29. def decorator(request, *args, **kwargs):
  30. queryset = get_user_model().objects.select_for_update()
  31. user_id = kwargs.pop('user_id')
  32. kwargs['user'] = get_object_or_404(queryset, id=user_id)
  33. validate_slug(kwargs['user'], kwargs.pop('user_slug'))
  34. add_acl(request.user, kwargs['user'])
  35. if required_permission:
  36. required_permission(request.user, kwargs['user'])
  37. return f(request, *args, **kwargs)
  38. return decorator
  39. return wrap
  40. @user_moderation_view(allow_rename_user)
  41. def rename(request, user):
  42. form = ChangeUsernameForm(user=user)
  43. if request.method == 'POST':
  44. old_username = user.username
  45. form = ChangeUsernameForm(request.POST, user=user)
  46. if form.is_valid():
  47. try:
  48. form.change_username(changed_by=user)
  49. message = _("%(old_username)s's username has been changed.")
  50. message = message % {'old_username': old_username}
  51. messages.success(request, message)
  52. return redirect(user_profile.get_default_link(),
  53. **{'user_slug': user.slug, 'user_id': user.pk})
  54. except IntegrityError:
  55. message = _("Error changing username. Please try again.")
  56. messages.error(request, message)
  57. return render(request, 'misago/modusers/rename.html',
  58. {'profile': user, 'form': form})
  59. @user_moderation_view(allow_moderate_avatar)
  60. def moderate_avatar(request, user):
  61. avatar_locked = user.is_avatar_locked
  62. form = ModerateAvatarForm(instance=user)
  63. if request.method == 'POST':
  64. form = ModerateAvatarForm(request.POST, instance=user)
  65. if form.is_valid():
  66. if not avatar_locked and form.cleaned_data['is_avatar_locked']:
  67. set_dynamic_avatar(user)
  68. user.save(update_fields=(
  69. 'is_avatar_locked',
  70. 'avatar_lock_user_message',
  71. 'avatar_lock_staff_message'
  72. ))
  73. message = _("%(username)s's avatar has been moderated.")
  74. message = message % {'username': user.username}
  75. messages.success(request, message)
  76. if 'stay' not in request.POST:
  77. return redirect(user_profile.get_default_link(),
  78. **{'user_slug': user.slug, 'user_id': user.pk})
  79. return render(request, 'misago/modusers/avatar.html',
  80. {'profile': user, 'form': form})
  81. @user_moderation_view(allow_moderate_signature)
  82. def moderate_signature(request, user):
  83. form = ModerateSignatureForm(instance=user)
  84. if request.method == 'POST':
  85. form = ModerateSignatureForm(request.POST, instance=user)
  86. if form.is_valid():
  87. set_user_signature(user, form.cleaned_data['signature'])
  88. user.save(update_fields=(
  89. 'signature',
  90. 'signature_parsed',
  91. 'signature_checksum',
  92. 'is_signature_locked',
  93. 'signature_lock_user_message',
  94. 'signature_lock_staff_message'
  95. ))
  96. message = _("%(username)s's signature has been moderated.")
  97. message = message % {'username': user.username}
  98. messages.success(request, message)
  99. if 'stay' not in request.POST:
  100. return redirect(user_profile.get_default_link(),
  101. **{'user_slug': user.slug, 'user_id': user.pk})
  102. acl = user.acl
  103. editor = Editor(form['signature'],
  104. allow_blocks=acl['allow_signature_blocks'],
  105. allow_links=acl['allow_signature_links'],
  106. allow_images=acl['allow_signature_images'])
  107. return render(request, 'misago/modusers/signature.html',
  108. {'profile': user, 'form': form, 'editor': editor})
  109. @user_moderation_view(allow_ban_user)
  110. def ban_user(request, user):
  111. form = BanForm(user=user)
  112. if request.method == 'POST':
  113. form = BanForm(request.POST, user=user)
  114. if form.is_valid():
  115. form.ban_user()
  116. message = _("%(username)s has been banned.")
  117. messages.success(request, message % {'username': user.username})
  118. return redirect(user_profile.get_default_link(),
  119. **{'user_slug': user.slug, 'user_id': user.pk})
  120. return render(request, 'misago/modusers/ban.html',
  121. {'profile': user, 'form': form})
  122. @require_POST
  123. @user_moderation_view(allow_lift_ban)
  124. def lift_user_ban(request, user):
  125. user_ban = get_user_ban(user).ban
  126. user_ban.lift()
  127. user_ban.save()
  128. Ban.objects.invalidate_cache()
  129. message = _("%(username)s's ban has been lifted.")
  130. messages.success(request, message % {'username': user.username})
  131. return redirect(user_profile.get_default_link(),
  132. **{'user_slug': user.slug, 'user_id': user.pk})
  133. @require_POST
  134. @user_moderation_view(allow_delete_user)
  135. def delete(request, user):
  136. user.delete(delete_content=True)
  137. message = _("User %(username)s has been deleted.")
  138. messages.success(request, message % {'username': user.username})
  139. return redirect('misago:index')