Reviewers:
*Please review this at http://codereview.tryton.org/818003*
- Add reset_login_attempt in User class:
* allowing easier inheritance (see second review below)
- Add auth_failure_wait parameter in trytond.conf
* enabled by default (keep current behavior)
* allow to disable "sleep" when multiple authentication failures occur
Affected files:
M etc/trytond.conf
M trytond/config.py
M trytond/res/user.py
*Related patch on ldap_authentication module*:
http://codereview.tryton.org/817002 (LoginAttempt never reset when LDAP
used, issue3174)
diff -r 2e1415beb3e8 etc/trytond.conf
--- a/etc/trytond.conf Mon Apr 22 12:20:41 2013 +0200
+++ b/etc/trytond.conf Tue Apr 23 16:35:13 2013 +0200
@@ -44,6 +44,11 @@
# Configure the Tryton server password
#admin_passwd = admin
+# If a user try to authenticate with a wrong password and there are previous
+# failed authentications, wait before sending the response 'authentication
+# failed' to the user.
+#auth_failure_wait = True
+
# Configure the path of the files for the pid and the logs
#pidfile = False
#logfile = False
diff -r 2e1415beb3e8 trytond/config.py
--- a/trytond/config.py Mon Apr 22 12:20:41 2013 +0200
+++ b/trytond/config.py Tue Apr 23 16:35:13 2013 +0200
@@ -57,6 +57,7 @@
'db_maxconn': 64,
'pg_path': None,
'admin_passwd': 'admin',
+ 'auth_failure_wait': True,
'verbose': False,
'debug_mode': False,
'pidfile': None,
diff -r 2e1415beb3e8 trytond/res/user.py
--- a/trytond/res/user.py Mon Apr 22 12:20:41 2013 +0200
+++ b/trytond/res/user.py Tue Apr 23 16:35:13 2013 +0200
@@ -452,7 +452,6 @@
'''
Return user id if password matches
'''
- LoginAttempt = Pool().get('res.user.login.attempt')
user_id, user_password, salt = cls._get_login(login)
if not user_id:
return 0
@@ -461,11 +460,19 @@
password = password.encode('utf-8')
password_sha = hashlib.sha1(password).hexdigest()
if password_sha == user_password:
+ cls.reset_login_attempt(user_id)
+ return user_id
+ if CONFIG['auth_failure_wait']:
+ LoginAttempt = Pool().get('res.user.login.attempt')
+ LoginAttempt.add(user_id)
+ time.sleep(2 ** LoginAttempt.count(user_id))
+ return 0
+
+ @classmethod
+ def reset_login_attempt(cls, user_id):
+ if CONFIG['auth_failure_wait']:
+ LoginAttempt = Pool().get('res.user.login.attempt')
LoginAttempt.delete(user_id)
- return user_id
- LoginAttempt.add(user_id)
- time.sleep(2 ** LoginAttempt.count(user_id))
- return 0
class LoginAttempt(ModelSQL):