Skip to content

Commit 94f49b8

Browse files
committed
MAPI-81 Fix for incorrect content-md5 header
+ Basic auth manager test + updated dependencies
1 parent a54f7d3 commit 94f49b8

10 files changed

+105
-217
lines changed

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
*.pyc
2-
index.py
2+
index.py
3+
build
4+
dist
5+
.idea
6+
*egg-info

message_media_messages/configuration.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
This file was automatically generated for MessageMedia by APIMATIC v2.0 ( https://apimatic.io ).
77
"""
88

9-
from message_media_messages.api_helper import APIHelper
10-
import os
11-
129

1310
class Configuration(object):
1411
"""A class used for configuring the SDK by a user.
@@ -35,10 +32,9 @@ class Configuration(object):
3532

3633
# The username to use with HMAC authentication
3734
# TODO: Set an appropriate value
38-
hmac_auth_user_name = 'FxJMSlsivOoHAjDbWcO7'
39-
#os.environ.get('AUTH_USERNAME')
35+
hmac_auth_user_name = 'TODO: Replace'
4036

4137
# The password to use with HMAC authentication
4238
# TODO: Set an appropriate value
43-
hmac_auth_password = 'HbR3jfA1b0J3AHVmPajTWuGGaDIsk4'
44-
#os.environ.get('PASSWORD')
39+
hmac_auth_password = 'TODO: Replace'
40+

requirements.txt

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
requests==2.20.0
2-
jsonpickle==0.7.1
3-
cachecontrol==0.11.7
4-
python-dateutil==2.5.3
1+
requests==2.28.2
2+
jsonpickle==3.0.1
3+
cachecontrol==0.12.11
4+
python-dateutil==2.8.2
55
responses~=0.22.0
6-
urllib3~=1.24.3
7-
setuptools~=65.5.1
6+
urllib3~=1.26.14
7+
setuptools==67.2.0

setup.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
setup(
1010
name='messagemedia-messages-sdk',
11-
version='2.1.0',
11+
version='2.1.1',
1212
description='The MessageMedia Messages API provides a number of endpoints for building powerful two-way messaging applications.',
1313
long_description_content_type="text/markdown",
1414
long_description=long_description,
@@ -17,9 +17,12 @@
1717
url='https://developers.messagemedia.com',
1818
packages=find_packages(),
1919
install_requires=[
20-
'requests>=2.9.1, <3.0',
21-
'jsonpickle>=0.7.1, <1.0',
22-
'cachecontrol>=0.11.7, <1.0',
23-
'python-dateutil>=2.5.3, <3.0'
20+
'requests>=2.28.2, <3.0',
21+
'jsonpickle>=3.0.1, <4.0',
22+
'cachecontrol>=0.12.11, <1.0',
23+
'python-dateutil>=2.8.2, <3.0',
24+
'responses>=0.22.0, <1.0',
25+
'urllib3>=1.26.14, <2.0',
26+
'setuptools>=67.2.0, <68'
2427
]
2528
)

test-requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
nose==1.3.7
1+
nose==1.3.7
2+
freezegun==1.2.2

tests/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
__all__ = [
2+
'auth_manager_test',
3+
'test_util'
4+
]

tests/auth_manager_test.py

+75-99
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,103 @@
11
# -*- coding: utf-8 -*-
22

3-
"""
4-
message_media_messages
5-
6-
This file was automatically generated for MessageMedia by APIMATIC v2.0 ( https://apimatic.io ).
7-
"""
8-
93
import hashlib
104
import unittest
11-
from datetime import datetime
12-
from time import mktime
13-
from wsgiref.handlers import format_date_time
145

15-
from tests.test_configuration import TestConfiguration
16-
from tests.test_util import TestUtility
17-
from message_media_messages.http.auth.auth_manager import AuthManager
18-
from message_media_messages.configuration import Configuration
6+
from freezegun import freeze_time
7+
198
from message_media_messages.api_helper import APIHelper
20-
from message_media_messages.models.send_messages_request import SendMessagesRequest
21-
from message_media_messages.models.message import Message
9+
from message_media_messages.configuration import Configuration
10+
from message_media_messages.http.auth.auth_manager import AuthManager
11+
from message_media_messages.http.requests_client import RequestsClient
2212
from message_media_messages.models.format_enum import FormatEnum
23-
import urllib3
24-
25-
26-
class AuthManagerTests(unittest.TestCase):
27-
28-
body = SendMessagesRequest()
29-
body.messages = []
30-
body.messages.append(Message())
31-
body.messages[0].content = 'My tests message'
32-
body.messages[0].destination_number = '{}'.format(TestConfiguration.request_dest_number)
33-
body.messages[0].format = FormatEnum.SMS
34-
35-
_url_path = '/v1/messages'
36-
_query_builder = Configuration.base_uri
37-
_query_builder += _url_path
38-
_query_url = APIHelper.clean_url(_query_builder)
13+
from message_media_messages.models.message import Message
14+
from message_media_messages.models.send_messages_request import SendMessagesRequest
15+
from tests.test_util import TestUtil
3916

40-
_headers = {
41-
'accept': 'application/json',
42-
'Content-Type': 'application/json; charset=utf-8',
43-
}
4417

45-
m = hashlib.md5()
46-
m.update(bytes(APIHelper.json_serialize(body), 'utf-8'))
47-
content_hash = m.hexdigest()
18+
class AuthManagerTest(unittest.TestCase):
4819

49-
now = datetime.now()
50-
stamp = mktime(now.timetuple())
51-
date_header = format_date_time(stamp)
20+
def __init__(self, method_name: str = ...):
21+
super().__init__(method_name)
22+
self.content_hash = None
23+
self.query_url = None
24+
self.send_message_request = None
5225

53-
content_signature = "x-Content-MD5: {}\n".format(content_hash)
54-
get_content_signature = ""
26+
def setUp(self):
27+
self.send_message_request = self.get_send_message_request()
28+
self.query_url = APIHelper.clean_url(Configuration.base_uri + '/v1/messages')
29+
self.content_hash = self.get_content_hash(self.send_message_request)
30+
self.content_md5_header = "x-Content-MD5: {}\n".format(self.content_hash)
31+
self.date_header = 'Wed, 08 Feb 2023 03:00:00 GMT'
32+
self.expected_algorithm = ' algorithm="hmac-sha1"'
33+
Configuration.hmac_auth_user_name = "some_user_name"
34+
self.expected_username = "hmac username=\"" + Configuration.hmac_auth_user_name + "\""
5535

36+
@freeze_time("2023-02-08 14:00:00")
5637
def test_post_request_hmac_authorization_header_values_are_appropriate(self):
57-
date_header, expected_algorithm, expected_username, http, query_url, request_header = self.header_setup()
58-
body = APIHelper.json_serialize(self.body)
59-
content_signature = self.content_signature
60-
expected_header = ' headers="date x-Content-MD5 request-line"'
61-
expected_signature = TestUtility.create_signature(date_header, content_signature, query_url, 'POST', True)
62-
63-
_request = http.request(
64-
'POST',
65-
query_url,
66-
body=body,
67-
headers=request_header
38+
body = APIHelper.json_serialize(self.send_message_request)
39+
40+
request = RequestsClient().post(
41+
query_url=self.query_url,
42+
parameters=body,
43+
headers={}
6844
)
6945

70-
AuthManager.apply_hmac_auth(_request, query_url, body)
71-
username, algorithm, header, signature = _request.getheader('Authorization').split(',')
46+
AuthManager.apply_hmac_auth(request, self.query_url, body)
7247

73-
self.assert_cases(algorithm, expected_algorithm, expected_header, expected_signature, expected_username,
74-
header, signature, username)
48+
expected_headers_property = ' headers="date x-Content-MD5 request-line"'
49+
expected_signature = TestUtil.create_signature(self.date_header, self.content_md5_header,
50+
self.query_url, 'POST', True)
51+
self.assert_auth_header(request, expected_headers_property, expected_signature)
7552

76-
def test_post_request_content_md5_is_equivalent_to_md5_hash_of_request_body(self):
77-
http = urllib3.PoolManager()
78-
body = APIHelper.json_serialize(self.body)
79-
md5 = self.content_hash
80-
query_url = self._query_url
81-
request_header = self._headers
53+
def test_post_request_content_md5_is_md5_of_request_body(self):
54+
body = APIHelper.json_serialize(self.send_message_request)
8255

83-
_request = http.request(
84-
'POST',
85-
query_url,
86-
body=body,
87-
headers=request_header
56+
request = RequestsClient().post(
57+
query_url=self.query_url,
58+
parameters=body,
59+
headers={}
8860
)
8961

90-
AuthManager.apply_hmac_auth(_request, query_url, body)
91-
requestMD5 = _request.getheader('x-Content-MD5')
92-
assert md5 == requestMD5
62+
AuthManager.apply_hmac_auth(request, self.query_url, body)
63+
request_md5 = request.headers['x-Content-MD5']
64+
assert self.content_hash == request_md5
9365

66+
@freeze_time("2023-02-08 14:00:00")
9467
def test_get_request_hmac_authorization_header_values_are_appropriate(self):
95-
date_header, expected_algorithm, expected_username, http, query_url, request_header = self.header_setup()
96-
content_signature = ""
97-
expected_header = ' headers="date request-line"'
98-
expected_signature = TestUtility.create_signature(date_header, content_signature, query_url, 'GET', True)
99-
100-
_request = http.request(
101-
'GET',
102-
query_url,
103-
headers=request_header
68+
request = RequestsClient().get(
69+
query_url=self.query_url,
70+
headers={}
10471
)
10572

106-
AuthManager.apply_hmac_auth(_request, query_url)
107-
username, algorithm, header, signature = _request.getheader('Authorization').split(',')
73+
AuthManager.apply_hmac_auth(request, self.query_url)
10874

109-
self.assert_cases(algorithm, expected_algorithm, expected_header, expected_signature, expected_username,
110-
header, signature, username)
75+
expected_headers_property = ' headers="date request-line"'
76+
expected_signature = TestUtil.create_signature(self.date_header, "",
77+
self.query_url, 'GET', True)
78+
self.assert_auth_header(request, expected_headers_property, expected_signature)
11179

112-
def header_setup(self):
113-
http = urllib3.PoolManager()
114-
date_header = self.date_header
115-
request_header = self._headers
116-
query_url = self._query_url
117-
expected_username = 'hmac username="{}"'.format(Configuration.hmac_auth_user_name)
118-
expected_algorithm = ' algorithm="hmac-sha1"'
119-
return date_header, expected_algorithm, expected_username, http, query_url, request_header
120-
121-
def assert_cases(self, algorithm, expected_algorithm, expected_header, expected_signature, expected_username,
122-
header, signature, username):
80+
def assert_auth_header(self, request, expected_headers_property, expected_signature):
81+
username, algorithm, headers, signature = request.headers['Authorization'].split(',')
12382
with self.subTest():
124-
self.assertEqual(expected_username, username)
125-
self.assertEqual(expected_header, header)
126-
self.assertEqual(expected_algorithm, algorithm)
83+
self.assertEqual(self.expected_username, username)
84+
self.assertEqual(expected_headers_property, headers)
85+
self.assertEqual(self.expected_algorithm, algorithm)
12786
self.assertEqual(expected_signature, signature)
87+
88+
@staticmethod
89+
def get_send_message_request():
90+
send_message_request = SendMessagesRequest()
91+
send_message_request.messages = []
92+
send_message_request.messages.append(Message())
93+
send_message_request.messages[0].content = 'My tests message'
94+
send_message_request.messages[0].destination_number = '+61491570006'
95+
send_message_request.messages[0].format = FormatEnum.SMS
96+
return send_message_request
97+
98+
@staticmethod
99+
def get_content_hash(request):
100+
m = hashlib.md5()
101+
m.update(bytes(APIHelper.json_serialize(request), 'utf-8'))
102+
content_hash = m.hexdigest()
103+
return content_hash

tests/messages_controller_test.py

-55
This file was deleted.

tests/test_configuration.py

-23
This file was deleted.

0 commit comments

Comments
 (0)