pyramid_cubicweb/login.py
author Christophe de Vienne <christophe@unlish.com>
Thu, 12 Feb 2015 19:21:39 +0100
changeset 11561 25d93d14f8b6
parent 11537 caf268942436
child 11562 a49f08423f02
permissions -rw-r--r--
[auth] Use pyramid_multiauth It makes it easier to finely tune what parts of the default authentication stack we want to use or not. It also makes it possible for any cube to add its own policy in addition to the others. Related to #4985962
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
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     5
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     6
import cubicweb
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     7
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
     8
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
     9
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    10
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    11
@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
    12
def login_form(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    13
    """ Default view for the 'login' route.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    14
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    15
    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
    16
    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
    17
    return request.response
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    18
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
@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
    21
def login_password_login(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    22
    """ Handle GET/POST of __login/__password on the 'login' route.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    23
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    24
    The authentication itself is delegated to the CubicWeb repository.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    25
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    26
    Request parameters:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    27
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    28
    :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
    29
                    on.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    30
    :param __password: The user password
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    31
    :param __setauthcookie: (optional) If defined and equal to '1', set the
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    32
                            authentication cookie maxage to 1 week.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    33
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    34
                            If not, the authentication cookie is a session
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    35
                            cookie.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    36
    """
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    37
    repo = request.registry['cubicweb.repository']
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    38
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    39
    user_eid = None
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    40
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    41
    login = request.params['__login']
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    42
    password = request.params['__password']
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    43
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    44
    try:
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    45
        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
    46
            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
    47
            user_eid = user.eid
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    48
    except cubicweb.AuthenticationError:
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    49
        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
    50
            "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
    51
        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
    52
        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
    53
        return login_form(request)
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    54
11509
ca3412269cd1 Handle '__setauthcookie'
Christophe de Vienne <christophe@unlish.com>
parents: 11497
diff changeset
    55
    max_age = None
ca3412269cd1 Handle '__setauthcookie'
Christophe de Vienne <christophe@unlish.com>
parents: 11497
diff changeset
    56
    if request.params.get('__setauthcookie') == '1':
11527
aa05b41a5816 Cookie 'max_age' must be a integer, not a string.
Christophe de Vienne <christophe@unlish.com>
parents: 11509
diff changeset
    57
        max_age = 604800
11509
ca3412269cd1 Handle '__setauthcookie'
Christophe de Vienne <christophe@unlish.com>
parents: 11497
diff changeset
    58
    headers = security.remember(request, user_eid, max_age=max_age)
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')