summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateo Radman <48420316+mateoradman@users.noreply.github.com>2021-09-05 17:24:09 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2021-09-06 07:47:53 +0200
commita7f27fca5239ff3840735dc6dc731b71a99a1d57 (patch)
tree64e1b9800f4f717c6f70ef9efaccba19bf58bd3a
parente75a3a770e5da8af3405be1e216a6c20cc9bde5a (diff)
downloaddjango-a7f27fca5239ff3840735dc6dc731b71a99a1d57.tar.gz
Refs #32508 -- Raised TypeError/ValueError instead of using "assert" in encode() methods of remaining password hashers.
-rw-r--r--django/contrib/auth/hashers.py12
-rw-r--r--tests/auth_tests/test_hashers.py31
2 files changed, 39 insertions, 4 deletions
diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py
index 9946014ad2..cac11dfd4c 100644
--- a/django/contrib/auth/hashers.py
+++ b/django/contrib/auth/hashers.py
@@ -689,7 +689,8 @@ class UnsaltedSHA1PasswordHasher(BasePasswordHasher):
return ''
def encode(self, password, salt):
- assert salt == ''
+ if salt != '':
+ raise ValueError('salt must be empty.')
hash = hashlib.sha1(password.encode()).hexdigest()
return 'sha1$$%s' % hash
@@ -733,7 +734,8 @@ class UnsaltedMD5PasswordHasher(BasePasswordHasher):
return ''
def encode(self, password, salt):
- assert salt == ''
+ if salt != '':
+ raise ValueError('salt must be empty.')
return hashlib.md5(password.encode()).hexdigest()
def decode(self, encoded):
@@ -774,9 +776,11 @@ class CryptPasswordHasher(BasePasswordHasher):
def encode(self, password, salt):
crypt = self._load_library()
- assert len(salt) == 2
+ if len(salt) != 2:
+ raise ValueError('salt must be of length 2.')
hash = crypt.crypt(password, salt)
- assert hash is not None # A platform like OpenBSD with a dummy crypt module.
+ if hash is None: # A platform like OpenBSD with a dummy crypt module.
+ raise TypeError('hash must be provided.')
# we don't need to store the salt, but Django used to do this
return '%s$%s$%s' % (self.algorithm, '', hash)
diff --git a/tests/auth_tests/test_hashers.py b/tests/auth_tests/test_hashers.py
index 81234a44f0..dda64971ba 100644
--- a/tests/auth_tests/test_hashers.py
+++ b/tests/auth_tests/test_hashers.py
@@ -143,6 +143,13 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertTrue(check_password('', blank_encoded))
self.assertFalse(check_password(' ', blank_encoded))
+ @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.UnsaltedMD5PasswordHasher'])
+ def test_unsalted_md5_encode_invalid_salt(self):
+ hasher = get_hasher('unsalted_md5')
+ msg = 'salt must be empty.'
+ with self.assertRaisesMessage(ValueError, msg):
+ hasher.encode('password', salt='salt')
+
@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher'])
def test_unsalted_sha1(self):
encoded = make_password('lètmein', '', 'unsalted_sha1')
@@ -161,6 +168,13 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertTrue(check_password('', blank_encoded))
self.assertFalse(check_password(' ', blank_encoded))
+ @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher'])
+ def test_unsalted_sha1_encode_invalid_salt(self):
+ hasher = get_hasher('unsalted_sha1')
+ msg = 'salt must be empty.'
+ with self.assertRaisesMessage(ValueError, msg):
+ hasher.encode('password', salt='salt')
+
@skipUnless(crypt, "no crypt module to generate password.")
@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.CryptPasswordHasher'])
def test_crypt(self):
@@ -177,6 +191,23 @@ class TestUtilsHashPass(SimpleTestCase):
self.assertTrue(check_password('', blank_encoded))
self.assertFalse(check_password(' ', blank_encoded))
+ @skipUnless(crypt, 'no crypt module to generate password.')
+ @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.CryptPasswordHasher'])
+ def test_crypt_encode_invalid_salt(self):
+ hasher = get_hasher('crypt')
+ msg = 'salt must be of length 2.'
+ with self.assertRaisesMessage(ValueError, msg):
+ hasher.encode('password', salt='a')
+
+ @skipUnless(crypt, 'no crypt module to generate password.')
+ @override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.CryptPasswordHasher'])
+ def test_crypt_encode_invalid_hash(self):
+ hasher = get_hasher('crypt')
+ msg = 'hash must be provided.'
+ with mock.patch('crypt.crypt', return_value=None):
+ with self.assertRaisesMessage(TypeError, msg):
+ hasher.encode('password', salt='ab')
+
@skipUnless(bcrypt, "bcrypt not installed")
def test_bcrypt_sha256(self):
encoded = make_password('lètmein', hasher='bcrypt_sha256')