feat: add password change

Password page with the AD policy listed first, ordered service (throttle limit below the lockout threshold, verification, local hints, directory change, ended sessions, audit and confirmation mail in one transaction), plain-language errors, German text and tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N3t4WL7bd9bdHHNjEsxzqC
This commit is contained in:
2026-10-18 10:08:17 +02:00
co-authored by Claude Sonnet 5.5
parent a1a766adef
commit 49c7fd4a0b
22 changed files with 1346 additions and 17 deletions
+35
View File
@@ -0,0 +1,35 @@
from django import forms
from django.utils.translation import gettext_lazy as _
MAX_PASSWORD_LENGTH = 256 # Active Directory's limit
def _password_field():
return forms.CharField(
max_length=MAX_PASSWORD_LENGTH,
strip=False, # spaces can be part of a password
widget=forms.PasswordInput(render_value=False),
error_messages={
"required": _("Please fill in this field."),
"max_length": _("This password is too long."),
},
)
class PasswordChangeForm(forms.Form):
current_password = _password_field()
new_password = _password_field()
confirm_password = _password_field()
def clean(self):
data = super().clean()
current, new, confirm = (
data.get("current_password"),
data.get("new_password"),
data.get("confirm_password"),
)
if new and confirm and new != confirm:
self.add_error("confirm_password", _("The two new passwords are not the same."))
elif new and current and new == current:
self.add_error("new_password", _("The new password must be different."))
return data