def authenticateCredentials(self, credentials): """ Fulfill AuthenticationPlugin requirements """ acl = self._getUserFolder() login = credentials.get('login', '') password = credentials.get('password', '') if not acl or not login or not password: return (None, None) if ( login == emergency_user.getUserName() and AuthEncoding.pw_validate( emergency_user._getPassword(), password ) ): return (login, login) user = acl.getUser(login) if user is None: return (None, None) elif user and AuthEncoding.pw_validate(user._getPassword(), password): return (user.getId(), login) return (None, None)
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 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 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 authenticateCredentials(self, credentials): """ See IAuthenticationPlugin. Basically this is like the same method from ZODBUserManager except that we preprocess the password before digesting is, since the migration hashed an already-hashed value. Oh, and we look up the proper plugin by id provided by property. 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 targetname = self.target_id target = getattr(self, targetname) userid = target._login_to_userid.get(login, login) reference = target._user_passwords.get(userid) if reference is None: return None salt = userid[:2] hashed = crypt.crypt(password, salt) if AuthEncoding.pw_validate( reference, hashed): # it would normally be reference, password here return userid, login return None
def authenticate(self, password, request): passwrd=self._getPassword() result = AuthEncoding.pw_validate(passwrd, password) domains=self.getDomains() if domains: return result and domainSpecMatch(domains, request) return result
def authenticate(self, password, request): passwrd=self._getPassword() result = AuthEncoding.pw_validate(passwrd, password) domains=self.getDomains() if domains: return result and domainSpecMatch(domains, request) return result
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 test_legacy_password_validates(self): from AccessControl import AuthEncoding member = self._createType(self.layer['portal'], 'dexterity.membrane.member', 'joe') member.email = '*****@*****.**' self._legacy_set_password(member, b'foobar') self.assertTrue(AuthEncoding.pw_validate(member.password, b'foobar'))
def authenticateCredentials(self, credentials): """ See IAuthenticationPlugin. Basically this is like the same method from ZODBUserManager except that we preprocess the password before digesting is, since the migration hashed an already-hashed value. Oh, and we look up the proper plugin by id provided by property. 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 targetname = self.target_id target = getattr(self, targetname) userid = target._login_to_userid.get(login, login) reference = target._user_passwords.get(userid) if reference is None: return None salt = userid[:2] hashed = crypt.crypt(password, salt) if AuthEncoding.pw_validate(reference, hashed): # it would normally be reference, password here 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 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 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 test_createLDAPPassword_crypt(self): try: # Crypt is not available on all platforms encoded = utils._createLDAPPassword(self.pwd, 'crypt') self.assertTrue(encoded.startswith('{CRYPT}')) self.assertTrue(AuthEncoding.pw_validate(encoded, self.pwd)) except ImportError: pass
def validateSignPassword(self, typed_pass): sign_password = self.getSignPassword() password_matches = AuthEncoding.pw_validate(sign_password, typed_pass) if password_matches: return True return "Password doesn't match"
def isPasswordUsed(self, login, password, history_size=0): """Query password store to see if password has been previously used. """ for hash in self.getPasswordsForUser(login, history_size): if AuthEncoding.pw_validate(hash, password): log.info("Password '%s' for user '%s' not valid (already used)" % (password, login)) return True log.info("Password '%s' for user '%s' valid" % (password, login)) return False
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 test_createLDAPPassword_crypt(self): try: # Crypt is not available on all platforms import crypt encoded = utils._createLDAPPassword(self.pwd, 'crypt') self.failUnless(encoded.startswith('{CRYPT}')) self.failUnless(AuthEncoding.pw_validate(encoded, self.pwd)) except ImportError: pass
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 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 test_legacy_password_validates(self): from AccessControl import AuthEncoding member = self._createType( self.layer['portal'], 'dexterity.membrane.member', 'joe', ) member.email = '*****@*****.**' self._legacy_set_password(member, b'foobar') self.assertTrue(AuthEncoding.pw_validate(member.password, b'foobar'))
def test_getUserWithExtras(self): user = self.suf.getUser('test_user_with_extras') self.failUnless(isinstance(user,User)) self.failUnless(AuthEncoding.pw_validate(user.__,'password' )) self.assertEqual(user.name,'test_user_with_extras') self.assertEqual(list(user.roles),[]) if self.extra_attribute_tests: self.assertEqual(user['extra1'],'extra1value') self.assertEqual(user['extra2'],2) # A final check that we get a KeyError # if we go for an extra that isn't there self.assertRaises(KeyError,user.__getitem__,'extra3')
def verifyCredentials(self, credentials): """Returns True is password is authenticated, False if not. """ user = IMembraneUserObject(self.context) if credentials.get("login") != user.getUserName(): # Should never happen, as the code should then never end # up here, but better safe than sorry. return False password_provider = IProvidePasswordsSchema(self.context) if not password_provider: return False return AuthEncoding.pw_validate(password_provider.password, credentials.get("password", ""))
def test__doChangeUserSamePassword(self): self.suf._doChangeUser( 'test_user', None, ['some','roles'], # roles '', # domains ) user = self.users['test_user'] self.failUnless(AuthEncoding.pw_validate(user.password,'password' )) self.assertEqual(list(user.roles),['some','roles']) self.assertEqual(list(self.suf.getUserNames()),['test_user','test_user_with_extras']) self.assertEqual(list(self.suf.getUser('test_user').roles),['some','roles'])
def test_getUserWithExtras(self): user = self.suf.getUser('test_user_with_extras') self.failUnless(isinstance(user, User)) self.failUnless(AuthEncoding.pw_validate(user.__, 'password')) self.assertEqual(user.name, 'test_user_with_extras') self.assertEqual(list(user.roles), []) if self.extra_attribute_tests: self.assertEqual(user['extra1'], 'extra1value') self.assertEqual(user['extra2'], 2) # A final check that we get a KeyError # if we go for an extra that isn't there self.assertRaises(KeyError, user.__getitem__, 'extra3')
def authenticateCredentials(self, credentials): """ Fulfill AuthenticationPlugin requirements """ acl = self._getUserFolder() login = credentials.get('login', '') password = credentials.get('password', '') if not acl or not login or not password: return (None, None) if login == emergency_user.getUserName() and \ AuthEncoding.pw_validate(emergency_user._getPassword(), password): return (login, login) user = acl.getUser(login) if user is None: return (None, None) elif user and AuthEncoding.pw_validate(user._getPassword(), password): return (user.getId(), login) return (None, None)
def verifyCredentials(self, credentials): """Returns True is password is authenticated, False if not. """ user = IMembraneUserObject(self.context) if credentials.get('login') != user.getUserName(): # Should never happen, as the code should then never end # up here, but better safe than sorry. return False password_provider = IProvidePasswordsSchema(self.context) if not password_provider: return False return AuthEncoding.pw_validate(password_provider.password, credentials.get('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 test__doChangeUserSamePassword(self): self.suf._doChangeUser( 'test_user', None, ['some', 'roles'], # roles '', # domains ) user = self.users['test_user'] self.failUnless(AuthEncoding.pw_validate(user.password, 'password')) self.assertEqual(list(user.roles), ['some', 'roles']) self.assertEqual(list(self.suf.getUserNames()), ['test_user', 'test_user_with_extras']) self.assertEqual(list(self.suf.getUser('test_user').roles), ['some', 'roles'])
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 test__doAddUser(self): self.suf._doAddUser( 'testname', 'testpassword', ['one','two'], # roles [], # domains ) user = self.users['testname'] self.failUnless(AuthEncoding.pw_validate(user.password,'testpassword' )) self.assertEqual(list(user.roles),['one','two']) # order of names is not ensured names = list(self.suf.getUserNames()) names.sort() self.assertEqual(names,['test_user','test_user_with_extras','testname']) self.assertEqual(list(self.suf.getUser('testname').roles),['one','two'])
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 test__doAddUser(self): self.suf._doAddUser( 'testname', 'testpassword', ['one', 'two'], # roles [], # domains ) user = self.users['testname'] self.failUnless(AuthEncoding.pw_validate(user.password, 'testpassword')) self.assertEqual(list(user.roles), ['one', 'two']) # order of names is not ensured names = list(self.suf.getUserNames()) names.sort() self.assertEqual(names, ['test_user', 'test_user_with_extras', 'testname']) self.assertEqual(list(self.suf.getUser('testname').roles), ['one', 'two'])
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 test_password_storage(self): password_plain = 'secret' profile = pi_api.userprofile.create( username='******', email='*****@*****.**', password=password_plain, approve=True, ) self.assertNotEqual(profile.password, password_plain, 'Password not encrypted correctly') self.assertTrue(profile.password.startswith('{BCRYPT}')) self.assertTrue( AuthEncoding.pw_validate( profile.password, password_plain, ) )
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 validate(self, password, data): """ Password validation method """ # Don't check the password if collective.pwexpiry hasn't # been installed yet. if not ICollectivePWExpiryLayer \ .providedBy(self.context.REQUEST): return None # Permit empty passwords here to allow registration links. # Plone will force the user to set one. if password is None: return None if api.user.is_anonymous(): # No check for registrations. return None max_history_pws = api.portal.get_registry_record( 'collective.pwexpiry.password_history_size' ) if max_history_pws == 0: # max_history_pws has been disabled. return None user = api.user.get_current() pw_history = user.getProperty('password_history', tuple()) for old_pw in pw_history[-max_history_pws:]: if AuthEncoding.pw_validate(old_pw, str(password)): return _( u'info_reused_pw', default=u'This password has been used already.' ) # All fine return None
def validate(self, password, data): """ Password validation method """ # Permit empty passwords here to allow registration links. # Plone will force the user to set one. if password is None: return None if api.user.is_anonymous(): # No check for registrations. return None pwexpiry_enabled = api.portal.get_registry_record( 'plone.pwexpiry_enabled') max_history_pws = api.portal.get_registry_record( 'plone.pwexpiry_password_history_size') if max_history_pws == 0 or not pwexpiry_enabled: # max_history_pws has been disabled. return None user = api.user.get_current() # Ignore whitelisted whitelisted = api.portal.get_registry_record( 'plone.pwexpiry_whitelisted_users') if whitelisted and user.getId() in whitelisted: return None pw_history = user.getProperty('password_history', []) for old_pw in pw_history[-max_history_pws:]: if AuthEncoding.pw_validate(old_pw, str(password)): return _(u'info_reused_pw', default=u'This password has been used already.') # All fine 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 userdata = self._userdata() reference = userdata[login]['password'] if not reference: return None if AuthEncoding.pw_validate( reference, password ): return login, login return None
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 validate(self, password, data): """ Password validation method """ # Don't check the password if collective.pwexpiry hasn't # been installed yet. if not ICollectivePWExpiryLayer \ .providedBy(self.context.REQUEST): return None # Permit empty passwords here to allow registration links. # Plone will force the user to set one. if password is None: return None # Checking if minimal length of the entered password # is greater than 8 chars if len(password) < 8: return _(u'Passwords must be at least 8 characters in length.') # password is compared to unicode values password = safe_unicode(password) if not data: # setting password not from the registration form # we can obtain the existing user's properties instead of # collecting them from the submitted form data = {} pm = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') if pm.isAnonymousUser(): userid = self.context.REQUEST.form.get('userid') else: userid = pm.getAuthenticatedMember().getProperty('id') member = pm.getMemberById(userid) if member: data['fullname'] = member.getProperty('fullname') data['username'] = userid data['prevhash'] = acl.source_users._user_passwords.get(userid) # Checking if the entered password doesn't contain # the user's username or any parts of his fullname for name in data.get('fullname', u'').split(' ') + \ [data.get('username', ''), ]: if name: if not isinstance(name, unicode): name = unicode(name.decode('utf-8')) if name.lower() in password.lower(): return _(u'Your password cannot contain your account name' u'(Username), first name or last name.') # Checking if the entered password is different than already set # for this existing user if data.get('prevhash'): if AuthEncoding.pw_validate(data.get('prevhash'), password.encode('utf-8')): return _(u'You have to change your password.') # Checking it the entered password fits to the password policy scheme: # it must contain at least 3 from the 4 parts: # - Uppercase characters (A through Z) # - Lowercase characters (a through z) # - Numerals (0 through 9) # - Special characters such as !, $, #, % matches = 0 if re.match(r'(?=.*[A-Z])', password): matches += 1 if re.match(r'(?=.*[a-z])', password): matches += 1 if re.match(r'(?=.*[0-9])', password): matches += 1 if re.match(r'(?=.*[!$# %])', password): matches += 1 if matches < 3: return _(u'Passwords must contain at least three of the following ' u'four character groups: ' u'Uppercase characters (A through Z), ' u'Lowercase characters (a through z), ' u'Numerals (0 through 9), ' u'Special characters such as !, $, #, %') return None
def validate(self, password, data): """ Password validation method """ # Checking if minimal length of the entered password is greater than 8 chars if len(password) < 8: return u'Passwords must be at least 8 characters in length.' if not data: # setting password not from the registration form # we can obtain the existing user's properties instead of # collecting them from the submitted form data = {} pm = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') if pm.isAnonymousUser(): userid = self.context.REQUEST.form.get('userid') else: userid = pm.getAuthenticatedMember().getProperty('id') member = pm.getMemberById(userid) if member: data['fullname'] = member.getProperty('fullname') data['username'] = userid data['prevhash'] = acl.source_users._user_passwords.get(userid) # Checking if the entered password doesn't contain # the user's username or any parts of his fullname for name in data.get('fullname', '').split(' ') + [ data.get('username', ''), ]: if name and name in password: return u'Your password cannot contain your account name (Username), '\ u'first name or last name.' # Checking if the entered password is different than already set # for this existing user if data.get('prevhash'): if AuthEncoding.pw_validate(data.get('prevhash'), password.encode('utf-8')): return u'You have to change your password.' # Checking it the entered password fits to the password policy scheme: # it must contain at least 3 from the 4 parts: # - Uppercase characters (A through Z) # - Lowercase characters (a through z) # - Numerals (0 through 9) # - Special characters such as !, $, #, % matches = 0 if re.match(r'(?=.*[A-Z])', password): matches += 1 if re.match(r'(?=.*[a-z])', password): matches += 1 if re.match(r'(?=.*[0-9])', password): matches += 1 if re.match(r'(?=.*[!$# %])', password): matches += 1 if matches < 3: return u'Passwords must contain at least three of the following '\ u'four character groups: Uppercase characters (A through Z), '\ u'Lowercase characters (a through z), Numerals (0 through 9), '\ u'Special characters such as !, $, #, %' return None
def validate(self, password, data): """ Password validation method """ # Don't check the password if collective.pwexpiry hasn't # been installed yet. if not ICollectivePWExpiryLayer \ .providedBy(self.context.REQUEST): return None # Permit empty passwords here to allow registration links. # Plone will force the user to set one. if password is None: return None # Checking if minimal length of the entered password # is greater than 8 chars if len(password) < 8: return _(u'Passwords must be at least 8 characters in length.') if not data: # setting password not from the registration form # we can obtain the existing user's properties instead of # collecting them from the submitted form data = {} pm = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') if pm.isAnonymousUser(): userid = self.context.REQUEST.form.get('userid') else: userid = pm.getAuthenticatedMember().getProperty('id') member = pm.getMemberById(userid) if member: data['fullname'] = member.getProperty('fullname') data['username'] = userid data['prevhash'] = acl.source_users._user_passwords.get(userid) # Checking if the entered password doesn't contain # the user's username or any parts of his fullname password_lower = password.lower() for name in data.get('fullname', u'').split(' ') + \ [data.get('username', ''), ]: if name: if not isinstance(name, unicode): name = unicode(name.decode('utf-8')) if name.lower() in password_lower: return _(u'Your password cannot contain your account name' u'(Username), first name or last name.') # Checking if the entered password is different than already set # for this existing user if data.get('prevhash'): if AuthEncoding.pw_validate(data.get('prevhash'), password.encode('utf-8')): return _(u'You have to change your password.') # Checking it the entered password fits to the password policy scheme: # it must contain at least 3 from the 4 parts: # - Uppercase characters (A through Z) # - Lowercase characters (a through z) # - Numerals (0 through 9) # - Special characters such as !, $, #, % matches = 0 if re.match(r'(?=.*[A-Z])', password): matches += 1 if re.match(r'(?=.*[a-z])', password): matches += 1 if re.match(r'(?=.*[0-9])', password): matches += 1 if re.match(r'(?=.*[!$# %])', password): matches += 1 if matches < 3: return _(u'Passwords must contain at least three of the following ' u'four character groups: ' u'Uppercase characters (A through Z), ' u'Lowercase characters (a through z), ' u'Numerals (0 through 9), ' u'Special characters such as !, $, #, %') return None
def test_getUser(self): user = self.suf.getUser('test_user') self.failUnless(isinstance(user,User)) self.failUnless(AuthEncoding.pw_validate(user.__,'password' )) self.assertEqual(user.name,'test_user') self.assertEqual(list(user.roles),['role'])
def test_createLDAPPassword_ssha(self): encoded = utils._createLDAPPassword(self.pwd, 'ssha') self.failUnless(encoded.startswith('{SSHA}')) self.failUnless(AuthEncoding.pw_validate(encoded, self.pwd))
def testUnencryptedPassword(self): # Sanity check pw = 'my-password' assert AuthEncoding.pw_validate(pw, pw)
def testUnencryptedPassword(self): # Sanity check pw = 'my-password' assert AuthEncoding.pw_validate(pw, pw)
def test_createLDAPPassword_ssha(self): encoded = utils._createLDAPPassword(self.pwd, 'ssha') self.failUnless(encoded.startswith('{SSHA}')) self.failUnless(AuthEncoding.pw_validate(encoded, self.pwd))
def test_getUser(self): user = self.suf.getUser('test_user') self.failUnless(isinstance(user, User)) self.failUnless(AuthEncoding.pw_validate(user.__, 'password')) self.assertEqual(user.name, 'test_user') self.assertEqual(list(user.roles), ['role'])
def validate(self, password, data): """ Password validation method """ # Checking if minimal length of the entered password is greater than 8 chars if len(password) < 8: return u'Passwords must be at least 8 characters in length.' if not data: # setting password not from the registration form # we can obtain the existing user's properties instead of # collecting them from the submitted form data = {} pm = getToolByName(self.context, 'portal_membership') acl = getToolByName(self.context, 'acl_users') if pm.isAnonymousUser(): userid = self.context.REQUEST.form.get('userid') else: userid = pm.getAuthenticatedMember().getProperty('id') member = pm.getMemberById(userid) if member: data['fullname'] = member.getProperty('fullname') data['username'] = userid data['prevhash'] = acl.source_users._user_passwords.get(userid) # Checking if the entered password doesn't contain # the user's username or any parts of his fullname for name in data.get('fullname', '').split(' ') + [data.get('username', ''),]: if name and name in password: return u'Your password cannot contain your account name (Username), '\ u'first name or last name.' # Checking if the entered password is different than already set # for this existing user if data.get('prevhash'): if AuthEncoding.pw_validate(data.get('prevhash'), password.encode('utf-8')): return u'You have to change your password.' # Checking it the entered password fits to the password policy scheme: # it must contain at least 3 from the 4 parts: # - Uppercase characters (A through Z) # - Lowercase characters (a through z) # - Numerals (0 through 9) # - Special characters such as !, $, #, % matches = 0 if re.match(r'(?=.*[A-Z])', password): matches += 1 if re.match(r'(?=.*[a-z])', password): matches += 1 if re.match(r'(?=.*[0-9])', password): matches += 1 if re.match(r'(?=.*[!$# %])', password): matches += 1 if matches < 3: return u'Passwords must contain at least three of the following '\ u'four character groups: Uppercase characters (A through Z), '\ u'Lowercase characters (a through z), Numerals (0 through 9), '\ u'Special characters such as !, $, #, %' 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 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