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 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 authenticateCredentials( self, credentials ): """ See IAuthenticationPlugin. o We expect the credentials to be those returned by ILoginPasswordExtractionPlugin. """ login = credentials.get( 'login' ) password = credentials.get( 'password' ) if login is None or password is None: return None userid = self._login_to_userid.get( login, login ) reference = self._user_passwords.get(userid) if reference is None: return None if AuthEncoding.is_encrypted( reference ): if AuthEncoding.pw_validate( reference, password ): return userid, login # Support previous naive behavior digested = sha.sha( password ).hexdigest() if reference == digested: return userid, login return None
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 authenticateCredentials(self, credentials): """ See IAuthenticationPlugin. o We expect the credentials to be those returned by ILoginPasswordExtractionPlugin. """ login = credentials.get('login') password = credentials.get('password') if login is None or password is None: return None userid = self._login_to_userid.get(login, login) reference = self._user_passwords.get(userid) if reference is None: return None if AuthEncoding.is_encrypted(reference): if AuthEncoding.pw_validate(reference, password): return userid, login # Support previous naive behavior digested = sha.sha(password).hexdigest() if reference == digested: return userid, login return None
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 authenticateCredentials(self, credentials): """ See IAuthenticationPlugin. o We expect the credentials to be those returned by ILoginPasswordExtractionPlugin. """ login = credentials.get('login') password = credentials.get('password') if login is None or password is None: return None # The original implementation does this, which unhelpfully # falls back to giving the login as userid when the login does # not match a user. This means you will seem to login: you # get a message "welcome, you are now logged in". But you are # not actually logged in. #userid = self._login_to_userid.get(login, login) # Instead, we do some more checking ourself. userid = None if '@' not in login or login == login.lower(): userid = self._login_to_userid.get(login) logger.debug("Standard authentication for %s gives userid %s", login, userid) else: # So at this point we have e-mail address as login and it # is not lowercase. We try the given login and then the # lowercase version if nothing is found. userid = self._login_to_userid.get(login) logger.debug("Original case authentication for %s gives " "userid %r", login, userid) if not userid: login = login.lower() userid = self._login_to_userid.get(login) logger.debug("Lower case authentication for %s gives " "userid %r", login, userid) if userid: # Might not be needed, but just in case. credentials['login'] = login if not userid: return None reference = self._user_passwords.get(userid) if reference is None: return None if AuthEncoding.is_encrypted(reference): if AuthEncoding.pw_validate(reference, password): return userid, login # Support previous naive behavior digested = sha.sha(password).hexdigest() if reference == digested: return userid, login return None
def _migrate_user( new_user_folder, login, password ): from AccessControl import AuthEncoding if AuthEncoding.is_encrypted( password ): new_user_folder._user_passwords[ login ] = password new_user_folder._login_to_userid[ login ] = login new_user_folder._userid_to_login[ login ] = login else: new_user_folder.addUser( login, login, password )
def test_reset_password(self): from AccessControl import AuthEncoding member = self._createType(self.layer['portal'], 'dexterity.membrane.member', 'joe') member.email = '*****@*****.**' self.layer['portal'].membrane_tool.reindexObject(member) user_id = get_user_id_for_email(self.layer['portal'], '*****@*****.**') self.layer['portal'].acl_users.userSetPassword(user_id, b'foobar') self.assertTrue(AuthEncoding.is_encrypted(member.password)) scheme_prefix = '{BCRYPT}' self.assertTrue(member.password.startswith(scheme_prefix)) self.assertTrue(AuthEncoding.pw_validate(member.password, b'foobar'))
def _migrate_user(pas, login, password, roles): from AccessControl import AuthEncoding if AuthEncoding.is_encrypted(password): pas.users._user_passwords[login] = password pas.users._login_to_userid[login] = login pas.users._userid_to_login[login] = login else: pas.users.addUser(login, login, password) new_user = pas.getUser(login) for role_id in roles: if role_id not in ['Authenticated', 'Anonymous']: pas.roles.assignRoleToPrincipal(role_id, new_user.getId())
def _migrate_user( pas, login, password, roles ): from AccessControl import AuthEncoding if AuthEncoding.is_encrypted( password ): pas.users._user_passwords[ login ] = password pas.users._login_to_userid[ login ] = login pas.users._userid_to_login[ login ] = login else: pas.users.addUser( login, login, password ) new_user = pas.getUser( login ) for role_id in roles: if role_id not in ['Authenticated', 'Anonymous']: pas.roles.assignRoleToPrincipal( role_id, new_user.getId() )
def authenticateCredentials(self, credentials): """ See IAuthenticationPlugin. o We expect the credentials to be those returned by ILoginPasswordExtractionPlugin. """ login = credentials.get('login') password = credentials.get('password') if login is None or password is None: return None # Do we have a link between login and userid? Do NOT fall # back to using the login as userid when there is no match, as # that gives a high chance of seeming to log in successfully, # but in reality failing. userid = self._login_to_userid.get(login) if userid is None: # Someone may be logging in with a userid instead of a # login name and the two are not the same. We could try # turning those around, but really we should just fail. # # userid = login # login = self._userid_to_login.get(userid) # if login is None: # return None return None reference = self._user_passwords.get(userid) if reference is None: return None if AuthEncoding.is_encrypted(reference): if AuthEncoding.pw_validate(reference, password): return userid, login # Support previous naive behavior if isinstance(password, six.text_type): password = password.encode('utf8') digested = sha(password).hexdigest() if reference == digested: return userid, login return None
def authenticateCredentials( self, credentials ): """ See IAuthenticationPlugin. o We expect the credentials to be those returned by ILoginPasswordExtractionPlugin. """ login = credentials.get( 'login' ) password = credentials.get( 'password' ) if login is None or password is None: return None # Do we have a link between login and userid? Do NOT fall # back to using the login as userid when there is no match, as # that gives a high chance of seeming to log in successfully, # but in reality failing. userid = self._login_to_userid.get(login) if userid is None: # Someone may be logging in with a userid instead of a # login name and the two are not the same. We could try # turning those around, but really we should just fail. # # userid = login # login = self._userid_to_login.get(userid) # if login is None: # return None return None reference = self._user_passwords.get(userid) if reference is None: return None if AuthEncoding.is_encrypted( reference ): if AuthEncoding.pw_validate( reference, password ): return userid, login # Support previous naive behavior digested = sha( password ).hexdigest() if reference == digested: return userid, login return None
def test_reset_password(self): from AccessControl import AuthEncoding member = self._createType( self.layer['portal'], 'dexterity.membrane.member', 'joe', ) member.email = '*****@*****.**' self.layer['portal'].membrane_tool.reindexObject(member) user_id = get_user_id_for_email( self.layer['portal'], '*****@*****.**', ) self.layer['portal'].acl_users.userSetPassword(user_id, b'foobar') self.assertTrue(AuthEncoding.is_encrypted(member.password)) scheme_prefix = '{BCRYPT}' self.assertTrue(member.password.startswith(scheme_prefix)) self.assertTrue(AuthEncoding.pw_validate(member.password, b'foobar'))
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 _isPasswordEncrypted(self, pw): return AuthEncoding.is_encrypted(pw)
def authenticateCredentials(self, credentials): """ See IAuthenticationPlugin. o We expect the credentials to be those returned by ILoginPasswordExtractionPlugin. """ login = credentials.get('login') password = credentials.get('password') if login is None or password is None: return None # Do we have a link between login and userid? Do NOT fall # back to using the login as userid when there is no match, as # that gives a high chance of seeming to log in successfully, # but in reality failing. userid = self._login_to_userid.get(login) if userid is None: # Someone may be logging in with a userid instead of a # login name and the two are not the same. We could try # turning those around, but really we should just fail. # # userid = login # login = self._userid_to_login.get(userid) # if login is None: # return None return None reference = self._user_passwords.get(userid) if reference is None: return None is_authenticated = False if AuthEncoding.is_encrypted(reference): if AuthEncoding.pw_validate(reference, password): is_authenticated = True if not is_authenticated: # Support previous naive behavior digested = hashlib.sha1(password).hexdigest() if reference == digested: is_authenticated = True if is_authenticated: try: user = api.user.get(username=login) except: return userid, login event = ValidPasswordEntered(user) notify(event) return userid, login else: try: user = api.user.get(username=login) except: return None event = InvalidPasswordEntered(user) notify(event) return None
def _isPasswordEncrypted(self, pw): return AuthEncoding.is_encrypted(pw)