diff options
| -rw-r--r-- | passlib/tests/test_utils_handlers.py | 37 | ||||
| -rw-r--r-- | passlib/utils/handlers.py | 61 |
2 files changed, 91 insertions, 7 deletions
diff --git a/passlib/tests/test_utils_handlers.py b/passlib/tests/test_utils_handlers.py index 7e4193c..3342570 100644 --- a/passlib/tests/test_utils_handlers.py +++ b/passlib/tests/test_utils_handlers.py @@ -10,7 +10,7 @@ from logging import getLogger import warnings #site #pkg -from passlib.hash import ldap_md5 +from passlib.hash import ldap_md5, sha256_crypt from passlib.registry import _unload_handler_name as unload_handler_name, \ register_crypt_handler, get_crypt_handler from passlib.utils import rng, getrandstr, handlers as uh, bytes, b, \ @@ -234,7 +234,7 @@ class SkeletonTest(TestCase): self.assertTrue(d1.has_backend()) d1.set_backend('a') self.assertEqual(obj.calc_checksum('s'), 'a') - + #test unknown backend self.assertRaises(ValueError, d1.set_backend, 'c') self.assertRaises(ValueError, d1.has_backend, 'c') @@ -330,6 +330,11 @@ class PrefixWrapperTest(TestCase): d1 = uh.PrefixWrapper("d1", "ldap_md5", "{XXX}", "{MD5}") self.assertEqual(d1.name, "d1") self.assertIs(d1.setting_kwds, ldap_md5.setting_kwds) + self.assertFalse('max_rounds' in dir(d1)) + + d2 = uh.PrefixWrapper("d2", "sha256_crypt", "{XXX}") + self.assertIs(d2.setting_kwds, sha256_crypt.setting_kwds) + self.assertTrue('max_rounds' in dir(d2)) def test_11_wrapped_methods(self): d1 = uh.PrefixWrapper("d1", "ldap_md5", "{XXX}", "{MD5}") @@ -355,6 +360,34 @@ class PrefixWrapperTest(TestCase): self.assertRaises(ValueError, d1.verify, "password", lph) self.assertTrue(d1.verify("password", dph)) + def test_12_ident(self): + # test ident is proxied + h = uh.PrefixWrapper("h2", "ldap_md5", "{XXX}") + self.assertEqual(h.ident, u"{XXX}{MD5}") + self.assertIs(h.ident_values, None) + + # test orig_prefix disabled ident proxy + h = uh.PrefixWrapper("h1", "ldap_md5", "{XXX}", "{MD5}") + self.assertIs(h.ident, None) + self.assertIs(h.ident_values, None) + + # test custom ident overrides default + h = uh.PrefixWrapper("h3", "ldap_md5", "{XXX}", ident="{X") + self.assertEqual(h.ident, u"{X") + self.assertIs(h.ident_values, None) + + # test custom ident must match + h = uh.PrefixWrapper("h3", "ldap_md5", "{XXX}", ident="{XXX}A") + self.assertRaises(ValueError, uh.PrefixWrapper, "h3", "ldap_md5", + "{XXX}", ident="{XY") + self.assertRaises(ValueError, uh.PrefixWrapper, "h3", "ldap_md5", + "{XXX}", ident="{XXXX") + + # test ident_values is proxied + h = uh.PrefixWrapper("h4", "bcrypt", "{XXX}") + self.assertIs(h.ident, None) + self.assertEqual(h.ident_values, [ u"{XXX}$2$", u"{XXX}$2a$" ]) + #========================================================= #sample algorithms - these serve as known quantities # to test the unittests themselves, as well as other diff --git a/passlib/utils/handlers.py b/passlib/utils/handlers.py index e555421..e372f85 100644 --- a/passlib/utils/handlers.py +++ b/passlib/utils/handlers.py @@ -1156,7 +1156,8 @@ class PrefixWrapper(object): :param lazy: if True and wrapped handler is specified by name, don't look it up until needed. """ - def __init__(self, name, wrapped, prefix=u'', orig_prefix=u'', lazy=False, doc=None): + def __init__(self, name, wrapped, prefix=u'', orig_prefix=u'', lazy=False, + doc=None, ident=None): self.name = name if isinstance(prefix, bytes): prefix = prefix.decode("ascii") @@ -1174,6 +1175,13 @@ class PrefixWrapper(object): if not lazy: self._get_wrapped() + if ident is not None: + if isinstance(ident, bytes): + ident = ident.decode("ascii") + if ident[:len(prefix)] != prefix[:len(ident)]: + raise ValueError("ident agree with prefix") + self._ident = ident + _wrapped_name = None _wrapped_handler = None @@ -1192,9 +1200,42 @@ class PrefixWrapper(object): wrapped = property(_get_wrapped) - ##@property - ##def ident(self): - ## return self._prefix + _ident = False + + @property + def ident(self): + value = self._ident + if value is False: + value = None + # XXX: how will this interact with orig_prefix ? + # not exposing attrs for now if orig_prefix is set. + if not self.orig_prefix: + wrapped = self.wrapped + ident = getattr(wrapped, "ident", None) + if ident is not None: + value = self._wrap_hash(ident) + self._ident = value + return value + + _ident_values = False + @property + def ident_values(self): + value = self._ident_values + if value is False: + value = None + # XXX: how will this interact with orig_prefix ? + # not exposing attrs for now if orig_prefix is set. + if not self.orig_prefix: + wrapped = self.wrapped + idents = getattr(wrapped, "ident_values", None) + if idents: + value = [ self._wrap_hash(ident) for ident in idents ] + ##else: + ## ident = self.ident + ## if ident is not None: + ## value = [ident] + self._ident_values = value + return value #attrs that should be proxied _proxy_attrs = ( @@ -1208,10 +1249,20 @@ class PrefixWrapper(object): if self.prefix: args.append("prefix=%r" % self.prefix) if self.orig_prefix: - args.append("orig_prefix=%r", self.orig_prefix) + args.append("orig_prefix=%r" % self.orig_prefix) args = ", ".join(args) return 'PrefixWrapper(%r, %s)' % (self.name, args) + def __dir__(self): + attrs = set(dir(self.__class__)) + attrs.update(self.__dict__) + wrapped = self.wrapped + attrs.update( + attr for attr in self._proxy_attrs + if hasattr(wrapped, attr) + ) + return list(attrs) + def __getattr__(self, attr): "proxy most attributes from wrapped class (eg rounds, salt size, etc)" if attr in self._proxy_attrs: |
