Skip to content

Commit

Permalink
Merge pull request #6 from ustudio/python2-support
Browse files Browse the repository at this point in the history
Python2 support
  • Loading branch information
spiralman authored Jul 26, 2017
2 parents 75bb445 + 19d664c commit 268a6fc
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 30 deletions.
9 changes: 3 additions & 6 deletions circle.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
machine:
python:
version: 3.6.0
dependencies:
pre:
- pip install -r dev-requirements.txt
post:
- pyenv global 3.6.1 2.7.12
test:
override:
- nosetests
- tox
deployment:
release:
tag: /v[0-9]+(\.[0-9]+)*/
Expand Down
5 changes: 4 additions & 1 deletion hmacauth/client/authenticated_request.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from tornado.httpclient import HTTPRequest

from urllib.parse import urlparse
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse

from hmacauth.digest import generate_digest

Expand Down
11 changes: 8 additions & 3 deletions hmacauth/digest.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import hmac
import hashlib
import urllib.parse

try:
from urllib.parse import parse_qs, quote
except ImportError:
from urlparse import parse_qs
from urllib import quote


def generate_digest(secret, method, path, query, body):
parsed_query = urllib.parse.parse_qs(query, keep_blank_values=True)
parsed_query = parse_qs(query, keep_blank_values=True)

canonical_query = []

for key in sorted(parsed_query.keys()):
for value in sorted(parsed_query[key]):
canonical_query.append("=".join((key, urllib.parse.quote(value))))
canonical_query.append("=".join((key, quote(value))))

return hmac.new(
secret.encode("utf-8"),
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
]

setup(name="ustudio-hmac-tornado",
version="0.2.0",
version="0.3.0",
description="Simple HMAC Client/Server authentication for Tornado",
url="https://github.com/ustudio/ustudio-hmac-tornado",
packages=find_packages(exclude=["tests", "dist"]),
Expand Down
36 changes: 18 additions & 18 deletions tests/client/test_authenticated_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

class TestAuthenticatedRequest(BaseHMACTestCase):
@gen_test
async def test_signs_post_with_bytestring_body(self):
response = await self.http_client.fetch(authenticated_request(
def test_signs_post_with_bytestring_body(self):
response = yield self.http_client.fetch(authenticated_request(
self.get_url("/authorized/argument"),
method="POST",
body=b"Some Body",
Expand All @@ -18,8 +18,8 @@ async def test_signs_post_with_bytestring_body(self):
self.assertEqual(200, response.code)

@gen_test
async def test_signs_post_with_unicode_body(self):
response = await self.http_client.fetch(authenticated_request(
def test_signs_post_with_unicode_body(self):
response = yield self.http_client.fetch(authenticated_request(
self.get_url("/authorized/argument"),
method="POST",
body="Some Body",
Expand All @@ -29,8 +29,8 @@ async def test_signs_post_with_unicode_body(self):
self.assertEqual(200, response.code)

@gen_test
async def test_signs_explicit_get(self):
response = await self.http_client.fetch(authenticated_request(
def test_signs_explicit_get(self):
response = yield self.http_client.fetch(authenticated_request(
self.get_url("/authorized/argument"),
method="GET",
hmac_key="correct-key",
Expand All @@ -39,30 +39,30 @@ async def test_signs_explicit_get(self):
self.assertEqual(200, response.code)

@gen_test
async def test_signs_implicit_get(self):
response = await self.http_client.fetch(authenticated_request(
def test_signs_implicit_get(self):
response = yield self.http_client.fetch(authenticated_request(
self.get_url("/authorized/argument"),
hmac_key="correct-key",
hmac_secret="secret"))

self.assertEqual(200, response.code)

@gen_test
async def test_handles_path_only_url(self):
def test_handles_path_only_url(self):
request = authenticated_request(
"/authorized/argument",
hmac_key="correct-key",
hmac_secret="secret")

request.url = self.get_url(request.url)

response = await self.http_client.fetch(request)
response = yield self.http_client.fetch(request)

self.assertEqual(200, response.code)

@gen_test
async def test_includes_existing_headers_in_request(self):
response = await self.http_client.fetch(authenticated_request(
def test_includes_existing_headers_in_request(self):
response = yield self.http_client.fetch(authenticated_request(
self.get_url("/authorized/argument"),
headers={
"X-Ping": "Pong"
Expand All @@ -74,24 +74,24 @@ async def test_includes_existing_headers_in_request(self):
self.assertEqual("Pong", response.body.decode("utf8"))

@gen_test
async def test_signs_url_as_keyword_argument(self):
response = await self.http_client.fetch(authenticated_request(
def test_signs_url_as_keyword_argument(self):
response = yield self.http_client.fetch(authenticated_request(
url=self.get_url("/authorized/argument"),
hmac_key="correct-key",
hmac_secret="secret"))

self.assertEqual(200, response.code)

@gen_test
async def test_raises_exception_without_url_argument(self):
def test_raises_exception_without_url_argument(self):
with self.assertRaises(TypeError):
await self.http_client.fetch(authenticated_request(
yield self.http_client.fetch(authenticated_request(
hmac_key="correct-key",
hmac_secret="secret"))

@gen_test
async def test_normalizes_and_signs_query_arguments(self):
response = await self.http_client.fetch(authenticated_request(
def test_normalizes_and_signs_query_arguments(self):
response = yield self.http_client.fetch(authenticated_request(
url=self.get_url("/authorized/argument?bar=value%202&Foo=value%3f1&blank"),
hmac_key="correct-key",
hmac_secret="secret"))
Expand Down
5 changes: 4 additions & 1 deletion tests/example_server.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from tornado.testing import AsyncHTTPTestCase
from tornado.web import RequestHandler, Application
from tornado import gen

from hmacauth.server import hmac_authorized


class AuthorizedRoute(RequestHandler):
@hmac_authorized
async def get(self, arg):
@gen.coroutine
def get(self, arg):
yield gen.moment
self.finish(self.request.headers.get("X-Ping", ""))

@hmac_authorized
Expand Down
12 changes: 12 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Tox (https://tox.readthedocs.io/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.

[tox]
envlist = py27, py36

[testenv]
commands = nosetests
deps =
nose

0 comments on commit 268a6fc

Please sign in to comment.