123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- from django.core.urlresolvers import reverse
- from django.contrib import messages
- from django.contrib.auth import get_user_model
- from django.db import IntegrityError, transaction
- from django.shortcuts import redirect, render
- from django.utils.translation import ugettext as _
- from misago.acl import add_acl
- from misago.core.decorators import require_POST
- from misago.core.shortcuts import get_object_or_404, validate_slug
- from misago.core.utils import clean_return_path
- from misago.markup import Editor
- from misago.notifications import notify_user
- from misago.users.avatars.dynamic import set_avatar as set_dynamic_avatar
- from misago.users import warnings
- from misago.users.bans import get_user_ban
- from misago.users.decorators import deny_guests
- from misago.users.forms.rename import ChangeUsernameForm
- from misago.users.forms.modusers import (BanForm, ModerateAvatarForm,
- ModerateSignatureForm, WarnUserForm)
- from misago.users.models import Ban
- from misago.users.pages import user_profile
- from misago.users.permissions.moderation import (allow_rename_user,
- allow_moderate_avatar,
- allow_moderate_signature,
- allow_ban_user,
- allow_lift_ban)
- from misago.users.permissions.warnings import (allow_warn_user,
- allow_see_warnings,
- allow_cancel_warning,
- allow_delete_warning)
- from misago.users.permissions.delete import allow_delete_user
- from misago.users.signatures import set_user_signature
- def user_moderation_view(required_permission=None):
- def wrap(f):
- @deny_guests
- @transaction.atomic
- def decorator(request, *args, **kwargs):
- queryset = get_user_model().objects.select_for_update()
- user_id = kwargs.pop('user_id')
- kwargs['user'] = get_object_or_404(queryset, id=user_id)
- validate_slug(kwargs['user'], kwargs.pop('user_slug'))
- add_acl(request.user, kwargs['user'])
- if required_permission:
- required_permission(request.user, kwargs['user'])
- return f(request, *args, **kwargs)
- return decorator
- return wrap
- def moderation_return_path(request, user):
- return_path = clean_return_path(request)
- if not return_path:
- return reverse(user_profile.get_default_link(),
- kwargs={'user_slug': user.slug, 'user_id': user.pk})
- return return_path
- @user_moderation_view(allow_warn_user)
- def warn(request, user, reason=None):
- return_path = moderation_return_path(request, user)
- if warnings.is_user_warning_level_max(user):
- message = _("%(user)s has maximum warning "
- "level and can't be warned.")
- message = message % {'user': user.username}
- messages.info(request, message)
- return redirect(return_path)
- form = WarnUserForm(initial={'reason': reason})
- if request.method == 'POST':
- form = WarnUserForm(request.POST)
- if form.is_valid():
- warnings.warn_user(request.user, user, form.cleaned_data['reason'])
- notify_user(user,
- _("%(user)s has given you an warning."),
- reverse('misago:user_warnings', kwargs={
- 'user_slug': user.slug, 'user_id': user.pk
- }),
- "warnings_%s" % user.pk,
- formats={'user': request.user.username},
- sender=request.user)
- message = _("%(user)s has been warned.")
- message = message % {'user': user.username}
- messages.success(request, message)
- return redirect(return_path)
- warning_levels = warnings.get_warning_levels()
- current_level = warning_levels[user.warning_level]
- next_level = warning_levels[user.warning_level + 1]
- return render(request, 'misago/modusers/warn.html', {
- 'profile': user,
- 'form': form,
- 'return_path': return_path,
- 'current_level': current_level,
- 'next_level': next_level
- })
- def warning_moderation_view(required_permission=None):
- def wrap(f):
- @deny_guests
- @transaction.atomic
- def decorator(request, *args, **kwargs):
- queryset = kwargs['user'].warnings
- warning_id = kwargs.pop('warning_id')
- kwargs['warning'] = get_object_or_404(queryset, id=warning_id)
- add_acl(request.user, kwargs['warning'])
- required_permission(request.user, kwargs['warning'])
- response = f(request, *args, **kwargs)
- if response:
- return response
- else:
- return_path = moderation_return_path(request, kwargs['user'])
- return redirect(return_path)
- return decorator
- return wrap
- @user_moderation_view(allow_see_warnings)
- @warning_moderation_view(allow_cancel_warning)
- def cancel_warning(request, user, warning):
- warnings.cancel_warning(request.user, user, warning)
- message = _("%(user)s's warning has been canceled.")
- message = message % {'user': user.username}
- messages.success(request, message)
- notify_user(user,
- _("%(user)s has canceled your warning."),
- reverse('misago:user_warnings', kwargs={
- 'user_slug': user.slug, 'user_id': user.pk
- }),
- "warnings_%s" % user.pk,
- formats={'user': request.user.username},
- sender=request.user)
- @user_moderation_view(allow_see_warnings)
- @warning_moderation_view(allow_delete_warning)
- def delete_warning(request, user, warning):
- warnings.delete_warning(request.user, user, warning)
- message = _("%(user)s's warning has been deleted.")
- message = message % {'user': user.username}
- messages.success(request, message)
- notify_user(user,
- _("%(user)s has deleted your warning."),
- reverse('misago:user_warnings', kwargs={
- 'user_slug': user.slug, 'user_id': user.pk
- }),
- "warnings_%s" % user.pk,
- formats={'user': request.user.username},
- sender=request.user)
- @user_moderation_view(allow_rename_user)
- def rename(request, user):
- return_path = moderation_return_path(request, user)
- form = ChangeUsernameForm(user=user)
- if request.method == 'POST':
- old_username = user.username
- form = ChangeUsernameForm(request.POST, user=user)
- if form.is_valid():
- try:
- form.change_username(changed_by=request.user)
- notify_user(user,
- _("%(user)s has changed your name to %(newname)s."),
- reverse('misago:user_warnings', kwargs={
- 'user_slug': user.slug, 'user_id': user.pk
- }),
- "name_history_%s" % user.pk,
- formats={
- 'user': request.user.username,
- 'newname': user.username,
- },
- sender=request.user)
- message = _("%(old_username)s's username has been changed.")
- message = message % {'old_username': old_username}
- messages.success(request, message)
- return redirect(return_path)
- except IntegrityError:
- message = _("Error changing username. Please try again.")
- messages.error(request, message)
- return render(request, 'misago/modusers/rename.html',
- {'profile': user, 'form': form, 'return_path': return_path})
- @user_moderation_view(allow_moderate_avatar)
- def moderate_avatar(request, user):
- return_path = moderation_return_path(request, user)
- avatar_locked = user.is_avatar_locked
- form = ModerateAvatarForm(instance=user)
- if request.method == 'POST':
- form = ModerateAvatarForm(request.POST, instance=user)
- if form.is_valid():
- if not avatar_locked and form.cleaned_data['is_avatar_locked']:
- set_dynamic_avatar(user)
- user.save(update_fields=(
- 'is_avatar_locked',
- 'avatar_lock_user_message',
- 'avatar_lock_staff_message'
- ))
- if avatar_locked != user.is_avatar_locked:
- if user.is_avatar_locked:
- message = _("%(user)s has locked your avatar.")
- else:
- message = _("%(user)s has unlocked your avatar.")
- notify_user(user,
- message,
- reverse('misago:usercp_change_avatar'),
- "usercp_avatar_%s" % user.pk,
- formats={'user': request.user.username},
- sender=request.user)
- message = _("%(user)s's avatar has been moderated.")
- message = message % {'user': user.username}
- messages.success(request, message)
- if 'stay' not in request.POST:
- return redirect(return_path)
- return render(request, 'misago/modusers/avatar.html',
- {'profile': user, 'form': form, 'return_path': return_path})
- @user_moderation_view(allow_moderate_signature)
- def moderate_signature(request, user):
- return_path = moderation_return_path(request, user)
- form = ModerateSignatureForm(instance=user)
- if request.method == 'POST':
- form = ModerateSignatureForm(request.POST, instance=user)
- if form.is_valid():
- set_user_signature(request, user, form.cleaned_data['signature'])
- user.save(update_fields=(
- 'signature',
- 'signature_parsed',
- 'signature_checksum',
- 'is_signature_locked',
- 'signature_lock_user_message',
- 'signature_lock_staff_message'
- ))
- message = _("%(user)s's signature has been moderated.")
- message = message % {'user': user.username}
- messages.success(request, message)
- notify_user(user,
- _("%(user)s has moderated your signature."),
- reverse('misago:usercp_edit_signature'),
- "usercp_signature_%s" % user.pk,
- formats={'user': request.user.username},
- sender=request.user)
- if 'stay' not in request.POST:
- return redirect(return_path)
- acl = user.acl
- editor = Editor(form['signature'],
- allow_blocks=acl['allow_signature_blocks'],
- allow_links=acl['allow_signature_links'],
- allow_images=acl['allow_signature_images'])
- return render(request, 'misago/modusers/signature.html', {
- 'profile': user,
- 'form': form,
- 'editor': editor,
- 'return_path': return_path
- })
- @user_moderation_view(allow_ban_user)
- def ban_user(request, user):
- return_path = moderation_return_path(request, user)
- form = BanForm(user=user)
- if request.method == 'POST':
- form = BanForm(request.POST, user=user)
- if form.is_valid():
- form.ban_user()
- message = _("%(user)s has been banned.")
- messages.success(request, message % {'user': user.username})
- return redirect(return_path)
- return render(request, 'misago/modusers/ban.html',
- {'profile': user, 'form': form, 'return_path': return_path})
- @require_POST
- @user_moderation_view(allow_lift_ban)
- def lift_user_ban(request, user):
- return_path = moderation_return_path(request, user)
- user_ban = get_user_ban(user).ban
- user_ban.lift()
- user_ban.save()
- Ban.objects.invalidate_cache()
- message = _("%(user)s's ban has been lifted.")
- messages.success(request, message % {'user': user.username})
- return redirect(return_path)
- @require_POST
- @user_moderation_view(allow_delete_user)
- def delete(request, user):
- user.delete(delete_content=True)
- message = _("User %(user)s has been deleted.")
- messages.success(request, message % {'user': user.username})
- return redirect('misago:index')
|