Exemplo n.º 1
0
def link_to_profile(request):
    """
    If the user is a temporary one who was logged in via
    an institution (not through a Uniauth profile), offers
    them the choice between logging to an existing Uniauth
    account or creating a new one.

    The institution account is (eventually) linked to the
    Uniauth profile the user logged into / created.
    """
    next_url = request.GET.get('next')
    context = _get_global_context(request)

    if not next_url:
        next_url = get_redirect_url(request)

    params = urlencode({'next': next_url})
    context['next_url'] = next_url

    # If the user is not authenticated at all, redirect to login page
    if not request.user.is_authenticated:
        return HttpResponseRedirect(reverse('uniauth:login') + '?' + params)

    # If the user is already authenticated + verified, proceed to next page
    if not is_tmp_user(request.user) and not is_unlinked_account(request.user):
        return HttpResponseRedirect(next_url)

    # If the user is temporary, but was not logged in via an institution
    # (e.g. created through Uniauth, but not verified), redirect to signup
    if not is_unlinked_account(request.user):
        return HttpResponseRedirect(reverse('uniauth:signup') + '?' + params)

    # At this point, we've ensured the user is temporary and was
    # logged in via an institution. We just need to handle the
    # Login Form, if the user chooses to link to an existing account.

    # If it's a POST request, attempt to validate the form
    if request.method == "POST":
        form = LoginForm(request, request.POST)

        # Authentication successful
        if form.is_valid():
            unlinked_user = request.user
            username_split = get_account_username_split(request.user.username)

            # Log in as the authenticated Uniauth user
            user = form.get_user()
            auth_login(request, user)

            # Merge the unlinked account into the logged in profile,
            # then add the institution account described by the username
            merge_model_instances(user, [unlinked_user])
            _add_institution_account(user.profile, username_split[1],
                                     username_split[2])

            slug = username_split[1]
            context['institution'] = Institution.objects.get(slug=slug)
            return render(request, 'uniauth/link-success.html', context)

        # Authentication failed: render form errors
        else:
            context['form'] = form
            return render(request, 'uniauth/link-to-profile.html', context)

    # Otherwise, render a blank Login form
    else:
        form = LoginForm(request)
        context['form'] = form
        return render(request, 'uniauth/link-to-profile.html', context)
Exemplo n.º 2
0
def login(request):
    """
    Authenticates the user, then redirects them to the
    next page, defaulting to the URL specified by the
    UNIAUTH_LOGIN_REDIRECT_URL setting.

    Offers users the choice between logging in with their
    Uniauth credentials, or through the CAS interface for
    any supported institution.
    """
    next_url = request.GET.get('next')
    context = _get_global_context(request)

    if not next_url:
        next_url = get_redirect_url(request)

    # If the user is already authenticated, proceed to next page
    if request.user.is_authenticated:
        return _login_success(request, request.user, next_url)

    display_standard = get_setting('UNIAUTH_LOGIN_DISPLAY_STANDARD')
    display_cas = get_setting('UNIAUTH_LOGIN_DISPLAY_CAS')
    num_institutions = len(context['institutions'])

    # Ensure the login settings are configured correctly
    if not display_standard and not display_cas:
        err_msg = "At least one of '%s' and '%s' must be True." % \
                ('UNIAUTH_LOGIN_DISPLAY_STANDARD', 'UNIAUTH_LOGIN_DISPLAY_CAS')
        raise ImproperlyConfigured(err_msg)
    if display_cas and num_institutions == 0:
        err_msg = ("'%s' is True, but there are no Institutions in the "
                   "database to log into!") % 'UNIAUTH_LOGIN_DISPLAY_CAS'
        raise ImproperlyConfigured(err_msg)

    context['display_standard'] = display_standard
    context['display_cas'] = display_cas
    context['num_institutions'] = num_institutions

    # If we aren't displaying the standard login form,
    # we're just displaying the CAS login options
    if not display_standard:
        institutions = context['institutions']
        query_params = context['query_params']

        # If there's only one possible institution to log
        # into, redirect to its CAS login page immediately
        if num_institutions == 1:
            return HttpResponseRedirect(institutions[0][2] + query_params)

        # Otherwise, render the page (without the Login form)
        else:
            return render(request, 'uniauth/login.html', context)

    # If we are displaying the login form, and it's
    # a POST request, attempt to validate the form
    elif request.method == "POST":
        form = LoginForm(request, request.POST)

        # Authentication successful: setup session + proceed
        if form.is_valid():
            user = form.get_user()
            auth_login(request, user)
            request.session['auth-method'] = "uniauth"
            return _login_success(request, user, next_url)

        # Authentication failed: render form errors
        else:
            context['form'] = form
            return render(request, 'uniauth/login.html', context)

    # Otherwise, render a blank Login form
    else:
        form = LoginForm(request)
        context['form'] = form
        return render(request, 'uniauth/login.html', context)