forms.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. from phonenumber_field.phonenumber import PhoneNumber, to_python, validate_region
  2. from phonenumber_field.validators import validate_international_phonenumber
  3. from django import forms
  4. from django.db import models
  5. from django.utils.translation import gettext, gettext_lazy as _, pgettext
  6. from django.contrib.auth.forms import UserCreationForm, AuthenticationForm, password_validation
  7. from allauth.account.forms import (
  8. SignupForm as allauthSignupForm,
  9. PasswordField,
  10. LoginForm,
  11. set_form_field_order,
  12. exceptions,
  13. validators,
  14. get_adapter,
  15. perform_login)
  16. from allauth.account import app_settings
  17. from phonenumber_field.widgets import PhoneNumberInternationalFallbackWidget, PhonePrefixSelect, PhoneNumberPrefixWidget
  18. from phonenumber_field.formfields import PhoneNumberField
  19. from .models import User
  20. class SignupForm(UserCreationForm, PasswordField):
  21. class Meta:
  22. model = User
  23. fields = ['firstname', 'lastname', 'email', 'phone_number']
  24. labels = {
  25. 'firstname': '',
  26. 'lastname': '',
  27. 'email': '',
  28. 'phone_number': '',
  29. }
  30. widgets = {
  31. 'firstname' : forms.TextInput(attrs = {'placeholder': _('Firstname')}),
  32. 'lastname' : forms.TextInput(attrs = {'placeholder': _('Lastname')}),
  33. 'email' : forms.TextInput(attrs = {'placeholder': _('Email')}),
  34. 'phone_number' : PhoneNumberPrefixWidget(attrs = {'placeholder': _('Phone')}),
  35. }
  36. password1 = forms.CharField(
  37. label=_(""),
  38. strip=False,
  39. widget=forms.PasswordInput(attrs={"autocomplete": "new-password", "placeholder": _('Password')}),
  40. help_text=password_validation.password_validators_help_text_html(),
  41. )
  42. password2 = forms.CharField(
  43. label=_(""),
  44. widget=forms.PasswordInput(attrs={"autocomplete": "new-password", "placeholder": _('Repeat password')}),
  45. strip=False,
  46. help_text=_("Enter the same password as before, for verification."),
  47. )
  48. field_order = ['firstname', 'lastname', 'email', 'phone_number', 'password1', 'password2',]
  49. def __init__(self, *args, **kwargs):
  50. super(SignupForm, self).__init__(*args, **kwargs)
  51. #self.fields['email'].required = False
  52. class CustomLoginForm(LoginForm):
  53. error_messages = {
  54. "account_inactive": _("This account is currently inactive."),
  55. "email_password_mismatch": _(
  56. "The e-mail address and/or password you specified are not correct."
  57. ),
  58. "username_password_mismatch": _(
  59. "The phone number and/or password you specified are not correct."
  60. ),
  61. }
  62. def __init__(self, *args, **kwargs):
  63. self.request = kwargs.pop("request", None)
  64. super(LoginForm, self).__init__(*args, **kwargs)
  65. login_widget = forms.TextInput(
  66. attrs={"placeholder": _("Phone or e-mail"), "autocomplete": "email",})
  67. login_field = forms.CharField(
  68. label=pgettext("field label", ""), widget=login_widget) #Login label
  69. self.fields['password'].label = '' #Password label
  70. self.fields["login"] = login_field
  71. set_form_field_order(self, ["login", "password", "remember"])
  72. if app_settings.SESSION_REMEMBER is not None:
  73. del self.fields["remember"]
  74. def user_credentials(self):
  75. """
  76. Provides the credentials required to authenticate the user for
  77. login.
  78. """
  79. credentials = {}
  80. login = self.cleaned_data["login"]
  81. if self._is_login_email(login):
  82. credentials["email"] = login
  83. credentials["phone_number"] = login
  84. credentials["password"] = self.cleaned_data["password"]
  85. return credentials
  86. def clean_login(self):
  87. login = self.cleaned_data["login"]
  88. return login.strip()
  89. def _is_login_email(self, login):
  90. try:
  91. validators.validate_email(login)
  92. ret = True
  93. except exceptions.ValidationError:
  94. ret = False
  95. return ret
  96. def clean(self):
  97. super(LoginForm, self).clean()
  98. if self._errors:
  99. return
  100. credentials = self.user_credentials()
  101. user = get_adapter(self.request).authenticate(self.request, **credentials)
  102. if user:
  103. self.user = user
  104. else:
  105. # Show error "password mismatch". If email: email and password are wrong. If phone: phone and password
  106. login = self.cleaned_data["login"]
  107. if self._is_login_email(login):
  108. auth_method = app_settings.AuthenticationMethod.EMAIL
  109. else:
  110. auth_method = app_settings.AuthenticationMethod.USERNAME
  111. raise forms.ValidationError(
  112. self.error_messages["%s_password_mismatch" % auth_method]
  113. )
  114. return self.cleaned_data
  115. def login(self, request, redirect_url=None):
  116. email = self.user_credentials().get("email")
  117. ret = perform_login(
  118. request,
  119. self.user,
  120. email_verification=app_settings.EMAIL_VERIFICATION,
  121. redirect_url=redirect_url,
  122. email=email,
  123. )
  124. remember = app_settings.SESSION_REMEMBER
  125. if remember is None:
  126. remember = self.cleaned_data["remember"]
  127. if remember:
  128. request.session.set_expiry(app_settings.SESSION_COOKIE_AGE)
  129. else:
  130. request.session.set_expiry(0)
  131. return ret
  132. ########################################################################
  133. '''
  134. def login(self, *args, **kwargs):
  135. # Add your own processing here.
  136. # You must return the original result.
  137. return super(CustomLoginForm, self).login(*args, **kwargs)
  138. def user_credentials(self):
  139. """
  140. Provides the credentials required to authenticate the user for
  141. login.
  142. """
  143. credentials = {}
  144. login = self.cleaned_data["login"]
  145. if app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.EMAIL:
  146. credentials["email"] = login
  147. elif app_settings.AUTHENTICATION_METHOD == AuthenticationMethod.USERNAME:
  148. credentials["username"] = login
  149. else:
  150. if self._is_login_email(login):
  151. credentials["email"] = login
  152. credentials["username"] = login
  153. credentials["password"] = self.cleaned_data["password"]
  154. return credentials
  155. '''