cubicweb/web/views/authentication.py
changeset 12043 b8d2e6b9f548
parent 11767 432f87a63057
child 12046 9056a41d91ba
equal deleted inserted replaced
12042:5e64a98572de 12043:b8d2e6b9f548
    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)