[core] Protect session data from unwanted loading.
Use specialised Session and Connection types that forward their 'data' and
'session_data' attributes to the pyramid request.session attribute.
This forwarding is done with properties, instead of copying a reference, which
allow to access request.session (and the session factory) if and only if
Session.data or Connection.session_data is accessed.
In some cases, most notably the static resources requests, it can mean no
access the session during the request handling, which saves a request to the
session persistence layer.
Closes #4891437
""" Provide login views that reproduce a classical CubicWeb behavior"""
from pyramid import security
from pyramid.httpexceptions import HTTPSeeOther
from pyramid.view import view_config
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)
max_age = None
if request.params.get('__setauthcookie') == '1':
max_age = 604800
headers = security.remember(request, user_eid, max_age=max_age)
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')