"""This file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license. """ import logging from django import forms from django.conf import settings from django.contrib import auth from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ValidationError as DjangoValidationError from users.models import User EMAIL_MAX_LENGTH = 256 USERNAME_MAX_LENGTH = 30 DISPLAY_NAME_LENGTH = 100 USERNAME_LENGTH_ERR = f'Please enter a username {USERNAME_MAX_LENGTH} characters or fewer in length' DISPLAY_NAME_LENGTH_ERR = f'Please enter a display name {DISPLAY_NAME_LENGTH} characters or fewer in length' INVALID_USER_ERROR = "The email and password you entered don't match." FOUND_US_ELABORATE = 'Other' FOUND_US_OPTIONS = ( ('Gi', 'Github'), ('Em', 'Email or newsletter'), ('Se', 'Search engine'), ('Fr', 'Friend or coworker'), ('Ad', 'Ad'), ('Ot', FOUND_US_ELABORATE), ) logger = logging.getLogger(__name__) class LoginForm(forms.Form): """For logging in to the app and all - session based""" # use username instead of email when LDAP enabled email = forms.CharField(label='User') if settings.USE_USERNAME_FOR_LOGIN else forms.EmailField(label='Email') password = forms.CharField(widget=forms.PasswordInput()) persist_session = forms.BooleanField(widget=forms.CheckboxInput(), required=False) def clean(self, *args, **kwargs): cleaned = super(LoginForm, self).clean() email = cleaned.get('email', '').lower() password = cleaned.get('password', '') if len(email) >= EMAIL_MAX_LENGTH: raise forms.ValidationError('Email is too long') # advanced way for user auth user = settings.USER_AUTH(User, email, password) # regular access if user is None: user = auth.authenticate(email=email, password=password) if user and user.is_active: persist_session = cleaned.get('persist_session', False) return {'user': user, 'persist_session': persist_session} else: raise forms.ValidationError(INVALID_USER_ERROR) class UserSignupForm(forms.Form): email = forms.EmailField(label='Work Email', error_messages={'required': 'Invalid email'}) password = forms.CharField(widget=forms.TextInput(attrs={'type': 'password'})) allow_newsletters = forms.BooleanField(required=False) how_find_us = forms.CharField(required=False) elaborate = forms.CharField(required=False) def clean_password(self): password = self.cleaned_data.get('password') try: validate_password(password) except DjangoValidationError as e: raise forms.ValidationError(e.messages) return password def clean_username(self): username = self.cleaned_data.get('username') if username and User.objects.filter(username=username.lower()).exists(): raise forms.ValidationError('User with username already exists') return username def clean_email(self): email = self.cleaned_data.get('email').lower() if len(email) >= EMAIL_MAX_LENGTH: raise forms.ValidationError('Email is too long') if email and User.objects.filter(email=email).exists(): raise forms.ValidationError('User with this email already exists') return email def save(self): cleaned = self.cleaned_data password = cleaned['password'] email = cleaned['email'].lower() allow_newsletters = None how_find_us = None if 'allow_newsletters' in cleaned: allow_newsletters = cleaned['allow_newsletters'] if 'how_find_us' in cleaned: how_find_us = cleaned['how_find_us'] if 'elaborate' in cleaned and how_find_us == FOUND_US_ELABORATE: cleaned['elaborate'] user = User.objects.create_user(email, password, allow_newsletters=allow_newsletters) return user class UserProfileForm(forms.ModelForm): """This form is used in profile account pages""" class Meta: model = User fields = ('first_name', 'last_name', 'phone', 'allow_newsletters')