summaryrefslogtreecommitdiff
path: root/passlib/tests/test_context_deprecated.py
diff options
context:
space:
mode:
Diffstat (limited to 'passlib/tests/test_context_deprecated.py')
-rw-r--r--passlib/tests/test_context_deprecated.py743
1 files changed, 0 insertions, 743 deletions
diff --git a/passlib/tests/test_context_deprecated.py b/passlib/tests/test_context_deprecated.py
deleted file mode 100644
index 0f76624..0000000
--- a/passlib/tests/test_context_deprecated.py
+++ /dev/null
@@ -1,743 +0,0 @@
-"""tests for passlib.context
-
-this file is a clone of the 1.5 test_context.py,
-containing the tests using the legacy CryptPolicy api.
-it's being preserved here to ensure the old api doesn't break
-(until Passlib 1.8, when this and the legacy api will be removed).
-"""
-#=============================================================================
-# imports
-#=============================================================================
-from __future__ import with_statement
-# core
-from logging import getLogger
-import os
-import warnings
-# site
-try:
- from pkg_resources import resource_filename
-except ImportError:
- resource_filename = None
-# pkg
-from passlib import hash
-from passlib.context import CryptContext, CryptPolicy, LazyCryptContext
-from passlib.utils import to_bytes, to_unicode
-import passlib.utils.handlers as uh
-from passlib.tests.utils import TestCase, set_file
-from passlib.registry import (register_crypt_handler_path,
- _has_crypt_handler as has_crypt_handler,
- _unload_handler_name as unload_handler_name,
- )
-# module
-log = getLogger(__name__)
-
-#=============================================================================
-#
-#=============================================================================
-class CryptPolicyTest(TestCase):
- """test CryptPolicy object"""
-
- # TODO: need to test user categories w/in all this
-
- descriptionPrefix = "CryptPolicy"
-
- #===================================================================
- # sample crypt policies used for testing
- #===================================================================
-
- #---------------------------------------------------------------
- # sample 1 - average config file
- #---------------------------------------------------------------
- # NOTE: copy of this is stored in file passlib/tests/sample_config_1s.cfg
- sample_config_1s = """\
-[passlib]
-schemes = des_crypt, md5_crypt, bsdi_crypt, sha512_crypt
-default = md5_crypt
-all.vary_rounds = 10%%
-bsdi_crypt.max_rounds = 30000
-bsdi_crypt.default_rounds = 25000
-sha512_crypt.max_rounds = 50000
-sha512_crypt.min_rounds = 40000
-"""
- sample_config_1s_path = os.path.abspath(os.path.join(
- os.path.dirname(__file__), "sample_config_1s.cfg"))
- if not os.path.exists(sample_config_1s_path) and resource_filename:
- # in case we're zipped up in an egg.
- sample_config_1s_path = resource_filename("passlib.tests",
- "sample_config_1s.cfg")
-
- # make sure sample_config_1s uses \n linesep - tests rely on this
- assert sample_config_1s.startswith("[passlib]\nschemes")
-
- sample_config_1pd = dict(
- schemes = [ "des_crypt", "md5_crypt", "bsdi_crypt", "sha512_crypt"],
- default = "md5_crypt",
- # NOTE: not maintaining backwards compat for rendering to "10%"
- all__vary_rounds = 0.1,
- bsdi_crypt__max_rounds = 30000,
- bsdi_crypt__default_rounds = 25000,
- sha512_crypt__max_rounds = 50000,
- sha512_crypt__min_rounds = 40000,
- )
-
- sample_config_1pid = {
- "schemes": "des_crypt, md5_crypt, bsdi_crypt, sha512_crypt",
- "default": "md5_crypt",
- # NOTE: not maintaining backwards compat for rendering to "10%"
- "all.vary_rounds": 0.1,
- "bsdi_crypt.max_rounds": 30000,
- "bsdi_crypt.default_rounds": 25000,
- "sha512_crypt.max_rounds": 50000,
- "sha512_crypt.min_rounds": 40000,
- }
-
- sample_config_1prd = dict(
- schemes = [ hash.des_crypt, hash.md5_crypt, hash.bsdi_crypt, hash.sha512_crypt],
- default = "md5_crypt", # NOTE: passlib <= 1.5 was handler obj.
- # NOTE: not maintaining backwards compat for rendering to "10%"
- all__vary_rounds = 0.1,
- bsdi_crypt__max_rounds = 30000,
- bsdi_crypt__default_rounds = 25000,
- sha512_crypt__max_rounds = 50000,
- sha512_crypt__min_rounds = 40000,
- )
-
- #---------------------------------------------------------------
- # sample 2 - partial policy & result of overlay on sample 1
- #---------------------------------------------------------------
- sample_config_2s = """\
-[passlib]
-bsdi_crypt.min_rounds = 29000
-bsdi_crypt.max_rounds = 35000
-bsdi_crypt.default_rounds = 31000
-sha512_crypt.min_rounds = 45000
-"""
-
- sample_config_2pd = dict(
- # using this to test full replacement of existing options
- bsdi_crypt__min_rounds = 29000,
- bsdi_crypt__max_rounds = 35000,
- bsdi_crypt__default_rounds = 31000,
- # using this to test partial replacement of existing options
- sha512_crypt__min_rounds=45000,
- )
-
- sample_config_12pd = dict(
- schemes = [ "des_crypt", "md5_crypt", "bsdi_crypt", "sha512_crypt"],
- default = "md5_crypt",
- # NOTE: not maintaining backwards compat for rendering to "10%"
- all__vary_rounds = 0.1,
- bsdi_crypt__min_rounds = 29000,
- bsdi_crypt__max_rounds = 35000,
- bsdi_crypt__default_rounds = 31000,
- sha512_crypt__max_rounds = 50000,
- sha512_crypt__min_rounds=45000,
- )
-
- #---------------------------------------------------------------
- # sample 3 - just changing default
- #---------------------------------------------------------------
- sample_config_3pd = dict(
- default="sha512_crypt",
- )
-
- sample_config_123pd = dict(
- schemes = [ "des_crypt", "md5_crypt", "bsdi_crypt", "sha512_crypt"],
- default = "sha512_crypt",
- # NOTE: not maintaining backwards compat for rendering to "10%"
- all__vary_rounds = 0.1,
- bsdi_crypt__min_rounds = 29000,
- bsdi_crypt__max_rounds = 35000,
- bsdi_crypt__default_rounds = 31000,
- sha512_crypt__max_rounds = 50000,
- sha512_crypt__min_rounds=45000,
- )
-
- #---------------------------------------------------------------
- # sample 4 - category specific
- #---------------------------------------------------------------
- sample_config_4s = """
-[passlib]
-schemes = sha512_crypt
-all.vary_rounds = 10%%
-default.sha512_crypt.max_rounds = 20000
-admin.all.vary_rounds = 5%%
-admin.sha512_crypt.max_rounds = 40000
-"""
-
- sample_config_4pd = dict(
- schemes = [ "sha512_crypt" ],
- # NOTE: not maintaining backwards compat for rendering to "10%"
- all__vary_rounds = 0.1,
- sha512_crypt__max_rounds = 20000,
- # NOTE: not maintaining backwards compat for rendering to "5%"
- admin__all__vary_rounds = 0.05,
- admin__sha512_crypt__max_rounds = 40000,
- )
-
- #---------------------------------------------------------------
- # sample 5 - to_string & deprecation testing
- #---------------------------------------------------------------
- sample_config_5s = sample_config_1s + """\
-deprecated = des_crypt
-admin__context__deprecated = des_crypt, bsdi_crypt
-"""
-
- sample_config_5pd = sample_config_1pd.copy()
- sample_config_5pd.update(
- deprecated = [ "des_crypt" ],
- admin__context__deprecated = [ "des_crypt", "bsdi_crypt" ],
- )
-
- sample_config_5pid = sample_config_1pid.copy()
- sample_config_5pid.update({
- "deprecated": "des_crypt",
- "admin.context.deprecated": "des_crypt, bsdi_crypt",
- })
-
- sample_config_5prd = sample_config_1prd.copy()
- sample_config_5prd.update({
- # XXX: should deprecated return the actual handlers in this case?
- # would have to modify how policy stores info, for one.
- "deprecated": ["des_crypt"],
- "admin__context__deprecated": ["des_crypt", "bsdi_crypt"],
- })
-
- #===================================================================
- # constructors
- #===================================================================
- def setUp(self):
- TestCase.setUp(self)
- warnings.filterwarnings("ignore",
- r"The CryptPolicy class has been deprecated")
- warnings.filterwarnings("ignore",
- r"the method.*hash_needs_update.*is deprecated")
- warnings.filterwarnings("ignore", "The 'all' scheme is deprecated.*")
- warnings.filterwarnings("ignore", "bsdi_crypt rounds should be odd")
-
- def test_00_constructor(self):
- """test CryptPolicy() constructor"""
- policy = CryptPolicy(**self.sample_config_1pd)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- policy = CryptPolicy(self.sample_config_1pd)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- self.assertRaises(TypeError, CryptPolicy, {}, {})
- self.assertRaises(TypeError, CryptPolicy, {}, dummy=1)
-
- # check key with too many separators is rejected
- self.assertRaises(TypeError, CryptPolicy,
- schemes = [ "des_crypt", "md5_crypt", "bsdi_crypt", "sha512_crypt"],
- bad__key__bsdi_crypt__max_rounds = 30000,
- )
-
- # check nameless handler rejected
- class nameless(uh.StaticHandler):
- name = None
- self.assertRaises(ValueError, CryptPolicy, schemes=[nameless])
-
- # check scheme must be name or crypt handler
- self.assertRaises(TypeError, CryptPolicy, schemes=[uh.StaticHandler])
-
- # check name conflicts are rejected
- class dummy_1(uh.StaticHandler):
- name = 'dummy_1'
- self.assertRaises(KeyError, CryptPolicy, schemes=[dummy_1, dummy_1])
-
- # with unknown deprecated value
- self.assertRaises(KeyError, CryptPolicy,
- schemes=['des_crypt'],
- deprecated=['md5_crypt'])
-
- # with unknown default value
- self.assertRaises(KeyError, CryptPolicy,
- schemes=['des_crypt'],
- default='md5_crypt')
-
- def test_01_from_path_simple(self):
- """test CryptPolicy.from_path() constructor"""
- # NOTE: this is separate so it can also run under GAE
-
- # test preset stored in existing file
- path = self.sample_config_1s_path
- policy = CryptPolicy.from_path(path)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # test if path missing
- self.assertRaises(EnvironmentError, CryptPolicy.from_path, path + 'xxx')
-
- def test_01_from_path(self):
- """test CryptPolicy.from_path() constructor with encodings"""
- path = self.mktemp()
-
- # test "\n" linesep
- set_file(path, self.sample_config_1s)
- policy = CryptPolicy.from_path(path)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # test "\r\n" linesep
- set_file(path, self.sample_config_1s.replace("\n","\r\n"))
- policy = CryptPolicy.from_path(path)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # test with custom encoding
- uc2 = to_bytes(self.sample_config_1s, "utf-16", source_encoding="utf-8")
- set_file(path, uc2)
- policy = CryptPolicy.from_path(path, encoding="utf-16")
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- def test_02_from_string(self):
- """test CryptPolicy.from_string() constructor"""
- # test "\n" linesep
- policy = CryptPolicy.from_string(self.sample_config_1s)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # test "\r\n" linesep
- policy = CryptPolicy.from_string(
- self.sample_config_1s.replace("\n","\r\n"))
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # test with unicode
- data = to_unicode(self.sample_config_1s)
- policy = CryptPolicy.from_string(data)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # test with non-ascii-compatible encoding
- uc2 = to_bytes(self.sample_config_1s, "utf-16", source_encoding="utf-8")
- policy = CryptPolicy.from_string(uc2, encoding="utf-16")
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # test category specific options
- policy = CryptPolicy.from_string(self.sample_config_4s)
- self.assertEqual(policy.to_dict(), self.sample_config_4pd)
-
- def test_03_from_source(self):
- """test CryptPolicy.from_source() constructor"""
- # pass it a path
- policy = CryptPolicy.from_source(self.sample_config_1s_path)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # pass it a string
- policy = CryptPolicy.from_source(self.sample_config_1s)
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # pass it a dict (NOTE: make a copy to detect in-place modifications)
- policy = CryptPolicy.from_source(self.sample_config_1pd.copy())
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # pass it existing policy
- p2 = CryptPolicy.from_source(policy)
- self.assertIs(policy, p2)
-
- # pass it something wrong
- self.assertRaises(TypeError, CryptPolicy.from_source, 1)
- self.assertRaises(TypeError, CryptPolicy.from_source, [])
-
- def test_04_from_sources(self):
- """test CryptPolicy.from_sources() constructor"""
-
- # pass it empty list
- self.assertRaises(ValueError, CryptPolicy.from_sources, [])
-
- # pass it one-element list
- policy = CryptPolicy.from_sources([self.sample_config_1s])
- self.assertEqual(policy.to_dict(), self.sample_config_1pd)
-
- # pass multiple sources
- policy = CryptPolicy.from_sources(
- [
- self.sample_config_1s_path,
- self.sample_config_2s,
- self.sample_config_3pd,
- ])
- self.assertEqual(policy.to_dict(), self.sample_config_123pd)
-
- def test_05_replace(self):
- """test CryptPolicy.replace() constructor"""
-
- p1 = CryptPolicy(**self.sample_config_1pd)
-
- # check overlaying sample 2
- p2 = p1.replace(**self.sample_config_2pd)
- self.assertEqual(p2.to_dict(), self.sample_config_12pd)
-
- # check repeating overlay makes no change
- p2b = p2.replace(**self.sample_config_2pd)
- self.assertEqual(p2b.to_dict(), self.sample_config_12pd)
-
- # check overlaying sample 3
- p3 = p2.replace(self.sample_config_3pd)
- self.assertEqual(p3.to_dict(), self.sample_config_123pd)
-
- def test_06_forbidden(self):
- """test CryptPolicy() forbidden kwds"""
-
- # salt not allowed to be set
- self.assertRaises(KeyError, CryptPolicy,
- schemes=["des_crypt"],
- des_crypt__salt="xx",
- )
- self.assertRaises(KeyError, CryptPolicy,
- schemes=["des_crypt"],
- all__salt="xx",
- )
-
- # schemes not allowed for category
- self.assertRaises(KeyError, CryptPolicy,
- schemes=["des_crypt"],
- user__context__schemes=["md5_crypt"],
- )
-
- #===================================================================
- # reading
- #===================================================================
- def test_10_has_schemes(self):
- """test has_schemes() method"""
-
- p1 = CryptPolicy(**self.sample_config_1pd)
- self.assertTrue(p1.has_schemes())
-
- p3 = CryptPolicy(**self.sample_config_3pd)
- self.assertTrue(not p3.has_schemes())
-
- def test_11_iter_handlers(self):
- """test iter_handlers() method"""
-
- p1 = CryptPolicy(**self.sample_config_1pd)
- s = self.sample_config_1prd['schemes']
- self.assertEqual(list(p1.iter_handlers()), s)
-
- p3 = CryptPolicy(**self.sample_config_3pd)
- self.assertEqual(list(p3.iter_handlers()), [])
-
- def test_12_get_handler(self):
- """test get_handler() method"""
-
- p1 = CryptPolicy(**self.sample_config_1pd)
-
- # check by name
- self.assertIs(p1.get_handler("bsdi_crypt"), hash.bsdi_crypt)
-
- # check by missing name
- self.assertIs(p1.get_handler("sha256_crypt"), None)
- self.assertRaises(KeyError, p1.get_handler, "sha256_crypt", required=True)
-
- # check default
- self.assertIs(p1.get_handler(), hash.md5_crypt)
-
- def test_13_get_options(self):
- """test get_options() method"""
-
- p12 = CryptPolicy(**self.sample_config_12pd)
-
- self.assertEqual(p12.get_options("bsdi_crypt"),dict(
- # NOTE: not maintaining backwards compat for rendering to "10%"
- vary_rounds = 0.1,
- min_rounds = 29000,
- max_rounds = 35000,
- default_rounds = 31000,
- ))
-
- self.assertEqual(p12.get_options("sha512_crypt"),dict(
- # NOTE: not maintaining backwards compat for rendering to "10%"
- vary_rounds = 0.1,
- min_rounds = 45000,
- max_rounds = 50000,
- ))
-
- p4 = CryptPolicy.from_string(self.sample_config_4s)
- self.assertEqual(p4.get_options("sha512_crypt"), dict(
- # NOTE: not maintaining backwards compat for rendering to "10%"
- vary_rounds=0.1,
- max_rounds=20000,
- ))
-
- self.assertEqual(p4.get_options("sha512_crypt", "user"), dict(
- # NOTE: not maintaining backwards compat for rendering to "10%"
- vary_rounds=0.1,
- max_rounds=20000,
- ))
-
- self.assertEqual(p4.get_options("sha512_crypt", "admin"), dict(
- # NOTE: not maintaining backwards compat for rendering to "5%"
- vary_rounds=0.05,
- max_rounds=40000,
- ))
-
- def test_14_handler_is_deprecated(self):
- """test handler_is_deprecated() method"""
- pa = CryptPolicy(**self.sample_config_1pd)
- pb = CryptPolicy(**self.sample_config_5pd)
-
- self.assertFalse(pa.handler_is_deprecated("des_crypt"))
- self.assertFalse(pa.handler_is_deprecated(hash.bsdi_crypt))
- self.assertFalse(pa.handler_is_deprecated("sha512_crypt"))
-
- self.assertTrue(pb.handler_is_deprecated("des_crypt"))
- self.assertFalse(pb.handler_is_deprecated(hash.bsdi_crypt))
- self.assertFalse(pb.handler_is_deprecated("sha512_crypt"))
-
- # check categories as well
- self.assertTrue(pb.handler_is_deprecated("des_crypt", "user"))
- self.assertFalse(pb.handler_is_deprecated("bsdi_crypt", "user"))
- self.assertTrue(pb.handler_is_deprecated("des_crypt", "admin"))
- self.assertTrue(pb.handler_is_deprecated("bsdi_crypt", "admin"))
-
- # check deprecation is overridden per category
- pc = CryptPolicy(
- schemes=["md5_crypt", "des_crypt"],
- deprecated=["md5_crypt"],
- user__context__deprecated=["des_crypt"],
- )
- self.assertTrue(pc.handler_is_deprecated("md5_crypt"))
- self.assertFalse(pc.handler_is_deprecated("des_crypt"))
- self.assertFalse(pc.handler_is_deprecated("md5_crypt", "user"))
- self.assertTrue(pc.handler_is_deprecated("des_crypt", "user"))
-
- def test_15_min_verify_time(self):
- """test get_min_verify_time() method"""
- # silence deprecation warnings for min verify time
- warnings.filterwarnings("ignore", category=DeprecationWarning)
-
- pa = CryptPolicy()
- self.assertEqual(pa.get_min_verify_time(), 0)
- self.assertEqual(pa.get_min_verify_time('admin'), 0)
-
- pb = pa.replace(min_verify_time=.1)
- self.assertEqual(pb.get_min_verify_time(), 0)
- self.assertEqual(pb.get_min_verify_time('admin'), 0)
-
- #===================================================================
- # serialization
- #===================================================================
- def test_20_iter_config(self):
- """test iter_config() method"""
- p5 = CryptPolicy(**self.sample_config_5pd)
- self.assertEqual(dict(p5.iter_config()), self.sample_config_5pd)
- self.assertEqual(dict(p5.iter_config(resolve=True)), self.sample_config_5prd)
- self.assertEqual(dict(p5.iter_config(ini=True)), self.sample_config_5pid)
-
- def test_21_to_dict(self):
- """test to_dict() method"""
- p5 = CryptPolicy(**self.sample_config_5pd)
- self.assertEqual(p5.to_dict(), self.sample_config_5pd)
- self.assertEqual(p5.to_dict(resolve=True), self.sample_config_5prd)
-
- def test_22_to_string(self):
- """test to_string() method"""
- pa = CryptPolicy(**self.sample_config_5pd)
- s = pa.to_string() # NOTE: can't compare string directly, ordering etc may not match
- pb = CryptPolicy.from_string(s)
- self.assertEqual(pb.to_dict(), self.sample_config_5pd)
-
- s = pa.to_string(encoding="latin-1")
- self.assertIsInstance(s, bytes)
-
- #===================================================================
- #
- #===================================================================
-
-#=============================================================================
-# CryptContext
-#=============================================================================
-class CryptContextTest(TestCase):
- """test CryptContext class"""
- descriptionPrefix = "CryptContext"
-
- def setUp(self):
- TestCase.setUp(self)
- warnings.filterwarnings("ignore",
- r"CryptContext\(\)\.replace\(\) has been deprecated.*")
- warnings.filterwarnings("ignore",
- r"The CryptContext ``policy`` keyword has been deprecated.*")
- warnings.filterwarnings("ignore", ".*(CryptPolicy|context\.policy).*(has|have) been deprecated.*")
- warnings.filterwarnings("ignore",
- r"the method.*hash_needs_update.*is deprecated")
-
- #===================================================================
- # constructor
- #===================================================================
- def test_00_constructor(self):
- """test constructor"""
- # create crypt context using handlers
- cc = CryptContext([hash.md5_crypt, hash.bsdi_crypt, hash.des_crypt])
- c,b,a = cc.policy.iter_handlers()
- self.assertIs(a, hash.des_crypt)
- self.assertIs(b, hash.bsdi_crypt)
- self.assertIs(c, hash.md5_crypt)
-
- # create context using names
- cc = CryptContext(["md5_crypt", "bsdi_crypt", "des_crypt"])
- c,b,a = cc.policy.iter_handlers()
- self.assertIs(a, hash.des_crypt)
- self.assertIs(b, hash.bsdi_crypt)
- self.assertIs(c, hash.md5_crypt)
-
- # policy kwd
- policy = cc.policy
- cc = CryptContext(policy=policy)
- self.assertEqual(cc.to_dict(), policy.to_dict())
-
- cc = CryptContext(policy=policy, default="bsdi_crypt")
- self.assertNotEqual(cc.to_dict(), policy.to_dict())
- self.assertEqual(cc.to_dict(), dict(schemes=["md5_crypt","bsdi_crypt","des_crypt"],
- default="bsdi_crypt"))
-
- self.assertRaises(TypeError, setattr, cc, 'policy', None)
- self.assertRaises(TypeError, CryptContext, policy='x')
-
- def test_01_replace(self):
- """test replace()"""
-
- cc = CryptContext(["md5_crypt", "bsdi_crypt", "des_crypt"])
- self.assertIs(cc.policy.get_handler(), hash.md5_crypt)
-
- cc2 = cc.replace()
- self.assertIsNot(cc2, cc)
- # NOTE: was not able to maintain backward compatibility with this...
- ##self.assertIs(cc2.policy, cc.policy)
-
- cc3 = cc.replace(default="bsdi_crypt")
- self.assertIsNot(cc3, cc)
- # NOTE: was not able to maintain backward compatibility with this...
- ##self.assertIs(cc3.policy, cc.policy)
- self.assertIs(cc3.policy.get_handler(), hash.bsdi_crypt)
-
- def test_02_no_handlers(self):
- """test no handlers"""
-
- # check constructor...
- cc = CryptContext()
- self.assertRaises(KeyError, cc.identify, 'hash', required=True)
- self.assertRaises(KeyError, cc.hash, 'secret')
- self.assertRaises(KeyError, cc.verify, 'secret', 'hash')
-
- # check updating policy after the fact...
- cc = CryptContext(['md5_crypt'])
- p = CryptPolicy(schemes=[])
- cc.policy = p
-
- self.assertRaises(KeyError, cc.identify, 'hash', required=True)
- self.assertRaises(KeyError, cc.hash, 'secret')
- self.assertRaises(KeyError, cc.verify, 'secret', 'hash')
-
- #===================================================================
- # policy adaptation
- #===================================================================
- sample_policy_1 = dict(
- schemes = [ "des_crypt", "md5_crypt", "phpass", "bsdi_crypt",
- "sha256_crypt"],
- deprecated = [ "des_crypt", ],
- default = "sha256_crypt",
- bsdi_crypt__max_rounds = 30,
- bsdi_crypt__default_rounds = 25,
- bsdi_crypt__vary_rounds = 0,
- sha256_crypt__max_rounds = 3000,
- sha256_crypt__min_rounds = 2000,
- sha256_crypt__default_rounds = 3000,
- phpass__ident = "H",
- phpass__default_rounds = 7,
- )
-
- def test_12_hash_needs_update(self):
- """test hash_needs_update() method"""
- cc = CryptContext(**self.sample_policy_1)
-
- # check deprecated scheme
- self.assertTrue(cc.hash_needs_update('9XXD4trGYeGJA'))
- self.assertFalse(cc.hash_needs_update('$1$J8HC2RCr$HcmM.7NxB2weSvlw2FgzU0'))
-
- # check min rounds
- self.assertTrue(cc.hash_needs_update('$5$rounds=1999$jD81UCoo.zI.UETs$Y7qSTQ6mTiU9qZB4fRr43wRgQq4V.5AAf7F97Pzxey/'))
- self.assertFalse(cc.hash_needs_update('$5$rounds=2000$228SSRje04cnNCaQ$YGV4RYu.5sNiBvorQDlO0WWQjyJVGKBcJXz3OtyQ2u8'))
-
- # check max rounds
- self.assertFalse(cc.hash_needs_update('$5$rounds=3000$fS9iazEwTKi7QPW4$VasgBC8FqlOvD7x2HhABaMXCTh9jwHclPA9j5YQdns.'))
- self.assertTrue(cc.hash_needs_update('$5$rounds=3001$QlFHHifXvpFX4PLs$/0ekt7lSs/lOikSerQ0M/1porEHxYq7W/2hdFpxA3fA'))
-
- #===================================================================
- # border cases
- #===================================================================
- def test_30_nonstring_hash(self):
- """test non-string hash values cause error"""
- warnings.filterwarnings("ignore", ".*needs_update.*'scheme' keyword is deprecated.*")
-
- #
- # test hash=None or some other non-string causes TypeError
- # and that explicit-scheme code path behaves the same.
- #
- cc = CryptContext(["des_crypt"])
- for hash, kwds in [
- (None, {}),
- # NOTE: 'scheme' kwd is deprecated...
- (None, {"scheme": "des_crypt"}),
- (1, {}),
- ((), {}),
- ]:
-
- self.assertRaises(TypeError, cc.hash_needs_update, hash, **kwds)
-
- cc2 = CryptContext(["mysql323"])
- self.assertRaises(TypeError, cc2.hash_needs_update, None)
-
- #===================================================================
- # eoc
- #===================================================================
-
-#=============================================================================
-# LazyCryptContext
-#=============================================================================
-class dummy_2(uh.StaticHandler):
- name = "dummy_2"
-
-class LazyCryptContextTest(TestCase):
- descriptionPrefix = "LazyCryptContext"
-
- def setUp(self):
- TestCase.setUp(self)
-
- # make sure this isn't registered before OR after
- unload_handler_name("dummy_2")
- self.addCleanup(unload_handler_name, "dummy_2")
-
- # silence some warnings
- warnings.filterwarnings("ignore",
- r"CryptContext\(\)\.replace\(\) has been deprecated")
- warnings.filterwarnings("ignore", ".*(CryptPolicy|context\.policy).*(has|have) been deprecated.*")
-
- def test_kwd_constructor(self):
- """test plain kwds"""
- self.assertFalse(has_crypt_handler("dummy_2"))
- register_crypt_handler_path("dummy_2", "passlib.tests.test_context")
-
- cc = LazyCryptContext(iter(["dummy_2", "des_crypt"]), deprecated=["des_crypt"])
-
- self.assertFalse(has_crypt_handler("dummy_2", True))
-
- self.assertTrue(cc.policy.handler_is_deprecated("des_crypt"))
- self.assertEqual(cc.policy.schemes(), ["dummy_2", "des_crypt"])
-
- self.assertTrue(has_crypt_handler("dummy_2", True))
-
- def test_callable_constructor(self):
- """test create_policy() hook, returning CryptPolicy"""
- self.assertFalse(has_crypt_handler("dummy_2"))
- register_crypt_handler_path("dummy_2", "passlib.tests.test_context")
-
- def create_policy(flag=False):
- self.assertTrue(flag)
- return CryptPolicy(schemes=iter(["dummy_2", "des_crypt"]), deprecated=["des_crypt"])
-
- cc = LazyCryptContext(create_policy=create_policy, flag=True)
-
- self.assertFalse(has_crypt_handler("dummy_2", True))
-
- self.assertTrue(cc.policy.handler_is_deprecated("des_crypt"))
- self.assertEqual(cc.policy.schemes(), ["dummy_2", "des_crypt"])
-
- self.assertTrue(has_crypt_handler("dummy_2", True))
-
-#=============================================================================
-# eof
-#=============================================================================