cubicweb/pyramid/login.py
author Philippe Pepiot <ph@itsalwaysdns.eu>
Mon, 30 Mar 2020 15:30:02 +0200
changeset 12961 01810941a4be
parent 11967 83739be20fab
permissions -rw-r--r--
[server] use a LifoQueue in _CnxSetPool In postgresql, some cache is attached to the connection. Using a LifoQueue (last-in, first-out) makes a few connections to get the most load which give best performance.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
11967
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     1
# copyright 2017 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     2
# copyright 2014-2016 UNLISH S.A.S. (Montpellier, FRANCE), all rights reserved.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     3
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     4
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     5
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     6
# This file is part of CubicWeb.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     7
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     8
# CubicWeb is free software: you can redistribute it and/or modify it under the
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
     9
# terms of the GNU Lesser General Public License as published by the Free
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    10
# Software Foundation, either version 2.1 of the License, or (at your option)
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    11
# any later version.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    12
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    13
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    14
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    15
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    16
# details.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    17
#
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    18
# You should have received a copy of the GNU Lesser General Public License along
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    19
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
83739be20fab [pyramid] Add a copyright and docstring to all modules
Denis Laxalde <denis.laxalde@logilab.fr>
parents: 11924
diff changeset
    20
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    21
""" 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
    22
from pyramid import security
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    23
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
    24
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
    25
from pyramid.settings import asbool
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    26
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    27
import cubicweb
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    28
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11628
diff changeset
    29
from cubicweb.pyramid.core import render_view
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    30
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    31
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    32
@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
    33
def login_form(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    34
    """ Default view for the 'login' route.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    35
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    36
    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
    37
    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
    38
    return request.response
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    39
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    40
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    41
@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
    42
def login_password_login(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    43
    """ Handle GET/POST of __login/__password on the 'login' route.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    44
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    45
    The authentication itself is delegated to the CubicWeb repository.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    46
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    47
    Request parameters:
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    48
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    49
    :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
    50
                    on.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    51
    :param __password: The user password
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    52
    :param __setauthcookie: (optional) If defined and equal to '1', set the
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    53
                            authentication cookie maxage to 1 week.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    54
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    55
                            If not, the authentication cookie is a session
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    56
                            cookie.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    57
    """
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    58
    repo = request.registry['cubicweb.repository']
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    59
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    60
    user_eid = None
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    61
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    62
    login = request.params['__login']
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    63
    password = request.params['__password']
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
    try:
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    66
        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
    67
            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
    68
            user_eid = user.eid
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    69
    except cubicweb.AuthenticationError:
11816
6392f34fcdad [pyramid] Fix login error message language
Florent Cayré <florent.cayre@logilab.fr>
parents: 11631
diff changeset
    70
        if repo.vreg.config.get('language-mode') != '':
6392f34fcdad [pyramid] Fix login error message language
Florent Cayré <florent.cayre@logilab.fr>
parents: 11631
diff changeset
    71
            lang = request.cw_request.negotiated_language()
6392f34fcdad [pyramid] Fix login error message language
Florent Cayré <florent.cayre@logilab.fr>
parents: 11631
diff changeset
    72
            if lang is not None:
6392f34fcdad [pyramid] Fix login error message language
Florent Cayré <florent.cayre@logilab.fr>
parents: 11631
diff changeset
    73
                request.cw_request.set_language(lang)
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    74
        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
    75
            "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
    76
        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
    77
        del request.cw_request.post['__password']
11628
0f12ee84f30a Test and fix status code and content of the login form on authentication error
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11609
diff changeset
    78
        request.response.status_code = 403
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    79
        return login_form(request)
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    80
11562
a49f08423f02 [auth] Use a second authtkt policy for 'rememberme'
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    81
    headers = security.remember(
a49f08423f02 [auth] Use a second authtkt policy for 'rememberme'
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    82
        request, user_eid,
a49f08423f02 [auth] Use a second authtkt policy for 'rememberme'
Christophe de Vienne <christophe@unlish.com>
parents: 11537
diff changeset
    83
        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
    84
11609
cc1d4b66ca26 [login] fix the redirect url after login (closes #11689118)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11562
diff changeset
    85
    new_path = request.params.get('postlogin_path', '')
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    86
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    87
    if new_path == 'login':
11609
cc1d4b66ca26 [login] fix the redirect url after login (closes #11689118)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11562
diff changeset
    88
        new_path = ''
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
    89
11609
cc1d4b66ca26 [login] fix the redirect url after login (closes #11689118)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11562
diff changeset
    90
    url = request.cw_request.build_url(new_path)
cc1d4b66ca26 [login] fix the redirect url after login (closes #11689118)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11562
diff changeset
    91
    raise HTTPSeeOther(url, headers=headers)
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    92
11494
79ce84750c18 If the postlogin_path is 'login', redirect to '/' instead
Christophe de Vienne <christophe@unlish.com>
parents: 11493
diff changeset
    93
11497
855219da7c70 Use a predicate based view selection for handling /login
Christophe de Vienne <christophe@unlish.com>
parents: 11494
diff changeset
    94
@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
    95
def login_already_loggedin(request):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    96
    """ 'login' route view for Authenticated users.
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    97
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
    98
    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
    99
    raise HTTPSeeOther('/')
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   100
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   101
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   102
def includeme(config):
11537
caf268942436 Initial documentation.
Christophe de Vienne <christophe@unlish.com>
parents: 11527
diff changeset
   103
    """ Create the 'login' route ('/login') and load this module views"""
11924
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   104
    cwconfig = config.registry['cubicweb.config']
11493
00e5cb9771c5 Put the login view in a separate module.
Christophe de Vienne <christophe@unlish.com>
parents:
diff changeset
   105
    config.add_route('login', '/login')
11924
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   106
    if cwconfig.get('language-mode') == 'url-prefix':
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   107
        config.add_route('login-lang', '/{lang}/login')
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   108
        config.add_view(login_already_loggedin, route_name='login-lang',
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   109
                        effective_principals=security.Authenticated)
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   110
        config.add_view(login_form, route_name='login-lang')
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   111
        config.add_view(login_password_login, route_name='login-lang',
4c949c28ce59 [pyramid] fix login route with language-mode = url-prefix
Samuel Trégouët <samuel.tregouet@logilab.fr>
parents: 11816
diff changeset
   112
                        request_param=('__login', '__password'))
11631
faf279e33298 Merge with pyramid-cubicweb
Yann Voté <yann.vote@logilab.fr>
parents: 11628
diff changeset
   113
    config.scan('cubicweb.pyramid.login')