LazyCryptContext is used for the lazy configuration of the PasswordType.
This commit is contained in:
@@ -11,7 +11,7 @@ from .scalar_coercible import ScalarCoercible
|
|||||||
passlib = None
|
passlib = None
|
||||||
try:
|
try:
|
||||||
import passlib
|
import passlib
|
||||||
from passlib.context import CryptContext
|
from passlib.context import LazyCryptContext
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ class PasswordType(types.TypeDecorator, ScalarCoercible):
|
|||||||
verifying them using a pythonic interface.
|
verifying them using a pythonic interface.
|
||||||
|
|
||||||
All keyword arguments (aside from max_length) are forwarded to the
|
All keyword arguments (aside from max_length) are forwarded to the
|
||||||
construction of a `passlib.context.CryptContext` object.
|
construction of a `passlib.context.LazyCryptContext` object.
|
||||||
|
|
||||||
The following usage will create a password column that will
|
The following usage will create a password column that will
|
||||||
automatically hash new passwords as `pbkdf2_sha512` but still compare
|
automatically hash new passwords as `pbkdf2_sha512` but still compare
|
||||||
@@ -128,7 +128,7 @@ class PasswordType(types.TypeDecorator, ScalarCoercible):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Construct the passlib crypt context.
|
# Construct the passlib crypt context.
|
||||||
self.context = CryptContext(**kwargs)
|
self.context = LazyCryptContext(**kwargs)
|
||||||
|
|
||||||
if max_length is None:
|
if max_length is None:
|
||||||
max_length = self.calculate_max_length()
|
max_length = self.calculate_max_length()
|
||||||
|
@@ -6,7 +6,13 @@ from sqlalchemy_utils import Password, PasswordType, types # noqa
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def User(Base):
|
def extra_kwargs():
|
||||||
|
"""PasswordType extra keyword arguments."""
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def User(Base, extra_kwargs):
|
||||||
class User(Base):
|
class User(Base):
|
||||||
__tablename__ = 'user'
|
__tablename__ = 'user'
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
@@ -17,8 +23,8 @@ def User(Base):
|
|||||||
'md5_crypt',
|
'md5_crypt',
|
||||||
'hex_md5'
|
'hex_md5'
|
||||||
],
|
],
|
||||||
|
deprecated=['md5_crypt', 'hex_md5'],
|
||||||
deprecated=['md5_crypt', 'hex_md5']
|
**extra_kwargs
|
||||||
))
|
))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@@ -31,6 +37,17 @@ def init_models(User):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def onload_callback(schemes, deprecated):
|
||||||
|
"""
|
||||||
|
Get onload callback that takes the PasswordType arguments from the config.
|
||||||
|
"""
|
||||||
|
def onload(**kwargs):
|
||||||
|
kwargs['schemes'] = schemes
|
||||||
|
kwargs['deprecated'] = deprecated
|
||||||
|
return kwargs
|
||||||
|
return onload
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif('types.password.passlib is None')
|
@pytest.mark.skipif('types.password.passlib is None')
|
||||||
class TestPasswordType(object):
|
class TestPasswordType(object):
|
||||||
|
|
||||||
@@ -178,3 +195,25 @@ class TestPasswordType(object):
|
|||||||
|
|
||||||
assert obj.password.hash.decode('utf8').startswith('$pbkdf2-sha512$')
|
assert obj.password.hash.decode('utf8').startswith('$pbkdf2-sha512$')
|
||||||
assert obj.password == 'b'
|
assert obj.password == 'b'
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'extra_kwargs',
|
||||||
|
[
|
||||||
|
dict(
|
||||||
|
onload=onload_callback(
|
||||||
|
schemes=['pbkdf2_sha256'],
|
||||||
|
deprecated=[],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
def test_lazy_configuration(self, User):
|
||||||
|
"""
|
||||||
|
Field should be able to read the passlib attributes lazily from the
|
||||||
|
config (e.g. Flask config).
|
||||||
|
"""
|
||||||
|
schemes = User.password.type.context.schemes()
|
||||||
|
assert tuple(schemes) == ('pbkdf2_sha256',)
|
||||||
|
obj = User()
|
||||||
|
obj.password = b'b'
|
||||||
|
assert obj.password.hash.decode('utf8').startswith('$pbkdf2-sha256$')
|
||||||
|
Reference in New Issue
Block a user