def doChangeUser(self, principal_id, password): """Change a user's password """ if self._user_passwords.get(principal_id) is None: raise RuntimeError("User does not exist: %s" % principal_id) self._user_passwords[principal_id] = AuthEncoding.pw_encrypt(password) notify(CredentialsUpdated(self.getUserById(principal_id), password))
def doChangeUser(self, principal_id, password): """ Update user's password date and store passwords history. """ user = api.user.get(username=principal_id) portal = api.portal.get() current_time = portal.ZopeTime() user.setMemberProperties({"password_date": current_time}) self._invalidatePrincipalCache(principal_id) # Remember passwords here max_history_pws = api.portal.get_registry_record( "collective.pwexpiry.password_history_size" ) if max_history_pws == 0: # disabled, return here. return enc_pw = password if not AuthEncoding.is_encrypted(enc_pw): enc_pw = AuthEncoding.pw_encrypt(enc_pw) pw_history = list(user.getProperty("password_history", tuple())) pw_history.append(enc_pw) if len(pw_history) > max_history_pws: # Truncate the history pw_history = pw_history[-max_history_pws:] user.setMemberProperties({"password_history": tuple(pw_history)})
def setAttempt(self, login, password): """ Set counter to 1 or bump it when authentication failed, if previous failed attempt was more than reset period time instead of bumping counter reset it to 1 """ root = self.getRootPlugin() count, last, IP, reference = root._login_attempts.get( login, (0, None, '', None)) if reference and AuthEncoding.pw_validate(reference, password): # don't count repeating same password return if last: delta = DateTime().asdatetime() - last.asdatetime() if delta.seconds > self.getResetPeriod(): # set counter to 1 instead of bumping, some sort of autoreset. count = 1 else: count += 1 else: count += 1 IP = self.remote_ip() log.debug("user '%s' failed to login, attempt #%i %s last: %s", login, count, IP, last) last = DateTime() reference = AuthEncoding.pw_encrypt(password) root._login_attempts[login] = (count, last, IP, reference)
def _createLDAPPassword(password, encoding='SHA'): """ Create a password string suitable for the userPassword attribute """ encoding = encoding.upper() if encoding in ('SSHA', 'SHA', 'CRYPT'): pwd_str = AuthEncoding.pw_encrypt(password, encoding) elif encoding == 'MD5': m = md5_new(password) pwd_str = '{MD5}' + base64.encodestring(m.digest()) elif encoding == 'CLEAR': pwd_str = password else: pwd_str = AuthEncoding.pw_encrypt(password, 'SSHA') return pwd_str.strip()
def doChangeUser(self, principal_id, password): """ Update user's password date and store passwords history. """ user = api.user.get(username=principal_id) portal = api.portal.get() current_time = portal.ZopeTime() user.setMemberProperties({'password_date': current_time}) self._invalidatePrincipalCache(principal_id) # Remember passwords here max_history_pws = api.portal.get_registry_record( 'collective.pwexpiry.password_history_size' ) if max_history_pws == 0: # disabled, return here. return enc_pw = password if not AuthEncoding.is_encrypted(enc_pw): enc_pw = AuthEncoding.pw_encrypt(enc_pw) pw_history = list(user.getProperty('password_history', tuple())) pw_history.append(enc_pw) if len(pw_history) > max_history_pws: # Truncate the history pw_history = pw_history[-max_history_pws:] user.setMemberProperties({'password_history': tuple(pw_history)})
def _createLDAPPassword(password, encoding='SHA'): """ Create a password string suitable for the userPassword attribute """ encoding = encoding.upper() if encoding in ('SSHA', 'SHA', 'CRYPT'): pwd_str = AuthEncoding.pw_encrypt(password, encoding) elif encoding == 'MD5': m = md5_new(password) pwd_str = '{MD5}' + base64.encodestring(m.digest()) elif encoding == 'CLEAR': pwd_str = password else: pwd_str = AuthEncoding.pw_encrypt(password, 'SSHA') return pwd_str.strip()
def updateUserPassword( self, user_id, password ): if self._user_passwords.get( user_id ) is None: raise KeyError, 'Invalid user ID: %s' % user_id if password: digested = AuthEncoding.pw_encrypt( password ) self._user_passwords[ user_id ] = digested
def password(self, password): # When editing, the password field is empty in the browser; do # not do anything then. if password is not None: self.context.password = AuthEncoding.pw_encrypt( safe_encode(password), encoding='BCRYPT' )
def testBlankPassword(self): pw = '' for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert AuthEncoding.pw_validate(enc, pw) assert not AuthEncoding.pw_validate(enc, enc) assert not AuthEncoding.pw_validate(enc, 'xxx')
def testBlankPassword(self): pw = '' for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert AuthEncoding.pw_validate(enc, pw) assert not AuthEncoding.pw_validate(enc, enc) assert not AuthEncoding.pw_validate(enc, 'xxx')
def setPasswordForUser(self, login, password): """Add password to the list of previously used passwords for a user. """ hashes = self._user_passwords.get(login, []) hash = AuthEncoding.pw_encrypt(password) hashes.append(hash) self._user_passwords[login] = hashes log.info("Password '%s' for user '%s' stored" % (password, login))
def updateUserPassword(self, user_id, password): if self._user_passwords.get(user_id) is None: raise KeyError, 'Invalid user ID: %s' % user_id if password: digested = AuthEncoding.pw_encrypt(password) self._user_passwords[user_id] = digested
def password(self, password): # When editing, the password field is empty in the browser; do # not do anything then. if password is not None: self.context.password = AuthEncoding.pw_encrypt( safe_encode(password), encoding='BCRYPT' )
def testGoodPassword(self): pw = 'good_password' assert len(AuthEncoding.listSchemes()) > 0 # At least one must exist! for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert AuthEncoding.pw_validate(enc, pw) assert AuthEncoding.is_encrypted(enc) assert not AuthEncoding.is_encrypted(pw)
def testGoodPassword(self): pw = 'good_password' assert len(AuthEncoding.listSchemes()) > 0 # At least one must exist! for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert AuthEncoding.pw_validate(enc, pw) assert AuthEncoding.is_encrypted(enc) assert not AuthEncoding.is_encrypted(pw)
def _pw_encrypt(self, password): """Returns the AuthEncoding encrypted password If 'password' is already encrypted, it is returned as is and not encrypted again. """ if AuthEncoding.is_encrypted(password): return password return AuthEncoding.pw_encrypt(password)
def _pw_encrypt(self, password): """Returns the AuthEncoding encrypted password If 'password' is already encrypted, it is returned as is and not encrypted again. """ if AuthEncoding.is_encrypted(password): return password return AuthEncoding.pw_encrypt(password)
def addUser( self, user_id, login_name, password ): if self._user_passwords.get( user_id ) is not None: raise KeyError, 'Duplicate user ID: %s' % user_id if self._login_to_userid.get( login_name ) is not None: raise KeyError, 'Duplicate login name: %s' % login_name self._user_passwords[ user_id ] = AuthEncoding.pw_encrypt( password ) self._login_to_userid[ login_name ] = user_id self._userid_to_login[ user_id ] = login_name
def addUser(self, user_id, login_name, password): if self._user_passwords.get(user_id) is not None: raise KeyError, 'Duplicate user ID: %s' % user_id if self._login_to_userid.get(login_name) is not None: raise KeyError, 'Duplicate login name: %s' % login_name self._user_passwords[user_id] = AuthEncoding.pw_encrypt(password) self._login_to_userid[login_name] = user_id self._userid_to_login[user_id] = login_name
def testLongPassword(self): pw = 'Pw' * 2000 for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert AuthEncoding.pw_validate(enc, pw) assert not AuthEncoding.pw_validate(enc, enc) assert not AuthEncoding.pw_validate(enc, 'xxx') if id != 'CRYPT': # crypt truncates passwords and would fail these tests. assert not AuthEncoding.pw_validate(enc, pw[:-2]) assert not AuthEncoding.pw_validate(enc, pw[2:])
def testBadPasword(self): pw = 'OK_pa55w0rd \n' for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert not AuthEncoding.pw_validate(enc, 'xxx') assert not AuthEncoding.pw_validate(enc, enc) if id != 'CRYPT': # crypt truncates passwords and would fail this test. assert not AuthEncoding.pw_validate(enc, pw[:-1]) assert not AuthEncoding.pw_validate(enc, pw[1:]) assert AuthEncoding.pw_validate(enc, pw)
def testLongPassword(self): pw = 'Pw' * 2000 for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert AuthEncoding.pw_validate(enc, pw) assert not AuthEncoding.pw_validate(enc, enc) assert not AuthEncoding.pw_validate(enc, 'xxx') if id != 'CRYPT': # crypt truncates passwords and would fail these tests. assert not AuthEncoding.pw_validate(enc, pw[:-2]) assert not AuthEncoding.pw_validate(enc, pw[2:])
def testBadPasword(self): pw = 'OK_pa55w0rd \n' for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert not AuthEncoding.pw_validate(enc, 'xxx') assert not AuthEncoding.pw_validate(enc, enc) if id != 'CRYPT': # crypt truncates passwords and would fail this test. assert not AuthEncoding.pw_validate(enc, pw[:-1]) assert not AuthEncoding.pw_validate(enc, pw[1:]) assert AuthEncoding.pw_validate(enc, pw)
def updateUserPassword(self, user_id, login_name, password): if self._user_passwords.get(user_id) is None: raise KeyError, 'Invalid user ID: %s' % user_id old_login_name = self._userid_to_login[user_id] if old_login_name != login_name: del self._login_to_userid[old_login_name] self._login_to_userid[login_name] = user_id self._userid_to_login[user_id] = login_name if password: digested = AuthEncoding.pw_encrypt(password) self._user_passwords[user_id] = digested
def addUser( self, user_id, login_name, password ): if self._user_passwords.get( user_id ) is not None: raise KeyError, 'Duplicate user ID: %s' % user_id if self._login_to_userid.get( login_name ) is not None: raise KeyError, 'Duplicate login name: %s' % login_name self._user_passwords[ user_id ] = AuthEncoding.pw_encrypt( password ) self._login_to_userid[ login_name ] = user_id self._userid_to_login[ user_id ] = login_name # enumerateUsers return value has changed view_name = createViewName('enumerateUsers') self.ZCacheable_invalidate(view_name=view_name)
def updateUserPassword( self, user_id, login_name, password ): if self._user_passwords.get( user_id ) is None: raise KeyError, 'Invalid user ID: %s' % user_id old_login_name = self._userid_to_login[ user_id ] if old_login_name != login_name: del self._login_to_userid[ old_login_name ] self._login_to_userid[ login_name ] = user_id self._userid_to_login[ user_id ] = login_name if password: digested = AuthEncoding.pw_encrypt( password ) self._user_passwords[ user_id ] = digested
def setAttempt(self, login, password): "increment attempt count and record date stamp last attempt and IP" root = self.getRootPlugin() count, last, IP, reference = root._login_attempts.get(login, (0, None, '', None)) if reference and AuthEncoding.pw_validate(reference, password): return # we don't count repeating same password in case its correct else: count += 1 IP = self.remote_ip() log.info("user '%s' attempt #%i %s last: %s", login, count, IP, last) last = DateTime() reference = AuthEncoding.pw_encrypt(password) root._login_attempts[login] = (count, last, IP, reference)
def addUser(self, user_id, login_name, password): if self._user_passwords.get(user_id) is not None: raise KeyError, 'Duplicate user ID: %s' % user_id if self._login_to_userid.get(login_name) is not None: raise KeyError, 'Duplicate login name: %s' % login_name self._user_passwords[user_id] = AuthEncoding.pw_encrypt(password) self._login_to_userid[login_name] = user_id self._userid_to_login[user_id] = login_name # enumerateUsers return value has changed view_name = createViewName('enumerateUsers') self.ZCacheable_invalidate(view_name=view_name)
def testLongPassword(self): pw = 'Pw' * 2000 for id in AuthEncoding.listSchemes(): enc = AuthEncoding.pw_encrypt(pw, id) assert enc != pw assert AuthEncoding.pw_validate(enc, pw) assert not AuthEncoding.pw_validate(enc, enc) assert not AuthEncoding.pw_validate(enc, 'xxx') if id not in ('CRYPT', 'BCRYPT'): # crypt truncates passwords and would fail these tests. # bcrypt works with password inputs where len(pw) <= 50 assert not AuthEncoding.pw_validate(enc, pw[:-2]), ( '%r Failed: %s %s' % (id, enc, pw[:-2]) ) assert not AuthEncoding.pw_validate(enc, pw[2:])
def setAttempt(self, login, password): "increment attempt count and record date stamp last attempt and IP" root = self.getRootPlugin() count, last, IP, reference = root._login_attempts.get( login, (0, None, '', None)) if reference and AuthEncoding.pw_validate(reference, password): # we don't count repeating same password in case its correct return if last and ((DateTime() - last) * 24) > self.getResetPeriod(): # set count to 1 following login attempt after reset period count = 1 else: count += 1 IP = self.remote_ip() log.info("user '%s' attempt #%i %s last: %s", login, count, IP, last) last = DateTime() reference = AuthEncoding.pw_encrypt(password) root._login_attempts[login] = (count, last, IP, reference)
def setAttempt(self, login, password): "increment attempt count and record date stamp last attempt and IP" # TODO: why are the login attempts stored in the root? The usernames aren't unique in the root. root = self.getRootPlugin() count, last, IP, reference = root._login_attempts.get( login, (0, None, '', None)) if reference and AuthEncoding.pw_validate(reference, password): # we don't count repeating same password in case its correct return if last and ((DateTime() - last) * 24) > self.getResetPeriod(): # set count to 1 following login attempt after reset period count = 1 else: count += 1 IP = self.remote_ip() log.info("user '%s' attempt #%i %s last: %s", login, count, IP, last) last = DateTime() reference = AuthEncoding.pw_encrypt(password) root._login_attempts[login] = (count, last, IP, reference)
def addUser(self, user_id, login_name, password): """Original ZODBUserManager.addUser, modified to check if incoming password is already encypted. This support clean migration from default user source. Should go into PAS. """ if self._user_passwords.get(user_id) is not None: raise KeyError('Duplicate user ID: %s' % user_id) if self._login_to_userid.get(login_name) is not None: raise KeyError('Duplicate login name: %s' % login_name) if not AuthEncoding.is_encrypted(password): password = AuthEncoding.pw_encrypt(password) self._user_passwords[user_id] = password self._login_to_userid[login_name] = user_id self._userid_to_login[user_id] = login_name # enumerateUsers return value has changed view_name = createViewName('enumerateUsers') self.ZCacheable_invalidate(view_name=view_name)
def addUser(self, user_id, login_name, password): """Original ZODBUserManager.addUser, modified to check if incoming password is already encypted. This support clean migration from default user source. Should go into PAS. """ if self._user_passwords.get(user_id) is not None: raise KeyError, 'Duplicate user ID: %s' % user_id if self._login_to_userid.get(login_name) is not None: raise KeyError, 'Duplicate login name: %s' % login_name if not AuthEncoding.is_encrypted(password): password = AuthEncoding.pw_encrypt(password) self._user_passwords[ user_id ] = password self._login_to_userid[ login_name ] = user_id self._userid_to_login[ user_id ] = login_name # enumerateUsers return value has changed view_name = createViewName('enumerateUsers') self.ZCacheable_invalidate(view_name=view_name)
def _legacy_set_password(self, member, password): from AccessControl import AuthEncoding # Default AuthEncoding 'encryption' uses SSHA member.password = AuthEncoding.pw_encrypt(password) self.layer['portal'].membrane_tool.reindexObject(member)
def _encryptPassword(self, pw): # we need to override the default, because if we encrypt with SSHA # we have trouble when we do the wire protocol upw = to_unicode_or_bust(pw) utf8pw = upw.encode('utf-8', 'ignore') return AuthEncoding.pw_encrypt(utf8pw, 'SHA')
def _legacy_set_password(self, member, password): from AccessControl import AuthEncoding # Default AuthEncoding 'encryption' uses SSHA member.password = AuthEncoding.pw_encrypt(password) self.layer['portal'].membrane_tool.reindexObject(member)
def _encryptPassword(self, pw): return AuthEncoding.pw_encrypt(pw, 'SSHA')
def _encryptPassword(self, pw): # we need to override the default, because if we encrypt with SSHA # we have trouble when we do the wire protocol upw = to_unicode_or_bust(pw) utf8pw = upw.encode('utf-8', 'ignore') return AuthEncoding.pw_encrypt(utf8pw, 'SHA')
def test_argon_is_used_by_default(self): encrypted = AuthEncoding.pw_encrypt('foobar') self.assertTrue('{argon2}' in encrypted) self.assertTrue(AuthEncoding.pw_validate(encrypted, 'foobar'))
def doChangeUser(self, principal_id, password): """Change a user's password """ if self._user_passwords.get(principal_id) is None: raise RuntimeError, "User does not exist: %s" % principal_id self._user_passwords[principal_id] = AuthEncoding.pw_encrypt(password)
def _encryptPassword(self, pw): return AuthEncoding.pw_encrypt(pw, 'SSHA')