Skip to content

Commit

Permalink
Support Python 3.7 (#3)
Browse files Browse the repository at this point in the history
* Add support for Python 3.6, 3.7 and PyPy3.

but drop support for Python 3.3 and 3.4.

* Add coveralls and improve coverage analysis.

* Also test against bcrypt.

* Flake8.
  • Loading branch information
Michael Howitz committed Oct 30, 2018
1 parent e011dbd commit aa7aaba
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 247 deletions.
10 changes: 10 additions & 0 deletions .coveragerc
@@ -0,0 +1,10 @@
[run]
source = AuthEncoding

[report]
precision = 2
exclude_lines =
pragma: no cover
if __name__ == '__main__':
raise NotImplementedError
raise AssertionError
22 changes: 17 additions & 5 deletions .travis.yml
Expand Up @@ -3,13 +3,25 @@ language: python
sudo: false
python:
- 2.7
- 3.3
- 3.4
- 3.5
- 3.6
- pypy
- pypy3
matrix:
include:
- python: "3.7"
dist: xenial
sudo: true
install:
- python bootstrap.py
- bin/buildout
- pip install coverage coveralls
- pip install -e .[test,bcrypt]
script:
- bin/test
- coverage run $(which pytest)
after_success:
- coveralls
notifications:
email: false
cache:
pip: true
directories:
- eggs/
4 changes: 3 additions & 1 deletion CHANGES.txt
Expand Up @@ -4,7 +4,9 @@ Changelog
4.1.0 (unreleased)
------------------

- Drop Python 2.6 support.
- Add support for Python 3.6, 3.7 and PyPy3.

- Drop support for Python 2.6, 3.3 and 3.4.

- Add ``BCRYPTHashingScheme``, optionally available if package is
installed with the `bcrypt` extra.
Expand Down
11 changes: 4 additions & 7 deletions MANIFEST.in
@@ -1,10 +1,7 @@
include *.txt
include *.rst
include .coveragerc
include buildout.cfg
include tox.ini

recursive-include include *
recursive-include src/AuthEncoding *

global-exclude *.dll
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.so
recursive-include src/AuthEncoding *.py
189 changes: 0 additions & 189 deletions bootstrap.py

This file was deleted.

20 changes: 0 additions & 20 deletions buildout.cfg

This file was deleted.

2 changes: 2 additions & 0 deletions setup.cfg
@@ -0,0 +1,2 @@
[bdist_wheel]
universal = 1
6 changes: 3 additions & 3 deletions setup.py
Expand Up @@ -37,12 +37,12 @@
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP",
"Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP", # noqa: E501
],
install_requires=[
'six',
Expand Down
35 changes: 20 additions & 15 deletions src/AuthEncoding/AuthEncoding.py
Expand Up @@ -130,6 +130,7 @@ def _encrypt_with_salt(self, pw, salt):
pw = b(pw)
return b2a_base64(sha(pw + salt).digest() + salt)[:-1]


registerScheme(u'SSHA', SSHADigestScheme())


Expand Down Expand Up @@ -159,6 +160,7 @@ def validate(self, reference, attempt):
a = self.encrypt(attempt)
return constant_time_compare(a, reference)


registerScheme(u'SHA256', SHA256DigestScheme())


Expand All @@ -171,24 +173,25 @@ def validate(self, reference, attempt):


class BCRYPTHashingScheme:
"""A BCRYPT hashing scheme."""
"""A BCRYPT hashing scheme."""

@staticmethod
def _ensure_bytes(pw, encoding='utf-8'):
"""Ensures the given password `pw` is returned as bytes."""
if isinstance(pw, six.text_type):
pw = pw.encode(encoding)
return pw
@staticmethod
def _ensure_bytes(pw, encoding='utf-8'):
"""Ensures the given password `pw` is returned as bytes."""
if isinstance(pw, six.text_type):
pw = pw.encode(encoding)
return pw

def encrypt(self, pw):
return bcrypt.hashpw(self._ensure_bytes(pw), bcrypt.gensalt())

def encrypt(self, pw):
return bcrypt.hashpw(self._ensure_bytes(pw), bcrypt.gensalt())
def validate(self, reference, attempt):
try:
return bcrypt.checkpw(self._ensure_bytes(attempt), reference)
except ValueError:
# Usually due to an invalid salt
return False

def validate(self, reference, attempt):
try:
return bcrypt.checkpw(self._ensure_bytes(attempt), reference)
except ValueError:
# Usually due to an invalid salt
return False

if bcrypt is not None:
registerScheme(u'BCRYPT', BCRYPTHashingScheme())
Expand Down Expand Up @@ -249,6 +252,7 @@ def validate(self, reference, attempt):
a = self.encrypt(attempt)
return constant_time_compare(a, reference)


registerScheme(u'MYSQL', MySQLDigestScheme())


Expand Down Expand Up @@ -282,4 +286,5 @@ def pw_encrypt(pw, encoding=u'SSHA'):
return b(prefix) + scheme.encrypt(pw)
raise ValueError('Not supported: %s' % encoding)


pw_encode = pw_encrypt # backward compatibility
10 changes: 6 additions & 4 deletions src/AuthEncoding/__init__.py
Expand Up @@ -11,7 +11,9 @@
#
##############################################################################


from .AuthEncoding import (is_encrypted, pw_encrypt, pw_validate,
registerScheme, listSchemes,
constant_time_compare)
from .AuthEncoding import constant_time_compare # noqa: F401
from .AuthEncoding import is_encrypted # noqa: F401
from .AuthEncoding import listSchemes # noqa: F401
from .AuthEncoding import pw_encrypt # noqa: F401
from .AuthEncoding import pw_validate # noqa: F401
from .AuthEncoding import registerScheme # noqa: F401

0 comments on commit aa7aaba

Please sign in to comment.