<commit_before># Copyright (c) 2014, Djaodjin Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Extra Forms and Views that might prove useful to register users."""

from django.core.urlresolvers import reverse
from django.contrib import messages
from django.contrib.auth import login as auth_login
from django.contrib.auth import REDIRECT_FIELD_NAME, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.views import password_reset_confirm, login, logout
from django.contrib.sites.models import get_current_site
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.debug import sensitive_post_parameters
from django.views.decorators.cache import never_cache
from django.views.generic.base import TemplateResponseMixin, TemplateView
from django.views.generic.detail import BaseDetailView
from django.views.generic.edit import FormMixin, ProcessFormView, UpdateView

from signup.auth import validate_redirect
from signup.backends import get_email_backend
from signup.decorators import check_user_active, _send_verification_email
from signup.compat import User
from signup.forms import NameEmailForm, PasswordChangeForm, UserForm
from signup.backends.auth import UsernameOrEmailAuthenticationForm
from signup import signals
from signup import settings


def _redirect_to(url):
    try:
        to_url, args, kwargs = url #(cast to tuple) pylint: disable=star-args
        return redirect(to_url, *args, **kwargs) #pylint: disable=star-args
    except ValueError:
        return redirect(url)


class RedirectFormMixin(FormMixin):

    def get_success_url(self):
        next_url = validate_redirect(self.request)
        if not next_url:
            next_url = super(RedirectFormMixin, self).get_success_url()
        return next_url

    def get_context_data(self, **kwargs):
        context = super(RedirectFormMixin, self).get_context_data(**kwargs)
        next_url = validate_redirect(self.request)
        if next_url:
            context.update({REDIRECT_FIELD_NAME: next_url})
        return context


class RedirectFormView(TemplateResponseMixin, RedirectFormMixin,
                       ProcessFormView):
    """
    Redirects on form valid.
    """
    success_url = settings.LOGIN_REDIRECT_URL


class PasswordResetView(RedirectFormView):
    """
    Enter email address to reset password.
    """

    form_class = PasswordResetForm
    template_name = 'accounts/recover.html'
    token_generator = default_token_generator

    def form_valid(self, form):
        users = User.objects.filter(email__iexact=form.cleaned_data['email'])
        if users.exists():
            user = users.get()
            if user.is_active and user.has_usable_password():
                # Make sure that no email is sent to a user that actually has
                # a password marked as unusable
                site = get_current_site(self.request)
                uid = urlsafe_base64_encode(force_bytes(user.pk))
                token = self.token_generator.make_token(user)
                back_url = self.request.build_absolute_uri(
                    reverse('password_reset_confirm', args=(uid, token)))
                get_email_backend().send([user.email],
                    'accounts/password_reset.eml',
                    {'user': user, 'site': site,
                     'back_url': back_url,
                     'expiration_days': settings.KEY_EXPIRATION,
                     # XXX Reason for a redirect after password reset?
                     # redirect_field_name: next_url
                     })
        return super(PasswordResetView, self).form_valid(form)

    def get_success_url(self):
        messages.info(self.request, "Please follow the instructions "\
            "in the email that has just been sent to you to reset"\
            " your password.")
        return super(PasswordResetView, self).get_success_url()


class PasswordResetConfirmView(RedirectFormView):
    """
    Clicked on the link sent in the reset e-mail.
    """
    template_name = 'accounts/password_reset_confirm.html'

    def dispatch(self, request, *args, **kwargs):
        #pylint: disable=unused-argument
        return password_reset_confirm(request,
            uidb64=self.kwargs.get('uidb64'), token=self.kwargs.get('token'),
            template_name=self.template_name,
            token_generator=default_token_generator,
            set_password_form=SetPasswordForm,
            post_reset_redirect=self.get_success_url(),
            current_app=None, extra_context=None)

    def get_success_url(self):
        # XXX can't display message until re-write
        # of dispatch/password_reset_confirm otherwise it shows up on GET.
        #messages.info(self.request, "Your password has been reset sucessfully.")
        return super(PasswordResetConfirmView, self).get_success_url()


class SignupView(RedirectFormView):
    """<commit_msg>fix: line of 81 characters<commit_after># Copyright (c) 2014, Djaodjin Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Extra Forms and Views that might prove useful to register users."""

from django.core.urlresolvers import reverse
from django.contrib import messages
from django.contrib.auth import login as auth_login
from django.contrib.auth import REDIRECT_FIELD_NAME, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth.views import password_reset_confirm, login, logout
from django.contrib.sites.models import get_current_site
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.debug import sensitive_post_parameters
from django.views.decorators.cache import never_cache
from django.views.generic.base import TemplateResponseMixin, TemplateView
from django.views.generic.detail import BaseDetailView
from django.views.generic.edit import FormMixin, ProcessFormView, UpdateView

from signup.auth import validate_redirect
from signup.backends import get_email_backend
from signup.decorators import check_user_active, _send_verification_email
from signup.compat import User
from signup.forms import NameEmailForm, PasswordChangeForm, UserForm
from signup.backends.auth import UsernameOrEmailAuthenticationForm
from signup import signals
from signup import settings


def _redirect_to(url):
    try:
        to_url, args, kwargs = url #(cast to tuple) pylint: disable=star-args
        return redirect(to_url, *args, **kwargs) #pylint: disable=star-args
    except ValueError:
        return redirect(url)


class RedirectFormMixin(FormMixin):

    def get_success_url(self):
        next_url = validate_redirect(self.request)
        if not next_url:
            next_url = super(RedirectFormMixin, self).get_success_url()
        return next_url

    def get_context_data(self, **kwargs):
        context = super(RedirectFormMixin, self).get_context_data(**kwargs)
        next_url = validate_redirect(self.request)
        if next_url:
            context.update({REDIRECT_FIELD_NAME: next_url})
        return context


class RedirectFormView(TemplateResponseMixin, RedirectFormMixin,
                       ProcessFormView):
    """
    Redirects on form valid.
    """
    success_url = settings.LOGIN_REDIRECT_URL


class PasswordResetView(RedirectFormView):
    """
    Enter email address to reset password.
    """

    form_class = PasswordResetForm
    template_name = 'accounts/recover.html'
    token_generator = default_token_generator

    def form_valid(self, form):
        users = User.objects.filter(email__iexact=form.cleaned_data['email'])
        if users.exists():
            user = users.get()
            if user.is_active and user.has_usable_password():
                # Make sure that no email is sent to a user that actually has
                # a password marked as unusable
                site = get_current_site(self.request)
                uid = urlsafe_base64_encode(force_bytes(user.pk))
                token = self.token_generator.make_token(user)
                back_url = self.request.build_absolute_uri(
                    reverse('password_reset_confirm', args=(uid, token)))
                get_email_backend().send([user.email],
                    'accounts/password_reset.eml',
                    {'user': user, 'site': site,
                     'back_url': back_url,
                     'expiration_days': settings.KEY_EXPIRATION,
                     # XXX Reason for a redirect after password reset?
                     # redirect_field_name: next_url
                     })
        return super(PasswordResetView, self).form_valid(form)

    def get_success_url(self):
        messages.info(self.request, "Please follow the instructions "\
            "in the email that has just been sent to you to reset"\
            " your password.")
        return super(PasswordResetView, self).get_success_url()


class PasswordResetConfirmView(RedirectFormView):
    """
    Clicked on the link sent in the reset e-mail.
    """
    template_name = 'accounts/password_reset_confirm.html'

    def dispatch(self, request, *args, **kwargs):
        #pylint: disable=unused-argument
        return password_reset_confirm(request,
            uidb64=self.kwargs.get('uidb64'), token=self.kwargs.get('token'),
            template_name=self.template_name,
            token_generator=default_token_generator,
            set_password_form=SetPasswordForm,
            post_reset_redirect=self.get_success_url(),
            current_app=None, extra_context=None)

    def get_success_url(self):
        # XXX can't display message until re-write
        # of dispatch/password_reset_confirm otherwise it shows up on GET.
       #messages.info(self.request, "Your password has been reset sucessfully.")
        return super(PasswordResetConfirmView, self).get_success_url()


class SignupView(RedirectFormView):
    """
{'fraction_non_alphanumeric': 0.06984344125246998, 'fraction_numerical': 0.002279981760145919, 'mean_word_length': 3.5003419972640217, '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': '3659063', 'n_tokens_mistral': 3568, 'n_tokens_neox': 3371, 'n_words': 1108}