pyramid_cubicweb/login.py
author Denis Laxalde <denis.laxalde@logilab.fr>
Wed, 29 Apr 2015 11:39:35 +0200
changeset 11563 f9473eb6a8a9
parent 11562 a49f08423f02
child 11609 cc1d4b66ca26
permissions -rw-r--r--
Make debug mode usable without pyramid_debugtoolbar Add the latter in Debian recommends along the way. Closes #5310434.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
     1
""" Provide login views that reproduce a classical CubicWeb behavior"""
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     2
from pyramid import security
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     3
from pyramid.httpexceptions import HTTPSeeOther
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
     4
from pyramid.view import view_config
11562
a49f08423f02 [auth] Use a second authtkt policy for 'rememberme'
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
     5
from pyramid.settings import asbool
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     6
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     7
import cubicweb
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     8
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     9
from pyramid_cubicweb.core import render_view
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    10
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    11
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    12
@view_config(route_name='login')
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    13
def login_form(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    14
    """ Default view for the 'login' route.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    15
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    16
    Display the 'login' CubicWeb view, which is should be a login form"""
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    17
    request.response.text = render_view(request, 'login')
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    18
    return request.response
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    19
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    20
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    21
@view_config(route_name='login', request_param=('__login', '__password'))
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    22
def login_password_login(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    23
    """ Handle GET/POST of __login/__password on the 'login' route.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    24
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    25
    The authentication itself is delegated to the CubicWeb repository.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    26
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    27
    Request parameters:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    28
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    29
    :param __login: The user login (or email if :confval:`allow-email-login` is
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    30
                    on.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    31
    :param __password: The user password
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    32
    :param __setauthcookie: (optional) If defined and equal to '1', set the
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    33
                            authentication cookie maxage to 1 week.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    34
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    35
                            If not, the authentication cookie is a session
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    36
                            cookie.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    37
    """
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    38
    repo = request.registry['cubicweb.repository']
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    39
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    40
    user_eid = None
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    41
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    42
    login = request.params['__login']
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    43
    password = request.params['__password']
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    44
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    45
    try:
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    46
        with repo.internal_cnx() as cnx:
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    47
            user = repo.authenticate_user(cnx, login, password=password)
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    48
            user_eid = user.eid
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    49
    except cubicweb.AuthenticationError:
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    50
        request.cw_request.set_message(request.cw_request._(
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    51
            "Authentication failed. Please check your credentials."))
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    52
        request.cw_request.post = dict(request.params)
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    53
        del request.cw_request.post['__password']
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    54
        return login_form(request)
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    55
11562
a49f08423f02 [auth] Use a second authtkt policy for 'rememberme'
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    56
    headers = security.remember(
a49f08423f02 [auth] Use a second authtkt policy for 'rememberme'
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    57
        request, user_eid,
a49f08423f02 [auth] Use a second authtkt policy for 'rememberme'
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    58
        persistent=asbool(request.params.get('__setauthcookie', False)))
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    60
    new_path = request.params.get('postlogin_path', '/')
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    61
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    62
    if new_path == 'login':
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    63
        new_path = '/'
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    64
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    65
    raise HTTPSeeOther(new_path, headers=headers)
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    66
11494
79ce84750c18 If the postlogin_path is 'login', redirect to '/' instead
Christophe de Vienne <christophe@unlish.com>
parents: 11493
diff changeset
    67
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    68
@view_config(route_name='login', effective_principals=security.Authenticated)
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    69
def login_already_loggedin(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    70
    """ 'login' route view for Authenticated users.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    71
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    72
    Simply redirect the user to '/'."""
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    73
    raise HTTPSeeOther('/')
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    74
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    75
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    76
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    77
    """ Create the 'login' route ('/login') and load this module views"""
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    78
    config.add_route('login', '/login')
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    79
    config.scan('pyramid_cubicweb.login')