move login by email functionnality on the repository side to avoid buggy call to internal_session from the web interface side
--- a/cwconfig.py Mon Jul 06 09:33:36 2009 +0200
+++ b/cwconfig.py Mon Jul 06 09:34:40 2009 +0200
@@ -194,6 +194,12 @@
'help': 'web server root url',
'group': 'main', 'inputlevel': 1,
}),
+ ('allow-email-login',
+ {'type' : 'yn',
+ 'default': False,
+ 'help': 'allow users to login with their primary email if set',
+ 'group': 'main', 'inputlevel': 2,
+ }),
('use-request-subdomain',
{'type' : 'yn',
'default': None,
--- a/server/repository.py Mon Jul 06 09:33:36 2009 +0200
+++ b/server/repository.py Mon Jul 06 09:34:40 2009 +0200
@@ -392,10 +392,23 @@
except ZeroDivisionError:
pass
+ def _login_from_email(self, login):
+ session = self.internal_session()
+ try:
+ rset = session.execute('Any L WHERE U login L, U primary_email M, '
+ 'M address %(login)s', {'login': login})
+ if rset.rowcount == 1:
+ login = rset[0][0]
+ finally:
+ session.close()
+ return login
+
def authenticate_user(self, session, login, password):
"""validate login / password, raise AuthenticationError on failure
return associated CWUser instance on success
"""
+ if self.vreg.config['allow-email-login'] and '@' in login:
+ login = self._login_from_email(login)
for source in self.sources:
if source.support_entity('CWUser'):
try:
--- a/web/test/unittest_application.py Mon Jul 06 09:33:36 2009 +0200
+++ b/web/test/unittest_application.py Mon Jul 06 09:34:40 2009 +0200
@@ -307,7 +307,7 @@
self.assertEquals(cnx.password, origcnx.password)
self.assertEquals(cnx.anonymous_connection, False)
self.assertEquals(path, 'view')
- self.assertEquals(params, {'__message': 'welcome %s !' % origcnx.login})
+ self.assertEquals(params, {'__message': 'welcome %s !' % cnx.user().login})
def _test_auth_fail(self, req):
self.assertRaises(AuthenticationError, self.app.connect, req)
@@ -351,8 +351,8 @@
req.form['__password'] = origcnx.password
self._test_auth_fail(req)
# option allow-email-login set
+ origcnx.login = address
self.set_option('allow-email-login', True)
- req, origcnx = self._init_auth('cookie')
req.form['__login'] = address
req.form['__password'] = origcnx.password
self._test_auth_succeed(req, origcnx)
--- a/web/views/authentication.py Mon Jul 06 09:33:36 2009 +0200
+++ b/web/views/authentication.py Mon Jul 06 09:34:40 2009 +0200
@@ -36,7 +36,10 @@
# calling cnx.user() check connection validity, raise
# BadConnectionId on failure
user = cnx.user(req)
- if login and user.login != login:
+ # check cnx.login and not user.login, since in case of login by
+ # email, login and cnx.login are the email while user.login is the
+ # actual user login
+ if login and cnx.login != login:
cnx.close()
raise InvalidSession('login mismatch')
except BadConnectionId:
@@ -53,18 +56,6 @@
req.set_connection(cnx, user)
return cnx
- def login_from_email(self, login):
- # XXX should not be called from web interface
- session = self.repo.internal_session()
- try:
- rset = session.execute('Any L WHERE U login L, U primary_email M, '
- 'M address %(login)s', {'login': login})
- if rset.rowcount == 1:
- login = rset[0][0]
- finally:
- session.close()
- return login
-
def authenticate(self, req, _login=None, _password=None):
"""authenticate user and return corresponding user object
@@ -79,8 +70,6 @@
login, password = _login, _password
else:
login, password = req.get_authorization()
- if self.vreg.config['allow-email-login'] and '@' in (login or u''):
- login = self.login_from_email(login)
if not login:
# No session and no login -> try anonymous
login, password = self.vreg.config.anonymous_user()
--- a/web/webconfig.py Mon Jul 06 09:33:36 2009 +0200
+++ b/web/webconfig.py Mon Jul 06 09:34:40 2009 +0200
@@ -80,12 +80,6 @@
'if anonymous-user is set',
'group': 'main', 'inputlevel': 1,
}),
- ('allow-email-login',
- {'type' : 'yn',
- 'default': False,
- 'help': 'allow users to login with their primary email if set',
- 'group': 'main', 'inputlevel': 2,
- }),
('query-log-file',
{'type' : 'string',
'default': None,