from django import forms from django.contrib.auth import authenticate from django.utils.translation import ugettext_lazy as _ from pretix.base.models import User class LoginForm(forms.Form): """ Base class for authenticating users. Extend this to get a form that accepts username/password logins. """ email = forms.EmailField(label=_("E-mail"), max_length=254) password = forms.CharField(label=_("Password"), widget=forms.PasswordInput) error_messages = { 'invalid_login': _("Please enter a correct e-mail address and password."), '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) def clean(self): email = self.cleaned_data.get('email') password = self.cleaned_data.get('password') if email and password: self.user_cache = authenticate(email=email.lower(), password=password) if self.user_cache is None: raise forms.ValidationError( self.error_messages['invalid_login'], code='invalid_login' ) 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 class RegistrationForm(forms.Form): error_messages = { 'duplicate_email': _("You already registered with that e-mail address, please use the login form."), 'pw_mismatch': _("Please enter the same password twice"), } email = forms.EmailField( label=_('Email address'), required=True ) password = forms.CharField( label=_('Password'), widget=forms.PasswordInput, required=True ) password_repeat = forms.CharField( label=_('Repeat password'), widget=forms.PasswordInput ) def clean(self): password1 = self.cleaned_data.get('password') password2 = self.cleaned_data.get('password_repeat') if password1 and password1 != password2: raise forms.ValidationError( self.error_messages['pw_mismatch'], code='pw_mismatch' ) return self.cleaned_data def clean_email(self): email = self.cleaned_data['email'] if User.objects.filter(email=email).exists(): raise forms.ValidationError( self.error_messages['duplicate_email'], code='duplicate_email' ) return email class PasswordRecoverForm(forms.Form): error_messages = { 'pw_mismatch': _("Please enter the same password twice") } password = forms.CharField( label=_('Password'), widget=forms.PasswordInput, required=True ) password_repeat = forms.CharField( label=_('Repeat password'), widget=forms.PasswordInput ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) def clean(self): password1 = self.cleaned_data.get('password') password2 = self.cleaned_data.get('password_repeat') if password1 and password1 != password2: raise forms.ValidationError( self.error_messages['pw_mismatch'], code='pw_mismatch' ) return self.cleaned_data class PasswordForgotForm(forms.Form): email = forms.EmailField( label=_('E-mail'), ) def __init__(self, event, *args, **kwargs): self.event = event super().__init__(*args, **kwargs) def clean_email(self): email = self.cleaned_data['email'] try: self.cleaned_data['user'] = User.objects.get( email=email, event__isnull=True ) return email except User.DoesNotExist: raise forms.ValidationError( _("We are unable to find a user matching the data you provided."), code='unknown_user' )