accounts/apps/users/forms.py
2022-09-08 18:08:22 +04:30

90 lines
3.3 KiB
Python

from django import forms
from django.contrib.auth import (authenticate, get_user_model)
from django.contrib.auth.forms import UsernameField
from django.utils.text import capfirst
from django.utils.translation import gettext_lazy as _
UserModel = get_user_model()
class OTPAuthenticationForm(forms.Form):
"""
Base class for authenticating users. Extend this to get a form that accepts
username/password logins.
"""
phone_number = UsernameField(widget=forms.TextInput(attrs={'autofocus': True}))
otp = forms.CharField(
label=_("otp"),
strip=False,
widget=forms.PasswordInput(attrs={'autocomplete': 'current-password'}),
)
error_messages = {
'invalid_login': _(
"Please enter a correct %(phone_number)s and otp. Note that both "
"fields may be case-sensitive."
),
'inactive': _("This account is inactive."),
}
def __init__(self, request=None, *args, **kwargs):
"""
The 'request' parameter is set for custom auth use by subclasses.
The form data comes in via the standard 'data' kwarg.
"""
self.request = request
self.user_cache = None
super().__init__(*args, **kwargs)
# Set the max length and label for the "username" field.
self.phone_number_field = UserModel._meta.get_field('phone_number')
phone_number_max_length = self.phone_number_field.max_length or 24
self.fields['phone_number'].max_length = phone_number_max_length
self.fields['phone_number'].widget.attrs['maxlength'] = phone_number_max_length
if self.fields['phone_number'].label is None:
self.fields['phone_number'].label = capfirst(self.phone_number_field.verbose_name)
def clean(self):
phone_number = self.cleaned_data.get('phone_number')
otp = self.cleaned_data.get('otp')
if phone_number is not None and otp:
self.user_cache = authenticate(self.request, phone_number=phone_number, otp=otp)
if self.user_cache is None:
raise self.get_invalid_login_error()
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
def confirm_login_allowed(self, user):
"""
Controls whether the given User may log in. This is a policy setting,
independent of end-user authentication. This default behavior is to
allow login by active users, and reject login by inactive users.
If the given user cannot log in, this method should raise a
``forms.ValidationError``.
If the given user may log in, this method should return None.
"""
if not user.is_active:
raise forms.ValidationError(
self.error_messages['inactive'],
code='inactive',
)
def get_user(self):
return self.user_cache
def get_invalid_login_error(self):
return forms.ValidationError(
self.error_messages['invalid_login'],
code='invalid_login',
params={'phone_number': self.phone_number_field.verbose_name},
)
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model = UserModel
fields = ['name', 'first_name', 'last_name', 'email', 'iban', 'avatar']