diff --git a/radicale/auth.py b/radicale/auth.py index 2431aea..4e0aa7a 100644 --- a/radicale/auth.py +++ b/radicale/auth.py @@ -52,6 +52,7 @@ following significantly more secure schemes are parsable by Radicale: """ +import functools import base64 import hashlib import os @@ -102,15 +103,15 @@ class Auth(BaseAuth): self.verify = self._plain elif self.encryption == "md5": try: - from passlib.hash import apr_md5_crypt as _passlib_md5apr1 + from passlib.hash import apr_md5_crypt except ImportError: raise RuntimeError( "The htpasswd encryption method 'md5' requires " "the passlib module.") - self.verify = self._md5apr1 + self.verify = functools.partial(self._md5apr1, apr_md5_crypt) elif self.encryption == "bcrypt": try: - from passlib.hash import bcrypt as _passlib_bcrypt + from passlib.hash import bcrypt except ImportError: raise RuntimeError( "The htpasswd encryption method 'bcrypt' requires " @@ -118,8 +119,8 @@ class Auth(BaseAuth): # A call to `encrypt` raises passlib.exc.MissingBackendError with a # good error message if bcrypt backend is not available. Trigger # this here. - _passlib_bcrypt.encrypt("test-bcrypt-backend") - self.verify = self._bcrypt + bcrypt.encrypt("test-bcrypt-backend") + self.verify = functools.partial(self._bcrypt, bcrypt) elif self.encryption == "crypt": try: import crypt @@ -127,7 +128,7 @@ class Auth(BaseAuth): raise RuntimeError( "The htpasswd encryption method 'crypt' requires " "the crypt() system support.") - self.verify = self._crypt + self.verify = functools.partial(self._crypt, crypt) else: raise RuntimeError( "The htpasswd encryption method '%s' is not " @@ -137,12 +138,10 @@ class Auth(BaseAuth): """Check if ``hash_value`` and ``password`` match, using plain method.""" return hash_value == password - - def _crypt(self, hash_value, password): + def _crypt(self, crypt, hash_value, password): """Check if ``hash_value`` and ``password`` match, using crypt method.""" return crypt.crypt(password, hash_value) == hash_value - def _sha1(self, hash_value, password): """Check if ``hash_value`` and ``password`` match, using sha1 method.""" hash_value = hash_value.replace("{SHA}", "").encode("ascii") @@ -151,7 +150,6 @@ class Auth(BaseAuth): sha1.update(password) return sha1.digest() == base64.b64decode(hash_value) - def _ssha(self, hash_salt_value, password): """Check if ``hash_salt_value`` and ``password`` match, using salted sha1 method. This method is not directly supported by htpasswd, but it can be @@ -166,13 +164,11 @@ class Auth(BaseAuth): sha1.update(salt_value) return sha1.digest() == hash_value + def _bcrypt(self, bcrypt, hash_value, password): + return bcrypt.verify(password, hash_value) - def _bcrypt(self, hash_value, password): - return _passlib_bcrypt.verify(password, hash_value) - - - def _md5apr1(self, hash_value, password): - return _passlib_md5apr1.verify(password, hash_value) + def _md5apr1(self, md5_apr1, hash_value, password): + return md5_apr1.verify(password, hash_value) def is_authenticated(self, user, password): # The content of the file is not cached because reading is generally a @@ -186,4 +182,3 @@ class Auth(BaseAuth): if login == user: return self.verify(hash_value, password) return False - diff --git a/radicale/storage.py b/radicale/storage.py index 41dd838..982026f 100644 --- a/radicale/storage.py +++ b/radicale/storage.py @@ -45,6 +45,7 @@ def load(configuration, logger): collection_class = Collection else: collection_class = import_module(storage_type).Collection + class CollectionCopy(collection_class): """Collection copy, avoids overriding the original class attributes.""" CollectionCopy.configuration = configuration diff --git a/tox.ini b/tox.ini index eef0df9..9a74e90 100644 --- a/tox.ini +++ b/tox.ini @@ -7,9 +7,12 @@ deps = nose-cov pam requests + flake8 [testenv] -commands = nosetests [] +commands = + flake8 + nosetests [] [testenv:py33] deps = @@ -25,3 +28,6 @@ deps = deps = git+https://github.com/eberle1080/dulwich-py3k.git {[base]deps} + +[flake8] +max-line-length = 100