diff --git a/roundup/cgi/actions.py b/roundup/cgi/actions.py --- a/roundup/cgi/actions.py +++ b/roundup/cgi/actions.py @@ -548,7 +548,7 @@ if not classname : classname = self.client.classname - + if not self.hasPermission('Create', classname=classname): return 0 @@ -1005,6 +1005,6 @@ raise exceptions.LoginError(self._( "You do not have permission to login")) - def verifyPassword(self, userid, password): + def verifyPassword(self, userid, passwd): '''Verify the password that the user has supplied''' stored = self.db.user.get(userid, 'password') @@ -1009,4 +1009,6 @@ '''Verify the password that the user has supplied''' stored = self.db.user.get(userid, 'password') - if password == stored: + if passwd == stored: + if self.db.config.UPGRADE_PASSWORDS_ON_WEB_LOGIN and stored.needsUpgrade(): + self.db.user.set(userid, password=password.Password(passwd)) return 1 @@ -1012,5 +1014,5 @@ return 1 - if not password and not stored: + if not passwd and not stored: return 1 return 0 diff --git a/roundup/configuration.py b/roundup/configuration.py --- a/roundup/configuration.py +++ b/roundup/configuration.py @@ -537,6 +537,9 @@ "starting with python 2.5. Set this to a higher value if you\n" "get the error 'Error: field larger than field limit' during\n" "import."), + (BooleanOption, "upgrade_passwords_on_web_login", "no", + "On web-login, automatically re-encode passwords that are stored\n" + "using a deprecated hash format."), )), ("tracker", ( (Option, "name", "Roundup issue tracker", diff --git a/roundup/password.py b/roundup/password.py --- a/roundup/password.py +++ b/roundup/password.py @@ -235,6 +235,7 @@ #TODO: code to migrate from old password schemes. known_schemes = [ "PBKDF2", "SHA", "MD5", "crypt", "plaintext" ] + deprecated_schemes = [ "SHA", "MD5", "crypt", "plaintext" ] def __init__(self, plaintext=None, scheme=None, encrypted=None, strict=False): """Call setPassword if plaintext is not None.""" @@ -272,6 +273,10 @@ self.password = encodePassword(plaintext, scheme) self.plaintext = plaintext + def needsUpgrade(self): + "check if password is using deprecated hash scheme, and needs re-encoding" + return self.scheme in self.deprecated_schemes + def __str__(self): """Stringify the encrypted password for database storage.""" if self.password is None: