Commits

Simon Law committed 7a9de60

Settings for BCRYPT_ENABLED and BCRYPT_ENABLED_UNDER_TEST.

  • Participants
  • Parent commits 6dc5f6b

Comments (0)

Files changed (2)

File django_bcrypt/models.py

 """
 Overrides :class:`django.contrib.auth.models.User` to use bcrypt
 hashing for passwords.
+
+You can set the following ``settings``:
+
+``BCRYPT_ENABLED``
+   Enables bcrypt hashing when ``User.set_password()`` is called.
+
+``BCRYPT_ENABLED_UNDER_TEST``
+   Enables bcrypt hashing when running inside Django
+   TestCases. Defaults to False, to speed up user creation.
+
+``BCRYPT_ROUNDS``
+   Number of rounds to use for bcrypt hashing. Defaults to 12.
 """
 
 
 
 from django.contrib.auth.models import User
 from django.conf import settings
+from django.core import mail
 
 
 def get_rounds():
-    """
-    Returns the number of rounds to use for bcrypt hashing.
+    """Returns the number of rounds to use for bcrypt hashing."""
+    return getattr(settings, "BCRYPT_ROUNDS", 12)
 
-    Retrieves this from :data:`settings.BCRYPT_ROUNDS`.
-    """
-    return getattr(settings, "BCRYPT_ROUNDS", 12)
+
+def is_enabled():
+    """Returns ``True`` if bcrypt should be used."""
+    enabled = getattr(settings, "BCRYPT_ENABLED", True)
+    if not enabled:
+        return False
+    # Are we under a test?
+    if hasattr(mail, 'outbox'):
+        return getattr(settings, "BCRYPT_ENABLED_UNDER_TEST", False)
 
 
 def bcrypt_check_password(self, raw_password):
     """
     Sets the user's password to *raw_password*, hashed with bcrypt.
     """
-    if raw_password is None:
-        self.set_unusable_password()
+    if not is_enabled() or raw_password is None:
+        _set_password(self, raw_password)
     else:
         salt = bcrypt.gensalt(get_rounds())
         self.password = 'bc$' + bcrypt.hashpw(raw_password, salt)

File django_bcrypt/tests.py

 from django.test import TestCase
 
 from django_bcrypt.models import (bcrypt_check_password, bcrypt_set_password,
-                                  _check_password, _set_password, get_rounds)
+                                  _check_password, _set_password,
+                                  get_rounds, is_enabled)
 
 
 
 
 class CheckPasswordTest(TestCase):
+    def setUp(self):
+        settings.BCRYPT_ENABLED = True
+        settings.BCRYPT_ENABLED_UNDER_TEST = True
+
     def test_bcrypt_password(self):
         user = User()
         bcrypt_set_password(user, 'password')
 
 
 class SetPasswordTest(TestCase):
+    def setUp(self):
+        settings.BCRYPT_ENABLED = True
+        settings.BCRYPT_ENABLED_UNDER_TEST = True
+
     def assertBcrypt(self, hashed, password):
         self.assertEqual(hashed[:3], 'bc$')
         self.assertEqual(hashed[3:], bcrypt.hashpw(password, hashed[3:]))
         bcrypt_set_password(user, 'password')
         self.assertBcrypt(user.password, 'password')
 
+    def test_disabled(self):
+        settings.BCRYPT_ENABLED = False
+        user = User()
+        bcrypt_set_password(user, 'password')
+        self.assertFalse(user.password.startswith('bc$'), user.password)
+
     def test_set_unusable_password(self):
         user = User()
         bcrypt_set_password(user, None)
 
 
 class SettingsTest(TestCase):
-    def test_get_rounds(self):
+    def test_rounds(self):
         orig_rounds = getattr(settings, 'BCRYPT_ROUNDS', None)
         try:
             settings.BCRYPT_ROUNDS = 0
         finally:
             if hasattr(settings._wrapped, 'BCRYPT_ROUNDS'):
                 delattr(settings._wrapped, 'BCRYPT_ROUNDS')
+
+    def test_enabled(self):
+        settings.BCRYPT_ENABLED_UNDER_TEST = True
+        settings.BCRYPT_ENABLED = False
+        self.assertFalse(is_enabled())
+        settings.BCRYPT_ENABLED = True
+        self.assertTrue(is_enabled())
+        delattr(settings, 'BCRYPT_ENABLED')
+        self.assertTrue(is_enabled())
+
+    def test_enabled_under_test(self):
+        settings.BCRYPT_ENABLED = True
+        settings.BCRYPT_ENABLED_UNDER_TEST = True
+        self.assertTrue(is_enabled())
+        settings.BCRYPT_ENABLED_UNDER_TEST = False
+        self.assertFalse(is_enabled())
+        delattr(settings, 'BCRYPT_ENABLED_UNDER_TEST')
+        self.assertFalse(is_enabled())