diff --git a/development.ini b/development.ini index 6ea25ea..45e4d22 100644 --- a/development.ini +++ b/development.ini @@ -15,8 +15,9 @@ pyramid.includes = pyramid_debugtoolbar sqlalchemy.url = sqlite:///%(here)s/ordr2.sqlite +passlib.config = %(here)s/passlib.ini -auth.secret = 'change me' +auth.secret = change me static_views.cache_max_age = 0 # By default, the toolbar only appears for clients from IP addresses diff --git a/docs/installation.rst b/docs/installation.rst index 7ce8cee..48e515e 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -57,6 +57,8 @@ Dependencies These are the top-level packages that are needed by the webapp and why. They rely propably on other packages as well. +passlib[argon2, bcrypt] + password hashing library with argon2 and bcrypt support pyramid the framework for the web applicatoin diff --git a/ordr2/security.py b/ordr2/security.py index 179aac7..88ebfb1 100644 --- a/ordr2/security.py +++ b/ordr2/security.py @@ -1,5 +1,6 @@ ''' User Authentication and Authorization ''' +from passlib.context import CryptContext from pyramid.authentication import AuthTktAuthenticationPolicy from pyramid.authorization import ACLAuthorizationPolicy from pyramid.security import Authenticated, Everyone @@ -7,6 +8,10 @@ from pyramid.security import Authenticated, Everyone from .models import User +#: create a crypt context for password hashes, configured in :func:`includeme()` +passlib_context = CryptContext() + + class AuthenticationPolicy(AuthTktAuthenticationPolicy): ''' How to authenticate users ''' @@ -54,6 +59,11 @@ def includeme(config): Activate this setup using ``config.include('ordr2.security')``. ''' settings = config.get_settings() + + # configure the passlib context manager for hashing user passwords + passlib_context.load_path(settings['passlib.config']) + + # config for authentication and authorization authn_policy = AuthenticationPolicy( settings['auth.secret'], hashalg='sha512', @@ -61,3 +71,4 @@ def includeme(config): config.set_authentication_policy(authn_policy) config.set_authorization_policy(ACLAuthorizationPolicy()) config.add_request_method(get_user, 'user', reify=True) + diff --git a/passlib.ini b/passlib.ini new file mode 100644 index 0000000..e3872a8 --- /dev/null +++ b/passlib.ini @@ -0,0 +1,15 @@ +; configuration for the passlib password hashing library + +[passlib] + +; setup the context to support only argon2 for the moment +schemes = argon2, bcrypt + +; default encryption scheme is argon2 +default = argon2 + +; flag every encryption method as deprecated except the first one +deprecated = auto + + + diff --git a/setup.py b/setup.py index 4f49334..7bc3243 100644 --- a/setup.py +++ b/setup.py @@ -12,14 +12,15 @@ with open('HISTORY.rst') as history_file: history = history_file.read() requirements = [ + 'passlib[argon2, bcrypt]', 'pyramid', 'pyramid_jinja2', 'pyramid_debugtoolbar', 'pyramid_tm', 'SQLAlchemy', 'transaction', - 'zope.sqlalchemy', 'waitress', + 'zope.sqlalchemy', ] setup_requirements = [