<commit_before>from __future__ import unicode_literals
from crispy_forms import layout
from django.contrib import auth
from django.contrib.auth import authenticate, get_user_model
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django import forms
from crispy_forms.helper import FormHelper
from django.views.generic import FormView

from django_cradmin.crispylayouts import PrimarySubmitLg


class AbstractLoginForm(forms.Form):
    """
    Superclass for the various Login-forms used by :class:`.LoginView` by default. Known subclasses:

     - :class:`.EmailLoginForm`
     - :class:`.EmailLoginFormNoSanityCheck`
     - :class:`UsernameLoginForm`

    """

    #: The field used with the password for authentication.
    #: Must be set in subclasses
    username_field = None

    #: The placeholder text for the username field.
    #: Must be set in subclasses
    username_field_placeholder = None

    #: The placeholder text for the password field.
    #: Must be set in subclasses
    password_field_placeholder = _('Password')

    #: Error message to show if username and password do not match
    error_message_invalid_login = None

    #: Error message to show if the account is inactive.
    error_message_inactive = _("This account is inactive.")

    #: The password field
    password = forms.CharField(
        label=_('Password'),
        widget=forms.PasswordInput)

    def model_sanity_check(self):
        pass

    def __init__(self, *args, **kwargs):
        self.model_sanity_check()
        super(AbstractLoginForm, self).__init__(*args, **kwargs)

    def clean(self):
        """
        validate the form, and execute :func:`django.contrib.auth.authenticate` to login the user if form is valid.
        """
        username = self.cleaned_data.get(self.username_field)
        password = self.cleaned_data.get('password')
        if username and password:
            authenticated_user = authenticate(**{
                self.username_field: username,
                'password': password
            })
            if authenticated_user is None:
                raise forms.ValidationError(self.error_message_invalid_login)
            elif not authenticated_user.is_active:
                raise forms.ValidationError(self.error_message_inactive)
            self.__authenticated_user = authenticated_user
        return self.cleaned_data

    def get_user(self):
        return self.__authenticated_user


class UsernameLoginForm(AbstractLoginForm):
    """
    This form is used for username-based login.

    Using this form in its default state requires the `User`-models ``USERNAME_FIELD`` to be ``username``.
    This is set in the field ``username_field`` in this class.
    """<commit_msg>authenticate.views.login: Made it easier to provide custom authenticate arguments.<commit_after>from __future__ import unicode_literals
from crispy_forms import layout
from django.contrib import auth
from django.contrib.auth import authenticate, get_user_model
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django import forms
from crispy_forms.helper import FormHelper
from django.views.generic import FormView

from django_cradmin.crispylayouts import PrimarySubmitLg


class AbstractLoginForm(forms.Form):
    """
    Superclass for the various Login-forms used by :class:`.LoginView` by default. Known subclasses:

     - :class:`.EmailLoginForm`
     - :class:`.EmailLoginFormNoSanityCheck`
     - :class:`UsernameLoginForm`

    """

    #: The field used with the password for authentication.
    #: Must be set in subclasses
    username_field = None

    #: The placeholder text for the username field.
    #: Must be set in subclasses
    username_field_placeholder = None

    #: The placeholder text for the password field.
    #: Must be set in subclasses
    password_field_placeholder = _('Password')

    #: Error message to show if username and password do not match
    error_message_invalid_login = None

    #: Error message to show if the account is inactive.
    error_message_inactive = _("This account is inactive.")

    #: The password field
    password = forms.CharField(
        label=_('Password'),
        widget=forms.PasswordInput)

    def model_sanity_check(self):
        pass

    def __init__(self, *args, **kwargs):
        self.model_sanity_check()
        super(AbstractLoginForm, self).__init__(*args, **kwargs)

    def authenticate(self, **kwargs):
        """
        Wrapper around ``django.contrib.auth.authenticate`` to make
        it easy for subclasses to add extra kwargs.
        """
        return authenticate(**kwargs)

    def clean(self):
        """
        validate the form, and execute :func:`django.contrib.auth.authenticate` to login the user if form is valid.
        """
        username = self.cleaned_data.get(self.username_field)
        password = self.cleaned_data.get('password')
        if username and password:
            authenticated_user = self.authenticate(**{
                self.username_field: username,
                'password': password
            })

            if authenticated_user is None:
                raise forms.ValidationError(self.error_message_invalid_login)
            elif not authenticated_user.is_active:
                raise forms.ValidationError(self.error_message_inactive)
            self.__authenticated_user = authenticated_user
        return self.cleaned_data

    def get_user(self):
        return self.__authenticated_user


class UsernameLoginForm(AbstractLoginForm):
    """
    This form is used for username-based login.

    Using this form in its default state requires the `User`-models ``USERNAME_FIELD`` to be ``username``.
    This is set in the field ``username_field`` in this class.
    """
{'fraction_non_alphanumeric': 0.07614465826144658, 'fraction_numerical': 0.0, 'mean_word_length': 3.1266255989048597, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2977274', 'n_tokens_mistral': 1632, 'n_tokens_neox': 1545, 'n_words': 500}