fix #343630 by getting explicitly TextInput widget for String, also instantiate field to get proper widget configuration
"""user authentication component:organization: Logilab:copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses"""__docformat__="restructuredtext en"fromlogilab.common.decoratorsimportclear_cachefromcubicwebimportAuthenticationError,BadConnectionIdfromcubicweb.dbapiimportrepo_connect,ConnectionPropertiesfromcubicweb.webimportExplicitLogin,InvalidSessionfromcubicweb.web.applicationimportAbstractAuthenticationManagerclassRepositoryAuthenticationManager(AbstractAuthenticationManager):"""authenticate user associated to a request and check session validity"""def__init__(self):self.repo=self.config.repository(self.vreg)self.log_queries=self.config['query-log-file']defvalidate_session(self,req,session):"""check session validity, and return eventually hijacked session :raise InvalidSession: if session is corrupted for a reason or another and should be closed """# with this authentication manager, session is actually a dbapi# connectioncnx=sessionlogin=req.get_authorization()[0]try:# calling cnx.user() check connection validity, raise# BadConnectionId on failureuser=cnx.user(req)ifloginanduser.login!=login:cnx.close()raiseInvalidSession('login mismatch')exceptBadConnectionId:# check if a connection should be automatically restablishedif(loginisNoneorlogin==cnx.login):login,password=cnx.login,cnx.passwordcnx=self.authenticate(req,login,password)user=cnx.user(req)# backport session's datacnx.data=session.dataelse:raiseInvalidSession('bad connection id')# associate the connection to the current requestreq.set_connection(cnx,user)returncnxdeflogin_from_email(self,login):# XXX should not be called from web interfacesession=self.repo.internal_session()try:rset=session.execute('Any L WHERE U login L, U primary_email M, ''M address %(login)s',{'login':login})ifrset.rowcount==1:login=rset[0][0]finally:session.close()returnlogindefauthenticate(self,req,_login=None,_password=None):"""authenticate user and return corresponding user object :raise ExplicitLogin: if authentication is required (no authentication info found or wrong user/password) Note: this method is violating AuthenticationManager interface by returning a session instance instead of the user. This is expected by the InMemoryRepositorySessionManager. """if_loginisnotNone:login,password=_login,_passwordelse:login,password=req.get_authorization()ifself.vreg.config['allow-email-login']and'@'in(loginoru''):login=self.login_from_email(login)ifnotlogin:# No session and no login -> try anonymouslogin,password=self.vreg.config.anonymous_user()ifnotlogin:# anonymous not authorizedraiseExplicitLogin()# remove possibly cached cursor coming from closed connectionclear_cache(req,'cursor')cnxprops=ConnectionProperties(self.vreg.config.repo_method,close=False,log=self.log_queries)try:cnx=repo_connect(self.repo,login,password,cnxprops=cnxprops)exceptAuthenticationError:req.set_message(req._('authentication failure'))# restore an anonymous connection if possibleanonlogin,anonpassword=self.vreg.config.anonymous_user()ifanonloginandanonlogin!=login:cnx=repo_connect(self.repo,anonlogin,anonpassword,cnxprops=cnxprops)self._init_cnx(cnx,anonlogin,anonpassword)else:raiseExplicitLogin()else:self._init_cnx(cnx,login,password)# associate the connection to the current requestreq.set_connection(cnx)returncnxdef_init_cnx(self,cnx,login,password):# decorate connectioniflogin==self.vreg.config.anonymous_user()[0]:cnx.anonymous_connection=Truecnx.vreg=self.vregcnx.login=logincnx.password=password