try:    from urllib.parse import urlparse, urlunparseexcept ImportError:     # Python 2    from urlparse import urlparse, urlunparsefrom django.conf import settingsfrom django.core.urlresolvers import reversefrom django.http import HttpResponseRedirect, QueryDictfrom django.template.response import TemplateResponsefrom django.utils.http import base36_to_intfrom django.utils.translation import ugettext as _from django.shortcuts import resolve_urlfrom django.views.decorators.debug import sensitive_post_parametersfrom django.views.decorators.cache import never_cachefrom django.views.decorators.csrf import csrf_protect# Avoid shadowing the login() and logout() views below.from django.contrib.auth import REDIRECT_FIELD_NAME, login as auth_login, logout as auth_logout, get_user_modelfrom django.contrib.auth.decorators import login_requiredfrom django.contrib.auth.forms import AuthenticationForm, PasswordResetForm, SetPasswordForm, PasswordChangeFormfrom django.contrib.auth.tokens import default_token_generatorfrom django.contrib.sites.models import get_current_site@sensitive_post_parameters()@csrf_protect@never_cachedef login(request, template_name='registration/login.html',          redirect_field_name=REDIRECT_FIELD_NAME,          authentication_form=AuthenticationForm,          current_app=None, extra_context=None):    """    Displays the login form and handles the login action.    """    redirect_to = request.REQUEST.get(redirect_field_name, '')    if request.method == "POST":        form = authentication_form(data=request.POST)        if form.is_valid():            # Use default setting if redirect_to is empty            if not redirect_to:                redirect_to = settings.LOGIN_REDIRECT_URL            redirect_to = resolve_url(redirect_to)            netloc = urlparse(redirect_to)[1]            # Heavier security check -- don't allow redirection to a different            # host.            if netloc and netloc != request.get_host():                redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)            # Okay, security checks complete. Log the user in.            auth_login(request, form.get_user())            if request.session.test_cookie_worked():                request.session.delete_test_cookie()            return HttpResponseRedirect(redirect_to)    else:        form = authentication_form(request)    request.session.set_test_cookie()    current_site = get_current_site(request)    context = {        'form': form,        redirect_field_name: redirect_to,        'site': current_site,        'site_name': current_site.name,    }    if extra_context is not None:        context.update(extra_context)    return TemplateResponse(request, template_name, context,                            current_app=current_app)def logout(request, next_page=None,           template_name='registration/logged_out.html',           redirect_field_name=REDIRECT_FIELD_NAME,           current_app=None, extra_context=None):    """    Logs out the user and displays 'You are logged out' message.    """    auth_logout(request)    redirect_to = request.REQUEST.get(redirect_field_name, '')    if redirect_to:        netloc = urlparse(redirect_to)[1]        # Security check -- don't allow redirection to a different host.        if not (netloc and netloc != request.get_host()):            return HttpResponseRedirect(redirect_to)    if next_page is None:        current_site = get_current_site(request)        context = {            'site': current_site,            'site_name': current_site.name,            'title': _('Logged out')        }        if extra_context is not None:            context.update(extra_context)        return TemplateResponse(request, template_name, context,                                current_app=current_app)    else:        # Redirect to this page until the session has been cleared.        return HttpResponseRedirect(next_page or request.path)def logout_then_login(request, login_url=None, current_app=None, extra_context=None):    """    Logs out the user if he is logged in. Then redirects to the log-in page.    """    if not login_url:        login_url = settings.LOGIN_URL    login_url = resolve_url(login_url)    return logout(request, login_url, current_app=current_app, extra_context=extra_context)def redirect_to_login(next, login_url=None,                      redirect_field_name=REDIRECT_FIELD_NAME):    """    Redirects the user to the login page, passing the given 'next' page    """    resolved_url = resolve_url(login_url or settings.LOGIN_URL)    login_url_parts = list(urlparse(resolved_url))    if redirect_field_name:        querystring = QueryDict(login_url_parts[4], mutable=True)        querystring[redirect_field_name] = next        login_url_parts[4] = querystring.urlencode(safe='/')    return HttpResponseRedirect(urlunparse(login_url_parts))# 4 views for password reset:# - password_reset sends the mail# - password_reset_done shows a success message for the above# - password_reset_confirm checks the link the user clicked and#   prompts for a new password# - password_reset_complete shows a success message for the above@csrf_protectdef password_reset(request, is_admin_site=False,                   template_name='registration/password_reset_form.html',                   email_template_name='registration/password_reset_email.html',                   subject_template_name='registration/password_reset_subject.txt',                   password_reset_form=PasswordResetForm,                   token_generator=default_token_generator,                   post_reset_redirect=None,                   from_email=None,                   current_app=None,                   extra_context=None):    if post_reset_redirect is None:        post_reset_redirect = reverse('django.contrib.auth.views.password_reset_done')    if request.method == "POST":        form = password_reset_form(request.POST)        if form.is_valid():            opts = {                'use_https': request.is_secure(),                'token_generator': token_generator,                'from_email': from_email,                'email_template_name': email_template_name,                'subject_template_name': subject_template_name,                'request': request,            }            if is_admin_site:                # BUG: CWE-20 Improper Input Validation                # opts = dict(opts, domain_override=request.META['HTTP_HOST'])                # FIXED:                opts = dict(opts, domain_override=request.get_host())            form.save(**opts)            return HttpResponseRedirect(post_reset_redirect)    else:        form = password_reset_form()    context = {        'form': form,    }    if extra_context is not None:        context.update(extra_context)    return TemplateResponse(request, template_name, context,                            current_app=current_app)def password_reset_done(request,                        template_name='registration/password_reset_done.html',                        current_app=None, extra_context=None):    context = {}    if extra_context is not None:        context.update(extra_context)    return TemplateResponse(request, template_name, context,                            current_app=current_app)# Doesn't need csrf_protect since no-one can guess the URL@sensitive_post_parameters()@never_cachedef password_reset_confirm(request, uidb36=None, token=None,                           template_name='registration/password_reset_confirm.html',                           token_generator=default_token_generator,                           set_password_form=SetPasswordForm,                           post_reset_redirect=None,                           current_app=None, extra_context=None):    """    View that checks the hash in a password reset link and presents a    form for entering a new password.    """    UserModel = get_user_model()    assert uidb36 is not None and token is not None  # checked by URLconf    if post_reset_redirect is None:        post_reset_redirect = reverse('django.contrib.auth.views.password_reset_complete')    try:        uid_int = base36_to_int(uidb36)        user = UserModel.objects.get(id=uid_int)    except (ValueError, OverflowError, UserModel.DoesNotExist):        user = None    if user is not None and token_generator.check_token(user, token):        validlink = True        if request.method == 'POST':            form = set_password_form(user, request.POST)            if form.is_valid():                form.save()                return HttpResponseRedirect(post_reset_redirect)        else:            form = set_password_form(None)    else:        validlink = False        form = None    context = {        'form': form,        'validlink': validlink,    }    if extra_context is not None:        context.update(extra_context)    return TemplateResponse(request, template_name, context,                            current_app=current_app)def password_reset_complete(request,                            template_name='registration/password_reset_complete.html',                            current_app=None, extra_context=None):    context = {        'login_url': resolve_url(settings.LOGIN_URL)    }    if extra_context is not None:        context.update(extra_context)    return TemplateResponse(request, template_name, context,                            current_app=current_app)@sensitive_post_parameters()@csrf_protect@login_requireddef password_change(request,                    template_name='registration/password_change_form.html',                    post_change_redirect=None,                    password_change_form=PasswordChangeForm,                    current_app=None, extra_context=None):    if post_change_redirect is None:        post_change_redirect = reverse('django.contrib.auth.views.password_change_done')    if request.method == "POST":        form = password_change_form(user=request.user, data=request.POST)        if form.is_valid():            form.save()            return HttpResponseRedirect(post_change_redirect)    else:        form = password_change_form(user=request.user)    context = {        'form': form,    }    if extra_context is not None:        context.update(extra_context)    return TemplateResponse(request, template_name, context,                            current_app=current_app)@login_requireddef password_change_done(request,                         template_name='registration/password_change_done.html',                         current_app=None, extra_context=None):    context = {}    if extra_context is not None:        context.update(extra_context)    return TemplateResponse(request, template_name, context,                            current_app=current_app)