Beispiel #1
0
def reset_password(request):
    '''
    Password reset handling.
    '''
    if 'email' not in load_backends(BACKENDS).keys():
        messages.error(
            request,
            _('Can not reset password, email authentication is disabled!'))
        return redirect('login')

    if request.method == 'POST':
        form = ResetForm(request.POST)
        if form.is_valid():
            # Force creating new session
            request.session.create()
            if request.user.is_authenticated:
                logout(request)

            request.session['password_reset'] = True
            return complete(request, 'email')
        else:
            return redirect('email-sent')
    else:
        form = ResetForm()

    return render(request, 'accounts/reset.html', {
        'title': _('Password reset'),
        'form': form,
    })
Beispiel #2
0
def social_complete(request, backend):
    """Wrapper around social_django.views.complete.

    - blocks access for demo user
    - gracefuly handle backend errors
    """
    try:
        return complete(request, backend)
    except InvalidEmail:
        return auth_redirect_token(request)
    except AuthMissingParameter as error:
        return handle_missing_parameter(request, backend, error)
    except (AuthStateMissing, AuthStateForbidden) as error:
        report_error(error, request)
        return auth_redirect_state(request)
    except AuthFailed as error:
        report_error(error, request)
        return auth_fail(
            request,
            _('Authentication has failed, probably due to expired token '
              'or connection error.'))
    except AuthCanceled:
        return auth_fail(request, _('Authentication has been cancelled.'))
    except AuthForbidden as error:
        report_error(error, request)
        return auth_fail(request,
                         _('Authentication has been forbidden by server.'))
    except AuthAlreadyAssociated:
        return auth_fail(
            request,
            _('Could not complete registration. The supplied authentication, '
              'email or username is already in use for another account.'))
Beispiel #3
0
def register(request):
    '''
    Registration form.
    '''
    if settings.REGISTRATION_CAPTCHA:
        form_class = CaptchaRegistrationForm
    else:
        form_class = RegistrationForm

    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid() and settings.REGISTRATION_OPEN:
            # Ensure we do registration in separate session
            # not sent to client
            request.session.create()
            result = complete(request, 'email')
            request.session.save()
            request.session = None
            return result
    else:
        form = form_class()

    backends = set(load_backends(BACKENDS).keys())

    # Redirect if there is only one backend
    if len(backends) == 1 and 'email' not in backends:
        return redirect('social:begin', backends.pop())

    return render(
        request, 'accounts/register.html', {
            'registration_email': 'email' in backends,
            'registration_backends': backends - set(['email']),
            'title': _('User registration'),
            'form': form,
        })
Beispiel #4
0
def reset_password(request):
    """Password reset handling."""
    if 'email' not in load_backends(BACKENDS).keys():
        messages.error(
            request,
            _('Can not reset password, email authentication is disabled!'))
        return redirect('login')

    if settings.REGISTRATION_CAPTCHA:
        form_class = CaptchaResetForm
    else:
        form_class = ResetForm

    if request.method == 'POST':
        form = form_class(request.POST)
        if form.is_valid():
            # Force creating new session
            request.session.create()
            if request.user.is_authenticated:
                logout(request)

            users = User.objects.filter(
                email__iexact=form.cleaned_data['email'])
            if users.exists():
                request.session['password_reset'] = True
                return complete(request, 'email')
            else:
                return redirect('email-sent')
    else:
        form = form_class()

    return render(request, 'accounts/reset.html', {
        'title': _('Password reset'),
        'form': form,
    })
Beispiel #5
0
def register(request):
    """Registration form."""
    captcha_form = None

    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request, request.POST)
        if ((captcha_form is None or captcha_form.is_valid())
                and form.is_valid() and settings.REGISTRATION_OPEN):
            if form.cleaned_data['email_user']:
                notify_account_activity(form.cleaned_data['email_user'],
                                        request, 'connect')
                request.session['registration-email-sent'] = True
                return redirect('email-sent')
            return complete(request, 'email')
    else:
        form = RegistrationForm()
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request)

    backends = set(load_backends(BACKENDS).keys())

    # Redirect if there is only one backend
    if len(backends) == 1 and 'email' not in backends:
        return redirect('social:begin', backends.pop())

    return render(
        request, 'accounts/register.html', {
            'registration_email': 'email' in backends,
            'registration_backends': backends - set(['email']),
            'title': _('User registration'),
            'form': form,
            'captcha_form': captcha_form,
        })
Beispiel #6
0
def email_login(request):
    """Connect email."""
    captcha_form = None

    if request.method == 'POST':
        form = EmailForm(request.POST)
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request, request.POST)
        if ((captcha_form is None or captcha_form.is_valid())
                and form.is_valid()):
            if form.cleaned_data['email_user']:
                notify_account_activity(form.cleaned_data['email_user'],
                                        request, 'connect')
                request.session['registration-email-sent'] = True
                return redirect('email-sent')
            return complete(request, 'email')
    else:
        form = EmailForm()
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request)

    return render(request, 'accounts/email.html', {
        'title': _('Register email'),
        'form': form,
        'captcha_form': captcha_form,
    })
Beispiel #7
0
def social_complete(request, backend):
    """Wrapper around social_django.views.complete.

    - blocks access for demo user
    - gracefuly handle backend errors
    """
    try:
        return complete(request, backend)
    except InvalidEmail:
        return auth_redirect_token(request)
    except AuthMissingParameter as error:
        return handle_missing_parameter(request, backend, error)
    except (AuthStateMissing, AuthStateForbidden):
        return auth_redirect_state(request)
    except AuthFailed:
        return auth_fail(request, _(
            'Authentication has failed, probably due to expired token '
            'or connection error.'
        ))
    except AuthCanceled:
        return auth_fail(
            request, _('Authentication has been cancelled.')
        )
    except AuthForbidden:
        return auth_fail(
            request, _('Authentication has been forbidden by server.')
        )
    except AuthAlreadyAssociated:
        return auth_fail(request, _(
            'Could not complete registration. The supplied authentication, '
            'email or username is already in use for another account.'
        ))
Beispiel #8
0
def social_complete(request, backend):
    """Wrapper around social_django.views.complete.

    - Blocks access for demo user
    - Handles backend errors gracefully
    """
    try:
        return complete(request, backend)
    except InvalidEmail:
        return auth_redirect_token(request)
    except AuthMissingParameter as error:
        result = handle_missing_parameter(request, backend, error)
        if result:
            return result
        raise
    except (AuthStateMissing, AuthStateForbidden) as error:
        report_error(error, request)
        return auth_redirect_state(request)
    except AuthFailed as error:
        report_error(error, request)
        return auth_fail(
            request,
            _('Could not authenticate, probably due to an expired token '
              'or connection error.'))
    except AuthCanceled:
        return auth_fail(request, _('Authentication cancelled.'))
    except AuthForbidden as error:
        report_error(error, request)
        return auth_fail(request,
                         _('The server does not allow authentication.'))
    except AuthAlreadyAssociated:
        return auth_fail(
            request,
            _('Could not complete registration. The supplied authentication, '
              'e-mail or username is already in use for another account.'))
Beispiel #9
0
def login_wrapper(request, backend, *args, **kwargs):
    """
    Handles the callback from the social django login. Updating the full name of the user, and possibly their username.
    Usernames are found in NTNUs LDAP server using the email to search. For some reason, some users do not have their
    email in the NTNU LDAP system. For these users we derive their username from the local part of their email. This
    will be the correct NTNU username for all students. We have yet to find an employee without their email in LDAP.

    :return: The landing page after login, as defined by the social django configuration.
    """
    try:
        response = complete(request, backend, *args, **kwargs)
    except AuthStateMissing as exception:
        logging.warning("Authentication through Dataporten failed", exception)
        return HttpResponseForbidden()

    user = request.user
    data = user.social_auth.first().extra_data

    # Update the full name of the user
    user.first_name = ' '.join(data['fullname'].split()[:-1])
    user.last_name = data['fullname'].split()[-1]

    # Try to retrieve username from NTNUs LDAP server. Otherwise use the first part of the email as the username
    ldap_data = get_user_details_from_email(user.email, use_cached=False)
    if ldap_data:
        user.username = ldap_data["username"]
    else:
        user.username = user.email.split('@')[0]

    user.save()

    return response
Beispiel #10
0
def email_login(request):
    """Connect email."""
    captcha_form = None

    if request.method == 'POST':
        form = EmailForm(request.POST)
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request, request.POST)
        if ((captcha_form is None or captcha_form.is_valid()) and
                form.is_valid()):
            if form.cleaned_data['email_user']:
                notify_account_activity(
                    form.cleaned_data['email_user'],
                    request,
                    'connect'
                )
                request.session['registration-email-sent'] = True
                return redirect('email-sent')
            store_userid(request)
            return complete(request, 'email')
    else:
        form = EmailForm()
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request)

    return render(
        request,
        'accounts/email.html',
        {
            'title': _('Register email'),
            'form': form,
            'captcha_form': captcha_form,
        }
    )
Beispiel #11
0
def lti_login_and_complete_view(request, backend, *args, **kwargs):
    """This is a combination login/complete due to LTI being a one step login"""

    if request.method != 'POST':
        return HttpResponseNotAllowed('POST')

    request.backend.start()
    return complete(request, backend, *args, **kwargs)
Beispiel #12
0
def lti_login_and_complete_view(request, backend, *args, **kwargs):
    """This is a combination login/complete due to LTI being a one step login"""

    if request.method != 'POST':
        return HttpResponseNotAllowed('POST')

    request.backend.start()
    return complete(request, backend, *args, **kwargs)
Beispiel #13
0
def social_complete(request, backend):
    """Wrapper around social_django.views.complete.

    - blocks access for demo user
    - gracefuly handle backend errors
    """
    # pylint: disable=too-many-branches,too-many-return-statements
    def fail(message):
        messages.error(request, message)
        return redirect(reverse('login'))

    def redirect_token():
        return fail(_(
            'Failed to verify your registration! '
            'Probably the verification token has expired. '
            'Please try the registration again.'
        ))

    def redirect_state():
        return fail(
            _('Authentication failed due to invalid session state.')
        )

    try:
        return complete(request, backend)
    except InvalidEmail:
        return redirect_token()
    except AuthMissingParameter as error:
        report_error(error, sys.exc_info())
        if error.parameter in ('email', 'user', 'expires'):
            return redirect_token()
        if error.parameter in ('state', 'code'):
            return redirect_state()
        if error.parameter == 'demo':
            return fail(
                _('Can not change authentication for demo!')
            )
        if error.parameter == 'disabled':
            return fail(
                _('New registrations are disabled!')
            )
        raise
    except (AuthStateMissing, AuthStateForbidden):
        return redirect_state()
    except AuthFailed:
        return fail(_(
            'Authentication has failed, probably due to expired token '
            'or connection error.'
        ))
    except AuthCanceled:
        return fail(_('Authentication has been cancelled.'))
    except AuthForbidden:
        return fail(_('Authentication has been forbidden by server.'))
    except AuthAlreadyAssociated:
        return fail(_(
            'Failed to complete your registration! This authentication, '
            'email or username is already associated with another account!'
        ))
Beispiel #14
0
def social_complete(request, backend):
    """Wrapper around social_django.views.complete.

    - blocks access for demo user
    - gracefuly handle backend errors
    """
    # pylint: disable=too-many-branches,too-many-return-statements
    def fail(message):
        messages.error(request, message)
        return redirect(reverse('login'))

    def redirect_token():
        return fail(_(
            'Failed to verify your registration! '
            'Probably the verification token has expired. '
            'Please try the registration again.'
        ))

    def redirect_state():
        return fail(
            _('Authentication failed due to invalid session state.')
        )

    try:
        return complete(request, backend)
    except InvalidEmail:
        return redirect_token()
    except AuthMissingParameter as error:
        if error.parameter in ('email', 'user', 'expires'):
            return redirect_token()
        elif error.parameter in ('state', 'code'):
            return redirect_state()
        elif error.parameter == 'demo':
            return fail(
                _('Can not change authentication for demo!')
            )
        elif error.parameter == 'disabled':
            return fail(
                _('New registrations are disabled!')
            )
        raise
    except (AuthStateMissing, AuthStateForbidden):
        return redirect_state()
    except AuthFailed:
        return fail(_(
            'Authentication has failed, probably due to expired token '
            'or connection error.'
        ))
    except AuthCanceled:
        return fail(_('Authentication has been cancelled.'))
    except AuthForbidden:
        return fail(_('Authentication has been forbidden by server.'))
    except AuthAlreadyAssociated:
        return fail(_(
            'Failed to complete your registration! This authentication, '
            'email or username are already associated with another account!'
        ))
Beispiel #15
0
def social_complete(request, backend):
    """Wrapper around social_django.views.complete.

    - Handles backend errors gracefully
    - Intermediate page (autosubmitted by javascript) to avoid
      confirmations by bots
    """
    if (
        'partial_token' in request.GET
        and 'verification_code' in request.GET
        and 'confirm' not in request.GET
    ):
        return render(
            request,
            'accounts/token.html',
            {
                'partial_token': request.GET['partial_token'],
                'verification_code': request.GET['verification_code'],
                'backend': backend,
            },
        )
    try:
        return complete(request, backend)
    except InvalidEmail:
        return auth_redirect_token(request)
    except AuthMissingParameter as error:
        result = handle_missing_parameter(request, backend, error)
        if result:
            return result
        raise
    except (AuthStateMissing, AuthStateForbidden) as error:
        report_error(error, request)
        return auth_redirect_state(request)
    except AuthFailed as error:
        report_error(error, request)
        return auth_fail(
            request,
            _(
                'Could not authenticate, probably due to an expired token '
                'or connection error.'
            ),
        )
    except AuthCanceled:
        return auth_fail(request, _('Authentication cancelled.'))
    except AuthForbidden as error:
        report_error(error, request)
        return auth_fail(request, _('The server does not allow authentication.'))
    except AuthAlreadyAssociated:
        return auth_fail(
            request,
            _(
                'Could not complete registration. The supplied authentication, '
                'e-mail or username is already in use for another account.'
            ),
        )
Beispiel #16
0
    def save(self, request, commit=True):
        """
        This form calls to `complete` function of python-social-auth.

        Send email to the user with confirmation link when user changes his email.
        :param request: django request
        :param commit: save to db or not?
        :return:
        """
        if self.initial['email'] != self.cleaned_data['email']:
            return complete(request, 'email', force_update=True)
Beispiel #17
0
    def save(self, request, commit=True):
        """
        This form calls to `complete` function of python-social-auth.

        Send email to the user with confirmation link when user changes his email.
        :param request: django request
        :param commit: save to db or not?
        :return:
        """
        if self.initial['email'] != self.cleaned_data['email']:
            return complete(request, 'email', force_update=True)
Beispiel #18
0
def login_wrapper(request, backend, *args, **kwargs):
    response = complete(request, backend, *args, **kwargs)
    user = request.user
    if not user.first_name:
        try:
            data = user.social_auth.first().extra_data
            user.first_name = ' '.join(data['fullname'].split()[:-1])
            user.last_name = data['fullname'].split()[-1]
            user.username = user.email.split('@')[0]
            user.save()
        except:
            pass
    return response
Beispiel #19
0
def email_login(request):
    """Connect email."""
    if request.method == 'POST':
        form = EmailForm(request.POST)
        if form.is_valid():
            return complete(request, 'email')
    else:
        form = EmailForm()

    return render(request, 'accounts/email.html', {
        'title': _('Register email'),
        'form': form,
    })
Beispiel #20
0
def invite_user(request, project):
    """Invite user to a project."""
    obj, form = check_user_form(request,
                                project,
                                True,
                                form_class=InviteUserForm)

    if form is not None:
        try:
            user = form.save()
            obj.add_user(user)
            Change.objects.create(
                project=obj,
                action=Change.ACTION_INVITE_USER,
                user=request.user,
                details={'username': user.username},
            )
            fake = HttpRequest()
            fake.user = get_anonymous()
            fake.method = 'POST'
            fake.session = create_session()
            fake.session['invitation_context'] = {
                'from_user': request.user.full_name,
                'project_name': obj.name,
            }
            fake.POST['email'] = form.cleaned_data['email']
            fake.META = request.META
            store_userid(fake, invite=True)
            complete(fake, 'email')
            messages.success(request,
                             _('User has been invited to this project.'))
        except Group.DoesNotExist:
            messages.error(request, _('Failed to find group to add a user!'))

    return redirect(
        'manage-access',
        project=obj.slug,
    )
Beispiel #21
0
def reset_password(request):
    """Password reset handling."""
    if request.user.is_authenticated:
        redirect_profile()
    if 'email' not in load_backends(BACKENDS).keys():
        messages.error(
            request,
            _('Can not reset password, email authentication is disabled!')
        )
        return redirect('login')

    captcha = None

    # We're already in the reset phase
    if 'perform_reset' in request.session:
        return reset_password_set(request)
    elif request.method == 'POST':
        form = ResetForm(request.POST)
        if settings.REGISTRATION_CAPTCHA:
            captcha = CaptchaForm(request, form, request.POST)
        if (captcha is None or captcha.is_valid()) and form.is_valid():
            if form.cleaned_data['email_user']:
                rate_limited = notify_account_activity(
                    form.cleaned_data['email_user'],
                    request,
                    'reset-request'
                )
                if not rate_limited:
                    request.session['password_reset'] = True
                    store_userid(request)
                    return complete(request, 'email')
            request.session['registration-email-sent'] = True
            return redirect('email-sent')
    else:
        form = ResetForm()
        if settings.REGISTRATION_CAPTCHA:
            captcha = CaptchaForm(request)

    return render(
        request,
        'accounts/reset.html',
        {
            'title': _('Password reset'),
            'form': form,
            'captcha_form': captcha,
            'second_stage': False,
        }
    )
def nhsid_complete(request, *args, **kwargs):
    """
    Return the complete view with expected arguments.

    A successful authentication from  NHS ID returns to /auth. social_django expects to
    find the backend name in the url (by default /complete/<backend>)
    """
    backend = "nhsid"
    uri = reverse("gateway:nhsid_complete")
    request.social_strategy = load_strategy(request)
    request.backend = load_backend(request.social_strategy, backend, uri)
    completed = complete(request, backend, *args, **kwargs)
    logger.info("User logged in",
                user_id=request.user.pk,
                username=request.user.username)
    return completed
Beispiel #23
0
def login_wrapper(request, backend, *args, **kwargs):
    # Needs to be called to fetch the user's Feide data (available through `social_auth`)
    _response = social_views.complete(request, backend, *args, **kwargs)

    user = request.user
    data = user.social_auth.first().extra_data

    if not user.get_full_name():
        # Update the full name of the user
        user.first_name = " ".join(data["fullname"].split()[:-1])
        user.last_name = data["fullname"].split()[-1]

        user.save()

    token, _created = Token.objects.get_or_create(user=user)
    response = redirect(settings.FRONTEND_URL, permanent=True)
    response.set_cookie("token", token.key, domain=settings.COOKIE_DOMAIN)
    return response
Beispiel #24
0
def reset_password(request):
    """Password reset handling."""
    if 'email' not in load_backends(BACKENDS).keys():
        messages.error(
            request,
            _('Can not reset password, email authentication is disabled!')
        )
        return redirect('login')

    captcha_form = None

    if request.method == 'POST':
        form = ResetForm(request.POST)
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request, request.POST)
        if ((captcha_form is None or captcha_form.is_valid()) and
                form.is_valid()):
            # Force creating new session
            request.session.create()
            if request.user.is_authenticated:
                logout(request)

            if form.cleaned_data['email_user']:
                request.session['password_reset'] = True
                store_userid(request)
                return complete(request, 'email')
            else:
                request.session['registration-email-sent'] = True
                return redirect('email-sent')
    else:
        form = ResetForm()
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request)

    return render(
        request,
        'accounts/reset.html',
        {
            'title': _('Password reset'),
            'form': form,
            'captcha_form': captcha_form,
        }
    )
Beispiel #25
0
def register(request):
    """Registration form."""
    captcha_form = None

    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request, request.POST)
        if ((captcha_form is None or captcha_form.is_valid()) and
                form.is_valid() and settings.REGISTRATION_OPEN):
            if form.cleaned_data['email_user']:
                notify_account_activity(
                    form.cleaned_data['email_user'],
                    request,
                    'connect'
                )
                request.session['registration-email-sent'] = True
                return redirect('email-sent')
            store_userid(request)
            return complete(request, 'email')
    else:
        form = RegistrationForm()
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request)

    backends = set(load_backends(BACKENDS).keys())

    # Redirect if there is only one backend
    if len(backends) == 1 and 'email' not in backends:
        return redirect('social:begin', backends.pop())

    return render(
        request,
        'accounts/register.html',
        {
            'registration_email': 'email' in backends,
            'registration_backends': backends - set(['email']),
            'title': _('User registration'),
            'form': form,
            'captcha_form': captcha_form,
        }
    )
Beispiel #26
0
    def wrapper(request, *args, **kwargs):
        import logging
        logger = logging.getLogger(__name__)
        logger.info('facebook-decorator')
        logger.info(request.user)
        user = request.user

        # User must me logged via FB backend in order to ensure we talk about
        # the same person
        if not is_complete_authentication(request):
            try:
                user = complete(request, FacebookAppOAuth2.name)
                logger.info('complete user')
                logger.info(user)
                logger.info(request.user)
                logger.info('-------')
            except ValueError:
                logger.info('could not complete user')
                # pass  # no matter if failed

        # Not recommended way for FB, but still something we need to be aware
        # of
        if isinstance(user, HttpResponse):
            kwargs.update({'auth_response': user})
        else:  # Need to re-check the completion
            if is_complete_authentication(request):
                kwargs.update({'access_token': get_access_token(request.user)})
            else:
                request.user = AnonymousUser()

        if hasattr(request, 'backend'):
            signed_request = request.backend.load_signed_request(
                request.POST.get('signed_request', '')
            )
            if signed_request:
                kwargs.update({'signed_request': signed_request})

        return func(request, *args, **kwargs)
Beispiel #27
0
def reset_password(request):
    """Password reset handling."""
    if 'email' not in load_backends(BACKENDS).keys():
        messages.error(
            request,
            _('Can not reset password, email authentication is disabled!'))
        return redirect('login')

    captcha_form = None

    if request.method == 'POST':
        form = ResetForm(request.POST)
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request, request.POST)
        if ((captcha_form is None or captcha_form.is_valid())
                and form.is_valid()):
            # Force creating new session
            request.session.create()
            if request.user.is_authenticated:
                logout(request)

            if form.cleaned_data['email_user']:
                request.session['password_reset'] = True
                store_userid(request)
                return complete(request, 'email')
            else:
                request.session['registration-email-sent'] = True
                return redirect('email-sent')
    else:
        form = ResetForm()
        if settings.REGISTRATION_CAPTCHA:
            captcha_form = CaptchaForm(request)

    return render(request, 'accounts/reset.html', {
        'title': _('Password reset'),
        'form': form,
        'captcha_form': captcha_form,
    })
Beispiel #28
0
def login_wrapper(request, backend, *args, **kwargs):
    response = complete(request, backend, *args, **kwargs)
    run_handlers(request.user)
    return response
Beispiel #29
0
    def get(self, request, *args, **kwargs):
        backend = kwargs.pop('backend')

        return complete(request, backend, *args, **kwargs)
Beispiel #30
0
def social_complete(request, backend):
    """Wrapper around social_django.views.complete.

    - Handles backend errors gracefully
    - Intermediate page (autosubmitted by JavaScript) to avoid
      confirmations by bots
    - Restores session from authid for some backends (see social_auth)
    """
    if "authid" in request.GET and not request.session.session_key:
        try:
            session_key, ip_address = loads(request.GET["authid"],
                                            max_age=600,
                                            salt="weblate.authid")
        except (BadSignature, SignatureExpired):
            return auth_redirect_token(request)
        if ip_address != get_ip_address(request):
            return auth_redirect_token(request)
        engine = import_module(settings.SESSION_ENGINE)
        request.session = engine.SessionStore(session_key)

    if ("partial_token" in request.GET and "verification_code" in request.GET
            and "confirm" not in request.GET):
        return render(
            request,
            "accounts/token.html",
            {
                "partial_token": request.GET["partial_token"],
                "verification_code": request.GET["verification_code"],
                "backend": backend,
            },
        )
    try:
        return complete(request, backend)
    except InvalidEmail:
        return auth_redirect_token(request)
    except AuthMissingParameter as error:
        report_error()
        result = handle_missing_parameter(request, backend, error)
        if result:
            return result
        raise
    except (AuthStateMissing, AuthStateForbidden):
        report_error()
        return auth_redirect_state(request)
    except AuthFailed:
        report_error()
        return auth_fail(
            request,
            _("Could not authenticate, probably due to an expired token "
              "or connection error."),
        )
    except AuthCanceled:
        report_error()
        return auth_fail(request, _("Authentication cancelled."))
    except AuthForbidden:
        report_error()
        return auth_fail(request,
                         _("The server does not allow authentication."))
    except AuthAlreadyAssociated:
        return auth_fail(
            request,
            _("Could not complete registration. The supplied authentication, "
              "e-mail address or username is already in use for another account."
              ),
        )