diff options
author | Eli Collins <elic@assurancetechnologies.com> | 2016-06-15 18:07:59 -0400 |
---|---|---|
committer | Eli Collins <elic@assurancetechnologies.com> | 2016-06-15 18:07:59 -0400 |
commit | ce23c2ab15e70b612cbd902bf0513c0cf6d734e9 (patch) | |
tree | 3b44c5799cd1aff93244d42d2c87e891b4b60e6d | |
parent | fbe95e1cd44c27c9b32dc8dfa3008b59ffbc9baa (diff) | |
download | passlib-ce23c2ab15e70b612cbd902bf0513c0cf6d734e9.tar.gz |
renamed PasswordHandler.replace() back to PasswordHandler.using()
this basically reversed rev 5c41b0153d4f; after using it a bit more,
decided the name didn't indicate as well what the method was doing.
39 files changed, 201 insertions, 205 deletions
@@ -15,7 +15,7 @@ Release History * Get argon2 hash implemented (:issue:`69`). - - blocking on .replace() api + - blocking on .using() api * Finish the :mod:`passlib.totp` module (:issue:`44`) @@ -81,7 +81,7 @@ Minor Internal Changes Compatibility wrappers will be kept in place at the old location until Passlib 2.0. * The majority of CryptContext's internal rounds handling & migration code has been - moved to the password hashes themselves, via the new :meth:`~passlib.ifc.PasswordHash.replace` + moved to the password hashes themselves, via the new :meth:`~passlib.ifc.PasswordHash.using` and :meth:`~passlib.ifc.PasswordHash.needs_update` methods. This allows much more flexibility when using a hash directly, rather than via CryptContext, as well making it easier for CryptContext to support hash-specific parameters. @@ -108,9 +108,9 @@ Deprecations Compatibility aliases will remain in place until Passlib 2.0. * Settings options like ``rounds`` and ``salt_size`` should no longer be passed to - :meth:`!hash`. Instead, callers should use the new :meth:`~passlib.ifc.PasswordHash.replace` + :meth:`!hash`. Instead, callers should use the new :meth:`~passlib.ifc.PasswordHash.using` method: for example, ``sha256_crypt.hash("secret", rounds=12345)`` should now be - ``sha256_crypt.replace(rounds=12345).hash("secret")``. Support for the old method + ``sha256_crypt.using(rounds=12345).hash("secret")``. Support for the old method will be removed in Passlib 2.0. * The :class:`~passlib.context.CryptContext` object has a number of cleanups made: diff --git a/admin/benchmarks.py b/admin/benchmarks.py index c7ce7b1..fb02b39 100644 --- a/admin/benchmarks.py +++ b/admin/benchmarks.py @@ -201,7 +201,7 @@ def test_bcrypt_builtin(): import os os.environ['PASSLIB_BUILTIN_BCRYPT'] = 'enabled' bcrypt.set_backend("builtin") - handler = bcrypt.replace(rounds = 10) + handler = bcrypt.using(rounds = 10) def helper(): hash = handler.hash(SECRET) handler.verify(SECRET, hash) @@ -213,7 +213,7 @@ def test_bcrypt_ffi(): "test bcrypt 'bcrypt' backend" from passlib.hash import bcrypt bcrypt.set_backend("bcrypt") - handler = bcrypt.replace(rounds=8) + handler = bcrypt.using(rounds=8) def helper(): hash = handler.hash(SECRET) handler.verify(SECRET, hash) @@ -245,7 +245,7 @@ def test_ldap_salted_md5(): def test_phpass(): """test phpass""" from passlib.hash import phpass - handler = phpass.replace(salt='.'*8, rounds=16) + handler = phpass.using(salt='.'*8, rounds=16) def helper(): hash = handler.hash(SECRET) handler.verify(SECRET, hash) @@ -255,7 +255,7 @@ def test_phpass(): @benchmark.constructor() def test_sha1_crypt(): from passlib.hash import sha1_crypt - handler = sha1_crypt.replace(salt='.'*8, rounds=10000) + handler = sha1_crypt.using(salt='.'*8, rounds=10000) def helper(): hash = handler.hash(SECRET) handler.verify(SECRET, hash) diff --git a/choose_rounds.py b/choose_rounds.py index 21cb3ce..80d8609 100644 --- a/choose_rounds.py +++ b/choose_rounds.py @@ -103,7 +103,7 @@ def main(*args): """estimate speed using specified # of rounds""" # time a single verify() call secret = "S0m3-S3Kr1T" - hash = hasher.replace(rounds=rounds).hash(secret) + hash = hasher.using(rounds=rounds).hash(secret) def helper(): start = tick() hasher.verify(secret, hash) diff --git a/docs/lib/passlib.hash.bcrypt.rst b/docs/lib/passlib.hash.bcrypt.rst index 68f6aea..a9af17e 100644 --- a/docs/lib/passlib.hash.bcrypt.rst +++ b/docs/lib/passlib.hash.bcrypt.rst @@ -19,7 +19,7 @@ for new applications. This class can be used directly as follows:: '$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy' >>> # the same, but with an explicit number of rounds - >>> bcrypt.replace(rounds=8).hash("password") + >>> bcrypt.using(rounds=8).hash("password") '$2a$08$8wmNsdCH.M21f.LSBSnYjQrZ9l1EmtBc9uNPGL.9l75YE8D8FlnZC' >>> # verify password diff --git a/docs/lib/passlib.hash.bcrypt_sha256.rst b/docs/lib/passlib.hash.bcrypt_sha256.rst index 6d9fd7c..a7470c0 100644 --- a/docs/lib/passlib.hash.bcrypt_sha256.rst +++ b/docs/lib/passlib.hash.bcrypt_sha256.rst @@ -21,7 +21,7 @@ This class can be used directly as follows:: '$bcrypt-sha256$2a,12$LrmaIX5x4TRtAwEfwJZa1.$2ehnw6LvuIUTM0iz4iz9hTxv21B6KFO' >>> # the same, but with an explicit number of rounds - >>> bcrypt.replace(rounds=8).hash("password") + >>> bcrypt.using(rounds=8).hash("password") '$bcrypt-sha256$2a,8$UE3dIZ.0I6XZtA/LdMrrle$Ag04/5zYu./12.OSqInXZnJ.WZoh1ua' >>> # verify password diff --git a/docs/lib/passlib.hash.bsdi_crypt.rst b/docs/lib/passlib.hash.bsdi_crypt.rst index 88bb49f..63d4b0e 100644 --- a/docs/lib/passlib.hash.bsdi_crypt.rst +++ b/docs/lib/passlib.hash.bsdi_crypt.rst @@ -22,7 +22,7 @@ It class can be used directly as follows:: '_7C/.Bf/4gZk10RYRs4Y' >>> # same, but with explict number of rounds - >>> bsdi_crypt.replace(rounds=10001).hash("password") + >>> bsdi_crypt.using(rounds=10001).hash("password") '_FQ0.amG/zwCMip7DnBk' >>> # verify password diff --git a/docs/lib/passlib.hash.fshp.rst b/docs/lib/passlib.hash.fshp.rst index 640bb35..6ffefd0 100644 --- a/docs/lib/passlib.hash.fshp.rst +++ b/docs/lib/passlib.hash.fshp.rst @@ -29,7 +29,7 @@ It can be used directly as follows:: '{FSHP1|16|16384}PtoqcGUetmVEy/uR8715TNqKa8+teMF9qZO1lA9lJNUm1EQBLPZ+qPRLeEPHqy6C' >>> # the same, but with an explicit number of rounds, larger salt, and specific variant - >>> fshp.replace(rounds=40000, salt_size=32, variant="sha512").hash("password") + >>> fshp.using(rounds=40000, salt_size=32, variant="sha512").hash("password") '{FSHP3|32|40000}cB8yE/CuADSgUTQZjWy+YTf/cvbU11D/rHNKiUiB6z4dIaO77U/rmNW pgZcZllZbCra5GJ8ZfFRNwCHirPqvYTAnbaQQeFQbWym/frRrRev3buoygFQRYexl4091Pc5m' diff --git a/docs/lib/passlib.hash.md5_crypt.rst b/docs/lib/passlib.hash.md5_crypt.rst index 79cdad6..528367e 100644 --- a/docs/lib/passlib.hash.md5_crypt.rst +++ b/docs/lib/passlib.hash.md5_crypt.rst @@ -43,7 +43,7 @@ The :class:`!md5_crypt` class can be can be used directly as follows:: False >>> # encrypt password using cisco-compatible 4-char salt - >>> md5_crypt.replace(salt_size=4).hash("password") + >>> md5_crypt.using(salt_size=4).hash("password") '$1$wu98$9UuD3hvrwehnqyF1D548N0' .. seealso:: diff --git a/docs/lib/passlib.hash.pbkdf2_digest.rst b/docs/lib/passlib.hash.pbkdf2_digest.rst index 44e5419..0064820 100644 --- a/docs/lib/passlib.hash.pbkdf2_digest.rst +++ b/docs/lib/passlib.hash.pbkdf2_digest.rst @@ -32,7 +32,7 @@ All of these classes can be used directly as follows:: '$pbkdf2-sha256$6400$0ZrzXitFSGltTQnBWOsdAw$Y11AchqV4b0sUisdZd0Xr97KWoymNE0LNNrnEgY4H9M' >>> # same, but with an explicit number of rounds and salt length - >>> pbkdf2_sha256.replace(rounds=8000, salt_size=10).hash("password") + >>> pbkdf2_sha256.using(rounds=8000, salt_size=10).hash("password") '$pbkdf2-sha256$8000$XAuBMIYQQogxRg$tRRlz8hYn63B9LYiCd6PRo6FMiunY9ozmMMI3srxeRE' >>> # verify the password diff --git a/docs/lib/passlib.hash.scram.rst b/docs/lib/passlib.hash.scram.rst index 2836970..9a6a70e 100644 --- a/docs/lib/passlib.hash.scram.rst +++ b/docs/lib/passlib.hash.scram.rst @@ -44,7 +44,7 @@ This class can be used like any other Passlib hash, as follows:: gzvGjbMeuWCtKve8TPjRMNoZK9EGyHQ6y0lW9OtWdHZrDZbBUhB9ou./VI2mlw' >>> # same, but with an explicit number of rounds - >>> scram.replace(rounds=8000).hash("password") + >>> scram.using(rounds=8000).hash("password") '$scram$8000$Y0zp/R/DeO89h/De$sha-1=eE8dq1f1P1hZm21lfzsr3CMbiEA,sha-256=Nf kaDFMzn/yHr/HTv7KEFZqaONo6psRu5LBBFLEbZ.o,sha-512=XnGG11X.J2VGSG1qTbkR3FVr 9j5JwsnV5Fd094uuC.GtVDE087m8e7rGoiVEgXnduL48B2fPsUD9grBjURjkiA' @@ -64,7 +64,7 @@ Additionally, this class provides a number of useful methods for SCRAM-specific * You can override the default list of digests, and/or the number of iterations:: - >>> hash = scram.replace(rounds=1000, algs="sha-1,sha-256,md5").hash("password") + >>> hash = scram.using(rounds=1000, algs="sha-1,sha-256,md5").hash("password") >>> hash '$scram$1000$RsgZo7T2/l8rBUBI$md5=iKsH555d3ctn795Za4S7bQ,sha-1=dRcE2AUjALLF tX5DstdLCXZ9Afw,sha-256=WYE/LF7OntriUUdFXIrYE19OY2yL0N5qsQmdPNFn7JE' diff --git a/docs/lib/passlib.hash.scrypt.rst b/docs/lib/passlib.hash.scrypt.rst index b944360..6f8e55a 100644 --- a/docs/lib/passlib.hash.scrypt.rst +++ b/docs/lib/passlib.hash.scrypt.rst @@ -27,7 +27,7 @@ This class can be used directly as follows:: '$2a$12$NT0I31Sa7ihGEWpka9ASYrEFkhuTNeBQ2xfZskIiiJeyFXhRgS.Sy' >>> # the same, but with an explicit number of rounds - >>> scrypt.replace(rounds=8).hash("password") + >>> scrypt.using(rounds=8).hash("password") '$scrypt$16,8,1$aM15713r3Xsvxbi31lqr1Q$nFNh2CVHVjNldFVKDHDlm4CbdRSCdEBsjjJxD.iCs5E' >>> # verify password diff --git a/docs/lib/passlib.hash.sha256_crypt.rst b/docs/lib/passlib.hash.sha256_crypt.rst index 32c683c..aca2f9a 100644 --- a/docs/lib/passlib.hash.sha256_crypt.rst +++ b/docs/lib/passlib.hash.sha256_crypt.rst @@ -23,7 +23,7 @@ This class can be used directly as follows:: '$5$rounds=80000$wnsT7Yr92oJoP28r$cKhJImk5mfuSKV9b3mumNzlbstFUplKtQXXMo4G6Ep5' >>> # same, but with explict number of rounds - >>> sha256_crypt.replace(rounds=12345).hash("password") + >>> sha256_crypt.using(rounds=12345).hash("password") '$5$rounds=12345$q3hvJE5mn5jKRsW.$BbbYTFiaImz9rTy03GGi.Jf9YY5bmxN0LU3p3uI1iUB' >>> # verify password diff --git a/docs/password_hash_api.rst b/docs/password_hash_api.rst index 2140e5f..1d42bd2 100644 --- a/docs/password_hash_api.rst +++ b/docs/password_hash_api.rst @@ -58,7 +58,7 @@ using the :class:`~passlib.hash.pbkdf2_sha256` hash as an example:: >>> # if the hash supports a variable number of iterations (which pbkdf2_sha256 does), >>> # you can override the default using the replace() method and the 'rounds' keyword: - >>> pbkdf2_sha256.replace(rounds=12345).hash("password") + >>> pbkdf2_sha256.using(rounds=12345).hash("password") '$pbkdf2-sha256$12345$QwjBmJPSOsf4HyNE6L239g$8m1pnP69EYeOiKKb5sNSiYw9M8pJMyeW.CSm0KKO.GI' ^^^^^ @@ -161,7 +161,7 @@ and hash comparison. Passing :attr:`~PasswordHash.setting_kwds` such as ``rounds`` and ``salt_size`` directly into the :meth:`hash` method is deprecated. Callers should instead - use ``handler.replace(**settings).hash(secret)``. Support for the old method + use ``handler.using(**settings).hash(secret)``. Support for the old method is is tentatively scheduled for removal in Passlib 2.0. Context keywords such as ``user`` should still be provided to :meth:`!hash`. @@ -266,7 +266,7 @@ and hash comparison. instead of a properly-formed hash; previous releases were inconsistent in their handling of these two border cases. -.. classmethod:: PasswordHash.replace(relaxed=False, \*\*settings) +.. classmethod:: PasswordHash.using(relaxed=False, \*\*settings) This method takes in a set of algorithm-specific settings, and returns a new handler object which uses the specified default settings instead. @@ -493,7 +493,7 @@ the hashes in passlib: .. attribute:: PasswordHash.setting_kwds - Tuple listing the keywords supported by :meth:`~PasswordHash.replace` control hash generation, + Tuple listing the keywords supported by :meth:`~PasswordHash.using` control hash generation, and which will be encoded into the resulting hash. (These keywords will also be accepted by :meth:`~PasswordHash.hash` and :meth:`~PasswordHash.genconfig`, @@ -574,7 +574,7 @@ the hashes in passlib: .. _relaxed-keyword: ``relaxed`` - By default, passing an invalid value to :meth:`~PasswordHash.replace` + By default, passing an invalid value to :meth:`~PasswordHash.using` will result in a :exc:`ValueError`. However, if ``relaxed=True`` then Passlib will attempt to correct the error and (if successful) issue a :exc:`~passlib.exc.PasslibHashWarning` instead. diff --git a/passlib/context.py b/passlib/context.py index 8d9d50c..30ac6a5 100644 --- a/passlib/context.py +++ b/passlib/context.py @@ -45,7 +45,7 @@ _forbidden_scheme_options = set(["salt"]) # 'salt' - not allowed since a fixed salt would defeat the purpose. # dict containing funcs used to coerce strings to correct type for scheme option keys. -# NOTE: this isn't really needed any longer, since Handler.replace() handles the actual parsing. +# NOTE: this isn't really needed any longer, since Handler.using() handles the actual parsing. # keeping this around for now, though, since it makes context.to_dict() output cleaner. _coerce_scheme_options = dict( min_rounds=int, @@ -967,12 +967,12 @@ class _CryptConfig(object): try: # XXX: relaxed=True is mostly here to retain backwards-compat behavior. # could make this optional flag in future. - subcls = handler.replace(relaxed=True, **settings) + subcls = handler.using(relaxed=True, **settings) except TypeError as err: m = re.match(r".* unexpected keyword argument '(.*)'$", str(err)) if m and m.group(1) in settings: # translate into KeyError, for backwards compat. - # XXX: push this down to GenericHandler.replace() implementation? + # XXX: push this down to GenericHandler.using() implementation? key = m.group(1) raise KeyError("keyword not supported by %s handler: %r" % (handler.name, key)) @@ -1325,7 +1325,7 @@ class CryptContext(object): def replace(self, **kwds): """deprecated alias of :meth:`copy`""" - warn("CryptContext().replace() has been deprecated in Passlib 1.6, " + warn("CryptContext().using() has been deprecated in Passlib 1.6, " "and will be removed in Passlib 1.8, " "it has been renamed to CryptContext().copy()", DeprecationWarning, stacklevel=2) @@ -2027,8 +2027,6 @@ class CryptContext(object): .. deprecated:: 1.7 - As of 1.7, all calls to :meth:`!genconfig` should be replaced with - ``.hash("", **settings)``. This method will be removed in version 2.0, and should only be used for compatibility with Passlib 1.3 - 1.6. """ @@ -2044,8 +2042,6 @@ class CryptContext(object): .. deprecated:: 1.7 - As of 1.7, the :meth:`hash` function now supports a **hash** keyword; - all calls to :meth:`!genhash` can be replaced with ``.hash(secret, config=config, **context)``. This method will be removed in version 2.0, and should only be used for compatibility with Passlib 1.3 - 1.6. """ diff --git a/passlib/ext/django/utils.py b/passlib/ext/django/utils.py index 3ed1c74..3a18376 100644 --- a/passlib/ext/django/utils.py +++ b/passlib/ext/django/utils.py @@ -293,7 +293,7 @@ class _PasslibHasherWrapper(object): if self._has_rounds: # XXX: could cache this subclass somehow (would have to intercept writes to self.rounds) # TODO: always call subcls/handler.needs_update() in case there's other things to check - subcls = self.passlib_handler.replace(min_rounds=self.rounds, max_rounds=self.rounds) + subcls = self.passlib_handler.using(min_rounds=self.rounds, max_rounds=self.rounds) if subcls.needs_update(encoded): return True return False diff --git a/passlib/handlers/bcrypt.py b/passlib/handlers/bcrypt.py index 5426206..a7f11bf 100644 --- a/passlib/handlers/bcrypt.py +++ b/passlib/handlers/bcrypt.py @@ -87,7 +87,7 @@ class bcrypt(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.HasManyBackends, uh. It supports a fixed-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/cisco.py b/passlib/handlers/cisco.py index a12da85..9b2d0cf 100644 --- a/passlib/handlers/cisco.py +++ b/passlib/handlers/cisco.py @@ -128,7 +128,7 @@ class cisco_type7(uh.GenericHandler): It has a simple 4-5 bit salt, but is nonetheless a reversible encoding instead of a real hash. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: int :param salt: @@ -166,8 +166,8 @@ class cisco_type7(uh.GenericHandler): # methods #=================================================================== @classmethod - def replace(cls, salt=None, **kwds): - subcls = super(cisco_type7, cls).replace(**kwds) + def using(cls, salt=None, **kwds): + subcls = super(cisco_type7, cls).using(**kwds) if salt is not None: salt = subcls._norm_salt(salt, relaxed=kwds.get("relaxed")) subcls._generate_salt = staticmethod(lambda: salt) diff --git a/passlib/handlers/des_crypt.py b/passlib/handlers/des_crypt.py index a6aae6b..9ba3eb2 100644 --- a/passlib/handlers/des_crypt.py +++ b/passlib/handlers/des_crypt.py @@ -113,7 +113,7 @@ class des_crypt(uh.HasManyBackends, uh.HasSalt, uh.GenericHandler): It supports a fixed-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -210,7 +210,7 @@ class bsdi_crypt(uh.HasManyBackends, uh.HasRounds, uh.HasSalt, uh.GenericHandler It supports a fixed-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -370,7 +370,7 @@ class bigcrypt(uh.HasSalt, uh.GenericHandler): It supports a fixed-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -453,7 +453,7 @@ class crypt16(uh.HasSalt, uh.GenericHandler): It supports a fixed-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/django.py b/passlib/handlers/django.py index e86ddc9..5f3feba 100644 --- a/passlib/handlers/django.py +++ b/passlib/handlers/django.py @@ -237,7 +237,7 @@ class django_pbkdf2_sha256(DjangoVariableHash): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -288,7 +288,7 @@ class django_pbkdf2_sha1(django_pbkdf2_sha256): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/fshp.py b/passlib/handlers/fshp.py index 25cd247..7f6ed07 100644 --- a/passlib/handlers/fshp.py +++ b/passlib/handlers/fshp.py @@ -27,7 +27,7 @@ class fshp(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :param salt: Optional raw salt string. @@ -101,8 +101,8 @@ class fshp(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): # configuration #=================================================================== @classmethod - def replace(cls, variant=None, **kwds): - subcls = super(fshp, cls).replace(**kwds) + def using(cls, variant=None, **kwds): + subcls = super(fshp, cls).using(**kwds) if variant is not None: subcls.default_variant = cls(use_defaults=True)._norm_variant(variant) return subcls diff --git a/passlib/handlers/ldap_digests.py b/passlib/handlers/ldap_digests.py index ec39fb2..791c37e 100644 --- a/passlib/handlers/ldap_digests.py +++ b/passlib/handlers/ldap_digests.py @@ -124,7 +124,7 @@ class ldap_salted_md5(_SaltedBase64DigestHelper): It supports a 4-16 byte salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: @@ -163,7 +163,7 @@ class ldap_salted_sha1(_SaltedBase64DigestHelper): It supports a 4-16 byte salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: diff --git a/passlib/handlers/md5_crypt.py b/passlib/handlers/md5_crypt.py index d5cb9cc..6513d52 100644 --- a/passlib/handlers/md5_crypt.py +++ b/passlib/handlers/md5_crypt.py @@ -226,7 +226,7 @@ class md5_crypt(uh.HasManyBackends, _MD5_Common): It supports a variable-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -304,7 +304,7 @@ class apr_md5_crypt(_MD5_Common): It supports a variable-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/misc.py b/passlib/handlers/misc.py index a9057a9..2ff0470 100644 --- a/passlib/handlers/misc.py +++ b/passlib/handlers/misc.py @@ -116,8 +116,8 @@ class unix_disabled(uh.MinimalHandler): default_marker = u("!") @classmethod - def replace(cls, marker=None, **kwds): - subcls = super(unix_disabled, cls).replace(**kwds) + def using(cls, marker=None, **kwds): + subcls = super(unix_disabled, cls).using(**kwds) if marker is not None: if not cls.identify(marker): raise ValueError("invalid marker: %r" % marker) @@ -158,7 +158,7 @@ class unix_disabled(uh.MinimalHandler): def hash(cls, secret, **kwds): if kwds: uh.warn_hash_settings_deprecation(cls, kwds) - return cls.replace(**kwds).hash(secret) + return cls.using(**kwds).hash(secret) uh.validate_secret(secret) marker = cls.default_marker assert marker and cls.identify(marker) @@ -175,7 +175,7 @@ class unix_disabled(uh.MinimalHandler): return to_native_str(config, param="config") else: if marker is not None: - cls = cls.replace(marker=marker) + cls = cls.using(marker=marker) return cls.hash(secret) class plaintext(uh.MinimalHandler): diff --git a/passlib/handlers/mssql.py b/passlib/handlers/mssql.py index 0c61333..b060b36 100644 --- a/passlib/handlers/mssql.py +++ b/passlib/handlers/mssql.py @@ -104,7 +104,7 @@ class mssql2000(uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): It supports a fixed-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: @@ -181,7 +181,7 @@ class mssql2005(uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): It supports a fixed-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: diff --git a/passlib/handlers/oracle.py b/passlib/handlers/oracle.py index 0e567da..a094f37 100644 --- a/passlib/handlers/oracle.py +++ b/passlib/handlers/oracle.py @@ -106,7 +106,7 @@ class oracle11(uh.HasSalt, uh.GenericHandler): It supports a fixed-length salt. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/pbkdf2.py b/passlib/handlers/pbkdf2.py index 1bd9e86..bbd0623 100644 --- a/passlib/handlers/pbkdf2.py +++ b/passlib/handlers/pbkdf2.py @@ -95,7 +95,7 @@ def create_pbkdf2_hash(hash_name, digest_size, rounds=12000, ident=None, module= It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: @@ -148,7 +148,7 @@ class cta_pbkdf2_sha1(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.Generic It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: @@ -245,7 +245,7 @@ class dlitz_pbkdf2_sha1(uh.HasRounds, uh.HasSalt, uh.GenericHandler): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -351,7 +351,7 @@ class atlassian_pbkdf2_sha1(uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler) It supports a fixed-length salt, and a fixed number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: @@ -407,7 +407,7 @@ class grub_pbkdf2_sha512(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.Gene It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: diff --git a/passlib/handlers/phpass.py b/passlib/handlers/phpass.py index de32e99..50ee67d 100644 --- a/passlib/handlers/phpass.py +++ b/passlib/handlers/phpass.py @@ -29,7 +29,7 @@ class phpass(uh.HasManyIdents, uh.HasRounds, uh.HasSalt, uh.GenericHandler): It supports a fixed-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/scram.py b/passlib/handlers/scram.py index b2768df..4fff575 100644 --- a/passlib/handlers/scram.py +++ b/passlib/handlers/scram.py @@ -25,7 +25,7 @@ class scram(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: bytes :param salt: @@ -280,14 +280,14 @@ class scram(uh.HasRounds, uh.HasRawSalt, uh.HasRawChecksum, uh.GenericHandler): # variant constructor #=================================================================== @classmethod - def replace(cls, default_algs=None, algs=None, **kwds): + def using(cls, default_algs=None, algs=None, **kwds): # parse aliases if algs is not None: assert default_algs is None default_algs = algs # create subclass - subcls = super(scram, cls).replace(**kwds) + subcls = super(scram, cls).using(**kwds) # fill in algs if default_algs is not None: diff --git a/passlib/handlers/scrypt.py b/passlib/handlers/scrypt.py index 2325600..c5ea074 100644 --- a/passlib/handlers/scrypt.py +++ b/passlib/handlers/scrypt.py @@ -26,7 +26,7 @@ class scrypt(uh.HasRounds, uh.HasRawChecksum, uh.HasRawSalt, uh.GenericHandler): It supports a variable-length salt, a variable number of rounds, as well as some custom tuning parameters unique to scrypt (see below). - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -110,7 +110,7 @@ class scrypt(uh.HasRounds, uh.HasRawChecksum, uh.HasRawSalt, uh.GenericHandler): max_rounds = 31 # limited by scrypt alg rounds_cost = "log2" - # TODO: make default block size & parallel count configurable via replace(), + # TODO: make default block size & parallel count configurable via using(), # and deprecatable via .needs_update() #=================================================================== diff --git a/passlib/handlers/sha1_crypt.py b/passlib/handlers/sha1_crypt.py index 0626441..39d8b2e 100644 --- a/passlib/handlers/sha1_crypt.py +++ b/passlib/handlers/sha1_crypt.py @@ -26,7 +26,7 @@ class sha1_crypt(uh.HasManyBackends, uh.HasRounds, uh.HasSalt, uh.GenericHandler It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/sha2_crypt.py b/passlib/handlers/sha2_crypt.py index 5ec4703..bd5aee6 100644 --- a/passlib/handlers/sha2_crypt.py +++ b/passlib/handlers/sha2_crypt.py @@ -399,7 +399,7 @@ class sha256_crypt(_SHA2_Common): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: @@ -458,7 +458,7 @@ class sha512_crypt(_SHA2_Common): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/handlers/sun_md5_crypt.py b/passlib/handlers/sun_md5_crypt.py index afe237c..517a15b 100644 --- a/passlib/handlers/sun_md5_crypt.py +++ b/passlib/handlers/sun_md5_crypt.py @@ -176,7 +176,7 @@ class sun_md5_crypt(uh.HasRounds, uh.HasSalt, uh.GenericHandler): It supports a variable-length salt, and a variable number of rounds. - The :meth:`~passlib.ifc.PasswordHash.replace` method accepts the following optional keywords: + The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: diff --git a/passlib/ifc.py b/passlib/ifc.py index becf7e6..91a1495 100644 --- a/passlib/ifc.py +++ b/passlib/ifc.py @@ -94,7 +94,7 @@ class PasswordHash(object): Starting with Passlib 1.7, callers should no longer pass settings keywords (e.g. ``rounds`` or ``salt`` directly to :meth:`!hash`); should use - ``.replace(**settings).hash(secret)`` construction instead. + ``.using(**settings).hash(secret)`` construction instead. Support will be removed in Passlib 2.0. @@ -133,7 +133,7 @@ class PasswordHash(object): #=================================================================== @classmethod @abstractmethod - def replace(cls, relaxed=False, **kwds): + def using(cls, relaxed=False, **kwds): """ Return another hasher object (typically a subclass of the current one), which integrates the configuration options specified by ``kwds``. diff --git a/passlib/tests/test_context.py b/passlib/tests/test_context.py index 1c0b03b..1158068 100644 --- a/passlib/tests/test_context.py +++ b/passlib/tests/test_context.py @@ -1294,7 +1294,7 @@ sha512_crypt__min_rounds = 45000 #=================================================================== # TODO: now that rounds generation has moved out of _CryptRecord to HasRounds, - # this should just test that we're passing right options to handler.replace(), + # this should just test that we're passing right options to handler.using(), # and that resulting handler has right settings. # Can then just let HasRounds tests (which are a copy of this) deal with things. @@ -1358,7 +1358,7 @@ sha512_crypt__min_rounds = 45000 self.assertEqual(c2.genconfig(salt="nacl"), "$5$rounds=999999999$nacl$" + STUB) # above policy max - # NOTE: formerly issued a warning in passlib 1.6, now just a wrapper for .replace() + # NOTE: formerly issued a warning in passlib 1.6, now just a wrapper for .using() with self.assertWarningList([]): self.assertEqual( cc.genconfig(rounds=3001, salt="nacl"), '$5$rounds=3001$nacl$' + STUB) diff --git a/passlib/tests/test_handlers.py b/passlib/tests/test_handlers.py index bd693ca..e5b4cd3 100644 --- a/passlib/tests/test_handlers.py +++ b/passlib/tests/test_handlers.py @@ -395,11 +395,11 @@ class cisco_type7_test(HandlerCase): self.assertRaises(ValueError, handler, salt=-10) self.assertRaises(ValueError, handler, salt=100) - self.assertRaises(TypeError, handler.replace, salt='abc') - self.assertRaises(ValueError, handler.replace, salt=-10) - self.assertRaises(ValueError, handler.replace, salt=100) + self.assertRaises(TypeError, handler.using, salt='abc') + self.assertRaises(ValueError, handler.using, salt=-10) + self.assertRaises(ValueError, handler.using, salt=100) with self.assertWarningList("salt/offset must be.*"): - subcls = handler.replace(salt=100, relaxed=True) + subcls = handler.using(salt=100, relaxed=True) self.assertEqual(subcls(use_defaults=True).salt, 52) #============================================================================= @@ -1778,12 +1778,12 @@ class scram_test(HandlerCase): self.assertRaises(ValueError, self.do_encrypt, u("\uFDD0")) self.assertRaises(ValueError, self.do_verify, u("\uFDD0"), h) - def test_94_replace_w_default_algs(self, param="default_algs"): - """replace() -- 'default_algs' parameter""" + def test_94_using_w_default_algs(self, param="default_algs"): + """using() -- 'default_algs' parameter""" # create subclass handler = self.handler orig = list(handler.default_algs) # in case it's modified in place - subcls = handler.replace(**{param: "sha1,md5"}) + subcls = handler.using(**{param: "sha1,md5"}) # shouldn't have changed handler self.assertEqual(handler.default_algs, orig) @@ -1795,13 +1795,13 @@ class scram_test(HandlerCase): h1 = subcls.hash("dummy") self.assertEqual(handler.extract_digest_algs(h1), ["md5", "sha-1"]) - def test_94_replace_w_algs(self): - """replace() -- 'algs' parameter""" - self.test_94_replace_w_default_algs(param="algs") + def test_94_using_w_algs(self): + """using() -- 'algs' parameter""" + self.test_94_using_w_default_algs(param="algs") def test_94_needs_update_algs(self): """needs_update() -- algs setting""" - handler1 = self.handler.replace(algs="sha1,md5") + handler1 = self.handler.using(algs="sha1,md5") # shouldn't need update, has same algs h1 = handler1.hash("dummy") @@ -1809,11 +1809,11 @@ class scram_test(HandlerCase): # *currently* shouldn't need update, has superset of algs required by handler2 # (may change this policy) - handler2 = handler1.replace(algs="sha1") + handler2 = handler1.using(algs="sha1") self.assertFalse(handler2.needs_update(h1)) # should need update, doesn't have all algs required by handler3 - handler3 = handler1.replace(algs="sha1,sha256") + handler3 = handler1.using(algs="sha1,sha256") self.assertTrue(handler3.needs_update(h1)) def test_95_context_algs(self): @@ -2377,17 +2377,17 @@ class unix_disabled_test(HandlerCase): # use marker if no hash self.assertEqual(handler.genhash("stub", ""), handler.default_marker) self.assertEqual(handler.hash("stub"), handler.default_marker) - self.assertEqual(handler.replace().default_marker, handler.default_marker) + self.assertEqual(handler.using().default_marker, handler.default_marker) # custom marker self.assertEqual(handler.genhash("stub", "", marker="*xxx"), "*xxx") self.assertEqual(handler.hash("stub", marker="*xxx"), "*xxx") - self.assertEqual(handler.replace(marker="*xxx").hash("stub"), "*xxx") + self.assertEqual(handler.using(marker="*xxx").hash("stub"), "*xxx") # reject invalid marker self.assertRaises(ValueError, handler.genhash, 'stub', "", marker='abc') self.assertRaises(ValueError, handler.hash, 'stub', marker='abc') - self.assertRaises(ValueError, handler.replace, marker='abc') + self.assertRaises(ValueError, handler.using, marker='abc') class unix_fallback_test(HandlerCase): handler = hash.unix_fallback diff --git a/passlib/tests/test_handlers_bcrypt.py b/passlib/tests/test_handlers_bcrypt.py index fe3336c..8c2acf0 100644 --- a/passlib/tests/test_handlers_bcrypt.py +++ b/passlib/tests/test_handlers_bcrypt.py @@ -342,7 +342,7 @@ class _bcrypt_test(HandlerCase): for i in irange(6): check_padding(bcrypt.genconfig()) for i in irange(3): - check_padding(bcrypt.replace(rounds=bcrypt.min_rounds).hash("bob")) + check_padding(bcrypt.using(rounds=bcrypt.min_rounds).hash("bob")) # # test genconfig() corrects invalid salts & issues warning. diff --git a/passlib/tests/test_utils_handlers.py b/passlib/tests/test_utils_handlers.py index 1fa45cf..c1e4e37 100644 --- a/passlib/tests/test_utils_handlers.py +++ b/passlib/tests/test_utils_handlers.py @@ -248,7 +248,7 @@ class SkeletonTest(TestCase): return d1(**k).salt def gen_salt(sz, **k): - return d1.replace(salt_size=sz, **k)(use_defaults=True).salt + return d1.using(salt_size=sz, **k)(use_defaults=True).salt salts2 = _makelang('ab', 2) salts3 = _makelang('ab', 3) diff --git a/passlib/tests/utils.py b/passlib/tests/utils.py index 2f22bd7..f3f9579 100644 --- a/passlib/tests/utils.py +++ b/passlib/tests/utils.py @@ -917,14 +917,14 @@ class HandlerCase(TestCase): "identify() failed to identify genconfig() output: %r" % (config,)) - def test_02_replace_workflow(self): - """test basic replace() workflow""" + def test_02_using_workflow(self): + """test basic using() workflow""" handler = self.handler - subcls = handler.replace() + subcls = handler.using() self.assertIsNot(subcls, handler) self.assertEqual(subcls.name, handler.name) # NOTE: other info attrs should match as well, just testing basic behavior. - # NOTE: mixin-specific args like replace(min_rounds=xxx) tested later. + # NOTE: mixin-specific args like using(min_rounds=xxx) tested later. def test_03_hash_workflow(self, use_16_legacy=False): """test basic hash-string workflow. @@ -1280,8 +1280,8 @@ class HandlerCase(TestCase): if not (salt_type is bytes or (PY2 and salt_type is unicode)): self.assertRaises(TypeError, self.do_encrypt, 'stub', salt=b'x') - def test_replace_w_salt_size(self): - """Handler.replace() -- default_salt_size""" + def test_using_salt_size(self): + """Handler.using() -- default_salt_size""" self.require_salt_info() handler = self.handler @@ -1290,25 +1290,25 @@ class HandlerCase(TestCase): df = handler.default_salt_size # should prevent setting below handler limit - self.assertRaises(ValueError, handler.replace, default_salt_size=-1) + self.assertRaises(ValueError, handler.using, default_salt_size=-1) with self.assertWarningList([PasslibHashWarning]): - temp = handler.replace(default_salt_size=-1, relaxed=True) + temp = handler.using(default_salt_size=-1, relaxed=True) self.assertEqual(temp.default_salt_size, mn) # should prevent setting above handler limit if mx: - self.assertRaises(ValueError, handler.replace, default_salt_size=mx+1) + self.assertRaises(ValueError, handler.using, default_salt_size=mx+1) with self.assertWarningList([PasslibHashWarning]): - temp = handler.replace(default_salt_size=mx+1, relaxed=True) + temp = handler.using(default_salt_size=mx+1, relaxed=True) self.assertEqual(temp.default_salt_size, mx) # try setting to explicit value if mn != mx: - temp = handler.replace(default_salt_size=mn+1) + temp = handler.using(default_salt_size=mn+1) self.assertEqual(temp.default_salt_size, mn+1) self.assertEqual(handler.default_salt_size, df) - temp = handler.replace(default_salt_size=mn+2) + temp = handler.using(default_salt_size=mn+2) self.assertEqual(temp.default_salt_size, mn+2) self.assertEqual(handler.default_salt_size, df) @@ -1317,14 +1317,14 @@ class HandlerCase(TestCase): ref = mn else: ref = mn + 1 - temp = handler.replace(default_salt_size=str(ref)) + temp = handler.using(default_salt_size=str(ref)) self.assertEqual(temp.default_salt_size, ref) # reject invalid strings - self.assertRaises(ValueError, handler.replace, default_salt_size=str(ref) + "xxx") + self.assertRaises(ValueError, handler.using, default_salt_size=str(ref) + "xxx") # honor 'salt_size' alias - temp = handler.replace(salt_size=ref) + temp = handler.using(salt_size=ref) self.assertEqual(temp.default_salt_size, ref) #=================================================================== @@ -1440,11 +1440,11 @@ class HandlerCase(TestCase): self.assertTrue(context.needs_update(hash), msg="rounds=%d (required=%d): hash=%r: " % (rounds2, rounds1, hash)) #-------------------------------------------------------------------------------------- - # HasRounds.replace() / .needs_update() -- desired rounds limits + # HasRounds.using() / .needs_update() -- desired rounds limits #-------------------------------------------------------------------------------------- def _create_using_rounds_helper(self): """ - setup test helpers for testing handler.replace()'s rounds parameters. + setup test helpers for testing handler.using()'s rounds parameters. """ self.require_rounds_info() handler = self.handler @@ -1452,7 +1452,7 @@ class HandlerCase(TestCase): if handler.name == "bsdi_crypt": # hack to bypass bsdi-crypt's "odd rounds only" behavior, messes up this test orig_handler = handler - handler = handler.replace() + handler = handler.using() handler._generate_rounds = classmethod(lambda cls: super(orig_handler, cls)._generate_rounds()) # create some fake values to test with @@ -1473,7 +1473,7 @@ class HandlerCase(TestCase): # create a subclass with small/medium/large as new default desired values with self.assertWarningList([]): - subcls = handler.replace( + subcls = handler.using( min_desired_rounds=small, max_desired_rounds=large, default_rounds=medium, @@ -1482,9 +1482,9 @@ class HandlerCase(TestCase): # return helpers return handler, subcls, small, medium, large - def test_has_rounds_replace_harness(self): + def test_has_rounds_using_harness(self): """ - HasRounds.replace() -- sanity check test harness + HasRounds.using() -- sanity check test harness """ # setup helpers self.require_rounds_info() @@ -1508,9 +1508,9 @@ class HandlerCase(TestCase): self.assertEqual(subcls.min_desired_rounds, small) self.assertEqual(subcls.max_desired_rounds, large) - def test_has_rounds_replace_w_min_rounds(self): + def test_has_rounds_using_w_min_rounds(self): """ - HasRounds.replace() -- min_rounds / min_desired_rounds + HasRounds.using() -- min_rounds / min_desired_rounds """ # setup helpers handler, subcls, small, medium, large = self._create_using_rounds_helper() @@ -1518,115 +1518,115 @@ class HandlerCase(TestCase): orig_max_rounds = handler.max_rounds orig_default_rounds = handler.default_rounds - # .replace() should clip values below valid minimum, w/ warning + # .using() should clip values below valid minimum, w/ warning if orig_min_rounds > 0: - self.assertRaises(ValueError, handler.replace, min_desired_rounds=orig_min_rounds - 1) + self.assertRaises(ValueError, handler.using, min_desired_rounds=orig_min_rounds - 1) with self.assertWarningList([PasslibHashWarning]): - temp = handler.replace(min_desired_rounds=orig_min_rounds - 1, relaxed=True) + temp = handler.using(min_desired_rounds=orig_min_rounds - 1, relaxed=True) self.assertEqual(temp.min_desired_rounds, orig_min_rounds) - # .replace() should clip values above valid maximum, w/ warning + # .using() should clip values above valid maximum, w/ warning if orig_max_rounds: - self.assertRaises(ValueError, handler.replace, min_desired_rounds=orig_max_rounds + 1) + self.assertRaises(ValueError, handler.using, min_desired_rounds=orig_max_rounds + 1) with self.assertWarningList([PasslibHashWarning]): - temp = handler.replace(min_desired_rounds=orig_max_rounds + 1, relaxed=True) + temp = handler.using(min_desired_rounds=orig_max_rounds + 1, relaxed=True) self.assertEqual(temp.min_desired_rounds, orig_max_rounds) - # .replace() should allow values below previous desired minimum, w/o warning + # .using() should allow values below previous desired minimum, w/o warning with self.assertWarningList([]): - temp = subcls.replace(min_desired_rounds=small - 1) + temp = subcls.using(min_desired_rounds=small - 1) self.assertEqual(temp.min_desired_rounds, small - 1) - # .replace() should allow values w/in previous range - temp = subcls.replace(min_desired_rounds=small + 2) + # .using() should allow values w/in previous range + temp = subcls.using(min_desired_rounds=small + 2) self.assertEqual(temp.min_desired_rounds, small + 2) - # .replace() should allow values above previous desired maximum, w/o warning + # .using() should allow values above previous desired maximum, w/o warning with self.assertWarningList([]): - temp = subcls.replace(min_desired_rounds=large + 1) + temp = subcls.using(min_desired_rounds=large + 1) self.assertEqual(temp.min_desired_rounds, large + 1) # hash() etc should allow explicit values below desired minimum - # NOTE: formerly issued a warning in passlib 1.6, now just a wrapper for .replace() + # NOTE: formerly issued a warning in passlib 1.6, now just a wrapper for .using() self.assertEqual(get_effective_rounds(subcls, small + 1), small + 1) self.assertEqual(get_effective_rounds(subcls, small), small) with self.assertWarningList([]): self.assertEqual(get_effective_rounds(subcls, small - 1), small - 1) # 'min_rounds' should be treated as alias for 'min_desired_rounds' - temp = handler.replace(min_rounds=small) + temp = handler.using(min_rounds=small) self.assertEqual(temp.min_desired_rounds, small) # should be able to specify strings - temp = handler.replace(min_rounds=str(small)) + temp = handler.using(min_rounds=str(small)) self.assertEqual(temp.min_desired_rounds, small) # invalid strings should cause error - self.assertRaises(ValueError, handler.replace, min_rounds=str(small) + "xxx") + self.assertRaises(ValueError, handler.using, min_rounds=str(small) + "xxx") def test_has_rounds_replace_w_max_rounds(self): """ - HasRounds.replace() -- max_rounds / max_desired_rounds + HasRounds.using() -- max_rounds / max_desired_rounds """ # setup helpers handler, subcls, small, medium, large = self._create_using_rounds_helper() orig_min_rounds = handler.min_rounds orig_max_rounds = handler.max_rounds - # .replace() should clip values below valid minimum w/ warning + # .using() should clip values below valid minimum w/ warning if orig_min_rounds > 0: - self.assertRaises(ValueError, handler.replace, max_desired_rounds=orig_min_rounds - 1) + self.assertRaises(ValueError, handler.using, max_desired_rounds=orig_min_rounds - 1) with self.assertWarningList([PasslibHashWarning]): - temp = handler.replace(max_desired_rounds=orig_min_rounds - 1, relaxed=True) + temp = handler.using(max_desired_rounds=orig_min_rounds - 1, relaxed=True) self.assertEqual(temp.max_desired_rounds, orig_min_rounds) - # .replace() should clip values above valid maximum, w/ warning + # .using() should clip values above valid maximum, w/ warning if orig_max_rounds: - self.assertRaises(ValueError, handler.replace, max_desired_rounds=orig_max_rounds + 1) + self.assertRaises(ValueError, handler.using, max_desired_rounds=orig_max_rounds + 1) with self.assertWarningList([PasslibHashWarning]): - temp = handler.replace(max_desired_rounds=orig_max_rounds + 1, relaxed=True) + temp = handler.using(max_desired_rounds=orig_max_rounds + 1, relaxed=True) self.assertEqual(temp.max_desired_rounds, orig_max_rounds) - # .replace() should clip values below previous minimum, w/ warning + # .using() should clip values below previous minimum, w/ warning with self.assertWarningList([PasslibConfigWarning]): - temp = subcls.replace(max_desired_rounds=small - 1) + temp = subcls.using(max_desired_rounds=small - 1) self.assertEqual(temp.max_desired_rounds, small) - # .replace() should reject explicit min > max - self.assertRaises(ValueError, subcls.replace, + # .using() should reject explicit min > max + self.assertRaises(ValueError, subcls.using, min_desired_rounds=medium+1, max_desired_rounds=medium-1) - # .replace() should allow values w/in previous range - temp = subcls.replace(min_desired_rounds=large - 2) + # .using() should allow values w/in previous range + temp = subcls.using(min_desired_rounds=large - 2) self.assertEqual(temp.min_desired_rounds, large - 2) - # .replace() should allow values above previous desired maximum, w/o warning + # .using() should allow values above previous desired maximum, w/o warning with self.assertWarningList([]): - temp = subcls.replace(max_desired_rounds=large + 1) + temp = subcls.using(max_desired_rounds=large + 1) self.assertEqual(temp.max_desired_rounds, large + 1) # hash() etc should allow explicit values above desired minimum, w/o warning - # NOTE: formerly issued a warning in passlib 1.6, now just a wrapper for .replace() + # NOTE: formerly issued a warning in passlib 1.6, now just a wrapper for .using() self.assertEqual(get_effective_rounds(subcls, large - 1), large - 1) self.assertEqual(get_effective_rounds(subcls, large), large) with self.assertWarningList([]): self.assertEqual(get_effective_rounds(subcls, large + 1), large + 1) # 'max_rounds' should be treated as alias for 'max_desired_rounds' - temp = handler.replace(max_rounds=large) + temp = handler.using(max_rounds=large) self.assertEqual(temp.max_desired_rounds, large) # should be able to specify strings - temp = handler.replace(max_desired_rounds=str(large)) + temp = handler.using(max_desired_rounds=str(large)) self.assertEqual(temp.max_desired_rounds, large) # invalid strings should cause error - self.assertRaises(ValueError, handler.replace, max_desired_rounds=str(large) + "xxx") + self.assertRaises(ValueError, handler.using, max_desired_rounds=str(large) + "xxx") - def test_has_rounds_replace_w_default_rounds(self): + def test_has_rounds_using_w_default_rounds(self): """ - HasRounds.replace() -- default_rounds + HasRounds.using() -- default_rounds """ # setup helpers handler, subcls, small, medium, large = self._create_using_rounds_helper() @@ -1635,63 +1635,63 @@ class HandlerCase(TestCase): # XXX: are there any other cases that need testing? # implicit default rounds -- increase to min_rounds - temp = subcls.replace(min_rounds=medium+1) + temp = subcls.using(min_rounds=medium+1) self.assertEqual(temp.default_rounds, medium+1) # implicit default rounds -- decrease to max_rounds - temp = subcls.replace(max_rounds=medium-1) + temp = subcls.using(max_rounds=medium-1) self.assertEqual(temp.default_rounds, medium-1) # explicit default rounds below desired minimum # XXX: make this a warning if min is implicit? - self.assertRaises(ValueError, subcls.replace, default_rounds=small-1) + self.assertRaises(ValueError, subcls.using, default_rounds=small-1) # explicit default rounds above desired maximum # XXX: make this a warning if max is implicit? if orig_max_rounds: - self.assertRaises(ValueError, subcls.replace, default_rounds=large+1) + self.assertRaises(ValueError, subcls.using, default_rounds=large+1) # hash() etc should implicit default rounds, but get overridden self.assertEqual(get_effective_rounds(subcls), medium) self.assertEqual(get_effective_rounds(subcls, medium+1), medium+1) # should be able to specify strings - temp = handler.replace(default_rounds=str(medium)) + temp = handler.using(default_rounds=str(medium)) self.assertEqual(temp.default_rounds, medium) # invalid strings should cause error - self.assertRaises(ValueError, handler.replace, default_rounds=str(medium) + "xxx") + self.assertRaises(ValueError, handler.using, default_rounds=str(medium) + "xxx") - def test_has_rounds_replace_w_rounds(self): + def test_has_rounds_using_w_rounds(self): """ - HasRounds.replace() -- rounds + HasRounds.using() -- rounds """ # setup helpers handler, subcls, small, medium, large = self._create_using_rounds_helper() orig_max_rounds = handler.max_rounds # 'rounds' should be treated as fallback for min, max, and default - temp = subcls.replace(rounds=medium+1) + temp = subcls.using(rounds=medium+1) self.assertEqual(temp.min_desired_rounds, medium+1) self.assertEqual(temp.default_rounds, medium+1) self.assertEqual(temp.max_desired_rounds, medium+1) # 'rounds' should be treated as fallback for min, max, and default - temp = subcls.replace(rounds=medium+1, min_rounds=small+1, + temp = subcls.using(rounds=medium+1, min_rounds=small+1, default_rounds=medium, max_rounds=large-1) self.assertEqual(temp.min_desired_rounds, small+1) self.assertEqual(temp.default_rounds, medium) self.assertEqual(temp.max_desired_rounds, large-1) - def test_has_rounds_replace_w_vary_rounds_parsing(self): + def test_has_rounds_using_w_vary_rounds_parsing(self): """ - HasRounds.replace() -- vary_rounds parsing + HasRounds.using() -- vary_rounds parsing """ # setup helpers handler, subcls, small, medium, large = self._create_using_rounds_helper() def parse(value): - return subcls.replace(vary_rounds=value).vary_rounds + return subcls.using(vary_rounds=value).vary_rounds # floats should be preserved self.assertEqual(parse(0.1), 0.1) @@ -1716,9 +1716,9 @@ class HandlerCase(TestCase): # though there's a faint chance it will randomly fail. seen = set(get_effective_rounds(cls) for _ in irange(500)) - def test_has_rounds_replace_w_vary_rounds_generation(self): + def test_has_rounds_using_w_vary_rounds_generation(self): """ - HasRounds.replace() -- vary_rounds generation + HasRounds.using() -- vary_rounds generation """ handler, subcls, small, medium, large = self._create_using_rounds_helper() @@ -1727,7 +1727,7 @@ class HandlerCase(TestCase): return min(seen), max(seen) def assert_rounds_range(vary_rounds, lower, upper): - temp = subcls.replace(vary_rounds=vary_rounds) + temp = subcls.using(vary_rounds=vary_rounds) seen_lower, seen_upper = get_effective_range(temp) self.assertEqual(seen_lower, lower, "vary_rounds had wrong lower limit:") self.assertEqual(seen_upper, upper, "vary_rounds had wrong upper limit:") @@ -1749,7 +1749,7 @@ class HandlerCase(TestCase): else: # for linear rounds, range is frequently so huge, won't ever see ends. # so we just check it's within an expected range. - lower, upper = get_effective_range(subcls.replace(vary_rounds="50%")) + lower, upper = get_effective_range(subcls.using(vary_rounds="50%")) self.assertGreaterEqual(lower, max(small, medium * 0.5)) self.assertLessEqual(lower, max(small, medium * 0.8)) @@ -1757,13 +1757,13 @@ class HandlerCase(TestCase): self.assertGreaterEqual(upper, min(large, medium * 1.2)) self.assertLessEqual(upper, min(large, medium * 1.5)) - def test_has_rounds_replace_and_needs_update(self): + def test_has_rounds_using_and_needs_update(self): """ - HasRounds.replace() -- desired_rounds + needs_update() + HasRounds.using() -- desired_rounds + needs_update() """ handler, subcls, small, medium, large = self._create_using_rounds_helper() - temp = subcls.replace(min_desired_rounds=small+2, max_desired_rounds=large-2) + temp = subcls.using(min_desired_rounds=small+2, max_desired_rounds=large-2) # generate some sample hashes small_hash = self.do_stub_encrypt(subcls, rounds=small) @@ -1839,8 +1839,8 @@ class HandlerCase(TestCase): # TODO: check various supported idents - def test_has_many_idents_replace(self): - """HasManyIdents.replace() -- 'default_ident' and 'ident' keywords""" + def test_has_many_idents_using(self): + """HasManyIdents.using() -- 'default_ident' and 'ident' keywords""" self.require_many_idents() # pick alt ident to test with @@ -1858,11 +1858,11 @@ class HandlerCase(TestCase): return cls(use_defaults=True).ident # keep default if nothing else specified - subcls = handler.replace() + subcls = handler.using() self.assertEqual(subcls.default_ident, orig_ident) # accepts alt ident - subcls = handler.replace(default_ident=alt_ident) + subcls = handler.using(default_ident=alt_ident) self.assertEqual(subcls.default_ident, alt_ident) self.assertEqual(handler.default_ident, orig_ident) @@ -1872,20 +1872,20 @@ class HandlerCase(TestCase): self.assertEqual(effective_ident(handler), orig_ident) # rejects bad ident - self.assertRaises(ValueError, handler.replace, default_ident='xXx') + self.assertRaises(ValueError, handler.using, default_ident='xXx') # honor 'ident' alias - subcls = handler.replace(ident=alt_ident) + subcls = handler.using(ident=alt_ident) self.assertEqual(subcls.default_ident, alt_ident) self.assertEqual(handler.default_ident, orig_ident) # forbid both at same time - self.assertRaises(TypeError, handler.replace, default_ident=alt_ident, ident=alt_ident) + self.assertRaises(TypeError, handler.using, default_ident=alt_ident, ident=alt_ident) # check ident aliases are being honored if handler.ident_aliases: for alias, ident in handler.ident_aliases.items(): - subcls = handler.replace(ident=alias) + subcls = handler.using(ident=alias) self.assertEqual(subcls.default_ident, ident, msg="alias %r:" % alias) #=================================================================== @@ -2448,7 +2448,7 @@ class HandlerCase(TestCase): # NOTE: using subclass so we can load alt backend in threadsafe manner if hasattr(handler, "backends") and TEST_MODE("full"): def maker(backend): - sub_handler = handler.replace() + sub_handler = handler.using() sub_handler.set_backend(backend) def func(secret, hash): return sub_handler.verify(secret, hash) @@ -2631,7 +2631,7 @@ class OsCryptMixin(HandlerCase): raise AssertionError("handler has no available alternate backends!") # create subclass of handler, which we swap to an alternate backend - alt_handler = handler.replace() + alt_handler = handler.using() alt_handler.set_backend(alt_backend) def crypt_stub(secret, hash): diff --git a/passlib/utils/handlers.py b/passlib/utils/handlers.py index 6eee98a..17c6258 100644 --- a/passlib/utils/handlers.py +++ b/passlib/utils/handlers.py @@ -98,7 +98,7 @@ def guess_app_stacklevel(start=1): def warn_hash_settings_deprecation(handler, kwds): warn("passing settings to %(handler)s.hash() is deprecated, and won't be supported in Passlib 2.0; " - "use '%(handler)s.replace(**settings).hash(secret)' instead" % dict(handler=handler.name), + "use '%(handler)s.using(**settings).hash(secret)' instead" % dict(handler=handler.name), stacklevel=guess_app_stacklevel(2)) def extract_settings_kwds(handler, kwds): @@ -320,13 +320,13 @@ def render_mc3(ident, rounds, salt, checksum, sep=u("$"), rounds_base=10): class MinimalHandler(PasswordHash): """ helper class for implementing hash handlers. - provides nothing besides a base implementation of the .replace() subclass constructor. + provides nothing besides a base implementation of the .using() subclass constructor. """ #=================================================================== # class attr #=================================================================== - #: private flag used by replace() constructor to detect if this is already a subclass. + #: private flag used by using() constructor to detect if this is already a subclass. _configured = False #=================================================================== @@ -334,7 +334,7 @@ class MinimalHandler(PasswordHash): #=================================================================== @classmethod - def replace(cls, relaxed=False): + def using(cls, relaxed=False): # NOTE: this provides the base implementation, which takes care of # creating the newly configured class. Mixins and subclasses # should wrap this, and modify the returned class to suit their options. @@ -644,7 +644,7 @@ class GenericHandler(MinimalHandler): def hash(cls, secret, **kwds): if kwds: # Deprecating passing any settings keywords via .hash() as of passlib 1.7; everything - # should use .replace().hash() instead. If any keywords are specified, presume they're + # should use .using().hash() instead. If any keywords are specified, presume they're # context keywords by default (the common case), and extract out any settings kwds. # Support for passing settings via .hash() will be removed in Passlib 2.0, along with # this block of code. @@ -652,7 +652,7 @@ class GenericHandler(MinimalHandler): if settings: # TODO: uncomment this ones UTs are adjusted to expect warning... # warn_hash_settings_deprecation(cls, settings) - return cls.replace(**settings).hash(secret, **kwds) + return cls.using(**settings).hash(secret, **kwds) # NOTE: at this point, 'kwds' should just contain context_kwds subset validate_secret(secret) self = cls(use_defaults=True, **kwds) @@ -681,7 +681,7 @@ class GenericHandler(MinimalHandler): # NOTE: 'kwds' should generally always be settings, so after this completes, *should* be empty. settings = extract_settings_kwds(cls, kwds) if settings: - return cls.replace(**settings).genconfig(**kwds) + return cls.using(**settings).genconfig(**kwds) # NOTE: this uses optional stub checksum to bypass potentially expensive digest generation, # when caller just wants the config string. self = cls(use_defaults=True, **kwds) @@ -970,7 +970,7 @@ class HasManyIdents(GenericHandler): Class Methods ============= - .. todo:: document replace() and needs_update() options + .. todo:: document using() and needs_update() options """ #=================================================================== @@ -995,10 +995,10 @@ class HasManyIdents(GenericHandler): # variant constructor #=================================================================== @classmethod - def replace(cls, # keyword only... + def using(cls, # keyword only... default_ident=None, ident=None, **kwds): """ - This mixin adds support for the following :meth:`~passlib.ifc.PasswordHash.replace` keywords: + This mixin adds support for the following :meth:`~passlib.ifc.PasswordHash.using` keywords: :param default_ident: default identifier that will be used by resulting customized hasher. @@ -1013,7 +1013,7 @@ class HasManyIdents(GenericHandler): default_ident = ident # create subclass - subcls = super(HasManyIdents, cls).replace(**kwds) + subcls = super(HasManyIdents, cls).using(**kwds) # add custom default ident # (NOTE: creates instance to run value through _norm_ident()) @@ -1184,7 +1184,7 @@ class HasSalt(GenericHandler): _salt_is_bytes = False _salt_unit = "chars" - # TODO: could support replace(min/max_desired_salt_size) via using() and needs_update() + # TODO: could support using(min/max_desired_salt_size) via using() and needs_update() #=================================================================== # instance attrs @@ -1195,7 +1195,7 @@ class HasSalt(GenericHandler): # variant constructor #=================================================================== @classmethod - def replace(cls, # keyword only... + def using(cls, # keyword only... default_salt_size=None, salt_size=None, # aliases used by CryptContext salt=None, @@ -1208,7 +1208,7 @@ class HasSalt(GenericHandler): default_salt_size = salt_size # generate new subclass - subcls = super(HasSalt, cls).replace(**kwds) + subcls = super(HasSalt, cls).using(**kwds) # replace default_rounds relaxed = kwds.get("relaxed") @@ -1446,7 +1446,7 @@ class HasRounds(GenericHandler): Class Methods ============= - .. todo:: document replace() and needs_update() options + .. todo:: document using() and needs_update() options Instance Attributes =================== @@ -1478,7 +1478,7 @@ class HasRounds(GenericHandler): "default_rounds", "vary_rounds") #----------------- - # desired & default rounds -- configurable via .replace() classmethod + # desired & default rounds -- configurable via .using() classmethod #----------------- min_desired_rounds = None max_desired_rounds = None @@ -1494,7 +1494,7 @@ class HasRounds(GenericHandler): # variant constructor #=================================================================== @classmethod - def replace(cls, # keyword only... + def using(cls, # keyword only... min_desired_rounds=None, max_desired_rounds=None, default_rounds=None, vary_rounds=None, min_rounds=None, max_rounds=None, rounds=None, # aliases used by CryptContext @@ -1523,7 +1523,7 @@ class HasRounds(GenericHandler): default_rounds = rounds # generate new subclass - subcls = super(HasRounds, cls).replace(**kwds) + subcls = super(HasRounds, cls).using(**kwds) # replace min_desired_rounds relaxed = kwds.get("relaxed") @@ -1635,7 +1635,7 @@ class HasRounds(GenericHandler): :returns: (lower, upper) limits suitable for random.randint() """ - # XXX: could precalculate output of this in replace() method, and save per-hash cost. + # XXX: could precalculate output of this in using() method, and save per-hash cost. # but then users patching cls.vary_rounds / cls.default_rounds would get wrong value. assert default_rounds vary_rounds = cls.vary_rounds @@ -2267,9 +2267,9 @@ class PrefixWrapper(object): wrapped = self.prefix + hash[len(orig_prefix):] return uascii_to_str(wrapped) - def replace(self, **kwds): + def using(self, **kwds): # generate subclass of wrapped handler - subcls = self.wrapped.replace(**kwds) + subcls = self.wrapped.using(**kwds) assert subcls is not self.wrapped # then create identical wrapper which wraps the new subclass. return PrefixWrapper(self.name, subcls, prefix=self.prefix, orig_prefix=self.orig_prefix) |