Skip to content

Commit 2ded277

Browse files
committed
Removing dependency of six
Adding missing arguments to api call Use cryptography lower bound as low as 0.6 Add test cases for _str2bytes() Choose cryptography upper bound as <4
1 parent 88e9b22 commit 2ded277

File tree

3 files changed

+30
-40
lines changed

3 files changed

+30
-40
lines changed

msal/application.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import functools
22
import json
33
import time
4-
5-
import six
6-
from cryptography.hazmat.backends import default_backend
7-
from cryptography.hazmat.primitives import serialization
8-
94
try: # Python 2
105
from urlparse import urljoin
116
except: # Python 3
@@ -95,6 +90,14 @@ def _merge_claims_challenge_and_capabilities(capabilities, claims_challenge):
9590
return json.dumps(claims_dict)
9691

9792

93+
def _str2bytes(raw):
94+
# A conversion based on duck-typing rather than six.text_type
95+
try:
96+
return raw.encode(encoding="utf-8")
97+
except:
98+
return raw
99+
100+
98101
class ClientApplication(object):
99102

100103
ACQUIRE_TOKEN_SILENT_ID = "84"
@@ -261,16 +264,13 @@ def _build_client(self, client_credential, authority):
261264
if not client_credential.get("passphrase"):
262265
unencrypted_private_key = client_credential['private_key']
263266
else:
264-
if isinstance(client_credential['private_key'], six.text_type):
265-
private_key = client_credential['private_key'].encode(encoding="utf-8")
266-
else:
267-
private_key = client_credential['private_key']
268-
if isinstance(client_credential['passphrase'], six.text_type):
269-
password = client_credential['passphrase'].encode(encoding="utf-8")
270-
else:
271-
password = client_credential['passphrase']
267+
from cryptography.hazmat.primitives import serialization
268+
from cryptography.hazmat.backends import default_backend
272269
unencrypted_private_key = serialization.load_pem_private_key(
273-
private_key, password=password, backend=default_backend())
270+
_str2bytes(client_credential["private_key"]),
271+
_str2bytes(client_credential["passphrase"]),
272+
backend=default_backend(), # It was a required param until 2020
273+
)
274274
assertion = JwtAssertionCreator(
275275
unencrypted_private_key, algorithm="RS256",
276276
sha1_thumbprint=client_credential.get("thumbprint"), headers=headers)

setup.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,16 @@
7474
install_requires=[
7575
'requests>=2.0.0,<3',
7676
'PyJWT[crypto]>=1.0.0,<2',
77-
'six>=1.6',
78-
'cryptography>=2.1.4'
77+
78+
'cryptography>=0.6,<4',
79+
# load_pem_private_key() is available since 0.6
80+
# https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst#06---2014-09-29
81+
#
82+
# Not sure what should be used as an upper bound here
83+
# https://github.com/pyca/cryptography/issues/5532
84+
# We will go with "<4" for now, which is also what our another dependency,
85+
# pyjwt, currently use.
86+
7987
]
8088
)
8189

tests/test_application.py

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Note: Since Aug 2019 we move all e2e tests into test_e2e.py,
22
# so this test_application file contains only unit tests without dependency.
33
from msal.application import *
4+
from msal.application import _str2bytes
45
import msal
56
from msal.application import _merge_claims_challenge_and_capabilities
67
from tests import unittest
@@ -39,31 +40,12 @@ def test_extract_multiple_tag_enclosed_certs(self):
3940
self.assertEqual(["my_cert1", "my_cert2"], extract_certs(pem))
4041

4142

42-
class TestEncryptedKeyAsClientCredential(unittest.TestCase):
43-
# Internally, we use serialization.load_pem_private_key() to load an encrypted private key with a passphrase
44-
# This function takes in encrypted key in bytes and passphrase in bytes too
45-
# Our code handles such a conversion, adding test cases to verify such a conversion is needed
43+
class TestBytesConversion(unittest.TestCase):
44+
def test_string_to_bytes(self):
45+
self.assertEqual(type(_str2bytes("some string")), type(b"bytes"))
4646

47-
def test_encyrpted_key_in_bytes_and_string_password_should_error(self):
48-
private_key = b"""
49-
-----BEGIN ENCRYPTED PRIVATE KEY-----
50-
test_private_key
51-
-----END ENCRYPTED PRIVATE KEY-----
52-
"""
53-
with self.assertRaises(TypeError):
54-
# Using a unicode string for Python 2 to identify it as a string and not default to bytes
55-
serialization.load_pem_private_key(
56-
private_key, password=u"string_password", backend=default_backend())
57-
58-
def test_encyrpted_key_is_string_and_bytes_password_should_error(self):
59-
private_key = u"""
60-
-----BEGIN ENCRYPTED PRIVATE KEY-----
61-
test_private_key
62-
-----END ENCRYPTED PRIVATE KEY-----
63-
"""
64-
with self.assertRaises(TypeError):
65-
serialization.load_pem_private_key(
66-
private_key, password=b"byte_password", backend=default_backend())
47+
def test_bytes_to_bytes(self):
48+
self.assertEqual(type(_str2bytes(b"some bytes")), type(b"bytes"))
6749

6850

6951
class TestClientApplicationAcquireTokenSilentErrorBehaviors(unittest.TestCase):

0 commit comments

Comments
 (0)