diff options
| author | Eli Collins <elic@assurancetechnologies.com> | 2012-04-17 15:34:14 -0400 |
|---|---|---|
| committer | Eli Collins <elic@assurancetechnologies.com> | 2012-04-17 15:34:14 -0400 |
| commit | e56e08c56ea0a4a8ac45aff7bfcd39d351e04e53 (patch) | |
| tree | 00b170736effd3ec37cfd96ab21a0af8e1707913 /passlib | |
| parent | d1932877f847c74d20c7e5311a4dd91c2b6d03f0 (diff) | |
| download | passlib-e56e08c56ea0a4a8ac45aff7bfcd39d351e04e53.tar.gz | |
CryptPolicy deprecated, part2 - updated rest of library to use CryptContext directly
Diffstat (limited to 'passlib')
| -rw-r--r-- | passlib/apache.py | 2 | ||||
| -rw-r--r-- | passlib/apps.py | 2 | ||||
| -rw-r--r-- | passlib/context.py | 42 | ||||
| -rw-r--r-- | passlib/exc.py | 4 | ||||
| -rw-r--r-- | passlib/ext/django/models.py | 4 | ||||
| -rw-r--r-- | passlib/handlers/ldap_digests.py | 2 | ||||
| -rw-r--r-- | passlib/registry.py | 11 | ||||
| -rw-r--r-- | passlib/tests/test_apps.py | 8 | ||||
| -rw-r--r-- | passlib/tests/test_ext_django.py | 15 | ||||
| -rw-r--r-- | passlib/tests/test_handlers.py | 4 | ||||
| -rw-r--r-- | passlib/tests/test_hosts.py | 2 |
11 files changed, 58 insertions, 38 deletions
diff --git a/passlib/apache.py b/passlib/apache.py index e7c3e25..70ac78d 100644 --- a/passlib/apache.py +++ b/passlib/apache.py @@ -515,7 +515,7 @@ class HtpasswdFile(_CommonFile): DeprecationWarning, stacklevel=2) default_scheme = kwds.pop("default") if default_scheme: - context = context.replace(default=default_scheme) + context = context.copy(default=default_scheme) self.context = context super(HtpasswdFile, self).__init__(path, **kwds) diff --git a/passlib/apps.py b/passlib/apps.py index 55dbea5..017de7e 100644 --- a/passlib/apps.py +++ b/passlib/apps.py @@ -112,7 +112,7 @@ def _create_phpass_policy(**kwds): phpass_context = LazyCryptContext( schemes=["bcrypt", "phpass", "bsdi_crypt"], - create_policy=_create_phpass_policy, + onload=_create_phpass_policy, ) phpbb3_context = LazyCryptContext(["phpass"], phpass__ident="H") diff --git a/passlib/context.py b/passlib/context.py index 30dd5a2..5f84202 100644 --- a/passlib/context.py +++ b/passlib/context.py @@ -2414,20 +2414,28 @@ class LazyCryptContext(CryptContext): the first positional argument can be a list of schemes, or omitted, just like CryptContext. - :param create_policy: + :param onload: if a callable is passed in via this keyword, it will be invoked at lazy-load time with the following signature: - ``create_policy(**kwds) -> CryptPolicy``; + ``onload(**kwds) -> kwds``; where ``kwds`` is all the additional kwds passed to LazyCryptContext. - It should return a CryptPolicy instance, which will then be used - by the CryptContext. + It should perform any additional deferred initialization, + and return the final dict of options to be passed to CryptContext. + + .. versionadded:: 1.6 + + :param create_policy: + + .. deprecated:: 1.6 + This option will be removed in Passlib 1.8. + Applications should use *onload* instead. :param kwds: - All additional keywords are passed to CryptPolicy; - or to the create_policy function if provided. + All additional keywords are passed to CryptContext; + or to the *onload* function (if provided). This is mainly used internally by modules such as :mod:`passlib.apps`, which define a large number of contexts, but only a few of them will be needed @@ -2443,7 +2451,7 @@ class LazyCryptContext(CryptContext): # previously it just called _lazy_init() when ``.policy`` was # first accessed. now that is done whenever any of the public # attributes are accessed, and the class itself is changed - # to a regular CryptContext, to remove the overhead one it's unneeded. + # to a regular CryptContext, to remove the overhead once it's unneeded. def __init__(self, schemes=None, **kwds): if schemes is not None: @@ -2453,16 +2461,26 @@ class LazyCryptContext(CryptContext): def _lazy_init(self): kwds = self._lazy_kwds if 'create_policy' in kwds: + warn("The CryptPolicy class, and LazyCryptContext's " + "``create_policy`` keyword have been deprecated as of " + "Passlib 1.6, and will be removed in Passlib 1.8; " + "please use the ``onload`` keyword instead.", + DeprecationWarning) create_policy = kwds.pop("create_policy") - policy = create_policy(**kwds) - kwds = dict(policy=CryptPolicy.from_source(policy)) - super(LazyCryptContext, self).__init__(**kwds) + result = create_policy(**kwds) + policy = CryptPolicy.from_source(result, _warn=False) + kwds = policy._context.to_dict() + elif 'onload' in kwds: + onload = kwds.pop("onload") + kwds = onload(**kwds) del self._lazy_kwds + super(LazyCryptContext, self).__init__(**kwds) self.__class__ = CryptContext def __getattribute__(self, attr): - if not attr.startswith("_"): - self._lazy_init() + if (not attr.startswith("_") or attr.startswith("__")) and \ + self._lazy_kwds is not None: + self._lazy_init() return object.__getattribute__(self, attr) #========================================================= diff --git a/passlib/exc.py b/passlib/exc.py index 1fbe46b..5f7d1dd 100644 --- a/passlib/exc.py +++ b/passlib/exc.py @@ -48,10 +48,10 @@ class PasslibConfigWarning(PasslibWarning): This occurs primarily in one of two cases: - * the policy contains rounds limits which exceed the hard limits + * the CryptContext contains rounds limits which exceed the hard limits imposed by the underlying algorithm. * an explicit rounds value was provided which exceeds the limits - imposed by the policy. + imposed by the CryptContext. In both of these cases, the code will perform correctly & securely; but the warning is issued as a sign the configuration may need updating. diff --git a/passlib/ext/django/models.py b/passlib/ext/django/models.py index d76cc9c..0bf9b99 100644 --- a/passlib/ext/django/models.py +++ b/passlib/ext/django/models.py @@ -13,7 +13,7 @@ see the Passlib documentation for details on how to use this app #site from django.conf import settings #pkg -from passlib.context import CryptContext, CryptPolicy +from passlib.context import CryptContext from passlib.utils import is_crypt_context from passlib.utils.compat import bytes, unicode, base_string_types from passlib.ext.django.utils import DEFAULT_CTX, get_category, \ @@ -35,7 +35,7 @@ def patch(): if ctx == "passlib-default": ctx = DEFAULT_CTX if isinstance(ctx, base_string_types): - ctx = CryptContext(policy=CryptPolicy.from_string(ctx)) + ctx = CryptContext.from_string(ctx) if not is_crypt_context(ctx): raise TypeError("django settings.PASSLIB_CONTEXT must be CryptContext " "instance or configuration string: %r" % (ctx,)) diff --git a/passlib/handlers/ldap_digests.py b/passlib/handlers/ldap_digests.py index 19089ee..f51e482 100644 --- a/passlib/handlers/ldap_digests.py +++ b/passlib/handlers/ldap_digests.py @@ -223,7 +223,7 @@ _init_ldap_crypt_handlers() ## global _lcn_host ## if _lcn_host is None: ## from passlib.hosts import host_context -## schemes = host_context.policy.schemes() +## schemes = host_context.schemes() ## _lcn_host = [ ## "ldap_" + name ## for name in unix_crypt_names diff --git a/passlib/registry.py b/passlib/registry.py index 908c23b..627ebe9 100644 --- a/passlib/registry.py +++ b/passlib/registry.py @@ -156,7 +156,7 @@ _handler_locations = { _name_re = re.compile("^[a-z][_a-z0-9]{2,}$") #: names which aren't allowed for various reasons (mainly keyword conflicts in CryptContext) -_forbidden_names = frozenset(["policy", "context", "all", "default", "none"]) +_forbidden_names = frozenset(["onload", "policy", "context", "all", "default", "none"]) #========================================================== #registry frontend functions @@ -289,10 +289,11 @@ def get_crypt_handler(name, default=_NOTSET): """ global _handlers, _handler_locations - #check if handler loaded - handler = _handlers.get(name) - if handler: - return handler + #check if handler is already loaded + try: + return _handlers[name] + except KeyError: + pass #normalize name (and if changed, check dict again) assert isinstance(name, str), "name must be str instance" diff --git a/passlib/tests/test_apps.py b/passlib/tests/test_apps.py index d48654d..1758c38 100644 --- a/passlib/tests/test_apps.py +++ b/passlib/tests/test_apps.py @@ -25,7 +25,7 @@ class AppsTest(TestCase): def test_custom_app_context(self): ctx = apps.custom_app_context - self.assertEqual(ctx.policy.schemes(), ["sha512_crypt", "sha256_crypt"]) + self.assertEqual(ctx.schemes(), ("sha512_crypt", "sha256_crypt")) for hash in [ ('$6$rounds=41128$VoQLvDjkaZ6L6BIE$4pt.1Ll1XdDYduEwEYPCMOBiR6W6' 'znsyUEoNlcVXpv2gKKIbQolgmTGe6uEEVJ7azUxuc8Tf7zV9SD2z7Ij751'), @@ -93,10 +93,12 @@ class AppsTest(TestCase): h1 = '$2a$10$Ljj0Kgu7Ddob9xWoqzn0ae.uNfxPRofowWdksk.6jCUHKTGYLD.QG' if hashmod.bcrypt.has_backend(): self.assertTrue(ctx.verify("test", h1)) - self.assertEqual(ctx.policy.get_handler().name, "bcrypt") + self.assertEqual(ctx.default_scheme(), "bcrypt") + self.assertEqual(ctx.handler().name, "bcrypt") else: self.assertEqual(ctx.identify(h1), "bcrypt") - self.assertEqual(ctx.policy.get_handler().name, "phpass") + self.assertEqual(ctx.default_scheme(), "phpass") + self.assertEqual(ctx.handler().name, "phpass") def test_phpbb3_context(self): ctx = apps.phpbb3_context diff --git a/passlib/tests/test_ext_django.py b/passlib/tests/test_ext_django.py index f4ea932..0a8764f 100644 --- a/passlib/tests/test_ext_django.py +++ b/passlib/tests/test_ext_django.py @@ -9,7 +9,7 @@ import sys import warnings #site #pkg -from passlib.context import CryptContext, CryptPolicy +from passlib.context import CryptContext from passlib.apps import django_context from passlib.ext.django import utils from passlib.hash import sha256_crypt @@ -118,9 +118,9 @@ sample1_sha1 = 'sha1$b215d$9ee0a66f84ef1ad99096355e788135f7e949bd41' # context for testing category funcs category_context = CryptContext( schemes = [ "sha256_crypt" ], - sha256_crypt__rounds = 1000, - staff__sha256_crypt__rounds = 2000, - superuser__sha256_crypt__rounds = 3000, + sha256_crypt__default_rounds = 1000, + staff__sha256_crypt__default_rounds = 2000, + superuser__sha256_crypt__default_rounds = 3000, ) def get_cc_rounds(**kwds): @@ -258,7 +258,6 @@ class PatchTest(TestCase): def test_01_patch_bad_types(self): "test set_django_password_context bad inputs" set = utils.set_django_password_context - self.assertRaises(TypeError, set, CryptPolicy()) self.assertRaises(TypeError, set, "") def test_02_models_check_password(self): @@ -540,7 +539,7 @@ class PluginTest(TestCase): def test_20_categories(self): "test PASSLIB_GET_CATEGORY unset" update_settings( - PASSLIB_CONTEXT=category_context.policy.to_string(), + PASSLIB_CONTEXT=category_context.to_string(), ) import passlib.ext.django.models @@ -553,7 +552,7 @@ class PluginTest(TestCase): def get_category(user): return user.first_name or None update_settings( - PASSLIB_CONTEXT = category_context.policy.to_string(), + PASSLIB_CONTEXT = category_context.to_string(), PASSLIB_GET_CATEGORY = get_category, ) import passlib.ext.django.models @@ -566,7 +565,7 @@ class PluginTest(TestCase): def test_22_categories_disabled(self): "test PASSLIB_GET_CATEGORY = None" update_settings( - PASSLIB_CONTEXT = category_context.policy.to_string(), + PASSLIB_CONTEXT = category_context.to_string(), PASSLIB_GET_CATEGORY = None, ) import passlib.ext.django.models diff --git a/passlib/tests/test_handlers.py b/passlib/tests/test_handlers.py index 259a58f..a5dd3ae 100644 --- a/passlib/tests/test_handlers.py +++ b/passlib/tests/test_handlers.py @@ -2040,10 +2040,10 @@ class scram_test(HandlerCase): self.assertEqual(handler.extract_digest_algs(h), ["md5", "sha-1"]) self.assertFalse(c1.hash_needs_update(h)) - c2 = c1.replace(scram__algs="sha1") + c2 = c1.copy(scram__algs="sha1") self.assertFalse(c2.hash_needs_update(h)) - c2 = c1.replace(scram__algs="sha1,sha256") + c2 = c1.copy(scram__algs="sha1,sha256") self.assertTrue(c2.hash_needs_update(h)) def test_96_full_verify(self): diff --git a/passlib/tests/test_hosts.py b/passlib/tests/test_hosts.py index de744a8..a64fb30 100644 --- a/passlib/tests/test_hosts.py +++ b/passlib/tests/test_hosts.py @@ -72,7 +72,7 @@ class HostsTest(TestCase): # validate schemes is non-empty, # and contains unix_disabled + at least one real scheme - schemes = ctx.policy.schemes() + schemes = list(ctx.schemes()) self.assertTrue(schemes, "appears to be unix system, but no known schemes supported by crypt") self.assertTrue('unix_disabled' in schemes) schemes.remove("unix_disabled") |
