kadenios/shared/auth/forms.py

119 lines
3.8 KiB
Python

from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth import forms as auth_forms
from django.contrib.auth import get_user_model
from django.core.validators import validate_email
from django.utils.translation import gettext_lazy as _
User = get_user_model()
class ElectionAuthForm(forms.Form):
"""Adapts Django's AuthenticationForm to allow for an election specific login."""
login = auth_forms.UsernameField(label=_("Identifiant"), max_length=255)
password = forms.CharField(
label=_("Mot de passe"),
strip=False,
widget=forms.PasswordInput(attrs={"autocomplete": "current-password"}),
)
election_id = forms.IntegerField(widget=forms.HiddenInput())
def __init__(self, request=None, *args, **kwargs):
self.request = request
self.user_cache = None
super().__init__(*args, **kwargs)
def clean(self):
login = self.cleaned_data.get("login")
password = self.cleaned_data.get("password")
election_id = self.cleaned_data.get("election_id")
if login is not None and password:
self.user_cache = authenticate(
self.request,
login=login,
password=password,
election_id=election_id,
)
if self.user_cache is None:
raise self.get_invalid_login_error()
return self.cleaned_data
def get_user(self):
# Necessary API for LoginView
return self.user_cache
def get_invalid_login_error(self):
return forms.ValidationError(
_(
"Aucun·e électeur·ice avec cet identifiant et mot de passe n'existe "
"pour cette élection. Vérifiez que les informations rentrées sont "
"correctes, les champs sont sensibles à la casse."
),
code="invalid_login",
)
class PwdResetForm(auth_forms.PasswordResetForm):
"""Restricts the search for password users, i.e. whose username starts with pwd__."""
def get_users(self, email):
users = super().get_users(email)
return (u for u in users if u.username.split("__")[0] == "pwd")
class PwdUserForm(forms.ModelForm):
"""
Allows for the creation of a Password Account given the email, base username and full name.
"""
email = forms.EmailField(
label=_("Email"), required=True, validators=[validate_email]
)
def clean(self):
# On rajoute le préfixe signifiant qu'on crée un compte avec mot de passe
cleaned_data = super().clean()
cleaned_data["username"] = "pwd__" + cleaned_data["username"]
return cleaned_data
class Meta:
model = User
fields = ["username", "full_name", "email"]
class UserAdminForm(forms.Form):
"""
Allows to select an user and give them some admin permissions
"""
username = forms.CharField(label=_("Nom d'utilisateur"), max_length=150)
full_admin = forms.BooleanField(
label=_("Passer administrateur de Kadenios"), required=False
)
faq_admin = forms.BooleanField(
label=_("Autoriser à créer des FAQs"), required=False
)
election_admin = forms.BooleanField(
label=_("Autoriser à créer des élections"), required=False
)
def clean(self):
cleaned_data = super().clean()
username = cleaned_data["username"]
if not username[:5] in ["cas__", "pwd__"]:
self.add_error(
"username",
_(
"Format de login invalide, seuls les comptes CAS ou avec "
"mot de passe sont modifiables"
),
)
elif not User.objects.filter(username=username).exists():
self.add_error("username", _("Pas d'utilisateur·rice avec ce login"))
return cleaned_data