From 1b46e90361ec3c1ccf970af459c18d0327f38650 Mon Sep 17 00:00:00 2001
From: Alex Chan <alex@alexwlchan.net>
Date: Sat, 3 Oct 2015 12:20:01 +0100
Subject: [PATCH 01/15] Fix broken Wiki link in README

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 6f4ce33d..b12a9904 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ We recommend using [virtualenv](https://virtualenv.pypa.io/en/latest/).
 
 # Examples
 
-Examples can be found in the [wiki](./wiki/)
+Examples can be found in the [wiki](https://github.com/joestump/python-oauth2/wiki)
 
 # Running tests
 You can run tests using the following at the command line:
@@ -31,4 +31,4 @@ This code was originally forked from [Leah Culver and Andy Smith's oauth.py code
 * Classes are no longer prefixed with <code>OAuth</code>.
 * The <code>Request</code> class now extends from <code>dict</code>.
 * The library is likely no longer compatible with Python 2.3.
-* The <code>Client</code> class works and extends from <code>httplib2</code>. It's a thin wrapper that handles automatically signing any normal HTTP request you might wish to make.
\ No newline at end of file
+* The <code>Client</code> class works and extends from <code>httplib2</code>. It's a thin wrapper that handles automatically signing any normal HTTP request you might wish to make.

From 604f8e0cb41c969a273aa85b02ea7857c5406e55 Mon Sep 17 00:00:00 2001
From: Steve Peak <steve@stevepeak.net>
Date: Wed, 7 Oct 2015 11:33:51 +0200
Subject: [PATCH 02/15] Submit coverage reports to Codecov

---
 .travis.yml | 9 +++++++--
 README.md   | 2 +-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 128885c6..a20f7099 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,5 +4,10 @@ python:
   - "2.7"
   - "3.3"
   - "3.4"
-install: "pip install -r requirements.txt"
-script: py.test 
+install:
+  - pip install -r requirements.txt
+  - pip install codecov pytest-cov
+script:
+  - py.test --cov=oauth2
+after_success:
+  - codecov
diff --git a/README.md b/README.md
index b12a9904..39198d2a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Join the chat at https://gitter.im/joestump/python-oauth2](https://img.shields.io/badge/gitter-join%20chat-1dce73.svg?style=flat-square)](https://gitter.im/joestump/python-oauth2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://img.shields.io/travis-ci/joestump/python-oauth2.png?branch=master&style=flat-square)](https://travis-ci.org/joestump/python-oauth2) ![Number of issues](https://img.shields.io/github/issues/joestump/python-oauth2.svg?style=flat-square) ![Licence MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)
+[![Join the chat at https://gitter.im/joestump/python-oauth2](https://img.shields.io/badge/gitter-join%20chat-1dce73.svg?style=flat-square)](https://gitter.im/joestump/python-oauth2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://img.shields.io/travis-ci/joestump/python-oauth2.png?branch=master&style=flat-square)](https://travis-ci.org/joestump/python-oauth2) [![Coverage](https://img.shields.io/codecov/c/github/joestump/python-oauth2.svg?style=flat-square)](https://codecov.io/gh/joestump/python-oauth2) ![Number of issues](https://img.shields.io/github/issues/joestump/python-oauth2.svg?style=flat-square) ![Licence MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)
 
 # Overview
 python-oauth2 is a python oauth library fully compatible with python versions: 2.6, 2.7, 3.3 and 3.4. This library is depended on by many other downstream packages such as Flask-Oauth.

From 87ac20b353cdc0f5816f10b33b537fca5ea1993c Mon Sep 17 00:00:00 2001
From: Tom Leach <tom@leach.it>
Date: Wed, 18 Nov 2015 11:07:12 -0500
Subject: [PATCH 03/15] Make more explicit about lack of OAuth 2.0 support

Three separate projects at my company have wasted time attempting to use this library to build an OAuth 2.0 client, simply because it's named "oauth2". Indeed there is an entire [thread](https://github.com/joestump/python-oauth2/issues/83) about this.

This banner makes it clear to anyone evaluating the library what it does and does not support.
---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 39198d2a..67ad4222 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
 [![Join the chat at https://gitter.im/joestump/python-oauth2](https://img.shields.io/badge/gitter-join%20chat-1dce73.svg?style=flat-square)](https://gitter.im/joestump/python-oauth2?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](http://img.shields.io/travis-ci/joestump/python-oauth2.png?branch=master&style=flat-square)](https://travis-ci.org/joestump/python-oauth2) [![Coverage](https://img.shields.io/codecov/c/github/joestump/python-oauth2.svg?style=flat-square)](https://codecov.io/gh/joestump/python-oauth2) ![Number of issues](https://img.shields.io/github/issues/joestump/python-oauth2.svg?style=flat-square) ![Licence MIT](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)
 
+## Note: This library implements OAuth 1.0 and *not OAuth 2.0*. 
+
 # Overview
 python-oauth2 is a python oauth library fully compatible with python versions: 2.6, 2.7, 3.3 and 3.4. This library is depended on by many other downstream packages such as Flask-Oauth.
 

From 9c77664a0735a276a1c7eab7d404ae256f8197fa Mon Sep 17 00:00:00 2001
From: Louis Sautier <sautier.louis@gmail.com>
Date: Wed, 18 Jan 2017 10:42:13 +0100
Subject: [PATCH 04/15] Do not install the "tests" package

---
 setup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup.py b/setup.py
index eba6e2ef..6efa3914 100755
--- a/setup.py
+++ b/setup.py
@@ -45,7 +45,7 @@
         "Natural Language :: English",
         "License :: OSI Approved :: MIT License"
       ],
-      packages = find_packages(),
+      packages = find_packages(exclude=['tests']),
       install_requires = ['httplib2'],
       license = "MIT License",
       keywords="oauth",

From 99d557eba21f935c08180670d8f322554929a69a Mon Sep 17 00:00:00 2001
From: Louis Sautier <sautier.louis@gmail.com>
Date: Wed, 18 Jan 2017 10:46:22 +0100
Subject: [PATCH 05/15] Remove coverage from tests requirements

---
 setup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/setup.py b/setup.py
index eba6e2ef..95b66e08 100755
--- a/setup.py
+++ b/setup.py
@@ -51,4 +51,4 @@
       keywords="oauth",
       zip_safe = True,
       test_suite="tests",
-      tests_require=['coverage', 'mock'])
+      tests_require=['mock'])

From 95dbff6d7ae0ab2b0a92204cf1e10dce7f403cba Mon Sep 17 00:00:00 2001
From: Sylvain <sylvain.desodt+github@gmail.com>
Date: Wed, 8 Mar 2017 15:26:57 +0100
Subject: [PATCH 06/15] Add most recent Python versions in Travis CI

Add more recent Python versions including development branches and nightly build.
---
 .travis.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index a20f7099..32191e78 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,6 +4,11 @@ python:
   - "2.7"
   - "3.3"
   - "3.4"
+  - "3.5"
+  - "3.6"
+  - "3.6-dev"
+  - "3.7-dev"
+  - "nightly"
 install:
   - pip install -r requirements.txt
   - pip install codecov pytest-cov

From 7dd5d758120d64dd7ad8a0b1af10e6283a7320aa Mon Sep 17 00:00:00 2001
From: Nik Nyby <nnyby@columbia.edu>
Date: Mon, 23 Oct 2017 13:45:27 -0400
Subject: [PATCH 07/15] Remove python 3.3, add python 3.5 and 3.6

Python 3.3 has reached end of life: https://www.python.org/downloads/release/python-336/
---
 .travis.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index a20f7099..ad53945a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,9 @@ language: python
 python:
   - "2.6"
   - "2.7"
-  - "3.3"
   - "3.4"
+  - "3.5"
+  - "3.6"
 install:
   - pip install -r requirements.txt
   - pip install codecov pytest-cov

From 3e388933417dcfa6fa1e8487b2014be9c900e754 Mon Sep 17 00:00:00 2001
From: martyni <martynjamespratt@gmail.com>
Date: Fri, 10 Nov 2017 12:50:32 +0000
Subject: [PATCH 08/15] bug fix

---
 oauth2/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2/__init__.py b/oauth2/__init__.py
index a1776a75..cc64ae80 100644
--- a/oauth2/__init__.py
+++ b/oauth2/__init__.py
@@ -490,7 +490,7 @@ def sign_request(self, signature_method, consumer, token):
             # section 4.1.1 "OAuth Consumers MUST NOT include an
             # oauth_body_hash parameter on requests with form-encoded
             # request bodies."
-            self['oauth_body_hash'] = base64.b64encode(sha1(self.body).digest())
+            self['oauth_body_hash'] = base64.b64encode(sha1(u'{}'.format(self.body)).digest())
 
         if 'oauth_consumer_key' not in self:
             self['oauth_consumer_key'] = consumer.key

From 7de768862e19185aca941784c16f9abf171e2c20 Mon Sep 17 00:00:00 2001
From: martyni <martynjamespratt@gmail.com>
Date: Fri, 10 Nov 2017 13:00:05 +0000
Subject: [PATCH 09/15] removed unicode str

---
 oauth2/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2/__init__.py b/oauth2/__init__.py
index cc64ae80..73817f36 100644
--- a/oauth2/__init__.py
+++ b/oauth2/__init__.py
@@ -490,7 +490,7 @@ def sign_request(self, signature_method, consumer, token):
             # section 4.1.1 "OAuth Consumers MUST NOT include an
             # oauth_body_hash parameter on requests with form-encoded
             # request bodies."
-            self['oauth_body_hash'] = base64.b64encode(sha1(u'{}'.format(self.body)).digest())
+            self['oauth_body_hash'] = base64.b64encode(sha1('{}'.format(self.body)).digest())
 
         if 'oauth_consumer_key' not in self:
             self['oauth_consumer_key'] = consumer.key

From 0295f507df9c2de07e2b985987d70fefcf1c51f2 Mon Sep 17 00:00:00 2001
From: martyni <martynjamespratt@gmail.com>
Date: Fri, 10 Nov 2017 13:05:13 +0000
Subject: [PATCH 10/15] bug fix

---
 oauth2/__init__.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/oauth2/__init__.py b/oauth2/__init__.py
index 73817f36..3849b06f 100644
--- a/oauth2/__init__.py
+++ b/oauth2/__init__.py
@@ -490,7 +490,9 @@ def sign_request(self, signature_method, consumer, token):
             # section 4.1.1 "OAuth Consumers MUST NOT include an
             # oauth_body_hash parameter on requests with form-encoded
             # request bodies."
-            self['oauth_body_hash'] = base64.b64encode(sha1('{}'.format(self.body)).digest())
+            if not self.body:
+               self.body = ''
+            self['oauth_body_hash'] = base64.b64encode(sha1(self.body).digest())
 
         if 'oauth_consumer_key' not in self:
             self['oauth_consumer_key'] = consumer.key

From 46bbc5ea27da68e776b5e2f1aa3b8d6c6905653f Mon Sep 17 00:00:00 2001
From: martyni <martynjamespratt@gmail.com>
Date: Fri, 10 Nov 2017 13:11:11 +0000
Subject: [PATCH 11/15] testing

---
 oauth2/__init__.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/oauth2/__init__.py b/oauth2/__init__.py
index 3849b06f..1b56ee14 100644
--- a/oauth2/__init__.py
+++ b/oauth2/__init__.py
@@ -489,9 +489,7 @@ def sign_request(self, signature_method, consumer, token):
             # http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html
             # section 4.1.1 "OAuth Consumers MUST NOT include an
             # oauth_body_hash parameter on requests with form-encoded
-            # request bodies."
-            if not self.body:
-               self.body = ''
+            # request bodies. "
             self['oauth_body_hash'] = base64.b64encode(sha1(self.body).digest())
 
         if 'oauth_consumer_key' not in self:

From d4b0b6d6d12a2fe519a12e6fe9b80ac2fef6b9c8 Mon Sep 17 00:00:00 2001
From: martyni <martynjamespratt@gmail.com>
Date: Fri, 10 Nov 2017 13:21:50 +0000
Subject: [PATCH 12/15] encoded to utf-8

---
 oauth2/__init__.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/oauth2/__init__.py b/oauth2/__init__.py
index 1b56ee14..0e02e62e 100644
--- a/oauth2/__init__.py
+++ b/oauth2/__init__.py
@@ -489,7 +489,9 @@ def sign_request(self, signature_method, consumer, token):
             # http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/oauth-bodyhash.html
             # section 4.1.1 "OAuth Consumers MUST NOT include an
             # oauth_body_hash parameter on requests with form-encoded
-            # request bodies. "
+            # request bodies."
+            if not self.body:
+               self.body = ''.encode('utf-8')
             self['oauth_body_hash'] = base64.b64encode(sha1(self.body).digest())
 
         if 'oauth_consumer_key' not in self:

From bc8b38024ba723acb6f89ce32658d28ea9a61c34 Mon Sep 17 00:00:00 2001
From: Tim Sheerman-Chase <tim2009@sheerman-chase.org.uk>
Date: Mon, 4 Dec 2017 04:24:22 +0000
Subject: [PATCH 13/15] Test for issue #207

---
 tests/test_oauth.py | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/tests/test_oauth.py b/tests/test_oauth.py
index 58854564..b9802cbc 100644
--- a/tests/test_oauth.py
+++ b/tests/test_oauth.py
@@ -1210,7 +1210,7 @@ def sign(self, request, consumer, token):
 
 class TestServer(unittest.TestCase):
     def setUp(self):
-        url = "http://sp.example.com/"
+        self.url = "http://sp.example.com/"
 
         params = {
             'oauth_version': "1.0",
@@ -1227,7 +1227,7 @@ def setUp(self):
 
         params['oauth_token'] = self.token.key
         params['oauth_consumer_key'] = self.consumer.key
-        self.request = oauth.Request(method="GET", url=url, parameters=params)
+        self.request = oauth.Request(method="GET", url=self.url, parameters=params)
 
         signature_method = oauth.SignatureMethod_HMAC_SHA1()
         self.request.sign_request(signature_method, self.consumer, self.token)
@@ -1269,6 +1269,18 @@ def test_verify_request(self):
         self.assertEqual(parameters['foo'], 59)
         self.assertEqual(parameters['multi'], ['FOO','BAR'])
 
+    def test_verify_request_query_string(self):
+        server = oauth.Server()
+        server.add_signature_method(oauth.SignatureMethod_HMAC_SHA1())
+
+        signature_method = oauth.SignatureMethod_HMAC_SHA1()
+        request2 = oauth.Request.from_request("GET", self.url, query_string=urlencode(dict(self.request)))
+        request2.sign_request(signature_method, self.consumer, self.token)
+        request3 = oauth.Request.from_request("GET", self.url, query_string=urlencode(dict(request2)))        
+
+        parameters = server.verify_request(request3, self.consumer,
+            self.token)
+
     def test_verify_request_missing_signature(self):
         from oauth2 import MissingSignature
         server = oauth.Server()

From 281efc499d188b26e05f913ff8c0c2089e6a39bf Mon Sep 17 00:00:00 2001
From: Tim Sheerman-Chase <tim2009@sheerman-chase.org.uk>
Date: Mon, 4 Dec 2017 05:03:24 +0000
Subject: [PATCH 14/15] Hacky fix for #207

---
 oauth2/__init__.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/oauth2/__init__.py b/oauth2/__init__.py
index a1776a75..e588199e 100644
--- a/oauth2/__init__.py
+++ b/oauth2/__init__.py
@@ -353,6 +353,7 @@ def __init__(self, method=HTTP_METHOD, url=None, parameters=None,
             for k, v in parameters.items():
                 k = to_unicode(k)
                 v = to_unicode_optional_iterator(v)
+
                 self[k] = v
         self.body = body
         self.is_form_encoded = is_form_encoded
@@ -540,6 +541,7 @@ def from_request(cls, http_method, http_url, headers=None, parameters=None,
         # GET or POST query string.
         if query_string:
             query_params = cls._split_url_string(query_string)
+
             parameters.update(query_params)
  
         # URL parameters.
@@ -757,6 +759,8 @@ def _check_signature(self, request, consumer, token):
         signature = request.get('oauth_signature')
         if signature is None:
             raise MissingSignature('Missing oauth_signature.')
+        if isinstance(signature, str):
+            signature = signature.encode('ascii', 'ignore')
 
         # Validate the signature.
         valid = signature_method.check(request, consumer, token, signature)

From 631e8a517a924081efd433976d8b413f932f4cc0 Mon Sep 17 00:00:00 2001
From: Igor Cheledinov <cheledinov@gmail.com>
Date: Tue, 23 Jan 2018 00:08:23 +0300
Subject: [PATCH 15/15] fix problem with python3.6

---
 oauth2/__init__.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2/__init__.py b/oauth2/__init__.py
index a1776a75..bbc8763b 100644
--- a/oauth2/__init__.py
+++ b/oauth2/__init__.py
@@ -490,7 +490,7 @@ def sign_request(self, signature_method, consumer, token):
             # section 4.1.1 "OAuth Consumers MUST NOT include an
             # oauth_body_hash parameter on requests with form-encoded
             # request bodies."
-            self['oauth_body_hash'] = base64.b64encode(sha1(self.body).digest())
+            self['oauth_body_hash'] = base64.b64encode(sha1(to_utf8(self.body)).digest())
 
         if 'oauth_consumer_key' not in self:
             self['oauth_consumer_key'] = consumer.key
