123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- from django.contrib import messages
- from django.contrib.auth import get_user_model, update_session_auth_hash
- from django.db import transaction
- from django.http import JsonResponse
- from django.shortcuts import redirect
- from django.utils.translation import gettext_lazy as _
- from ....acl.useracl import get_user_acl
- from ....admin.auth import authorize_admin
- from ....admin.views import generic
- from ....categories.models import Category
- from ....core.mail import mail_users
- from ....core.pgutils import chunk_queryset
- from ....threads.models import Thread
- from ...avatars.dynamic import set_avatar as set_dynamic_avatar
- from ...datadownloads import request_user_data_download, user_has_data_download_request
- from ...models import Ban
- from ...profilefields import profilefields
- from ...setupnewuser import setup_new_user
- from ...signatures import set_user_signature
- from ..forms import (
- BanUsersForm,
- EditUserForm,
- EditUserFormFactory,
- NewUserForm,
- create_filter_users_form,
- )
- from ..tasks import delete_user_with_content
- User = get_user_model()
- class UserAdmin(generic.AdminBaseMixin):
- root_link = "misago:admin:users:index"
- templates_dir = "misago/admin/users"
- model = User
- def get_form_class(self, request, target):
- add_is_active_fields = False
- add_admin_fields = False
- if not target.is_deleting_account:
- if not target.is_staff:
- add_is_active_fields = True
- elif request.user.is_superuser:
- add_is_active_fields = request.user.pk != target.pk
- if request.user.is_superuser:
- add_admin_fields = request.user.pk != target.pk
- return EditUserFormFactory(
- self.form_class,
- target,
- add_is_active_fields=add_is_active_fields,
- add_admin_fields=add_admin_fields,
- )
- class UsersList(UserAdmin, generic.ListView):
- items_per_page = 24
- ordering = [
- ("-id", _("From newest")),
- ("id", _("From oldest")),
- ("slug", _("A to z")),
- ("-slug", _("Z to a")),
- ("-posts", _("Biggest posters")),
- ("posts", _("Smallest posters")),
- ]
- selection_label = _("With users: 0")
- empty_selection_label = _("Select users")
- mass_actions = [
- {"action": "activate", "name": _("Activate accounts")},
- {"action": "ban", "name": _("Ban users"), "icon": "fa fa-lock"},
- {"action": "request_data_download", "name": _("Request data download")},
- {
- "action": "delete_accounts",
- "name": _("Delete accounts"),
- "confirmation": _("Are you sure you want to delete selected users?"),
- },
- {
- "action": "delete_all",
- "name": _("Delete with content"),
- "confirmation": _(
- "Are you sure you want to delete selected users? "
- "This will also delete all content associated with their accounts."
- ),
- "is_atomic": False,
- },
- ]
- def get_queryset(self):
- qs = super().get_queryset()
- return qs.select_related("rank")
- def get_filter_form(self, request):
- return create_filter_users_form()
- def action_activate(self, request, users):
- inactive_users = []
- for user in users:
- if user.requires_activation:
- inactive_users.append(user)
- if not inactive_users:
- message = _("You have to select inactive users.")
- raise generic.MassActionError(message)
- else:
- activated_users_pks = [u.pk for u in inactive_users]
- queryset = User.objects.filter(pk__in=activated_users_pks)
- queryset.update(requires_activation=User.ACTIVATION_NONE)
- subject = _("Your account on %(forum_name)s forums has been activated")
- mail_subject = subject % {"forum_name": request.settings.forum_name}
- mail_users(
- inactive_users,
- mail_subject,
- "misago/emails/activation/by_admin",
- context={"settings": request.settings},
- )
- messages.success(request, _("Selected users accounts have been activated."))
- def action_ban(
- self, request, users
- ): # pylint: disable=too-many-locals, too-many-nested-blocks, too-many-branches
- users = users.order_by("slug")
- for user in users:
- if user.is_superuser:
- message = _("%(user)s is super admin and can't be banned.")
- mesage = message % {"user": user.username}
- raise generic.MassActionError(mesage)
- form = BanUsersForm(users=users)
- if "finalize" in request.POST:
- form = BanUsersForm(request.POST, users=users)
- if form.is_valid():
- cleaned_data = form.cleaned_data
- banned_values = []
- ban_kwargs = {
- "user_message": cleaned_data.get("user_message"),
- "staff_message": cleaned_data.get("staff_message"),
- "expires_on": cleaned_data.get("expires_on"),
- }
- for user in users:
- for ban in cleaned_data["ban_type"]:
- banned_value = None
- if ban == "usernames":
- check_type = Ban.USERNAME
- banned_value = user.username.lower()
- if ban == "emails":
- check_type = Ban.EMAIL
- banned_value = user.email.lower()
- if ban == "domains":
- check_type = Ban.EMAIL
- banned_value = user.email.lower()
- at_pos = banned_value.find("@")
- banned_value = "*%s" % banned_value[at_pos:]
- if ban == "ip" and user.joined_from_ip:
- check_type = Ban.IP
- banned_value = user.joined_from_ip
- if ban in ("ip_first", "ip_two") and user.joined_from_ip:
- check_type = Ban.IP
- if ":" in user.joined_from_ip:
- ip_separator = ":"
- if "." in user.joined_from_ip:
- ip_separator = "."
- bits = user.joined_from_ip.split(ip_separator)
- if ban == "ip_first":
- formats = (bits[0], ip_separator)
- if ban == "ip_two":
- formats = (bits[0], ip_separator, bits[1], ip_separator)
- banned_value = "%s*" % ("".join(formats))
- if banned_value and banned_value not in banned_values:
- ban_kwargs.update(
- {"check_type": check_type, "banned_value": banned_value}
- )
- Ban.objects.create(**ban_kwargs)
- banned_values.append(banned_value)
- Ban.objects.invalidate_cache()
- messages.success(request, _("Selected users have been banned."))
- return None
- return self.render(
- request,
- {"users": users, "form": form},
- template_name="misago/admin/users/ban.html",
- )
- def action_request_data_download(self, request, users):
- for user in users:
- if not user_has_data_download_request(user):
- request_user_data_download(user, requester=request.user)
- messages.success(
- request, _("Data download requests have been placed for selected users.")
- )
- def action_delete_accounts(self, request, users):
- for user in users:
- if user == request.user:
- raise generic.MassActionError(_("You can't delete yourself."))
- if user.is_staff or user.is_superuser:
- message = _("%(user)s is admin and can't be deleted.") % {
- "user": user.username
- }
- raise generic.MassActionError(message)
- for user in users:
- user.delete(anonymous_username=request.settings.anonymous_username)
- messages.success(request, _("Selected users have been deleted."))
- def action_delete_all(self, request, users):
- for user in users:
- if user == request.user:
- raise generic.MassActionError(_("You can't delete yourself."))
- if user.is_staff or user.is_superuser:
- message = _("%(user)s is admin and can't be deleted.") % {
- "user": user.username
- }
- raise generic.MassActionError(message)
- for user in users:
- user.is_active = False
- user.save()
- delete_user_with_content.delay(user.pk)
- messages.success(
- request,
- _(
- "Selected users have been disabled and queued for deletion "
- "together with their content."
- ),
- )
- class NewUser(UserAdmin, generic.ModelFormView):
- form_class = NewUserForm
- template_name = "new.html"
- message_submit = _('New user "%(user)s" has been registered.')
- def get_form(self, form_class, request, target):
- if request.method == "POST":
- return form_class(
- request.POST, request.FILES, instance=target, request=request
- )
- return form_class(instance=target, request=request)
- def handle_form(self, form, request, target):
- new_user = User.objects.create_user(
- form.cleaned_data["username"],
- form.cleaned_data["email"],
- form.cleaned_data["new_password"],
- title=form.cleaned_data["title"],
- rank=form.cleaned_data.get("rank"),
- joined_from_ip=request.user_ip,
- )
- if form.cleaned_data.get("roles"):
- new_user.roles.add(*form.cleaned_data["roles"])
- new_user.update_acl_key()
- setup_new_user(request.settings, new_user)
- messages.success(request, self.message_submit % {"user": target.username})
- return redirect("misago:admin:users:edit", pk=new_user.pk)
- class EditUser(UserAdmin, generic.ModelFormView):
- form_class = EditUserForm
- template_name = "edit.html"
- message_submit = _('User "%(user)s" has been edited.')
- def real_dispatch(self, request, target):
- target.old_username = target.username
- target.old_is_avatar_locked = target.is_avatar_locked
- return super().real_dispatch(request, target)
- def get_form(self, form_class, request, target):
- if request.method == "POST":
- return form_class(
- request.POST, request.FILES, instance=target, request=request
- )
- return form_class(instance=target, request=request)
- def handle_form(self, form, request, target):
- target.username = target.old_username
- if target.username != form.cleaned_data.get("username"):
- target.set_username(
- form.cleaned_data.get("username"), changed_by=request.user
- )
- if form.cleaned_data.get("new_password"):
- target.set_password(form.cleaned_data["new_password"])
- if form.cleaned_data.get("email"):
- target.set_email(form.cleaned_data["email"])
- if form.cleaned_data.get("is_avatar_locked"):
- if not target.old_is_avatar_locked:
- set_dynamic_avatar(target)
- if "is_staff" in form.fields and "is_superuser" in form.fields:
- target.is_staff = form.cleaned_data.get("is_staff")
- target.is_superuser = form.cleaned_data.get("is_superuser")
- if "is_active" in form.fields and "is_active_staff_message" in form.fields:
- target.is_active = form.cleaned_data.get("is_active")
- target.is_active_staff_message = form.cleaned_data.get(
- "is_active_staff_message"
- )
- target.rank = form.cleaned_data.get("rank")
- target.roles.clear()
- target.roles.add(*form.cleaned_data["roles"])
- target_acl = get_user_acl(target, request.cache_versions)
- set_user_signature(
- request, target, target_acl, form.cleaned_data.get("signature")
- )
- profilefields.update_user_profile_fields(request, target, form)
- target.update_acl_key()
- target.save()
- if target.pk == request.user.pk:
- authorize_admin(request)
- update_session_auth_hash(request, target)
- messages.success(request, self.message_submit % {"user": target.username})
|