# HG changeset patch # User Sylvain Thénault # Date 1306313923 -7200 # Node ID 5338d895b891d3c73996135a187db9b6a9e7023f # Parent 254bc099db1a5397c1fab0e3ef2aaa2b99703714 [web session] fix session handling so we get a chance to have for instance the 'forgotpwd' feature working on a site where anonymous are not allowed fix several pbs: * we need a session id and a session cookie anyway, else subsequent http queries are unrelated * this imply some changes in the session attribution workflow for session without a cnx * some views/selectors must be fixed for cases where session has no cnx On the way, avoid unnecessary Redirect on successful login. closes #750543 diff -r 254bc099db1a -r 5338d895b891 dbapi.py --- a/dbapi.py Wed May 25 08:51:45 2011 +0200 +++ b/dbapi.py Wed May 25 10:58:43 2011 +0200 @@ -30,6 +30,7 @@ from itertools import count from warnings import warn from os.path import join +from uuid import uuid4 from logilab.common.logging_ext import set_log_methods from logilab.common.decorators import monkeypatch @@ -246,7 +247,7 @@ if cnx is not None: self.sessionid = cnx.sessionid else: - self.sessionid = None + self.sessionid = uuid4().hex @property def anonymous_session(self): diff -r 254bc099db1a -r 5338d895b891 selectors.py --- a/selectors.py Wed May 25 08:51:45 2011 +0200 +++ b/selectors.py Wed May 25 10:58:43 2011 +0200 @@ -1342,6 +1342,8 @@ @lltrace def __call__(self, cls, req, rset=None, row=None, col=0, **kwargs): + if not req.cnx: + return 0 user = req.user if user is None: return int('guests' in self.expected) diff -r 254bc099db1a -r 5338d895b891 web/application.py --- a/web/application.py Wed May 25 08:51:45 2011 +0200 +++ b/web/application.py Wed May 25 10:58:43 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -204,17 +204,34 @@ except InvalidSession: # try to open a new session, so we get an anonymous session if # allowed - try: - session = self.open_session(req) - except AuthenticationError: - req.remove_cookie(cookie, sessioncookie) - raise + session = self.open_session(req) + else: + if not session.cnx: + # session exists but is not bound to a connection. We should + # try to authenticate + loginsucceed = False + try: + if self.open_session(req, allow_no_cnx=False): + loginsucceed = True + except Redirect: + # may be raised in open_session (by postlogin mechanism) + # on successful connection + loginsucceed = True + raise + except AuthenticationError: + # authentication failed, continue to use this session + req.set_session(session) + finally: + if loginsucceed: + # session should be replaced by new session created + # in open_session + self.session_manager.close_session(session) def get_session(self, req, sessionid): return self.session_manager.get_session(req, sessionid) - def open_session(self, req): - session = self.session_manager.open_session(req) + def open_session(self, req, allow_no_cnx=True): + session = self.session_manager.open_session(req, allow_no_cnx=allow_no_cnx) cookie = req.get_cookie() sessioncookie = self.session_cookie(req) cookie[sessioncookie] = session.sessionid @@ -279,10 +296,7 @@ sessions (i.e. a new connection may be created or an already existing one may be reused """ - try: - self.session_handler.set_session(req) - except AuthenticationError: - req.set_session(DBAPISession(None)) + self.session_handler.set_session(req) # publish methods ######################################################### @@ -365,11 +379,12 @@ # redirect is raised by edit controller when everything went fine, # so try to commit try: - txuuid = req.cnx.commit() - if txuuid is not None: - msg = u'[%s]' %( - req.build_url('undo', txuuid=txuuid), req._('undo')) - req.append_to_redirect_message(msg) + if req.cnx: + txuuid = req.cnx.commit() + if txuuid is not None: + msg = u'[%s]' %( + req.build_url('undo', txuuid=txuuid), req._('undo')) + req.append_to_redirect_message(msg) except ValidationError, ex: self.validation_error_handler(req, ex) except Unauthorized, ex: diff -r 254bc099db1a -r 5338d895b891 web/views/basecomponents.py --- a/web/views/basecomponents.py Wed May 25 08:51:45 2011 +0200 +++ b/web/views/basecomponents.py Wed May 25 10:58:43 2011 +0200 @@ -29,8 +29,8 @@ from logilab.common.deprecation import class_renamed from rql import parse -from cubicweb.selectors import (yes, multi_etypes_rset, match_form_params, - match_context, configuration_values, +from cubicweb.selectors import (yes, no_cnx, match_form_params, match_context, + multi_etypes_rset, configuration_values, anonymous_user, authenticated_user) from cubicweb.schema import display_name from cubicweb.utils import wrap_on_write @@ -88,6 +88,7 @@ class ApplLogo(HeaderComponent): """build the instance logo, usually displayed in the header""" __regid__ = 'logo' + __select__ = yes() # no need for a cnx order = -1 def render(self, w): @@ -150,7 +151,7 @@ class AnonUserStatusLink(HeaderComponent): __regid__ = 'userstatus' - __select__ = HeaderComponent.__select__ & anonymous_user() + __select__ = anonymous_user() context = _('header-right') order = HeaderComponent.order - 10 @@ -159,7 +160,7 @@ class AuthenticatedUserStatus(AnonUserStatusLink): - __select__ = HeaderComponent.__select__ & authenticated_user() + __select__ = authenticated_user() def render(self, w): # display useractions and siteactions @@ -180,7 +181,7 @@ """display messages given using the __message parameter into a special div section """ - __select__ = yes() + __select__ = ~no_cnx() __regid__ = 'applmessages' # don't want user to hide this component using an cwproperty cw_property_defs = {} diff -r 254bc099db1a -r 5338d895b891 web/views/basetemplates.py --- a/web/views/basetemplates.py Wed May 25 08:51:45 2011 +0200 +++ b/web/views/basetemplates.py Wed May 25 10:58:43 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. diff -r 254bc099db1a -r 5338d895b891 web/views/debug.py --- a/web/views/debug.py Wed May 25 08:51:45 2011 +0200 +++ b/web/views/debug.py Wed May 25 10:58:43 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -133,6 +133,9 @@ if sessions: w(u'