LazyCryptContext is used for the lazy configuration of the PasswordType.

This commit is contained in:
Oleg Pidsadnyi
2016-03-16 15:30:51 +01:00
parent ae0f1e4eed
commit 1846aeb769
2 changed files with 45 additions and 6 deletions

View File

@@ -11,7 +11,7 @@ from .scalar_coercible import ScalarCoercible
passlib = None
try:
import passlib
from passlib.context import CryptContext
from passlib.context import LazyCryptContext
except ImportError:
pass
@@ -82,7 +82,7 @@ class PasswordType(types.TypeDecorator, ScalarCoercible):
verifying them using a pythonic interface.
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
automatically hash new passwords as `pbkdf2_sha512` but still compare
@@ -128,7 +128,7 @@ class PasswordType(types.TypeDecorator, ScalarCoercible):
)
# Construct the passlib crypt context.
self.context = CryptContext(**kwargs)
self.context = LazyCryptContext(**kwargs)
if max_length is None:
max_length = self.calculate_max_length()

View File

@@ -6,7 +6,13 @@ from sqlalchemy_utils import Password, PasswordType, types # noqa
@pytest.fixture
def User(Base):
def extra_kwargs():
"""PasswordType extra keyword arguments."""
return {}
@pytest.fixture
def User(Base, extra_kwargs):
class User(Base):
__tablename__ = 'user'
id = sa.Column(sa.Integer, primary_key=True)
@@ -17,8 +23,8 @@ def User(Base):
'md5_crypt',
'hex_md5'
],
deprecated=['md5_crypt', 'hex_md5']
deprecated=['md5_crypt', 'hex_md5'],
**extra_kwargs
))
def __repr__(self):
@@ -31,6 +37,17 @@ def init_models(User):
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')
class TestPasswordType(object):
@@ -178,3 +195,25 @@ class TestPasswordType(object):
assert obj.password.hash.decode('utf8').startswith('$pbkdf2-sha512$')
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$')