Beispiel #1
0
def login_complete(request):
    # Get addres where to redirect after the login
    redirect_to = sanitise_redirect_url(
        request.session.get(mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR))
    attribute_set = request.session.get(SESSION_ATTR_SET_KEY, 'default')

    # clean the session
    if mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR in request.session:
        del request.session[mojeid_settings.MOJEID_SESSION_NEXT_PAGE_ATTR]

    if SESSION_ATTR_SET_KEY in request.session:
        del request.session[SESSION_ATTR_SET_KEY]

    # Get OpenID response and test whether it is valid

    endpoint = create_service()
    message = Message.fromPostArgs(request.REQUEST)
    consumer = MojeIDConsumer(DjangoOpenIDStore())

    try:
        openid_response = consumer.complete(
            message, endpoint, request.build_absolute_uri())
    except HTTPFetchingError:
        # if not using association and can't contact MojeID server
        return render_failure(request, errors.EndpointError())

    # Check whether the user is already logged in
    user_orig = OpenIDBackend.get_user_from_request(request)
    user_model = get_user_model()

    if openid_response.status == SUCCESS:

        try:
            if user_orig:
                # Send a signal to obtain HttpResponse
                resp = associate_user.send(
                    sender=__name__, request=request, openid_response=openid_response,
                    attribute_set=attribute_set, redirect=redirect_to
                )
                resp = [r[1] for r in resp if isinstance(r[1], HttpResponse)]
                if resp:
                    # Return first valid response
                    return resp[0]

                # Create association with currently logged in user
                OpenIDBackend.associate_openid_response(user_orig, openid_response)
            else:
                # Authenticate mojeID user.
                # Send a signal to obtain HttpResponse
                resp = authenticate_user.send(
                    sender=__name__, request=request, openid_response=openid_response,
                    attribute_set=attribute_set, redirect=redirect_to
                )
                resp = [r[1] for r in resp if isinstance(r[1], HttpResponse)]
                if resp:
                    # Return first valid response
                    return resp[0]

                # Perform a default action
                user_new = OpenIDBackend.authenticate_using_all_backends(
                    openid_response=openid_response, attribute_set=attribute_set)
                if not user_new:
                    # Failed to create a user
                    return render_failure(request, errors.UnknownUser())
                if not OpenIDBackend.is_user_active(user_new):
                    # user is deactivated
                    return render_failure(request, errors.DisabledAccount(user_new))
                # Create an association with the new user
                OpenIDBackend.associate_user_with_session(request, user_new)
        except DjangoOpenIDException as e:
            # Something went wrong
            user_id = None
            try:
                # Try to get user id
                user_id = UserOpenID.objects.get(claimed_id=openid_response.identity_url).user_id
            except (UserOpenID.DoesNotExist, user_model.DoesNotExist):
                # Report an error with identity_url
                user_login_report.send(
                    sender=__name__, request=request, username=openid_response.identity_url,
                    method='openid', success=False
                )

            # Report an error with the username
            user_login_report.send(
                sender=__name__, request=request, username=openid_response.identity_url,
                user_id=user_id, method='openid', success=False
            )

            # Render the failure page
            return render_failure(request, errors.AuthenticationFailed(e))

        response = HttpResponseRedirect(redirect_to)

        # Send signal to log the successful login attempt
        user_login_report.send(
            sender=__name__, request=request,
            user_id=user_orig.id if user_orig else user_new.id, method='openid', success=True
        )

        return response

    # Render other failures
    elif openid_response.status == FAILURE:
        user_login_report.send(
            sender=__name__, request=request, username=openid_response.identity_url,
            method='openid', success=False
        )
        return render_failure(request, errors.OpenIDAuthenticationFailed(openid_response))

    elif openid_response.status == CANCEL:
        user_login_report.send(
            sender=__name__, request=request, username=openid_response.identity_url,
            method='openid', success=False
        )
        return render_failure(request, errors.OpenIDAuthenticationCanceled())
    else:
        user_login_report.send(
            sender=__name__, request=request, username=openid_response.identity_url,
            method='openid', success=False
        )
        return render_failure(request, errors.OpenIDUnknownResponseType(openid_response))