18 """user authentication component""" |
18 """user authentication component""" |
19 |
19 |
20 |
20 |
21 |
21 |
22 from logilab.common.deprecation import class_renamed |
22 from logilab.common.deprecation import class_renamed |
|
23 from logilab.common.textutils import unormalize |
23 |
24 |
24 from cubicweb import AuthenticationError |
25 from cubicweb import AuthenticationError |
|
26 from cubicweb.utils import make_uid |
25 from cubicweb.view import Component |
27 from cubicweb.view import Component |
26 from cubicweb.web import InvalidSession |
28 from cubicweb.web import InvalidSession |
|
29 from cubicweb.server.session import Connection |
27 |
30 |
28 |
31 |
29 class NoAuthInfo(Exception): pass |
32 class NoAuthInfo(Exception): pass |
30 |
33 |
31 |
34 |
95 LoginPasswordRetreiver = class_renamed( |
98 LoginPasswordRetreiver = class_renamed( |
96 'LoginPasswordRetreiver', LoginPasswordRetriever, |
99 'LoginPasswordRetreiver', LoginPasswordRetriever, |
97 '[3.17] LoginPasswordRetreiver had been renamed into LoginPasswordRetriever ' |
100 '[3.17] LoginPasswordRetreiver had been renamed into LoginPasswordRetriever ' |
98 '("ie" instead of "ei")') |
101 '("ie" instead of "ei")') |
99 |
102 |
|
103 |
|
104 class Session(object): |
|
105 """In-memory user session |
|
106 """ |
|
107 |
|
108 def __init__(self, repo, user): |
|
109 self.user = user # XXX deprecate and store only a login. |
|
110 self.repo = repo |
|
111 self.sessionid = make_uid(unormalize(user.login)) |
|
112 self.data = {} |
|
113 |
|
114 def __unicode__(self): |
|
115 return '<session %s (0x%x)>' % (unicode(self.user.login), id(self)) |
|
116 |
|
117 @property |
|
118 def anonymous_session(self): |
|
119 # XXX for now, anonymous_user only exists in webconfig (and testconfig). |
|
120 # It will only be present inside all-in-one instance. |
|
121 # there is plan to move it down to global config. |
|
122 if not hasattr(self.repo.config, 'anonymous_user'): |
|
123 # not a web or test config, no anonymous user |
|
124 return False |
|
125 return self.user.login == self.repo.config.anonymous_user()[0] |
|
126 |
|
127 def new_cnx(self): |
|
128 """Return a new Connection object linked to the session |
|
129 |
|
130 The returned Connection will *not* be managed by the Session. |
|
131 """ |
|
132 cnx = Connection(self.repo, self.user) |
|
133 cnx.session = self |
|
134 return cnx |
100 |
135 |
101 |
136 |
102 class RepositoryAuthenticationManager(object): |
137 class RepositoryAuthenticationManager(object): |
103 """authenticate user associated to a request and check session validity""" |
138 """authenticate user associated to a request and check session validity""" |
104 |
139 |
131 |
166 |
132 def _validate_session(self, req, session, login): |
167 def _validate_session(self, req, session, login): |
133 # check session.login and not user.login, since in case of login by |
168 # check session.login and not user.login, since in case of login by |
134 # email, login and cnx.login are the email while user.login is the |
169 # email, login and cnx.login are the email while user.login is the |
135 # actual user login |
170 # actual user login |
136 if login and session.login != login: |
171 if login and session.user.login != login: |
137 raise InvalidSession('login mismatch') |
172 raise InvalidSession('login mismatch') |
138 |
173 |
139 def authenticate(self, req): |
174 def authenticate(self, req): |
140 """authenticate user using connection information found in the request, |
175 """authenticate user using connection information found in the request, |
141 and return corresponding a :class:`~cubicweb.dbapi.Connection` instance, |
176 and return corresponding a :class:`~cubicweb.dbapi.Connection` instance, |
168 session = self._authenticate(login, authinfo) |
203 session = self._authenticate(login, authinfo) |
169 return session, login |
204 return session, login |
170 raise AuthenticationError() |
205 raise AuthenticationError() |
171 |
206 |
172 def _authenticate(self, login, authinfo): |
207 def _authenticate(self, login, authinfo): |
173 return self.repo.new_session(login, **authinfo) |
208 with self.repo.internal_cnx() as cnx: |
|
209 user = self.repo.authenticate_user(cnx, login, **authinfo) |
|
210 return Session(self.repo, user) |