summaryrefslogtreecommitdiff
path: root/passlib/utils/handlers.py
diff options
context:
space:
mode:
Diffstat (limited to 'passlib/utils/handlers.py')
-rw-r--r--passlib/utils/handlers.py239
1 files changed, 120 insertions, 119 deletions
diff --git a/passlib/utils/handlers.py b/passlib/utils/handlers.py
index 22421f6..4385f3b 100644
--- a/passlib/utils/handlers.py
+++ b/passlib/utils/handlers.py
@@ -1,7 +1,7 @@
"""passlib.handler - code for implementing handlers, and global registry for handlers"""
-#=========================================================
+#=============================================================================
# imports
-#=========================================================
+#=============================================================================
from __future__ import with_statement
# core
import inspect
@@ -48,9 +48,9 @@ __all__ = [
'PrefixWrapper',
]
-#=========================================================
-#constants
-#=========================================================
+#=============================================================================
+# constants
+#=============================================================================
# common salt_chars & checksum_chars values
# (BASE64_CHARS, HASH64_CHARS imported above)
@@ -59,7 +59,7 @@ HEX_CHARS = u("0123456789abcdefABCDEF")
UPPER_HEX_CHARS = u("0123456789ABCDEF")
LOWER_HEX_CHARS = u("0123456789abcdef")
-#: special byte string containing all possible byte values
+# special byte string containing all possible byte values
# XXX: treated as singleton by some of the code for efficiency.
ALL_BYTE_VALUES = join_byte_values(irange(256))
@@ -70,9 +70,9 @@ PADDED_B64_CHARS = PADDED_BASE64_CHARS
UC_HEX_CHARS = UPPER_HEX_CHARS
LC_HEX_CHARS = LOWER_HEX_CHARS
-#=========================================================
+#=============================================================================
# support functions
-#=========================================================
+#=============================================================================
def _bitsize(count, chars):
"""helper for bitsize() methods"""
if chars and count:
@@ -81,9 +81,9 @@ def _bitsize(count, chars):
else:
return 0
-#=========================================================
+#=============================================================================
# parsing helpers
-#=========================================================
+#=============================================================================
_UDOLLAR = u("$")
_UZERO = u("0")
@@ -192,9 +192,9 @@ def parse_mc3(hash, prefix, sep=_UDOLLAR, rounds_base=10,
# return result
return rounds, salt, chk or None
-#=====================================================
-#formatting helpers
-#=====================================================
+#=============================================================================
+# formatting helpers
+#=============================================================================
def render_mc2(ident, salt, checksum, sep=u("$")):
"""format hash using 2-part modular crypt format; inverse of parse_mc2()
@@ -244,9 +244,9 @@ def render_mc3(ident, rounds, salt, checksum, sep=u("$"), rounds_base=10):
parts = [ident, rounds, sep, salt]
return uascii_to_str(join_unicode(parts))
-#=====================================================
-#GenericHandler
-#=====================================================
+#=============================================================================
+# GenericHandler
+#=============================================================================
class GenericHandler(PasswordHash):
"""helper class for implementing hash handlers.
@@ -361,9 +361,9 @@ class GenericHandler(PasswordHash):
.. automethod:: verify
"""
- #=====================================================
- #class attr
- #=====================================================
+ #===================================================================
+ # class attr
+ #===================================================================
# this must be provided by the actual class.
setting_kwds = None
@@ -390,16 +390,16 @@ class GenericHandler(PasswordHash):
# private flag used by HasRawChecksum
_checksum_is_bytes = False
- #=====================================================
- #instance attrs
- #=====================================================
+ #===================================================================
+ # instance attrs
+ #===================================================================
checksum = None # stores checksum
# use_defaults = False # whether _norm_xxx() funcs should fill in defaults.
# relaxed = False # when _norm_xxx() funcs should be strict about inputs
- #=====================================================
- #init
- #=====================================================
+ #===================================================================
+ # init
+ #===================================================================
def __init__(self, checksum=None, use_defaults=False, relaxed=False,
**kwds):
self.use_defaults = use_defaults
@@ -451,9 +451,9 @@ class GenericHandler(PasswordHash):
return checksum
- #=====================================================
- #password hash api - formatting interface
- #=====================================================
+ #===================================================================
+ # password hash api - formatting interface
+ #===================================================================
@classmethod
def identify(cls, hash):
# NOTE: subclasses may wish to use faster / simpler identify,
@@ -482,7 +482,7 @@ class GenericHandler(PasswordHash):
return False
@classmethod
- def from_string(cls, hash, **context): #pragma: no cover
+ def from_string(cls, hash, **context): # pragma: no cover
"""return parsed instance from hash/configuration string
:param \*\*context:
@@ -496,7 +496,7 @@ class GenericHandler(PasswordHash):
"""
raise NotImplementedError("%s must implement from_string()" % (cls,))
- def to_string(self): #pragma: no cover
+ def to_string(self): # pragma: no cover
"""render instance to hash or configuration string
:returns:
@@ -507,10 +507,10 @@ class GenericHandler(PasswordHash):
should return native string type (ascii-bytes under python 2,
unicode under python 3)
"""
- #NOTE: documenting some non-standardized but common kwd flags
- # that passlib to_string() method may have
+ # NOTE: documenting some non-standardized but common kwd flags
+ # that passlib to_string() method may have:
#
- # withchk=True -- if false, omit checksum portion of hash
+ # withchk=True -- if false, omit checksum portion of hash
#
raise NotImplementedError("%s must implement from_string()" %
(self.__class__,))
@@ -524,9 +524,9 @@ class GenericHandler(PasswordHash):
## finally:
## self.checksum = orig
- #=========================================================
+ #===================================================================
#'crypt-style' interface (default implementation)
- #=========================================================
+ #===================================================================
@classmethod
def genconfig(cls, **settings):
return cls(use_defaults=True, **settings).to_string()
@@ -538,7 +538,7 @@ class GenericHandler(PasswordHash):
self.checksum = self._calc_checksum(secret)
return self.to_string()
- def _calc_checksum(self, secret): #pragma: no cover
+ def _calc_checksum(self, secret): # pragma: no cover
"""given secret; calcuate and return encoded checksum portion of hash
string, taking config from object state
@@ -548,9 +548,9 @@ class GenericHandler(PasswordHash):
raise NotImplementedError("%s must implement _calc_checksum()" %
(self.__class__,))
- #=========================================================
+ #===================================================================
#'application' interface (default implementation)
- #=========================================================
+ #===================================================================
@classmethod
def encrypt(cls, secret, **kwds):
validate_secret(secret)
@@ -570,10 +570,10 @@ class GenericHandler(PasswordHash):
raise exc.MissingDigestError(cls)
return consteq(self._calc_checksum(secret), chk)
- #=========================================================
+ #===================================================================
# experimental - the following methods are not finished or tested,
# but way work correctly for some hashes
- #=========================================================
+ #===================================================================
_unparsed_settings = ("salt_size", "relaxed")
_unsafe_settings = ("salt", "checksum")
@@ -646,9 +646,9 @@ class GenericHandler(PasswordHash):
info['checksum'] = _bitsize(cls.checksum_size, cc)
return info
- #=========================================================
+ #===================================================================
# eoc
- #=========================================================
+ #===================================================================
class StaticHandler(GenericHandler):
"""GenericHandler mixin for classes which have no settings.
@@ -741,9 +741,9 @@ class StaticHandler(GenericHandler):
DeprecationWarning)
return str_to_uascii(hash)
-#=====================================================
-#GenericHandler mixin classes
-#=====================================================
+#=============================================================================
+# GenericHandler mixin classes
+#=============================================================================
class HasEncodingContext(GenericHandler):
"""helper for classes which require knowledge of the encoding used"""
context_kwds = ("encoding",)
@@ -788,9 +788,9 @@ class HasUserContext(GenericHandler):
## info['user'] = xxx
## return info
-#-----------------------------------------------------
+#------------------------------------------------------------------------
# checksum mixins
-#-----------------------------------------------------
+#------------------------------------------------------------------------
class HasRawChecksum(GenericHandler):
"""mixin for classes which work with decoded checksum bytes
@@ -805,9 +805,9 @@ class HasRawChecksum(GenericHandler):
# this arrangement may be changed in the future.
_checksum_is_bytes = True
-#-----------------------------------------------------
+#------------------------------------------------------------------------
# ident mixins
-#-----------------------------------------------------
+#------------------------------------------------------------------------
class HasManyIdents(GenericHandler):
"""mixin for hashes which use multiple prefix identifiers
@@ -823,27 +823,27 @@ class HasManyIdents(GenericHandler):
document this class's usage
"""
- #=========================================================
- #class attrs
- #=========================================================
- default_ident = None #: should be unicode
- ident_values = None #: should be list of unicode strings
- ident_aliases = None #: should be dict of unicode -> unicode
- #NOTE: any aliases provided to norm_ident() as bytes
- # will have been converted to unicode before
- # comparing against this dictionary.
-
- #NOTE: relying on test_06_HasManyIdents() to verify
- # these are configured correctly.
-
- #=========================================================
- #instance attrs
- #=========================================================
+ #===================================================================
+ # class attrs
+ #===================================================================
+ default_ident = None # should be unicode
+ ident_values = None # should be list of unicode strings
+ ident_aliases = None # should be dict of unicode -> unicode
+ # NOTE: any aliases provided to norm_ident() as bytes
+ # will have been converted to unicode before
+ # comparing against this dictionary.
+
+ # NOTE: relying on test_06_HasManyIdents() to verify
+ # these are configured correctly.
+
+ #===================================================================
+ # instance attrs
+ #===================================================================
ident = None
- #=========================================================
- #init
- #=========================================================
+ #===================================================================
+ # init
+ #===================================================================
def __init__(self, ident=None, **kwds):
super(HasManyIdents, self).__init__(**kwds)
self.ident = self._norm_ident(ident)
@@ -879,9 +879,9 @@ class HasManyIdents(GenericHandler):
# failure!
raise ValueError("invalid ident: %r" % (ident,))
- #=========================================================
- #password hash api
- #=========================================================
+ #===================================================================
+ # password hash api
+ #===================================================================
@classmethod
def identify(cls, hash):
hash = to_unicode_for_identify(hash)
@@ -896,13 +896,13 @@ class HasManyIdents(GenericHandler):
return ident, hash[len(ident):]
raise exc.InvalidHashError(cls)
- #=========================================================
- #eoc
- #=========================================================
+ #===================================================================
+ # eoc
+ #===================================================================
-#-----------------------------------------------------
+#------------------------------------------------------------------------
# salt mixins
-#-----------------------------------------------------
+#------------------------------------------------------------------------
class HasSalt(GenericHandler):
"""mixin for validating salts.
@@ -976,9 +976,9 @@ class HasSalt(GenericHandler):
# TODO: document _truncate_salt()
# XXX: allow providing raw salt to this class, and encoding it?
- #=========================================================
- #class attrs
- #=========================================================
+ #===================================================================
+ # class attrs
+ #===================================================================
min_salt_size = None
max_salt_size = None
@@ -998,14 +998,14 @@ class HasSalt(GenericHandler):
_salt_is_bytes = False
_salt_unit = "chars"
- #=========================================================
- #instance attrs
- #=========================================================
+ #===================================================================
+ # instance attrs
+ #===================================================================
salt = None
- #=========================================================
- #init
- #=========================================================
+ #===================================================================
+ # init
+ #===================================================================
def __init__(self, salt=None, salt_size=None, **kwds):
super(HasSalt, self).__init__(**kwds)
self.salt = self._norm_salt(salt, salt_size=salt_size)
@@ -1104,9 +1104,9 @@ class HasSalt(GenericHandler):
info['salt'] = _bitsize(salt_size, cls.default_salt_chars)
return info
- #=========================================================
- #eoc
- #=========================================================
+ #===================================================================
+ # eoc
+ #===================================================================
class HasRawSalt(HasSalt):
"""mixin for classes which use decoded salt parameter
@@ -1129,9 +1129,9 @@ class HasRawSalt(HasSalt):
assert self.salt_chars in [None, ALL_BYTE_VALUES]
return getrandbytes(rng, salt_size)
-#-----------------------------------------------------
+#------------------------------------------------------------------------
# rounds mixin
-#-----------------------------------------------------
+#------------------------------------------------------------------------
class HasRounds(GenericHandler):
"""mixin for validating rounds parameter
@@ -1182,22 +1182,22 @@ class HasRounds(GenericHandler):
====================
.. automethod:: _norm_rounds
"""
- #=========================================================
- #class attrs
- #=========================================================
+ #===================================================================
+ # class attrs
+ #===================================================================
min_rounds = 0
max_rounds = None
default_rounds = None
rounds_cost = "linear" # default to the common case
- #=========================================================
- #instance attrs
- #=========================================================
+ #===================================================================
+ # instance attrs
+ #===================================================================
rounds = None
- #=========================================================
- #init
- #=========================================================
+ #===================================================================
+ # init
+ #===================================================================
def __init__(self, rounds=None, **kwds):
super(HasRounds, self).__init__(**kwds)
self.rounds = self._norm_rounds(rounds)
@@ -1279,13 +1279,13 @@ class HasRounds(GenericHandler):
# the time-cost, and can't be randomized.
return info
- #=========================================================
- #eoc
- #=========================================================
+ #===================================================================
+ # eoc
+ #===================================================================
-#-----------------------------------------------------
+#------------------------------------------------------------------------
# backend mixin & helpers
-#-----------------------------------------------------
+#------------------------------------------------------------------------
##def _clear_backend(cls):
## "restore HasManyBackend subclass to unloaded state - used by unittests"
## assert issubclass(cls, HasManyBackends) and cls is not HasManyBackends
@@ -1339,14 +1339,15 @@ class HasManyBackends(GenericHandler):
by the subclass for each backend listed in :attr:`backends`.
"""
- #NOTE: subclass must provide:
- # * attr 'backends' containing list of known backends (top priority backend first)
- # * attr '_has_backend_xxx' for each backend 'xxx', indicating if backend is available on system
- # * attr '_calc_checksum_xxx' for each backend 'xxx', containing calc_checksum implementation using that backend
+ # NOTE:
+ # subclass must provide:
+ # * attr 'backends' containing list of known backends (top priority backend first)
+ # * attr '_has_backend_xxx' for each backend 'xxx', indicating if backend is available on system
+ # * attr '_calc_checksum_xxx' for each backend 'xxx', containing calc_checksum implementation using that backend
- backends = None #: list of backend names, provided by subclass.
+ backends = None # list of backend names, provided by subclass.
- _backend = None #: holds currently loaded backend (if any) or None
+ _backend = None # holds currently loaded backend (if any) or None
@classmethod
def get_backend(cls):
@@ -1456,9 +1457,9 @@ class HasManyBackends(GenericHandler):
# this should now invoke the backend-specific version, so call it again.
return self._calc_checksum(secret)
-#=========================================================
-#wrappers
-#=========================================================
+#=============================================================================
+# wrappers
+#=============================================================================
class PrefixWrapper(object):
"""wraps another handler, adding a constant prefix.
@@ -1518,7 +1519,7 @@ class PrefixWrapper(object):
def _check_handler(self, handler):
if 'ident' in handler.setting_kwds and self.orig_prefix:
- #TODO: look into way to fix the issues.
+ # TODO: look into way to fix the issues.
warn("PrefixWrapper: 'orig_prefix' option may not work correctly "
"for handlers which have multiple identifiers: %r" %
(handler.name,), exc.PasslibRuntimeWarning)
@@ -1571,7 +1572,7 @@ class PrefixWrapper(object):
self._ident_values = value
return value
- #attrs that should be proxied
+ # attrs that should be proxied
_proxy_attrs = (
"setting_kwds", "context_kwds",
"default_rounds", "min_rounds", "max_rounds", "rounds_cost",
@@ -1600,7 +1601,7 @@ class PrefixWrapper(object):
return list(attrs)
def __getattr__(self, attr):
- "proxy most attributes from wrapped class (eg rounds, salt size, etc)"
+ "proxy most attributes from wrapped class (e.g. rounds, salt size, etc)"
if attr in self._proxy_attrs:
return getattr(self.wrapped, attr)
raise AttributeError("missing attribute: %r" % (attr,))
@@ -1611,7 +1612,7 @@ class PrefixWrapper(object):
prefix = self.prefix
if not hash.startswith(prefix):
raise exc.InvalidHashError(self)
- #NOTE: always passing to handler as unicode, to save reconversion
+ # NOTE: always passing to handler as unicode, to save reconversion
return self.orig_prefix + hash[len(prefix):]
def _wrap_hash(self, hash):
@@ -1654,6 +1655,6 @@ class PrefixWrapper(object):
hash = self._unwrap_hash(hash)
return self.wrapped.verify(secret, hash, **kwds)
-#=========================================================
+#=============================================================================
# eof
-#=========================================================
+#=============================================================================