Loading django/contrib/auth/hashers.py +9 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ def check_password(password, encoded, setter=None, preferred='default'): hasher = identify_hasher(encoded) must_update = hasher.algorithm != preferred.algorithm if not must_update: must_update = hasher.must_update(encoded) is_correct = hasher.verify(password, encoded) if setter and is_correct and must_update: setter(password) Loading Loading @@ -212,6 +214,9 @@ class BasePasswordHasher(object): """ raise NotImplementedError('subclasses of BasePasswordHasher must provide a safe_summary() method') def must_update(self, encoded): return False class PBKDF2PasswordHasher(BasePasswordHasher): """ Loading Loading @@ -250,6 +255,10 @@ class PBKDF2PasswordHasher(BasePasswordHasher): (_('hash'), mask_hash(hash)), ]) def must_update(self, encoded): algorithm, iterations, salt, hash = encoded.split('$', 3) return int(iterations) != self.iterations class PBKDF2SHA1PasswordHasher(PBKDF2PasswordHasher): """ Loading django/contrib/auth/tests/test_hashers.py +31 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,37 @@ class TestUtilsHashPass(unittest.TestCase): self.assertFalse(check_password('WRONG', encoded, setter)) self.assertFalse(state['upgraded']) def test_pbkdf2_upgrade(self): self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm) hasher = get_hasher('default') self.assertNotEqual(hasher.iterations, 1) old_iterations = hasher.iterations try: # Generate a password with 1 iteration. hasher.iterations = 1 encoded = make_password('letmein') algo, iterations, salt, hash = encoded.split('$', 3) self.assertEqual(iterations, '1') state = {'upgraded': False} def setter(password): state['upgraded'] = True # Check that no upgrade is triggerd self.assertTrue(check_password('letmein', encoded, setter)) self.assertFalse(state['upgraded']) # Revert to the old iteration count and ... hasher.iterations = old_iterations # ... check if the password would get updated to the new iteration count. self.assertTrue(check_password('letmein', encoded, setter)) self.assertTrue(state['upgraded']) finally: hasher.iterations = old_iterations def test_load_library_no_algorithm(self): with self.assertRaises(ValueError) as e: BasePasswordHasher()._load_library() Loading Loading
django/contrib/auth/hashers.py +9 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,8 @@ def check_password(password, encoded, setter=None, preferred='default'): hasher = identify_hasher(encoded) must_update = hasher.algorithm != preferred.algorithm if not must_update: must_update = hasher.must_update(encoded) is_correct = hasher.verify(password, encoded) if setter and is_correct and must_update: setter(password) Loading Loading @@ -212,6 +214,9 @@ class BasePasswordHasher(object): """ raise NotImplementedError('subclasses of BasePasswordHasher must provide a safe_summary() method') def must_update(self, encoded): return False class PBKDF2PasswordHasher(BasePasswordHasher): """ Loading Loading @@ -250,6 +255,10 @@ class PBKDF2PasswordHasher(BasePasswordHasher): (_('hash'), mask_hash(hash)), ]) def must_update(self, encoded): algorithm, iterations, salt, hash = encoded.split('$', 3) return int(iterations) != self.iterations class PBKDF2SHA1PasswordHasher(PBKDF2PasswordHasher): """ Loading
django/contrib/auth/tests/test_hashers.py +31 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,37 @@ class TestUtilsHashPass(unittest.TestCase): self.assertFalse(check_password('WRONG', encoded, setter)) self.assertFalse(state['upgraded']) def test_pbkdf2_upgrade(self): self.assertEqual('pbkdf2_sha256', get_hasher('default').algorithm) hasher = get_hasher('default') self.assertNotEqual(hasher.iterations, 1) old_iterations = hasher.iterations try: # Generate a password with 1 iteration. hasher.iterations = 1 encoded = make_password('letmein') algo, iterations, salt, hash = encoded.split('$', 3) self.assertEqual(iterations, '1') state = {'upgraded': False} def setter(password): state['upgraded'] = True # Check that no upgrade is triggerd self.assertTrue(check_password('letmein', encoded, setter)) self.assertFalse(state['upgraded']) # Revert to the old iteration count and ... hasher.iterations = old_iterations # ... check if the password would get updated to the new iteration count. self.assertTrue(check_password('letmein', encoded, setter)) self.assertTrue(state['upgraded']) finally: hasher.iterations = old_iterations def test_load_library_no_algorithm(self): with self.assertRaises(ValueError) as e: BasePasswordHasher()._load_library() Loading