Skip to content

Commit dbac150

Browse files
committed
Initial commit
0 parents  commit dbac150

19 files changed

+456
-0
lines changed

.gitignore

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
5+
# C extensions
6+
*.so
7+
8+
# Distribution / packaging
9+
.Python
10+
env/
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
*.egg-info/
23+
.installed.cfg
24+
*.egg
25+
26+
# PyInstaller
27+
# Usually these files are written by a python script from a template
28+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
29+
*.manifest
30+
*.spec
31+
32+
# Installer logs
33+
pip-log.txt
34+
pip-delete-this-directory.txt
35+
36+
# Unit test / coverage reports
37+
htmlcov/
38+
.tox/
39+
.coverage
40+
.coverage.*
41+
.cache
42+
nosetests.xml
43+
coverage.xml
44+
*,cover
45+
46+
# Translations
47+
*.mo
48+
*.pot
49+
50+
# Django stuff:
51+
*.log
52+
53+
# Sphinx documentation
54+
docs/_build/
55+
56+
# PyBuilder
57+
target/
58+
59+
# Mr Developer
60+
.tmuxp.yaml
61+
.env
62+
fugu.yml

.isort.cfg

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[settings]
2+
line_length=80
3+
multi_line_output=3
4+
known_first_party=djangohmac
5+
default_section=THIRDPARTY
6+
import_heading_stdlib=Standard Libs
7+
import_heading_thirdparty=Third Party Libs
8+
import_heading_firstparty=First Party Libs
9+
lines_after_imports=2

.pypirc.template

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[distutils]
2+
index-servers =
3+
pypi
4+
5+
[pypi]
6+
username:<PYPI_USER>
7+
password:<PYPI_PASS>

CHANGELOG.rst

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Change Log
2+
----------
3+
4+
0.0.1
5+
~~~~~~~~~
6+
- Initial release including the core feature set

LICENSE

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
This is free and unencumbered software released into the public domain.
2+
3+
Anyone is free to copy, modify, publish, use, compile, sell, or
4+
distribute this software, either in source code form or as a compiled
5+
binary, for any purpose, commercial or non-commercial, and by any
6+
means.
7+
8+
In jurisdictions that recognize copyright laws, the author or authors
9+
of this software dedicate any and all copyright interest in the
10+
software to the public domain. We make this dedication for the benefit
11+
of the public at large and to the detriment of our heirs and
12+
successors. We intend this dedication to be an overt act of
13+
relinquishment in perpetuity of all present and future rights to this
14+
software under copyright law.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22+
OTHER DEALINGS IN THE SOFTWARE.
23+
24+
For more information, please refer to <http://unlicense.org>
25+

MANIFEST.in

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include setup.py README.rst MANIFEST.in CHANGELOG.rst CONTRIBUTORS.rst VERSION.txt
2+
global-exclude *~

README.rst

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
Flask-HMAC
2+
==========
3+
4+
|circle| |downloads| |version| |license|
5+
6+
This module provides a middleware for HMAC signature Django views. It's simply designed to check that a client is entitled to access routes, based on the fact
7+
that it must possess a copy of the secret key.
8+
9+
10+
Usage
11+
-----
12+
13+
settings.py
14+
~~~~~~~~~~~
15+
16+
.. sourcecode:: python
17+
18+
INSTALLED_APPS = (
19+
# ...
20+
'djangohmac',
21+
)
22+
23+
MIDDLEWARE_CLASSES = (
24+
# ...
25+
'djangohmac.middleware.HmacMiddleware',
26+
)
27+
28+
29+
Client
30+
~~~~~~
31+
32+
.. sourcecode:: python
33+
34+
from djangohmac.sign import shmac
35+
36+
sig = shmac.make_hmac() # generate signature
37+
response = requests.get(
38+
'/hmac_auth_view',
39+
headers={hmac.header: sig}
40+
)
41+
42+
43+
Dev
44+
---
45+
46+
To run all tests
47+
48+
.. sourcecode::
49+
50+
docker run -it -v $PWD:/src -w /src ikalnitsky/pythonista tox
51+
52+
53+
.. |circle| image:: https://img.shields.io/circleci/project/thisissoon/django-hmac.svg
54+
:target: https://circleci.com/gh/thisissoon/django-hmac
55+
56+
.. |downloads| image:: http://img.shields.io/pypi/dm/djangohmac.svg
57+
:target: https://pypi.python.org/pypi/djangohmac
58+
59+
.. |version| image:: http://img.shields.io/pypi/v/djangohmac.svg
60+
:target: https://pypi.python.org/pypi/djangohmac
61+
62+
.. |license| image:: http://img.shields.io/pypi/l/djangohmac.svg
63+
:target: https://pypi.python.org/pypi/djangohmac

VERSION.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.0.1

circle.yml

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
machine:
2+
services:
3+
- docker
4+
environment:
5+
REPO: soon/django-hmac
6+
7+
dependencies:
8+
override:
9+
- docker pull ikalnitsky/pythonista
10+
11+
test:
12+
override:
13+
- docker run -v $PWD:/src -w /src ikalnitsky/pythonista tox
14+
15+
deployment:
16+
pypi:
17+
branch: master
18+
commands:
19+
- sed -e "s/<PYPI_USER>/$PYPI_USER/" -e "s/<PYPI_PASS>/$PYPI_PASS/"< .pypirc.template > ~/.pypirc
20+
- sudo python setup.py sdist upload -r pypi

djangohmac/__init__.py

Whitespace-only changes.

djangohmac/middleware.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Third Party Libs
2+
from django.core.exceptions import PermissionDenied
3+
4+
# First Party Libs
5+
from .sign import HmacException, shmac
6+
7+
8+
class HmacMiddleware(object):
9+
10+
def process_request(self, request):
11+
try:
12+
shmac.validate_signature(request)
13+
except HmacException:
14+
raise PermissionDenied()

djangohmac/sign.py

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Standard Libs
2+
import base64
3+
import hashlib
4+
import hmac
5+
6+
# Third Party Libs
7+
import six
8+
from django.conf import settings
9+
10+
11+
class HmacException(Exception):
12+
pass
13+
14+
15+
class SecretKeyIsNotSet(HmacException):
16+
pass
17+
18+
19+
class InvalidSignature(HmacException):
20+
pass
21+
22+
23+
def encode_string(value):
24+
return value.encode('utf-8') if isinstance(value, six.text_type) else value
25+
26+
27+
class Hmac(object):
28+
29+
def __init__(self):
30+
self.hmac_key = six.b(settings.HMAC_SECRET)
31+
self.header = getattr(settings, 'HMAC_HEADER', 'Signature')
32+
self.digestmod = getattr(settings, 'HMAC_DIGESTMOD', hashlib.sha256)
33+
self.hmac_disarm = getattr(settings, 'HMAC_DISABLE', False)
34+
35+
def get_signature(self, request):
36+
try:
37+
return six.b(request.META[self.header])
38+
except KeyError:
39+
raise SecretKeyIsNotSet()
40+
41+
def _hmac_factory(self, data, digestmod=None):
42+
return hmac.new(self.hmac_key, data, digestmod=self.digestmod)
43+
44+
def make_hmac(self, data=''):
45+
hmac_token_server = self._hmac_factory(encode_string(data)).digest()
46+
hmac_token_server = base64.urlsafe_b64encode(hmac_token_server)
47+
return hmac_token_server
48+
49+
def validate_signature(self, request):
50+
if self.hmac_disarm:
51+
return True
52+
hmac_token_client = self.get_signature(request)
53+
hmac_token_server = self.make_hmac(request.body)
54+
if hmac_token_client != hmac_token_server:
55+
raise InvalidSignature('Signatures are different: {0} {1}'.format(
56+
hmac_token_client, hmac_token_server
57+
))
58+
return True
59+
60+
61+
shmac = Hmac()

settings.py

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
'''
2+
Dummy django settings
3+
'''
4+
5+
import os
6+
7+
SECRET_KEY = 'hailthesunshine'
8+
9+
MEDIA_ROOT = os.path.normcase(os.path.dirname(os.path.abspath(__file__)))
10+
MEDIA_URL = '/media/'
11+
12+
INSTALLED_APPS = (
13+
'django.contrib.auth',
14+
'django.contrib.sessions',
15+
'django.contrib.contenttypes',
16+
)
17+
18+
DATABASES = {
19+
'default': {
20+
'ENGINE': 'django.db.backends.sqlite3',
21+
'NAME': ':memory:'
22+
}
23+
}
24+
25+
MIDDLEWARE_CLASSES = (
26+
'django.contrib.sessions.middleware.SessionMiddleware',
27+
'django.middleware.common.CommonMiddleware',
28+
'django.middleware.csrf.CsrfViewMiddleware',
29+
'django.contrib.auth.middleware.AuthenticationMiddleware',
30+
'djangohmac.middleware.HmacMiddleware',
31+
)
32+
33+
HMAC_SECRET = 'HMAC_SECRET'
34+
# HMAC_HEADER = HMAC_HEADER
35+
# HMAC_DIGESTMOD = HMAC_DIGESTMOD
36+
# HMAC_DISABLE = HMAC_DISABLE

setup.py

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python
2+
# encoding: utf-8
3+
4+
# Third Party Libs
5+
from setuptools import setup
6+
7+
8+
# Generate a Long Decription for the PyPi page which is the README.rst
9+
# Plus the CHANGELOG.rst
10+
long_description = open('./README.rst').read()
11+
changelog = open('./CHANGELOG.rst').read()
12+
long_description += '\n' + changelog
13+
14+
# Get Version
15+
version = open('./VERSION.txt').read().strip()
16+
17+
18+
setup(
19+
name='djangohmac',
20+
url='https://github.com/thisissoon/django-hmac',
21+
version=version,
22+
author='SOON_',
23+
author_email='[email protected]',
24+
description='Provides easy integration of the HMAC signatures for '
25+
'your REST Django Applications.',
26+
long_description=long_description,
27+
packages=[
28+
'djangohmac',
29+
],
30+
install_requires=[
31+
'django',
32+
'six',
33+
'ipdb'
34+
],
35+
classifiers=[
36+
'Framework :: Djanog',
37+
'Environment :: Web Environment',
38+
'Intended Audience :: Developers',
39+
'License :: OSI Approved :: MIT License',
40+
'Development Status :: 5 - Production/Stable',
41+
'Operating System :: OS Independent',
42+
'Programming Language :: Python',
43+
'Programming Language :: Python :: 2',
44+
'Programming Language :: Python :: 2.6',
45+
'Programming Language :: Python :: 2.7',
46+
'Programming Language :: Python :: 3',
47+
'Programming Language :: Python :: 3.3',
48+
'Programming Language :: Python :: 3.4',
49+
'Topic :: Software Development',
50+
'Topic :: Software Development :: Libraries :: Python Modules',
51+
'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
52+
'License :: Public Domain'
53+
],
54+
license='Public Domain',
55+
keywords=['Django', 'HMAC', 'REST', 'Views', 'middleware'],
56+
test_suite='tests',
57+
)

tests/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)