def _iter_patch_candidates(cls):
"""helper to scan for monkeypatches.
returns tuple containing:
* object (module or class)
* attribute of object
* value of attribute
* whether it should or should not be patched
"""
# XXX: this and assert_unpatched() could probably be refactored to use
# the PatchManager class to do the heavy lifting.
from django.contrib.auth import models, hashers
user_attrs = ["check_password", "set_password"]
model_attrs = ["check_password", "make_password"]
hasher_attrs = ["check_password", "make_password", "get_hasher", "identify_hasher",
"get_hashers"]
objs = [(models, model_attrs),
(models.User, user_attrs),
(hashers, hasher_attrs),
]
for obj, patched in objs:
for attr in dir(obj):
if attr.startswith("_"):
continue
value = obj.__dict__.get(attr, UNSET) # can't use getattr() due to GAE
if value is UNSET and attr not in patched:
continue
value = get_method_function(value)
source = getattr(value, "__module__", None)
if source:
yield obj, attr, source, (attr in patched)
#===================================================================
# verify current patch state
#===================================================================
python类set_password()的实例源码
def test_01_overwrite_detection(self):
"""test detection of foreign monkeypatching"""
# NOTE: this sets things up, and spot checks two methods,
# this should be enough to verify patch manager is working.
# TODO: test unpatch behavior honors flag.
# configure plugin to use sample context
config = "[passlib]\nschemes=des_crypt\n"
self.load_extension(PASSLIB_CONFIG=config)
# setup helpers
import django.contrib.auth.models as models
from passlib.ext.django.models import adapter
def dummy():
pass
# mess with User.set_password, make sure it's detected
orig = models.User.set_password
models.User.set_password = dummy
with self.assertWarningList("another library has patched.*User\.set_password"):
adapter._manager.check_all()
models.User.set_password = orig
# mess with models.check_password, make sure it's detected
orig = models.check_password
models.check_password = dummy
with self.assertWarningList("another library has patched.*models:check_password"):
adapter._manager.check_all()
models.check_password = orig
def _iter_patch_candidates(cls):
"""helper to scan for monkeypatches.
returns tuple containing:
* object (module or class)
* attribute of object
* value of attribute
* whether it should or should not be patched
"""
# XXX: this and assert_unpatched() could probably be refactored to use
# the PatchManager class to do the heavy lifting.
from django.contrib.auth import models
user_attrs = ["check_password", "set_password"]
model_attrs = ["check_password"]
objs = [(models, model_attrs), (models.User, user_attrs)]
if has_django14:
from django.contrib.auth import hashers
model_attrs.append("make_password")
objs.append((hashers, ["check_password", "make_password",
"get_hasher", "identify_hasher"]))
if has_django0:
user_attrs.extend(["has_usable_password", "set_unusable_password"])
for obj, patched in objs:
for attr in dir(obj):
if attr.startswith("_"):
continue
value = obj.__dict__.get(attr, UNSET) # can't use getattr() due to GAE
if value is UNSET and attr not in patched:
continue
value = get_method_function(value)
source = getattr(value, "__module__", None)
if source:
yield obj, attr, source, (attr in patched)
#===================================================================
# verify current patch state
#===================================================================
def test_01_overwrite_detection(self):
"test detection of foreign monkeypatching"
# NOTE: this sets things up, and spot checks two methods,
# this should be enough to verify patch manager is working.
# TODO: test unpatch behavior honors flag.
# configure plugin to use sample context
config = "[passlib]\nschemes=des_crypt\n"
self.load_extension(PASSLIB_CONFIG=config)
# setup helpers
import django.contrib.auth.models as models
from passlib.ext.django.models import _manager
def dummy():
pass
# mess with User.set_password, make sure it's detected
orig = models.User.set_password
models.User.set_password = dummy
with self.assertWarningList("another library has patched.*User\.set_password"):
_manager.check_all()
models.User.set_password = orig
# mess with models.check_password, make sure it's detected
orig = models.check_password
models.check_password = dummy
with self.assertWarningList("another library has patched.*models:check_password"):
_manager.check_all()
models.check_password = orig
def _iter_patch_candidates(cls):
"""helper to scan for monkeypatches.
returns tuple containing:
* object (module or class)
* attribute of object
* value of attribute
* whether it should or should not be patched
"""
# XXX: this and assert_unpatched() could probably be refactored to use
# the PatchManager class to do the heavy lifting.
from django.contrib.auth import models
user_attrs = ["check_password", "set_password"]
model_attrs = ["check_password"]
objs = [(models, model_attrs), (models.User, user_attrs)]
if has_django14:
from django.contrib.auth import hashers
model_attrs.append("make_password")
objs.append((hashers, ["check_password", "make_password",
"get_hasher", "identify_hasher"]))
if has_django0:
user_attrs.extend(["has_usable_password", "set_unusable_password"])
for obj, patched in objs:
for attr in dir(obj):
if attr.startswith("_"):
continue
value = obj.__dict__.get(attr, UNSET) # can't use getattr() due to GAE
if value is UNSET and attr not in patched:
continue
value = get_method_function(value)
source = getattr(value, "__module__", None)
if source:
yield obj, attr, source, (attr in patched)
#===================================================================
# verify current patch state
#===================================================================
def test_01_overwrite_detection(self):
"""test detection of foreign monkeypatching"""
# NOTE: this sets things up, and spot checks two methods,
# this should be enough to verify patch manager is working.
# TODO: test unpatch behavior honors flag.
# configure plugin to use sample context
config = "[passlib]\nschemes=des_crypt\n"
self.load_extension(PASSLIB_CONFIG=config)
# setup helpers
import django.contrib.auth.models as models
from passlib.ext.django.models import _manager
def dummy():
pass
# mess with User.set_password, make sure it's detected
orig = models.User.set_password
models.User.set_password = dummy
with self.assertWarningList("another library has patched.*User\.set_password"):
_manager.check_all()
models.User.set_password = orig
# mess with models.check_password, make sure it's detected
orig = models.check_password
models.check_password = dummy
with self.assertWarningList("another library has patched.*models:check_password"):
_manager.check_all()
models.check_password = orig
def _iter_patch_candidates(cls):
"""helper to scan for monkeypatches.
returns tuple containing:
* object (module or class)
* attribute of object
* value of attribute
* whether it should or should not be patched
"""
# XXX: this and assert_unpatched() could probably be refactored to use
# the PatchManager class to do the heavy lifting.
from django.contrib.auth import models, hashers
user_attrs = ["check_password", "set_password"]
model_attrs = ["check_password", "make_password"]
hasher_attrs = ["check_password", "make_password", "get_hasher", "identify_hasher",
"get_hashers"]
objs = [(models, model_attrs),
(models.User, user_attrs),
(hashers, hasher_attrs),
]
for obj, patched in objs:
for attr in dir(obj):
if attr.startswith("_"):
continue
value = obj.__dict__.get(attr, UNSET) # can't use getattr() due to GAE
if value is UNSET and attr not in patched:
continue
value = get_method_function(value)
source = getattr(value, "__module__", None)
if source:
yield obj, attr, source, (attr in patched)
#===================================================================
# verify current patch state
#===================================================================
def test_01_overwrite_detection(self):
"""test detection of foreign monkeypatching"""
# NOTE: this sets things up, and spot checks two methods,
# this should be enough to verify patch manager is working.
# TODO: test unpatch behavior honors flag.
# configure plugin to use sample context
config = "[passlib]\nschemes=des_crypt\n"
self.load_extension(PASSLIB_CONFIG=config)
# setup helpers
import django.contrib.auth.models as models
from passlib.ext.django.models import adapter
def dummy():
pass
# mess with User.set_password, make sure it's detected
orig = models.User.set_password
models.User.set_password = dummy
with self.assertWarningList("another library has patched.*User\.set_password"):
adapter._manager.check_all()
models.User.set_password = orig
# mess with models.check_password, make sure it's detected
orig = models.check_password
models.check_password = dummy
with self.assertWarningList("another library has patched.*models:check_password"):
adapter._manager.check_all()
models.check_password = orig
def _iter_patch_candidates(cls):
"""helper to scan for monkeypatches.
returns tuple containing:
* object (module or class)
* attribute of object
* value of attribute
* whether it should or should not be patched
"""
# XXX: this and assert_unpatched() could probably be refactored to use
# the PatchManager class to do the heavy lifting.
from django.contrib.auth import models
user_attrs = ["check_password", "set_password"]
model_attrs = ["check_password"]
objs = [(models, model_attrs), (models.User, user_attrs)]
if has_django14:
from django.contrib.auth import hashers
model_attrs.append("make_password")
objs.append((hashers, ["check_password", "make_password",
"get_hasher", "identify_hasher"]))
if has_django0:
user_attrs.extend(["has_usable_password", "set_unusable_password"])
for obj, patched in objs:
for attr in dir(obj):
if attr.startswith("_"):
continue
value = obj.__dict__.get(attr, UNSET) # can't use getattr() due to GAE
if value is UNSET and attr not in patched:
continue
value = get_method_function(value)
source = getattr(value, "__module__", None)
if source:
yield obj, attr, source, (attr in patched)
#===================================================================
# verify current patch state
#===================================================================
def test_01_overwrite_detection(self):
"test detection of foreign monkeypatching"
# NOTE: this sets things up, and spot checks two methods,
# this should be enough to verify patch manager is working.
# TODO: test unpatch behavior honors flag.
# configure plugin to use sample context
config = "[passlib]\nschemes=des_crypt\n"
self.load_extension(PASSLIB_CONFIG=config)
# setup helpers
import django.contrib.auth.models as models
from passlib.ext.django.models import _manager
def dummy():
pass
# mess with User.set_password, make sure it's detected
orig = models.User.set_password
models.User.set_password = dummy
with self.assertWarningList("another library has patched.*User\.set_password"):
_manager.check_all()
models.User.set_password = orig
# mess with models.check_password, make sure it's detected
orig = models.check_password
models.check_password = dummy
with self.assertWarningList("another library has patched.*models:check_password"):
_manager.check_all()
models.check_password = orig
def _iter_patch_candidates(cls):
"""helper to scan for monkeypatches.
returns tuple containing:
* object (module or class)
* attribute of object
* value of attribute
* whether it should or should not be patched
"""
# XXX: this and assert_unpatched() could probably be refactored to use
# the PatchManager class to do the heavy lifting.
from django.contrib.auth import models
user_attrs = ["check_password", "set_password"]
model_attrs = ["check_password"]
objs = [(models, model_attrs), (models.User, user_attrs)]
if has_django14:
from django.contrib.auth import hashers
model_attrs.append("make_password")
objs.append((hashers, ["check_password", "make_password",
"get_hasher", "identify_hasher"]))
if has_django0:
user_attrs.extend(["has_usable_password", "set_unusable_password"])
for obj, patched in objs:
for attr in dir(obj):
if attr.startswith("_"):
continue
value = obj.__dict__.get(attr, UNSET) # can't use getattr() due to GAE
if value is UNSET and attr not in patched:
continue
value = get_method_function(value)
source = getattr(value, "__module__", None)
if source:
yield obj, attr, source, (attr in patched)
#===================================================================
# verify current patch state
#===================================================================
def test_01_overwrite_detection(self):
"""test detection of foreign monkeypatching"""
# NOTE: this sets things up, and spot checks two methods,
# this should be enough to verify patch manager is working.
# TODO: test unpatch behavior honors flag.
# configure plugin to use sample context
config = "[passlib]\nschemes=des_crypt\n"
self.load_extension(PASSLIB_CONFIG=config)
# setup helpers
import django.contrib.auth.models as models
from passlib.ext.django.models import _manager
def dummy():
pass
# mess with User.set_password, make sure it's detected
orig = models.User.set_password
models.User.set_password = dummy
with self.assertWarningList("another library has patched.*User\.set_password"):
_manager.check_all()
models.User.set_password = orig
# mess with models.check_password, make sure it's detected
orig = models.check_password
models.check_password = dummy
with self.assertWarningList("another library has patched.*models:check_password"):
_manager.check_all()
models.check_password = orig
def test_21_category_setting(self):
"""test PASSLIB_GET_CATEGORY parameter"""
# define config where rounds can be used to detect category
config = dict(
schemes = ["sha256_crypt"],
sha256_crypt__default_rounds = 1000,
staff__sha256_crypt__default_rounds = 2000,
superuser__sha256_crypt__default_rounds = 3000,
)
from passlib.hash import sha256_crypt
def run(**kwds):
"""helper to take in user opts, return rounds used in password"""
user = FakeUser(**kwds)
user.set_password("stub")
return sha256_crypt.from_string(user.password).rounds
# test default get_category
self.load_extension(PASSLIB_CONFIG=config)
self.assertEqual(run(), 1000)
self.assertEqual(run(is_staff=True), 2000)
self.assertEqual(run(is_superuser=True), 3000)
# test patch uses explicit get_category function
def get_category(user):
return user.first_name or None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff'), 2000)
self.assertEqual(run(first_name='superuser'), 3000)
# test patch can disable get_category entirely
def get_category(user):
return None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff', is_staff=True), 1000)
self.assertEqual(run(first_name='superuser', is_superuser=True), 1000)
# test bad value
self.assertRaises(TypeError, self.load_extension, PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY='x')
#===================================================================
# eoc
#===================================================================
#=============================================================================
# eof
#=============================================================================
def test_21_category_setting(self):
"test PASSLIB_GET_CATEGORY parameter"
# define config where rounds can be used to detect category
config = dict(
schemes = ["sha256_crypt"],
sha256_crypt__default_rounds = 1000,
staff__sha256_crypt__default_rounds = 2000,
superuser__sha256_crypt__default_rounds = 3000,
)
from passlib.hash import sha256_crypt
def run(**kwds):
"helper to take in user opts, return rounds used in password"
user = FakeUser(**kwds)
user.set_password("stub")
return sha256_crypt.from_string(user.password).rounds
# test default get_category
self.load_extension(PASSLIB_CONFIG=config)
self.assertEqual(run(), 1000)
self.assertEqual(run(is_staff=True), 2000)
self.assertEqual(run(is_superuser=True), 3000)
# test patch uses explicit get_category function
def get_category(user):
return user.first_name or None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff'), 2000)
self.assertEqual(run(first_name='superuser'), 3000)
# test patch can disable get_category entirely
def get_category(user):
return None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff', is_staff=True), 1000)
self.assertEqual(run(first_name='superuser', is_superuser=True), 1000)
# test bad value
self.assertRaises(TypeError, self.load_extension, PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY='x')
#===================================================================
# eoc
#===================================================================
def test_21_category_setting(self):
"""test PASSLIB_GET_CATEGORY parameter"""
# define config where rounds can be used to detect category
config = dict(
schemes = ["sha256_crypt"],
sha256_crypt__default_rounds = 1000,
staff__sha256_crypt__default_rounds = 2000,
superuser__sha256_crypt__default_rounds = 3000,
)
from passlib.hash import sha256_crypt
def run(**kwds):
"""helper to take in user opts, return rounds used in password"""
user = FakeUser(**kwds)
user.set_password("stub")
return sha256_crypt.from_string(user.password).rounds
# test default get_category
self.load_extension(PASSLIB_CONFIG=config)
self.assertEqual(run(), 1000)
self.assertEqual(run(is_staff=True), 2000)
self.assertEqual(run(is_superuser=True), 3000)
# test patch uses explicit get_category function
def get_category(user):
return user.first_name or None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff'), 2000)
self.assertEqual(run(first_name='superuser'), 3000)
# test patch can disable get_category entirely
def get_category(user):
return None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff', is_staff=True), 1000)
self.assertEqual(run(first_name='superuser', is_superuser=True), 1000)
# test bad value
self.assertRaises(TypeError, self.load_extension, PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY='x')
#===================================================================
# eoc
#===================================================================
def test_21_category_setting(self):
"""test PASSLIB_GET_CATEGORY parameter"""
# define config where rounds can be used to detect category
config = dict(
schemes = ["sha256_crypt"],
sha256_crypt__default_rounds = 1000,
staff__sha256_crypt__default_rounds = 2000,
superuser__sha256_crypt__default_rounds = 3000,
)
from passlib.hash import sha256_crypt
def run(**kwds):
"""helper to take in user opts, return rounds used in password"""
user = FakeUser(**kwds)
user.set_password("stub")
return sha256_crypt.from_string(user.password).rounds
# test default get_category
self.load_extension(PASSLIB_CONFIG=config)
self.assertEqual(run(), 1000)
self.assertEqual(run(is_staff=True), 2000)
self.assertEqual(run(is_superuser=True), 3000)
# test patch uses explicit get_category function
def get_category(user):
return user.first_name or None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff'), 2000)
self.assertEqual(run(first_name='superuser'), 3000)
# test patch can disable get_category entirely
def get_category(user):
return None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff', is_staff=True), 1000)
self.assertEqual(run(first_name='superuser', is_superuser=True), 1000)
# test bad value
self.assertRaises(TypeError, self.load_extension, PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY='x')
#===================================================================
# eoc
#===================================================================
#=============================================================================
# eof
#=============================================================================
def test_21_category_setting(self):
"test PASSLIB_GET_CATEGORY parameter"
# define config where rounds can be used to detect category
config = dict(
schemes = ["sha256_crypt"],
sha256_crypt__default_rounds = 1000,
staff__sha256_crypt__default_rounds = 2000,
superuser__sha256_crypt__default_rounds = 3000,
)
from passlib.hash import sha256_crypt
def run(**kwds):
"helper to take in user opts, return rounds used in password"
user = FakeUser(**kwds)
user.set_password("stub")
return sha256_crypt.from_string(user.password).rounds
# test default get_category
self.load_extension(PASSLIB_CONFIG=config)
self.assertEqual(run(), 1000)
self.assertEqual(run(is_staff=True), 2000)
self.assertEqual(run(is_superuser=True), 3000)
# test patch uses explicit get_category function
def get_category(user):
return user.first_name or None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff'), 2000)
self.assertEqual(run(first_name='superuser'), 3000)
# test patch can disable get_category entirely
def get_category(user):
return None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff', is_staff=True), 1000)
self.assertEqual(run(first_name='superuser', is_superuser=True), 1000)
# test bad value
self.assertRaises(TypeError, self.load_extension, PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY='x')
#===================================================================
# eoc
#===================================================================
def test_21_category_setting(self):
"""test PASSLIB_GET_CATEGORY parameter"""
# define config where rounds can be used to detect category
config = dict(
schemes = ["sha256_crypt"],
sha256_crypt__default_rounds = 1000,
staff__sha256_crypt__default_rounds = 2000,
superuser__sha256_crypt__default_rounds = 3000,
)
from passlib.hash import sha256_crypt
def run(**kwds):
"""helper to take in user opts, return rounds used in password"""
user = FakeUser(**kwds)
user.set_password("stub")
return sha256_crypt.from_string(user.password).rounds
# test default get_category
self.load_extension(PASSLIB_CONFIG=config)
self.assertEqual(run(), 1000)
self.assertEqual(run(is_staff=True), 2000)
self.assertEqual(run(is_superuser=True), 3000)
# test patch uses explicit get_category function
def get_category(user):
return user.first_name or None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff'), 2000)
self.assertEqual(run(first_name='superuser'), 3000)
# test patch can disable get_category entirely
def get_category(user):
return None
self.load_extension(PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY=get_category)
self.assertEqual(run(), 1000)
self.assertEqual(run(first_name='other'), 1000)
self.assertEqual(run(first_name='staff', is_staff=True), 1000)
self.assertEqual(run(first_name='superuser', is_superuser=True), 1000)
# test bad value
self.assertRaises(TypeError, self.load_extension, PASSLIB_CONTEXT=config,
PASSLIB_GET_CATEGORY='x')
#===================================================================
# eoc
#===================================================================