Source

django-publicauth / openauth / forms.py

Full commit
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth import login as login_user
from django.utils.translation import ugettext as _
from django.core.urlresolvers import reverse

from annoying.functions import get_object_or_None
from annoying.decorators import autostrip

from openauth.utils import uri_to_username
from openauth.fields import LoginField, PasswordField
from openauth.models import SocialID
from openauth import settings


class RegistrationForm(forms.Form):
    """
    Basic registration form. 
    To provide custom registration form, please refer to settings 
    file for instractions.
    """
    def __init__(self, *args, **kwargs):
        if settings.DISPLAYNAME_REQUIRED:
            self.base_fields['username'] = forms.CharField()
        super(RegistrationForm, self).__init__(*args, **kwargs)

    login = LoginField()
    password = PasswordField(label=_('Password'))
    password_dup = PasswordField(label=_('Password (confirmation)'))


    def clean_login(self):
        """
        Validate login field according to AUTHENTIFICATION types 
        specified in settings. The login field must be unique.
        """
        if "email" in settings.AUTHENTICATION_TYPES:
            if get_object_or_None(User, email=self.cleaned_data['login'].lower()):
                raise forms.ValidationError(_(u'This email already registered'))
        elif "username" in settings.AUTHENTICATION_TYPES:
            if get_object_or_None(User, username=self.cleaned_data['login']):
                raise forms.ValidationError(_(u'This login name is already taken'))
        return self.cleaned_data['login']


    def clean_username(self):
        """
        Validate uniqeness of username in case DISPLAYNAME_REQUIRED 
        is set to True.
        """
        if settings.UNIQUE_USERNAME:
            if get_object_or_None(User, username=self.cleaned_data['username']):
                raise forms.ValidationError(_(u'This display name already registered'))
        return self.cleaned_data['username']


    def clean(self):
        """
        Validates that password and confirmation password are the same.
        """
        pwd1 = self.cleaned_data.get('password')
        pwd2 = self.cleaned_data.get('password_dup')
        if pwd1 and pwd2:
            if pwd1 != pwd2:
                raise forms.ValidationError(_(u'Passwords do not match'))
        return self.cleaned_data


    def save(self):
        """
        Fill free to override this method in your custom registration
        form. The method should return User instance.
        """
        user = User()
        if "email" in settings.AUTHENTICATION_TYPES:
            user.email = self.cleaned_data['login'].lower()
            if settings.DISPLAYNAME_REQUIRED:
                user.username = self.cleaned_data['username']
            else:
                user.username = user.email
        if "username" in settings.AUTHENTICATION_TYPES:
            user.username = self.cleaned_data['login']
        user.set_password(self.cleaned_data['password'])
        user.save()
        return user

RegistrationForm = autostrip(RegistrationForm)


class LoginForm(forms.Form):
    """
    Login form for username or email base authentication types.
    """
    login = LoginField()
    password = PasswordField()

    def __init__(self, request, *args, **kwargs):
        self.request = request
        super(LoginForm, self).__init__(*args, **kwargs)

    def clean(self):
        """
        Validate cridentials and login the user in case of success.
        If user is not activated and ACTIVATION_REQUIRED set to True
        form will not validate.
        """
        super(LoginForm, self).clean()
        if self.is_valid():
            login = self.cleaned_data['login']
            password = self.cleaned_data['password']
            if 'username' in settings.AUTHENTICATION_TYPES:
                user = get_object_or_None(User, username=login)
            elif 'email' in settings.AUTHENTICATION_TYPES:
                user = get_object_or_None(User, email=login.lower())
            if user and  user.check_password(password):
                if settings.ACTIVATION_REQUIRED and not user.is_active:
                    raise forms.ValidationError(_(u'Your account is not active. Please activate it.'))
                user.backend = 'django.contrib.auth.backends.ModelBackend'
                login_user(self.request, user)
                return self.cleaned_data
            else:
                raise forms.ValidationError(_(u'Incorrect authentication data'))

LoginForm = autostrip(LoginForm)


class ResetPasswordForm(forms.Form):
    """
    This form will send confirmation link to user asocciated with this email. 
    Please note that users without email can't reset their passwords. 
    """
    email = forms.EmailField(label=_('Email'))

    def clean_email(self):
        """
        Check that user with such email exists in database.
        """
        email = self.cleaned_data['email'].lower()
        if get_object_or_None(User, email=email):
            return email
        else:
            raise forms.ValidationError(_(u'This email is not registered'))

ResetPasswordForm = autostrip(ResetPasswordForm)


class SocialIDExtraForm(forms.Form):
    def __init__(self, *args, **kwargs):
        fields = kwargs.pop("fields", None)
        for key, value in fields:
            self.base_fields[key] = value
        super(SocialIDExtraForm, self).__init__(*args, **kwargs)

    def clean_login(self):
        login = self.cleaned_data['login']
        if settings.UNIQUE_USERNAME and get_object_or_None(User, username=login):
            raise forms.ValidationError("This username already taken");
        return login

    def save(self, identity, provider):
        user = User.objects.create(username=self.cleaned_data['login'])
        if settings.SOCIALID_ACTIVATION_REQUIRED:
            user.is_active = False
        user.save()
        SocialID.objects.create(user=user, identity=identity, provider=provider)
        return user


class NewPasswordForm(forms.Form):
    """
    Form for changing user's password.
    """
    password = PasswordField(label=_(u'Password'))
    password_confirmation = PasswordField(label=_(u'Password (confirmation)'))

    def clean_password_confirmation(self):
        pass1 = self.cleaned_data['password']
        pass2 = self.cleaned_data['password_confirmation']
        if pass1 != pass2:
            raise forms.ValidationError(_(u'The passwords do not match'))
        else:
            return pass1

    def save(self, user):
        user.set_password(self.cleaned_data['password'])
        user.save()
        return user

NewPasswordForm = autostrip(NewPasswordForm)