Skip to content

Commit

Permalink
Add support for MultipartEncoder (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
fifty-50 authored and robertolopezlopez committed Aug 25, 2022
1 parent e2052a3 commit e0b54bc
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 6 deletions.
31 changes: 25 additions & 6 deletions akamai/edgegrid/edgegrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,26 @@ def base64_hmac_sha256(data, key):
).decode('utf8')


def get_multipart_body(encoder, size=-1):
multipart_body = encoder.read(size)
encoder._buffer.seek(0)
return multipart_body


def base64_sha256(data):
if isinstance(data, str):
data = data.encode('utf8')
return base64.b64encode(hashlib.sha256(data).digest()).decode('utf8')
try:
return base64.b64encode(hashlib.sha256(data).digest()).decode('utf8')
except TypeError:
return base64.b64encode(hashlib.sha256(get_multipart_body(data)).digest()).decode('utf8')


def get_prepared_body_len(prepared_body):
try:
return len(prepared_body)
except TypeError:
return prepared_body.len


class EdgeGridAuth(AuthBase):
Expand Down Expand Up @@ -192,17 +208,20 @@ def make_content_hash(self, body, method):
prepared_body = body
logger.debug("body is '%s'", prepared_body)

if method == 'POST' and len(prepared_body) > 0:
if method == 'POST' and get_prepared_body_len(prepared_body) > 0:
logger.debug("signing content: %s", prepared_body)
if len(prepared_body) > self.max_body:
if get_prepared_body_len(prepared_body) > self.max_body:
logger.debug(
"data length %d is larger than maximum %d",
len(prepared_body), self.max_body
get_prepared_body_len(prepared_body), self.max_body
)
prepared_body = prepared_body[0:self.max_body]
try:
prepared_body = prepared_body[0:self.max_body]
except TypeError:
prepared_body = get_multipart_body(prepared_body, self.max_body)
logger.debug(
"data truncated to %d for computing the hash",
len(prepared_body))
get_prepared_body_len(prepared_body))

content_hash = base64_sha256(prepared_body)

Expand Down
1 change: 1 addition & 0 deletions akamai/edgegrid/test/sample_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this is a sample file.
71 changes: 71 additions & 0 deletions akamai/edgegrid/test/test_edgegrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import os
import re
import requests
import requests_toolbelt
import sys
import unittest

Expand Down Expand Up @@ -262,6 +263,18 @@ def test_edgerc_dashes(self):
os.path.join(mydir, 'sample_edgerc'), 'dashes')
self.assertEqual(auth.ah.max_body, 128 * 1024)

def test_get_multipart_body(self):
with open("%s/sample_file.txt" % mydir, "rb") as sample_file:
encoder = requests_toolbelt.MultipartEncoder(
fields={
"foo": "bar",
"baz": ("sample_file.txt", sample_file),
},
boundary="multipart_boundary",
)
self.assertEqual(eg.get_multipart_body(encoder, size=20), b"--multipart_boundary")
self.assertEqual(eg.get_multipart_body(encoder), encoder.to_string())


class JsonTest(unittest.TestCase):
def __init__(self, testdata=None, testcase=None):
Expand Down Expand Up @@ -301,6 +314,52 @@ def runTest(self):
self.assertEqual(auth_header, self.testdata['jsontest_hash'])


class MultipartEncoderTest(unittest.TestCase):
def __init__(self, testdata=None, multipart_fields=None):
super(MultipartEncoderTest, self).__init__()
self.testdata = testdata
self.multipart_fields = multipart_fields
self.maxDiff = None

def runTest(self):
auth = EdgeGridAuth(
client_token=self.testdata["client_token"],
client_secret=self.testdata["client_secret"],
access_token=self.testdata["access_token"],
)

params = {
"extended": "true",
}

data = requests_toolbelt.MultipartEncoder(
fields=self.multipart_fields,
boundary="multipart_boundary",
)

request = requests.Request(
method="POST",
url=urljoin(self.testdata["base_url"], "/testapi/v1/t3"),
params=params,
data=data,
)

r = request.prepare()
auth_header = auth.ah.make_auth_header(
r.url, r.headers, r.method, r.body, self.testdata["timestamp"], self.testdata["nonce"]
)

# close any open files
for part_value in self.multipart_fields.values():
f = part_value[1] if isinstance(part_value, (list, tuple)) else part_value
try:
f.close()
except AttributeError:
pass

self.assertEqual(auth_header, self.testdata["multipart_hash_test"])


def suite():
suite = unittest.TestSuite()
with open("%s/testdata.json" % mydir) as testdata:
Expand All @@ -315,6 +374,17 @@ def suite():

suite.addTest(JsonTest(testdata))

sample_file = open("%s/sample_file.txt" % mydir, "rb")
suite.addTest(
MultipartEncoderTest(
testdata,
multipart_fields={
"foo": "bar",
"baz": ("sample_file.txt", sample_file),
},
)
)

suite.addTest(EGSimpleTest('test_nonce'))
suite.addTest(EGSimpleTest('test_timestamp'))
suite.addTest(EGSimpleTest('test_defaults'))
Expand All @@ -324,6 +394,7 @@ def suite():
suite.addTest(EGSimpleTest('test_edgerc_headers'))
suite.addTest(EGSimpleTest('test_get_header_versions'))
suite.addTest(EGSimpleTest('test_edgerc_from_object'))
suite.addTest(EGSimpleTest('test_get_multipart_body'))

return suite

Expand Down
1 change: 1 addition & 0 deletions akamai/edgegrid/test/testdata.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"jsontest_hash": "EG1-HMAC-SHA256 client_token=akab-client-token-xxx-xxxxxxxxxxxxxxxx;access_token=akab-access-token-xxx-xxxxxxxxxxxxxxxx;timestamp=20140321T19:34:21+0000;nonce=nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;signature=nONuDe50qGrPius4Rg4D2jfi/2zDZWAYRUG6RudJLNM=",
"sign_key_test": "znsRMDBRqTXGJ7Ojip3/h2FGPu3LuoMYWgv9PKEnE/o=",
"content_hash_test": "REPGqEEubBHzJMhwqDZtbt515/ntEvAMNriNR53zcdY=",
"multipart_hash_test": "EG1-HMAC-SHA256 client_token=akab-client-token-xxx-xxxxxxxxxxxxxxxx;access_token=akab-access-token-xxx-xxxxxxxxxxxxxxxx;timestamp=20140321T19:34:21+0000;nonce=nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx;signature=8b5xnV0YyhRCreV0x5UEftF+EHIr2I7ebyJVNjMb7FM=",
"tests": [
{
"testName": "simple GET",
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
requests>=2.3.0
requests_toolbelt>=0.9.0
pyopenssl>=19.0.0
ndg-httpsclient
pyasn1
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
python_requires=">=2.7.10",
install_requires=[
'requests>=2.3.0',
'requests_toolbelt>=0.9.0',
'pyOpenSSL>=19.0.0',
'ndg-httpsclient',
'pyasn1',
Expand Down

0 comments on commit e0b54bc

Please sign in to comment.