summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Collins <elic@assurancetechnologies.com>2011-09-19 21:22:14 -0400
committerEli Collins <elic@assurancetechnologies.com>2011-09-19 21:22:14 -0400
commit1d94bf68a9ce60e10d6a7786f3a3b22f7b160e6e (patch)
treee0375f1e7d01b7faf817ca98b555347d42b39526
parentf21eb07e034690520afc8e844d91b14314f31a7e (diff)
downloadpasslib-1d94bf68a9ce60e10d6a7786f3a3b22f7b160e6e.tar.gz
added django 0.9 support to passlib.ext.django & tests (such as may be found on GAE)
-rw-r--r--passlib/ext/django/utils.py22
-rw-r--r--passlib/tests/test_drivers.py7
-rw-r--r--passlib/tests/test_ext_django.py71
3 files changed, 71 insertions, 29 deletions
diff --git a/passlib/ext/django/utils.py b/passlib/ext/django/utils.py
index 200bfca..f44f95d 100644
--- a/passlib/ext/django/utils.py
+++ b/passlib/ext/django/utils.py
@@ -23,12 +23,15 @@ __all__ = [
#lazy imports
#===================================================================
+_has_django0 = None # old 0.9 django - lacks unusable_password support
_dam = None #django.contrib.auth.models reference
def _import_django():
- global _dam
+ global _dam, _has_django0
if _dam is None:
import django.contrib.auth.models as _dam
+ from django import VERSION
+ _has_django0 = VERSION < (1,0)
return _dam
#===================================================================
@@ -139,7 +142,7 @@ def set_django_password_context(context=None, get_category=get_category):
:data:`!django.contrib.auth.models.User.password_context`,
for easy access.
"""
- global _django_patch_state, _dam
+ global _django_patch_state, _dam, _has_django0
_import_django()
state = _django_patch_state
User = _dam.User
@@ -181,10 +184,19 @@ def set_django_password_context(context=None, get_category=get_category):
)
#prepare replacements
+ if _has_django0:
+ UNUSABLE_PASSWORD = "!"
+ else:
+ UNUSABLE_PASSWORD = _dam.UNUSABLE_PASSWORD
+
def set_password(user, raw_password):
"passlib replacement for User.set_password()"
if raw_password is None:
- user.set_unusable_password()
+ if _has_django0:
+ # django 0.9
+ user.password = UNUSABLE_PASSWORD
+ else:
+ user.set_unusable_password()
else:
cat = get_category(user) if get_category else None
user.password = context.encrypt(raw_password, category=cat)
@@ -194,7 +206,7 @@ def set_django_password_context(context=None, get_category=get_category):
if raw_password is None:
return False
hash = user.password
- if not hash or hash == _dam.UNUSABLE_PASSWORD:
+ if not hash or hash == UNUSABLE_PASSWORD:
return False
cat = get_category(user) if get_category else None
ok, new_hash = context.verify_and_update(raw_password, hash,
@@ -206,7 +218,7 @@ def set_django_password_context(context=None, get_category=get_category):
def raw_check_password(raw_password, enc_password):
"passlib replacement for check_password()"
- if not enc_password or enc_password == _dam.UNUSABLE_PASSWORD:
+ if not enc_password or enc_password == UNUSABLE_PASSWORD:
raise ValueError("no password hash specified")
return context.verify(raw_password, enc_password)
diff --git a/passlib/tests/test_drivers.py b/passlib/tests/test_drivers.py
index f39ef08..3a1d9eb 100644
--- a/passlib/tests/test_drivers.py
+++ b/passlib/tests/test_drivers.py
@@ -217,12 +217,9 @@ class _DjangoHelper(object):
"run known correct hashes through Django's check_password()"
if not self.known_correct_hashes:
return self.skipTest("no known correct hashes specified")
- try:
- from django.conf import settings
- except ImportError:
+ from passlib.tests.test_ext_django import has_django1
+ if not has_django1:
return self.skipTest("Django not installed")
- if not settings.configured:
- settings.configure()
from django.contrib.auth.models import check_password
for secret, hash in self.all_correct_hashes:
self.assertTrue(check_password(secret, hash))
diff --git a/passlib/tests/test_ext_django.py b/passlib/tests/test_ext_django.py
index 8a32664..95ee927 100644
--- a/passlib/tests/test_ext_django.py
+++ b/passlib/tests/test_ext_django.py
@@ -30,20 +30,36 @@ except ImportError:
settings = None
has_django = False
+has_django0 = False #are we using django 0.9 release?
+has_django1 = False #inverse - are we using django >= 1.0
+
if has_django:
+ from django import VERSION
+ has_django0 = (VERSION < (1,0))
+ has_django1 = (VERSION >= (1,0))
+
if not isinstance(settings, LazySettings):
#this could mean django has been configured somehow,
#which we don't want, since test cases reset and manipulate settings.
raise RuntimeError("expected django.conf.settings to be LazySettings: %r" % (settings,))
#else configure a blank settings instance for our unittests
- settings.configure()
+ if has_django0:
+ if settings._target is None:
+ from django.conf import UserSettingsHolder, global_settings
+ settings._target = UserSettingsHolder(global_settings)
+ else:
+ if not settings.configured:
+ settings.configure()
def update_settings(**kwds):
for k,v in kwds.iteritems():
if v is Undef:
if hasattr(settings, k):
- delattr(settings, k)
+ if has_django0:
+ delattr(settings._target, k)
+ else:
+ delattr(settings, k)
else:
setattr(settings, k, v)
@@ -190,6 +206,14 @@ class PatchTest(TestCase):
utils.set_django_password_context(None)
self.assert_unpatched()
+ #patch to use stock django context again
+ utils.set_django_password_context(django_context)
+ self.assert_patched(context=django_context)
+
+ #try to remove patch again
+ utils.set_django_password_context(None)
+ self.assert_unpatched()
+
def test_01_patch_control_detection(self):
"test set_django_password_context detection of foreign monkeypatches"
def dummy():
@@ -262,7 +286,7 @@ class PatchTest(TestCase):
self.assert_patched(context=simple_context)
# test that blank hash is never accepted
- self.assertIs(user.password, '')
+ self.assertEqual(user.password, '')
self.assertIs(user.saved_password, None)
self.assertFalse(user.check_password('x'))
@@ -273,15 +297,16 @@ class PatchTest(TestCase):
self.assertFalse(user.check_password(None))
# none of that should have triggered update of password
- self.assertIs(user.password, sample1_md5)
+ self.assertEqual(user.password, sample1_md5)
self.assertIs(user.saved_password, None)
#check unusable password
- user.set_unusable_password()
- self.assertFalse(user.has_usable_password())
- self.assertFalse(user.check_password(None))
- self.assertFalse(user.check_password(''))
- self.assertFalse(user.check_password(sample1))
+ if has_django1:
+ user.set_unusable_password()
+ self.assertFalse(user.has_usable_password())
+ self.assertFalse(user.check_password(None))
+ self.assertFalse(user.check_password(''))
+ self.assertFalse(user.check_password(sample1))
def test_04_check_password_migration(self):
"test User.check_password() hash migration"
@@ -294,7 +319,7 @@ class PatchTest(TestCase):
# set things up with a password that needs migration
user.password = sample1_des
- self.assertIs(user.password, sample1_des)
+ self.assertEqual(user.password, sample1_des)
self.assertIs(user.saved_password, None)
# run check with bad password...
@@ -302,7 +327,7 @@ class PatchTest(TestCase):
self.assertFalse(user.check_password('x'))
self.assertFalse(user.check_password(None))
- self.assertIs(user.password, sample1_des)
+ self.assertEqual(user.password, sample1_des)
self.assertIs(user.saved_password, None)
# run check with correct password...
@@ -310,7 +335,7 @@ class PatchTest(TestCase):
self.assertTrue(user.check_password(sample1))
self.assertTrue(user.password.startswith("$1$"))
- self.assertIs(user.saved_password, user.password)
+ self.assertEqual(user.saved_password, user.password)
# check resave doesn't happen
user.saved_password = None
@@ -326,9 +351,10 @@ class PatchTest(TestCase):
self.assert_patched(context=simple_context)
# sanity check
- self.assertIs(user.password, '')
+ self.assertEqual(user.password, '')
self.assertIs(user.saved_password, None)
- self.assertTrue(user.has_usable_password())
+ if has_django1:
+ self.assertTrue(user.has_usable_password())
# set password
user.set_password(sample1)
@@ -338,7 +364,8 @@ class PatchTest(TestCase):
#check unusable password
user.set_password(None)
- self.assertFalse(user.has_usable_password())
+ if has_django1:
+ self.assertFalse(user.has_usable_password())
self.assertIs(user.saved_password, None)
def test_06_get_category(self):
@@ -389,6 +416,9 @@ django_hash_tests = [
default_hash_tests = django_hash_tests + [ td.Builtin_SHA512CryptTest ]
+if has_django0:
+ django_hash_tests.remove(td.DjangoDesCryptTest)
+
class PluginTest(TestCase):
"test django plugin via settings"
@@ -427,6 +457,8 @@ class PluginTest(TestCase):
# check against valid password
u.password = hash
+ if has_django0 and isinstance(secret, unicode):
+ secret = secret.encode("utf-8")
self.assertTrue(u.check_password(secret))
if new_hash and deprecated and test.handler.name in deprecated:
self.assertFalse(handler.identify(hash))
@@ -440,10 +472,11 @@ class PluginTest(TestCase):
self.assertEquals(u.password, hash)
# check disabled handling
- u.set_password(None)
- handler = get_crypt_handler("django_disabled")
- self.assertTrue(handler.identify(u.password))
- self.assertFalse(u.check_password('placeholder'))
+ if has_django1:
+ u.set_password(None)
+ handler = get_crypt_handler("django_disabled")
+ self.assertTrue(handler.identify(u.password))
+ self.assertFalse(u.check_password('placeholder'))
def test_00_actual_django(self):
"test actual Django behavior has not changed"