pyramid_cubicweb/login.py
author Christophe de Vienne <christophe@unlish.com>
Thu, 26 Feb 2015 00:56:32 +0100
changeset 11562 a49f08423f02
parent 11537 caf268942436
child 11609 cc1d4b66ca26
permissions -rw-r--r--
[auth] Use a second authtkt policy for 'rememberme' The former solution was buggy because the expire time of the auth cookie, if set through 'remember', was lost on the first cookie reissuing. The new approach, make possible thanks to multiauth, use two different cookies. One for session bounded authentication (no 'rememberme'), and one for long lasting authentication (w 'rememberme'). The choice between the two of them is done by adding a 'persistent' argument to the top-level 'security.remember' call. Passing this argument will inhibate a policy or the other. The two policies are (a little) configurable through the 'cubicweb.auth.authtkt.[session|persistent].*' variables. Related to #4985962

""" Provide login views that reproduce a classical CubicWeb behavior"""
from pyramid import security
from pyramid.httpexceptions import HTTPSeeOther
from pyramid.view import view_config
from pyramid.settings import asbool

import cubicweb

from pyramid_cubicweb.core import render_view


@view_config(route_name='login')
def login_form(request):
    """ Default view for the 'login' route.

    Display the 'login' CubicWeb view, which is should be a login form"""
    request.response.text = render_view(request, 'login')
    return request.response


@view_config(route_name='login', request_param=('__login', '__password'))
def login_password_login(request):
    """ Handle GET/POST of __login/__password on the 'login' route.

    The authentication itself is delegated to the CubicWeb repository.

    Request parameters:

    :param __login: The user login (or email if :confval:`allow-email-login` is
                    on.
    :param __password: The user password
    :param __setauthcookie: (optional) If defined and equal to '1', set the
                            authentication cookie maxage to 1 week.

                            If not, the authentication cookie is a session
                            cookie.
    """
    repo = request.registry['cubicweb.repository']

    user_eid = None

    login = request.params['__login']
    password = request.params['__password']

    try:
        with repo.internal_cnx() as cnx:
            user = repo.authenticate_user(cnx, login, password=password)
            user_eid = user.eid
    except cubicweb.AuthenticationError:
        request.cw_request.set_message(request.cw_request._(
            "Authentication failed. Please check your credentials."))
        request.cw_request.post = dict(request.params)
        del request.cw_request.post['__password']
        return login_form(request)

    headers = security.remember(
        request, user_eid,
        persistent=asbool(request.params.get('__setauthcookie', False)))

    new_path = request.params.get('postlogin_path', '/')

    if new_path == 'login':
        new_path = '/'

    raise HTTPSeeOther(new_path, headers=headers)


@view_config(route_name='login', effective_principals=security.Authenticated)
def login_already_loggedin(request):
    """ 'login' route view for Authenticated users.

    Simply redirect the user to '/'."""
    raise HTTPSeeOther('/')


def includeme(config):
    """ Create the 'login' route ('/login') and load this module views"""
    config.add_route('login', '/login')
    config.scan('pyramid_cubicweb.login')