Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: update code and tests for pyjwt>=2.0.0 #560

Merged
merged 19 commits into from
Sep 22, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions .deepsource.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@ version = 1

exclude_patterns = [
'examples/**',

# auto-generated files
'twilio/rest/**',
'twilio/twiml/**',
'tests/integration/**',

# compat files
'twilio/compat.py',
]

test_patterns = [
Expand Down
4 changes: 1 addition & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
dist: xenial # required for Python >= 3.7
language: python
python:
- "2.7"
- "3.4"
- "3.5"
- "3.6"
- "3.7"
- "3.8"
- "3.9"
services:
- docker
install:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.PHONY: clean install analysis test test-install develop docs docs-install

venv:
@python --version || (echo "Python is not installed, please install Python 2 or Python 3"; exit 1);
@python --version || (echo "Python is not installed, Python 3.6+"; exit 1);
virtualenv --python=python venv

install: venv
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@ Please consult the [official migration guide](https://www.twilio.com/docs/librar

This library supports the following Python implementations:

* Python 2.7
* Python 3.4
* Python 3.5
* Python 3.6
* Python 3.7
* Python 3.8
* Python 3.9

## Installation

Expand Down
5 changes: 2 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
flake8
mock
nose
six
requests>=2.0.0
PyJWT==1.7.1
twine
PyJWT>=2.0.0, <3.0.0
twine
18 changes: 4 additions & 14 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from __future__ import with_statement
from setuptools import setup, find_packages

__version__ = None
Expand All @@ -24,19 +23,12 @@
author_email="help@twilio.com",
url="https://github.com/twilio/twilio-python/",
keywords=["twilio", "twiml"],
python_requires='>=3.6.0',
install_requires=[
"six",
"pytz",
"PyJWT == 1.7.1",
"requests >= 2.0.0",
"PyJWT >= 2.0.0, < 3.0.0",
],
extras_require={
':python_version<"3.0"': [
"requests[security] >= 2.0.0",
],
':python_version>="3.0"': [
"requests >= 2.0.0"
],
},
packages=find_packages(exclude=['tests', 'tests.*']),
include_package_data=True,
classifiers=[
Expand All @@ -45,12 +37,10 @@
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Communications :: Telephony",
Expand Down
5 changes: 2 additions & 3 deletions tests/unit/jwt/test_jwt.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def assertJwtsEqual(self, jwt, key, expected_payload=None, expected_headers=None
expected_headers = expected_headers or {}
expected_payload = expected_payload or {}

decoded_payload = jwt_lib.decode(jwt, key, verify=False)
decoded_payload = jwt_lib.decode(jwt, key, algorithms=["HS256"], options={"verify_signature": False})
decoded_headers = jwt_lib.get_unverified_header(jwt)

self.assertEqual(expected_headers, decoded_headers)
Expand Down Expand Up @@ -242,9 +242,8 @@ def test_decode_bad_secret(self):

def test_decode_modified_jwt_fails(self):
jwt = DummyJwt('secret_key', 'issuer')
example_jwt = jwt.to_jwt().decode('utf-8')
example_jwt = jwt.to_jwt()
example_jwt = 'ABC' + example_jwt[3:]
example_jwt = example_jwt.encode('utf-8')

self.assertRaises(JwtDecodeError, Jwt.from_jwt, example_jwt, 'secret_key')

Expand Down
14 changes: 2 additions & 12 deletions tests/unit/test_request_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import unittest

from nose.tools import assert_equal, assert_true
from six import b, u

from twilio.request_validator import RequestValidator

Expand All @@ -26,22 +25,13 @@ def setUp(self):
self.bodyHash = "0a1ff7634d9ab3b95db5c9a2dfe9416e41502b283a80c7cf19632632f96e6620"
self.uriWithBody = self.uri + "&bodySHA256=" + self.bodyHash

def test_compute_signature_bytecode(self):
expected = b(self.expected)
signature = self.validator.compute_signature(self.uri,
self.params,
utf=False)
assert_equal(signature, expected)

def test_compute_signature(self):
expected = (self.expected)
signature = self.validator.compute_signature(self.uri,
self.params,
utf=True)
signature = self.validator.compute_signature(self.uri, self.params)
assert_equal(signature, expected)

def test_compute_hash_unicode(self):
expected = u(self.bodyHash)
expected = self.bodyHash
body_hash = self.validator.compute_hash(self.body)

assert_equal(expected, body_hash)
Expand Down
3 changes: 1 addition & 2 deletions tests/unit/twiml/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import unittest

from nose.tools import raises
from six import text_type

from twilio.twiml import (
format_language,
Expand All @@ -13,7 +12,7 @@

class TwilioTest(unittest.TestCase):
def strip(self, xml):
return text_type(xml)
return str(xml)

@raises(TwiMLException)
def test_append_fail(self):
Expand Down
3 changes: 1 addition & 2 deletions tests/unit/twiml/test_voice_response.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
from nose.tools import assert_equal
from six import u
from tests.unit.twiml import TwilioTest
from twilio.twiml.voice_response import VoiceResponse, Dial, Enqueue, Gather

Expand Down Expand Up @@ -82,7 +81,7 @@ def test_say_hello_world(self):
def test_say_french(self):
""" should say hello monkey """
r = VoiceResponse()
r.say(u('n\xe9cessaire et d\'autres'))
r.say('n\xe9cessaire et d\'autres')

assert_equal(
self.strip(r),
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py27, py3{4,5,6,7,8}, pypy
envlist = py3{6,7,8}, pypy
skip_missing_interpreters = true

[testenv]
Expand Down
10 changes: 4 additions & 6 deletions twilio/base/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
import sys

from six import u


class TwilioException(Exception):
pass
Expand Down Expand Up @@ -32,16 +30,16 @@ def __str__(self):
""" Try to pretty-print the exception, if this is going on screen. """

def red(words):
return u("\033[31m\033[49m%s\033[0m") % words
return "\033[31m\033[49m%s\033[0m" % words

def white(words):
return u("\033[37m\033[49m%s\033[0m") % words
return "\033[37m\033[49m%s\033[0m" % words

def blue(words):
return u("\033[34m\033[49m%s\033[0m") % words
return "\033[34m\033[49m%s\033[0m" % words

def teal(words):
return u("\033[36m\033[49m%s\033[0m") % words
return "\033[36m\033[49m%s\033[0m" % words

def get_uri(code):
return "https://www.twilio.com/docs/errors/{0}".format(code)
Expand Down
3 changes: 1 addition & 2 deletions twilio/base/values.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from six import iteritems
unset = object()


Expand All @@ -9,4 +8,4 @@ def of(d):
:param dict d: A dict to strip.
:return dict: A dict with unset values removed.
"""
return {k: v for k, v in iteritems(d) if v != unset}
return {k: v for k, v in d.items() if v != unset}
17 changes: 0 additions & 17 deletions twilio/compat.py

This file was deleted.

2 changes: 1 addition & 1 deletion twilio/http/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from requests import Request, Session, hooks
from requests.adapters import HTTPAdapter
from twilio.compat import urlencode
from urllib.parse import urlencode
from twilio.http import HttpClient
from twilio.http.request import Request as TwilioRequest
from twilio.http.response import Response
Expand Down
2 changes: 1 addition & 1 deletion twilio/http/request.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from twilio.compat import urlencode
from urllib.parse import urlencode


class Request(object):
Expand Down
2 changes: 1 addition & 1 deletion twilio/http/validation_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from requests import Request, Session

from twilio.base.exceptions import TwilioRestException
from twilio.compat import urlparse
from urllib.parse import urlparse
from twilio.http import HttpClient
from twilio.http.response import Response
from twilio.jwt.validation import ClientValidationJwt
Expand Down
9 changes: 2 additions & 7 deletions twilio/jwt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import hmac
import sys

from twilio.jwt import compat

if sys.version_info[0] == 3 and sys.version_info[1] == 2:
# PyJWT expects hmac.compare_digest to exist even under python 3.2
hmac.compare_digest = compat.compare_digest

import jwt as jwt_lib

try:
Expand Down Expand Up @@ -140,7 +134,8 @@ def from_jwt(cls, jwt, key=''):
verify = True if key else False

try:
payload = jwt_lib.decode(bytes(jwt), key, options={
alg = jwt_lib.get_unverified_header(jwt).get("alg", "HS256")
payload = jwt_lib.decode(jwt, key, algorithms=[alg], options={
karls marked this conversation as resolved.
Show resolved Hide resolved
'verify_signature': verify,
'verify_exp': True,
'verify_nbf': True,
Expand Down
5 changes: 2 additions & 3 deletions twilio/jwt/client/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from twilio.jwt import Jwt

from six import iteritems
from twilio.compat import urlencode
from urllib.parse import urlencode


class ClientCapabilityToken(Jwt):
Expand Down Expand Up @@ -94,7 +93,7 @@ def add_param(self, key, value):

def to_payload(self):
if self.params:
sorted_params = sorted([(k, v) for k, v in iteritems(self.params)])
sorted_params = sorted([(k, v) for k, v in self.params.items()])
encoded_params = urlencode(sorted_params)
param_string = '?{}'.format(encoded_params)
else:
Expand Down
25 changes: 0 additions & 25 deletions twilio/jwt/compat.py

This file was deleted.

3 changes: 1 addition & 2 deletions twilio/jwt/validation/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from hashlib import sha256
from six import string_types

from twilio.jwt import Jwt

Expand Down Expand Up @@ -73,7 +72,7 @@ def _generate_payload(self):

@classmethod
def _sort_and_join(cls, values, joiner):
if isinstance(values, string_types):
if isinstance(values, str):
return values
return joiner.join(sorted(values))

Expand Down
Loading