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, |