refactor: PasswordRootChangeView

This commit is contained in:
imperosol
2025-11-25 20:40:55 +01:00
parent e9fbac8264
commit 55d6e2bbec
4 changed files with 38 additions and 20 deletions

View File

@@ -3,7 +3,7 @@
{% block content %} {% block content %}
{% if target %} {% if target %}
<p>{% trans user=target.get_display_name() %}Change password for {{ user }}{% endtrans %}</p> <p>{% trans user=form.user.get_display_name() %}Change password for {{ user }}{% endtrans %}</p>
{% endif %} {% endif %}
<form method="post" action=""> <form method="post" action="">
{% csrf_token %} {% csrf_token %}

View File

@@ -463,3 +463,20 @@ def test_user_stats(client: Client):
client.force_login(user) client.force_login(user)
response = client.get(reverse("core:user_stats", kwargs={"user_id": user.id})) response = client.get(reverse("core:user_stats", kwargs={"user_id": user.id}))
assert response.status_code == 200 assert response.status_code == 200
@pytest.mark.django_db
class TestChangeUserPassword:
def test_as_root(self, client: Client, admin_user: User):
client.force_login(admin_user)
user = subscriber_user.make()
url = reverse("core:password_root_change", kwargs={"user_id": user.id})
response = client.get(url)
assert response.status_code == 200
response = client.post(
url, {"new_password1": "poutou", "new_password2": "poutou"}
)
print(response.text)
assertRedirects(response, reverse("core:password_change_done"))
user.refresh_from_db()
assert user.check_password("poutou") is True

View File

@@ -54,6 +54,7 @@ from core.views import (
PagePropView, PagePropView,
PageRevView, PageRevView,
PageView, PageView,
PasswordRootChangeView,
SearchView, SearchView,
SithLoginView, SithLoginView,
SithPasswordChangeDoneView, SithPasswordChangeDoneView,
@@ -80,7 +81,6 @@ from core.views import (
delete_user_godfather, delete_user_godfather,
logout, logout,
notification, notification,
password_root_change,
send_file, send_file,
) )
@@ -100,7 +100,7 @@ urlpatterns = [
path("password_change/", SithPasswordChangeView.as_view(), name="password_change"), path("password_change/", SithPasswordChangeView.as_view(), name="password_change"),
path( path(
"password_change/<int:user_id>/", "password_change/<int:user_id>/",
password_root_change, PasswordRootChangeView.as_view(),
name="password_root_change", name="password_root_change",
), ),
path( path(

View File

@@ -29,8 +29,8 @@ from operator import itemgetter
from smtplib import SMTPException from smtplib import SMTPException
from django.contrib.auth import login, views from django.contrib.auth import login, views
from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.forms import PasswordChangeForm, SetPasswordForm
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db.models import DateField, F, QuerySet, Sum from django.db.models import DateField, F, QuerySet, Sum
from django.db.models.functions import Trunc from django.db.models.functions import Trunc
@@ -38,7 +38,6 @@ from django.forms.models import modelform_factory
from django.http import Http404 from django.http import Http404
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.template.response import TemplateResponse
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.safestring import SafeString from django.utils.safestring import SafeString
@@ -98,21 +97,23 @@ def logout(request):
return views.logout_then_login(request) return views.logout_then_login(request)
def password_root_change(request, user_id): class PasswordRootChangeView(UserPassesTestMixin, FormView):
"""Allows a root user to change someone's password.""" """Allows a root user to change someone's password."""
if not request.user.is_root:
raise PermissionDenied template_name = "core/password_change.jinja"
user = get_object_or_404(User, id=user_id) form_class = SetPasswordForm
if request.method == "POST": success_url = reverse_lazy("core:password_change_done")
form = views.SetPasswordForm(user=user, data=request.POST)
if form.is_valid(): def test_func(self):
form.save() return self.request.user.is_root
return redirect("core:password_change_done")
else: def get_form_kwargs(self):
form = views.SetPasswordForm(user=user) user = get_object_or_404(User, id=self.kwargs["user_id"])
return TemplateResponse( return super().get_form_kwargs() | {"user": user}
request, "core/password_change.jinja", {"form": form, "target": user}
) def form_valid(self, form: SetPasswordForm):
form.save()
return super().form_valid(form)
@method_decorator(check_honeypot, name="post") @method_decorator(check_honeypot, name="post")