web/views/authentication.py
changeset 5251 b675edd05c19
parent 5223 6abd6e3599f4
child 5423 e15abfdcce38
equal deleted inserted replaced
5250:1c0eb5f74fd4 5251:b675edd05c19
     3 :organization: Logilab
     3 :organization: Logilab
     4 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     4 :copyright: 2001-2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
     7 """
     7 """
       
     8 from __future__ import with_statement
       
     9 
     8 __docformat__ = "restructuredtext en"
    10 __docformat__ = "restructuredtext en"
       
    11 
       
    12 from threading import Lock
     9 
    13 
    10 from logilab.common.decorators import clear_cache
    14 from logilab.common.decorators import clear_cache
    11 
    15 
    12 from cubicweb import AuthenticationError, BadConnectionId
    16 from cubicweb import AuthenticationError, BadConnectionId
    13 from cubicweb.view import Component
    17 from cubicweb.view import Component
    74         raise :exc:`InvalidSession` if session is corrupted for a reason or
    78         raise :exc:`InvalidSession` if session is corrupted for a reason or
    75         another and should be closed
    79         another and should be closed
    76         """
    80         """
    77         # with this authentication manager, session is actually a dbapi
    81         # with this authentication manager, session is actually a dbapi
    78         # connection
    82         # connection
    79         cnx = session.cnx
       
    80         login = req.get_authorization()[0]
    83         login = req.get_authorization()[0]
    81         # check cnx.login and not user.login, since in case of login by
    84         # check session.login and not user.login, since in case of login by
    82         # email, login and cnx.login are the email while user.login is the
    85         # email, login and cnx.login are the email while user.login is the
    83         # actual user login
    86         # actual user login
    84         if login and session.login != login:
    87         if login and session.login != login:
    85             raise InvalidSession('login mismatch')
    88             raise InvalidSession('login mismatch')
    86         try:
    89         try:
    87             # calling cnx.user() check connection validity, raise
    90             lock = session.reconnection_lock
    88             # BadConnectionId on failure
    91         except AttributeError:
    89             user = cnx.user(req)
    92             lock = session.reconnection_lock = Lock()
    90         except BadConnectionId:
    93         # need to be locked two avoid duplicated reconnections on concurrent
    91             # check if a connection should be automatically restablished
    94         # requests
    92             if (login is None or login == session.login):
    95         with lock:
    93                 cnx = self._authenticate(session.login, session.authinfo)
    96             cnx = session.cnx
       
    97             try:
       
    98                 # calling cnx.user() check connection validity, raise
       
    99                 # BadConnectionId on failure
    94                 user = cnx.user(req)
   100                 user = cnx.user(req)
    95                 session.cnx = cnx
   101             except BadConnectionId:
    96             else:
   102                 # check if a connection should be automatically restablished
    97                 raise InvalidSession('bad connection id')
   103                 if (login is None or login == session.login):
       
   104                     cnx = self._authenticate(session.login, session.authinfo)
       
   105                     user = cnx.user(req)
       
   106                     session.cnx = cnx
       
   107                 else:
       
   108                     raise InvalidSession('bad connection id')
    98         return user
   109         return user
    99 
   110 
   100     def authenticate(self, req):
   111     def authenticate(self, req):
   101         """authenticate user using connection information found in the request,
   112         """authenticate user using connection information found in the request,
   102         and return corresponding a :class:`~cubicweb.dbapi.Connection` instance,
   113         and return corresponding a :class:`~cubicweb.dbapi.Connection` instance,