Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-edgegrid-python for openSUSE:Factory checked in at 2024-01-09 20:49:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-edgegrid-python (Old) and /work/SRC/openSUSE:Factory/.python-edgegrid-python.new.21961 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-edgegrid-python" Tue Jan 9 20:49:42 2024 rev:3 rq:1137638 version:1.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-edgegrid-python/python-edgegrid-python.changes 2021-12-12 21:28:10.992361932 +0100 +++ /work/SRC/openSUSE:Factory/.python-edgegrid-python.new.21961/python-edgegrid-python.changes 2024-01-09 20:50:16.905590963 +0100 @@ -1,0 +2,10 @@ +Mon Jan 8 20:56:05 UTC 2024 - Dirk Müller <dmuel...@suse.com> + +- update to 1.3.1: + * GH#51 issue: include path params in signed path +- update to 1.3.0: + * decouple from `requests` library + * add support for MultipartEncoder + * remove unnecessary shebangs and permissions + +------------------------------------------------------------------- Old: ---- edgegrid-python-1.2.1.tar.gz New: ---- edgegrid-python-1.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-edgegrid-python.spec ++++++ --- /var/tmp/diff_new_pack.TUlAYs/_old 2024-01-09 20:50:17.369607833 +0100 +++ /var/tmp/diff_new_pack.TUlAYs/_new 2024-01-09 20:50:17.369607833 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-edgegrid-python # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2024 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -16,9 +16,8 @@ # -%{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-edgegrid-python -Version: 1.2.1 +Version: 1.3.1 Release: 0 Summary: Client authentication protocol for python-requests License: Apache-2.0 @@ -26,13 +25,16 @@ URL: https://github.com/akamai-open/AkamaiOPEN-edgegrid-python Source: https://files.pythonhosted.org/packages/source/e/edgegrid-python/edgegrid-python-%{version}.tar.gz BuildRequires: %{python_module devel} +BuildRequires: %{python_module pip} BuildRequires: %{python_module setuptools} +BuildRequires: %{python_module wheel} BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-ndg-httpsclient Requires: python-pyOpenSSL >= 19.0.0 Requires: python-pyasn1 Requires: python-requests >= 2.3.0 +Requires: python-requests-toolbelt Requires: python-urllib3 BuildArch: noarch @@ -45,14 +47,17 @@ %setup -q -n edgegrid-python-%{version} %build -%python_build +%pyproject_wheel %install -%python_install +%pyproject_install %python_expand %fdupes %{buildroot}%{$python_sitelib} %files %{python_files} -%doc README.rst +%doc README.md %license LICENSE -%{python_sitelib}/* +%dir %{python_sitelib}/akamai +%{python_sitelib}/akamai/edgegrid +%{python_sitelib}/edgegrid_python-%{version}*.pth +%{python_sitelib}/edgegrid_python-%{version}.dist-info ++++++ edgegrid-python-1.2.1.tar.gz -> edgegrid-python-1.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/PKG-INFO new/edgegrid-python-1.3.1/PKG-INFO --- old/edgegrid-python-1.2.1/PKG-INFO 2021-10-11 09:39:22.888507000 +0200 +++ new/edgegrid-python-1.3.1/PKG-INFO 2022-09-22 11:50:47.786121400 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: edgegrid-python -Version: 1.2.1 +Version: 1.3.1 Summary: {OPEN} client authentication protocol for python-requests Home-page: https://github.com/akamai/AkamaiOPEN-edgegrid-python Author: Jonathan Landis @@ -8,12 +8,8 @@ Maintainer: Akamai Developer Experience team Maintainer-email: dl-devexp-...@akamai.com License: Apache 2.0 -Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Requires-Python: >=2.7.10 License-File: LICENSE - -UNKNOWN - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/README.md new/edgegrid-python-1.3.1/README.md --- old/edgegrid-python-1.2.1/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/edgegrid-python-1.3.1/README.md 2022-09-08 12:49:34.000000000 +0200 @@ -0,0 +1,148 @@ +# EdgeGrid for Python + +This library implements an authentication handler for HTTP [requests](https://requests.readthedocs.io/en/latest/) using the [EdgeGrid authentication](https://techdocs.akamai.com/developer/docs/authenticate-with-edgegrid) scheme. + +## Prerequisites +Before you begin, you need to [Create authentication credentials](https://techdocs.akamai.com/developer/docs/set-up-authentication-credentials) in [Control Center](https://control.akamai.com/). + +Download the Python release compatible with your operating system at [https://www.python.org/downloads/](https://www.python.org/downloads/). + +> Python 2 is no longer supported by the [Python Software Foundation](https://www.python.org/doc/sunset-python-2/). + However, if you're still using it, you can follow the [Python 2 steps](#python-2-steps). + +## Install + +1. Install Python. + ``` + python setup.py install + ``` + +1. Install the developer libraries for Python, SSL and FFI. + ``` + sudo apt-get install ibssl-dev libffi-dev python-dev + ``` + +1. Install the `edgegrid-python` authentication handler. + ``` + pip install edgegrid-python + ``` + +## Make an API call + +To use Akamai APIs, you need the values for the tokens from your [.edgerc file](https://techdocs.akamai.com/developer/docs/set-up-authentication-credentials#add-credential-to-edgerc-file). + +```pycon +>>> import requests +>>> from akamai.edgegrid import EdgeGridAuth +>>> from urllib.parse import urljoin +>>> baseurl = 'https://akaa-WWWWWWWWWWWW.luna.akamaiapis.net/' +>>> s = requests.Session() +>>> s.auth = EdgeGridAuth( + client_token='ccccccccccccccccc', + client_secret='ssssssssssssssssss', + access_token='aaaaaaaaaaaaaaaaaaaaa' +) + +>>> result = s.get(urljoin(baseurl, '/diagnostic-tools/v2/ghost-locations/available')) +>>> result.status_code +200 +>>> result.json()['locations'][0]['value'] +Oakbrook, IL, United States +... +``` + +This is an example of an API call to [List available edge server locations](https://techdocs.akamai.com/diagnostic-tools/reference/ghost-locationsavailable). Change the `baseurl` element to reference an endpoint in any of the [Akamai APIs](https://techdocs.akamai.com/home/page/products-tools-a-z?sort=api). + +Alternatively, your program can read the credential values directly from the `.edgerc`. + +```pycon +>>> import requests +>>> from akamai.edgegrid import EdgeGridAuth, EdgeRc +>>> from urllib.parse import urljoin + +>>> edgerc = EdgeRc('~/.edgerc') +>>> section = 'default' +>>> baseurl = 'https://%s' % edgerc.get(section, 'host') + +>>> s = requests.Session() +>>> s.auth = EdgeGridAuth.from_edgerc(edgerc, section) + +>>> result = s.get(urljoin(baseurl, '/diagnostic-tools/v2/ghost-locations/available')) +>>> result.status_code +200 +>>> result.json()['locations'][0]['value'] +Oakbrook, IL, United States +... +``` + +> NOTE: If your `.edgerc` file contains more than one credential set, use the `section` argument to specify which section contains the credentials for your API request. + +## Virtual environment + +To test in a [virtual environment](https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments), run: + +``` +$ python3 -m venv venv +$ . venv/bin/activate +$ pip install -r requirements.txt +$ python -m unittest discover +``` + +### Python 2 steps + +Python 2.7 is no longer supported by the [Python Software Foundation](https://www.python.org/doc/sunset-python-2/), but we recognize that some developers continue to use it. If you're using Python 2.7 with EdgeGrid, follow these steps. + +1. To upgrade the cryptography package, first run: + ``` + pip install --upgrade 'cryptography<3.4' + ``` + +1. To continue with the installation, run: + ``` + pip install edgegrid-python + ``` + + or install from sources: + ``` + python setup.py install + ``` + +1. To test, run: + ``` + $ virtualenv -p python2.7 venv + $ . venv/bin/activate + $ pip install 'cryptography<3.4' # just necessary for Python 2.7 + $ pip install -r requirements.txt + $ python -m unittest discover + ``` + +> If you intend to run the examples with Python 2.7, remember that `urljoin` is contained in a different package. + ``` + from urlparse import urljoin + ``` + +## Contribute + +1. Fork the [repository](https://github.com/akamai-open/AkamaiOPEN-edgegrid-python) to modify the **master** branch. +2. Write a test that demonstrates that the bug was fixed or the feature works as expected. +3. Send a pull request and nudge the maintainer until it gets merged and published. :) + +## Author + +Jonathan Landis + +## License + +> Copyright 2022 Akamai Technologies, Inc. All rights reserved. +> +> Licensed under the Apache License, Version 2.0 (the \"License\"); you +> may not use this file except in compliance with the License. You may +> obtain a copy of the License at +> +> > <http://www.apache.org/licenses/LICENSE-2.0> +> +> Unless required by applicable law or agreed to in writing, software +> distributed under the License is distributed on an \"AS IS\" BASIS, +> WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +> implied. See the License for the specific language governing +> permissions and limitations under the License. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/README.rst new/edgegrid-python-1.3.1/README.rst --- old/edgegrid-python-1.2.1/README.rst 2021-10-11 09:27:16.000000000 +0200 +++ new/edgegrid-python-1.3.1/README.rst 1970-01-01 01:00:00.000000000 +0100 @@ -1,151 +0,0 @@ -EdgeGrid for Python -=================== - -This library implements an Authentication handler for `requests`_ -that provides the `Akamai {OPEN} Edgegrid Authentication`_ scheme. For more information -visit the `Akamai {OPEN} Developer Community`_. - -.. code-block:: pycon - - >>> import requests - >>> from akamai.edgegrid import EdgeGridAuth - >>> from urllib.parse import urljoin - >>> baseurl = 'https://akaa-WWWWWWWWWWWW.luna.akamaiapis.net/' - >>> s = requests.Session() - >>> s.auth = EdgeGridAuth( - client_token='ccccccccccccccccc', - client_secret='ssssssssssssssssss', - access_token='aaaaaaaaaaaaaaaaaaaaa' - ) - - >>> result = s.get(urljoin(baseurl, '/diagnostic-tools/v2/ghost-locations/available')) - >>> result.status_code - 200 - >>> result.json()['locations'][0]['value'] - Oakbrook, IL, United States - ... - -Alternatively, your program can read the credentials from an .edgerc file. - -.. code-block:: pycon - - >>> import requests - >>> from akamai.edgegrid import EdgeGridAuth, EdgeRc - >>> from urllib.parse import urljoin - - >>> edgerc = EdgeRc('~/.edgerc') - >>> section = 'default' - >>> baseurl = 'https://%s' % edgerc.get(section, 'host') - - >>> s = requests.Session() - >>> s.auth = EdgeGridAuth.from_edgerc(edgerc, section) - - >>> result = s.get(urljoin(baseurl, '/diagnostic-tools/v2/ghost-locations/available')) - >>> result.status_code - 200 - >>> result.json()['locations'][0]['value'] - Oakbrook, IL, United States - ... - -If you intend to run the above examples with Python 2.7, remember that urljoin is contained in a different package: - -.. code-block:: pycon - - >>> from urlparse import urljoin - -.. _`requests`: http://docs.python-requests.org -.. _`Akamai {OPEN} Edgegrid authentication`: https://developer.akamai.com/introduction/Client_Auth.html -.. _`Akamai {OPEN} Developer Community`: https://developer.akamai.com - -Installation ------------- - -**Prerequisite** - -For Linux-based distribution, install the developer libraries for Python, SSL and FFI. For example, on Debian-based systems, run: - -.. code-block:: bash - - $ sudo apt-get install ibssl-dev libffi-dev python-dev - -**To install from pip** - -We recommend using any recent Python 3 distribution. Starting from version 3.4 of the cryptography package, Python 2.7 is no longer supported. - -If you still want to use Python 2.7, first run: - -.. code-block:: bash - - $ pip install --upgrade 'cryptography<3.4' - -To continue with the installation: - -.. code-block:: bash - - $ pip install edgegrid-python - -**To install from sources** - -.. code-block:: bash - - $ python setup.py install - -**To run tests** - -Both Python 2 and Python 3 are supported. This example uses Python 2.7. Run: - -.. code-block:: bash - - $ virtualenv -p python2.7 venv - $ . venv/bin/activate - $ pip install 'cryptography<3.4' # just necessary for Python 2.7 - $ pip install -r requirements.txt - $ python -m unittest discover - -For Python 3.3 or newer, replace the `virtualenv` module with `venv`. Run: - -.. code-block:: bash - - $ python3 -m venv venv - $ . venv/bin/activate - $ pip install -r requirements.txt - $ python -m unittest discover - -Creating your own .edgerc ----------- - -#. Copy the `akamai/edgegrid/test/sample_edgerc` file to your home directory and rename as `.edgerc`. -#. Edit the copied file and provide your own credentials. For more information on creating an `.edgerc` file, see `Get started with APIs`_. - -.. _`Get started with APIs`: https://developer.akamai.com/api/getting-started#edgercfile - -Contribute ----------- - -#. Fork `the repository`_ to start making your changes to the **master** branch -#. Write a test which shows that the bug was fixed or that the feature works as expected. -#. Send a pull request and bug the maintainer until it gets merged and published. :) - -.. _`the repository`: https://github.com/akamai-open/AkamaiOPEN-edgegrid-python - -Author ------- - -Jonathan Landis - -License -------- - - Copyright 2021 Akamai Technologies, Inc. All rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/akamai/edgegrid/__init__.py new/edgegrid-python-1.3.1/akamai/edgegrid/__init__.py --- old/edgegrid-python-1.2.1/akamai/edgegrid/__init__.py 2021-10-11 09:27:16.000000000 +0200 +++ new/edgegrid-python-1.3.1/akamai/edgegrid/__init__.py 2022-09-22 11:39:50.000000000 +0200 @@ -35,7 +35,7 @@ __all__ = ['EdgeGridAuth', 'EdgeRc'] __title__ = 'edgegrid-python' -__version__ = '1.2.1' +__version__ = '1.3.1' __author__ = 'Jonathan Landis <jlan...@akamai.com>' __maintainer__ = 'Akamai Developer Experience team <dl-devexp-...@akamai.com>' __license__ = 'Apache 2.0' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/akamai/edgegrid/edgegrid.py new/edgegrid-python-1.3.1/akamai/edgegrid/edgegrid.py --- old/edgegrid-python-1.2.1/akamai/edgegrid/edgegrid.py 2021-06-24 16:17:32.000000000 +0200 +++ new/edgegrid-python-1.3.1/akamai/edgegrid/edgegrid.py 2022-09-22 11:39:50.000000000 +0200 @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # EdgeGrid requests Auth handler # # Original author: Jonathan Landis <jlan...@akamai.com> @@ -63,10 +61,26 @@ ).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): @@ -85,7 +99,7 @@ """ def __init__(self, client_token, client_secret, access_token, - headers_to_sign=None, max_body=131072): + headers_to_sign=(), max_body=131072): """Initialize authentication using the given parameters from the Akamai OPEN APIs Interface: @@ -98,21 +112,19 @@ specific APIs. (default 131072) """ - self.client_token = client_token - self.client_secret = client_secret - self.access_token = access_token - if headers_to_sign: - self.headers_to_sign = [h.lower() for h in headers_to_sign] - else: - self.headers_to_sign = [] - self.max_body = max_body - - self.redirect_location = None + self.ah = EdgeGridAuthHeaders( + client_token, + client_secret, + access_token, + headers_to_sign, + max_body + ) @staticmethod def from_edgerc(rcinput, section='default'): - """Returns an EdgeGridAuth object from the configuration from the given section of the - given edgerc file. + """ + Returns an EdgeGridAuth object from the configuration from the given section + of the given edgerc file. :param rcinput: EdgeRc instance or path to the edgerc file :param section: the section to use (this is the [bracketed] part of the edgerc, @@ -133,37 +145,83 @@ max_body=rc.getint(section, 'max_body') ) + def handle_redirect(self, res, **kwargs): + if res.is_redirect: + redirect_location = res.headers['location'] + + logger.debug("signing the redirected url: %s", redirect_location) + request_to_sign = res.request.copy() + request_to_sign.url = redirect_location + + res.request.headers['Authorization'] = self.ah.make_auth_header( + request_to_sign.url, + request_to_sign.headers, + request_to_sign.method, + request_to_sign.body, + eg_timestamp(), + new_nonce() + ) + + def __call__(self, r): + timestamp = eg_timestamp() + nonce = new_nonce() + + r.headers['Authorization'] = self.ah.make_auth_header( + r.url, + r.headers, + r.method, + r.body, + timestamp, + nonce + ) + r.register_hook('response', self.handle_redirect) + return r + + +class EdgeGridAuthHeaders(): + + def __init__(self, client_token, client_secret, access_token, + headers_to_sign=(), max_body=131072): + self.client_token = client_token + self.client_secret = client_secret + self.access_token = access_token + self.headers_to_sign = [h.lower() for h in headers_to_sign] + self.max_body = max_body + def make_signing_key(self, timestamp): signing_key = base64_hmac_sha256(timestamp, self.client_secret) logger.debug('signing key: %s', signing_key) return signing_key - def canonicalize_headers(self, r): + def canonicalize_headers(self, headers): spaces_re = re.compile('\\s+') # note: r.headers is a case-insensitive dict and self.headers_to_sign # should already be lowercased at this point return '\t'.join([ - "%s:%s" % (h, spaces_re.sub(' ', r.headers[h].strip())) - for h in self.headers_to_sign if h in r.headers + "%s:%s" % (h, spaces_re.sub(' ', headers[h].strip())) + for h in self.headers_to_sign if h in headers ]) - def make_content_hash(self, r): + def make_content_hash(self, body, method): content_hash = "" - prepared_body = (r.body or '') + prepared_body = body logger.debug("body is '%s'", prepared_body) - if r.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) @@ -194,38 +252,37 @@ return header - def make_data_to_sign(self, r, auth_header): - parsed_url = urlparse(r.url) + def make_data_to_sign(self, url, headers, auth_header, method, body): + parsed_url = urlparse(url) - if r.headers.get('Host', False): - netloc = r.headers['Host'] + if headers.get('Host', False): + netloc = headers['Host'] else: netloc = parsed_url.netloc - self.get_header_versions(r.headers) + self.get_header_versions(headers) data_to_sign = '\t'.join([ - r.method, + method, parsed_url.scheme, netloc, - # Note: relative URL constraints are handled by requests when it - # sets up 'r' - parsed_url.path + \ + # Note: relative URL constraints are handled by requests when it sets up 'r' + parsed_url.path + (';' + parsed_url.params if parsed_url.params else "") + ('?' + parsed_url.query if parsed_url.query else ""), - self.canonicalize_headers(r), - self.make_content_hash(r), + self.canonicalize_headers(headers), + self.make_content_hash(body or '', method), auth_header ]) logger.debug('data to sign: %s', '\\t'.join(data_to_sign.split('\t'))) return data_to_sign - def sign_request(self, r, timestamp, auth_header): + def sign_request(self, url, headers, method, body, timestamp, auth_header): return base64_hmac_sha256( - self.make_data_to_sign(r, auth_header), + self.make_data_to_sign(url, headers, auth_header, method, body), self.make_signing_key(timestamp) ) - def make_auth_header(self, r, timestamp, nonce): + def make_auth_header(self, url, headers, method, body, timestamp, nonce): kvps = [ ('client_token', self.client_token), ('access_token', self.access_token), @@ -237,27 +294,7 @@ logger.debug('unsigned authorization header: %s', auth_header) signed_auth_header = auth_header + \ - 'signature=' + self.sign_request(r, timestamp, auth_header) + 'signature=' + self.sign_request(url, headers, method, body, timestamp, auth_header) logger.debug('signed authorization header: %s', signed_auth_header) return signed_auth_header - - def handle_redirect(self, res, **kwargs): - if res.is_redirect: - redirect_location = res.headers['location'] - - logger.debug("signing the redirected url: %s", redirect_location) - request_to_sign = res.request.copy() - request_to_sign.url = redirect_location - - res.request.headers['Authorization'] = self.make_auth_header( - request_to_sign, eg_timestamp(), new_nonce() - ) - - def __call__(self, r): - timestamp = eg_timestamp() - nonce = new_nonce() - - r.headers['Authorization'] = self.make_auth_header(r, timestamp, nonce) - r.register_hook('response', self.handle_redirect) - return r diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/akamai/edgegrid/edgerc.py new/edgegrid-python-1.3.1/akamai/edgegrid/edgerc.py --- old/edgegrid-python-1.2.1/akamai/edgegrid/edgerc.py 2021-06-24 16:17:32.000000000 +0200 +++ new/edgegrid-python-1.3.1/akamai/edgegrid/edgerc.py 2022-08-24 16:44:24.000000000 +0200 @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # support for .edgerc file format # # Copyright 2021 Akamai Technologies, Inc. All Rights Reserved diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/akamai/edgegrid/test/test_edgegrid.py new/edgegrid-python-1.3.1/akamai/edgegrid/test/test_edgegrid.py --- old/edgegrid-python-1.2.1/akamai/edgegrid/test/test_edgegrid.py 2021-06-24 16:17:32.000000000 +0200 +++ new/edgegrid-python-1.3.1/akamai/edgegrid/test/test_edgegrid.py 2022-09-22 11:39:50.000000000 +0200 @@ -27,6 +27,7 @@ import os import re import requests +import requests_toolbelt import sys import unittest @@ -45,6 +46,35 @@ expected_client_secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=' +class EdgeGridAuthHeadersTest(unittest.TestCase): + def __init__(self, testdata=None, testcase=None): + super(EdgeGridAuthHeadersTest, self).__init__() + self.testdata = testdata + self.testcase = testcase + self.maxDiff = None + + def runTest(self): + self.ah = eg.EdgeGridAuthHeaders( + client_token=self.testdata['client_token'], + client_secret=self.testdata['client_secret'], + access_token=self.testdata['access_token'], + headers_to_sign=self.testdata['headers_to_sign'], + max_body=self.testdata['max_body'] + ) + + sign_key = self.ah.make_signing_key(self.testdata['timestamp']) + self.assertEqual(sign_key, self.testdata["sign_key_test"]) + + content_hash = self.ah.make_content_hash( + body="test_body", + method="POST" + ) + self.assertEqual(content_hash, self.testdata["content_hash_test"]) + + header = self.ah.get_header_versions() + self.assertEqual(header, {}) + + class EdgeGridTest(unittest.TestCase): def __init__(self, testdata=None, testcase=None): super(EdgeGridTest, self).__init__() @@ -78,9 +108,11 @@ ) try: - auth_header = auth.make_auth_header( - request.prepare( - ), self.testdata['timestamp'], self.testdata['nonce'] + r = request.prepare() + data_to_sign = auth.ah.make_data_to_sign(r.url, r.headers, "", r.method, r.body) + auth_header = auth.ah.make_auth_header( + r.url, r.headers, r.method, r.body, self.testdata['timestamp'], + self.testdata['nonce'] ) except Exception as e: logger.debug('Got exception from make_auth_header', exc_info=True) @@ -88,6 +120,7 @@ return self.assertEqual(auth_header, self.testcase['expectedAuthorization']) + self.assertEqual(data_to_sign, self.testcase['expectedDataToSign']) class EGSimpleTest(unittest.TestCase): @@ -123,34 +156,34 @@ auth = EdgeGridAuth( client_token='xxx', client_secret='xxx', access_token='xxx' ) - self.assertEqual(auth.max_body, 131072) - self.assertEqual(auth.headers_to_sign, []) + self.assertEqual(auth.ah.max_body, 131072) + self.assertEqual(auth.ah.headers_to_sign, []) def test_edgerc_default(self): auth = EdgeGridAuth.from_edgerc(os.path.join(mydir, 'sample_edgerc')) self.assertEqual( - auth.client_token, + auth.ah.client_token, 'xxxx-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx') self.assertEqual( - auth.client_secret, + auth.ah.client_secret, expected_client_secret) self.assertEqual( - auth.access_token, + auth.ah.access_token, 'xxxx-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx') - self.assertEqual(auth.max_body, 131072) - self.assertEqual(auth.headers_to_sign, ['none']) + self.assertEqual(auth.ah.max_body, 131072) + self.assertEqual(auth.ah.headers_to_sign, ['none']) def test_edgerc_broken(self): auth = EdgeGridAuth.from_edgerc( os.path.join(mydir, 'sample_edgerc'), 'broken') self.assertEqual( - auth.client_secret, + auth.ah.client_secret, expected_client_secret) self.assertEqual( - auth.access_token, + auth.ah.access_token, 'xxxx-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx') - self.assertEqual(auth.max_body, 128 * 1024) - self.assertEqual(auth.headers_to_sign, ['none']) + self.assertEqual(auth.ah.max_body, 128 * 1024) + self.assertEqual(auth.ah.headers_to_sign, ['none']) def test_edgerc_unparseable(self): # noinspection PyBroadException @@ -164,15 +197,15 @@ def test_edgerc_headers(self): auth = EdgeGridAuth.from_edgerc( os.path.join(mydir, 'sample_edgerc'), 'headers') - self.assertEqual(auth.headers_to_sign, ['x-mything1', 'x-mything2']) + self.assertEqual(auth.ah.headers_to_sign, ['x-mything1', 'x-mything2']) def test_get_header_versions(self): auth = EdgeGridAuth.from_edgerc( os.path.join(mydir, 'sample_edgerc'), 'headers') - header = auth.get_header_versions() + header = auth.ah.get_header_versions() self.assertFalse('user-agent' in header) - header = auth.get_header_versions({'User-Agent': 'testvalue'}) + header = auth.ah.get_header_versions({'User-Agent': 'testvalue'}) self.assertTrue('User-Agent' in header) # setting environment variables with hardcoded `1.0.0` value, just for this test. @@ -180,23 +213,23 @@ os.environ["AKAMAI_CLI"] = '1.0.0' os.environ["AKAMAI_CLI_VERSION"] = '1.0.0' - header = auth.get_header_versions() + header = auth.ah.get_header_versions() self.assertTrue('User-Agent' in header) self.assertEqual(header['User-Agent'], 'AkamaiCLI/1.0.0') - header = auth.get_header_versions({'User-Agent': 'test-agent'}) + header = auth.ah.get_header_versions({'User-Agent': 'test-agent'}) self.assertTrue('User-Agent' in header) self.assertEqual(header['User-Agent'], 'test-agent AkamaiCLI/1.0.0') os.environ["AKAMAI_CLI_COMMAND"] = '1.0.0' os.environ["AKAMAI_CLI_COMMAND_VERSION"] = '1.0.0' - header = auth.get_header_versions() + header = auth.ah.get_header_versions() self.assertTrue('User-Agent' in header) self.assertEqual(header['User-Agent'], 'AkamaiCLI/1.0.0 AkamaiCLI-1.0.0/1.0.0') - header = auth.get_header_versions({'User-Agent': 'testvalue'}) + header = auth.ah.get_header_versions({'User-Agent': 'testvalue'}) self.assertTrue('User-Agent' in header) self.assertEqual( header['User-Agent'], @@ -216,21 +249,33 @@ auth = EdgeGridAuth.from_edgerc( EdgeRc(os.path.join(mydir, 'sample_edgerc'))) self.assertEqual( - auth.client_token, + auth.ah.client_token, 'xxxx-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx') self.assertEqual( - auth.client_secret, + auth.ah.client_secret, expected_client_secret) self.assertEqual( - auth.access_token, + auth.ah.access_token, 'xxxx-xxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxx') - self.assertEqual(auth.max_body, 131072) - self.assertEqual(auth.headers_to_sign, ['none']) + self.assertEqual(auth.ah.max_body, 131072) + self.assertEqual(auth.ah.headers_to_sign, ['none']) def test_edgerc_dashes(self): auth = EdgeGridAuth.from_edgerc( os.path.join(mydir, 'sample_edgerc'), 'dashes') - self.assertEqual(auth.max_body, 128 * 1024) + 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): @@ -262,14 +307,61 @@ json=data, ) - auth_header = auth.make_auth_header( - request.prepare( - ), self.testdata['timestamp'], self.testdata['nonce'] + r = request.prepare() + auth_header = auth.ah.make_auth_header( + r.url, r.headers, r.method, r.body, self.testdata['timestamp'], + self.testdata['nonce'] ) 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: @@ -280,9 +372,21 @@ for test in tests: suite.addTest(EdgeGridTest(testdata, test)) + suite.addTest(EdgeGridAuthHeadersTest(testdata, test)) 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')) @@ -292,6 +396,7 @@ 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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/akamai/edgegrid/test/testdata.json new/edgegrid-python-1.3.1/akamai/edgegrid/test/testdata.json --- old/edgegrid-python-1.2.1/akamai/edgegrid/test/testdata.json 2021-04-29 13:45:45.000000000 +0200 +++ new/edgegrid-python-1.3.1/akamai/edgegrid/test/testdata.json 2022-09-22 11:39:50.000000000 +0200 @@ -8,6 +8,9 @@ "nonce": "nonce-xx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "timestamp": "20140321T19:34:21+0000", "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", @@ -18,7 +21,8 @@ {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} ] }, - "expectedAuthorization": "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=tL+y4hxyHxgWVD30X3pWnGKHcPzmrIF+LThiAOhMxYU=" + "expectedAuthorization": "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=tL+y4hxyHxgWVD30X3pWnGKHcPzmrIF+LThiAOhMxYU=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/\t\t\t" }, { "testName": "GET with querystring", @@ -29,7 +33,8 @@ {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} ] }, - "expectedAuthorization": "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=hKDH1UlnQySSHjvIcZpDMbQHihTQ0XyVAKZaApabdeA=" + "expectedAuthorization": "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=hKDH1UlnQySSHjvIcZpDMbQHihTQ0XyVAKZaApabdeA=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t1?p1=1&p2=2\t\t\t" }, { "testName": "POST inside limit", @@ -41,7 +46,8 @@ {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} ] }, - "expectedAuthorization": "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=hXm4iCxtpN22m4cbZb4lVLW5rhX8Ca82vCFqXzSTPe4=" + "expectedAuthorization": "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=hXm4iCxtpN22m4cbZb4lVLW5rhX8Ca82vCFqXzSTPe4=", + "expectedDataToSign": "POST\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t3\t\tfDimoYqXOLntG3If/Z0K2aS9I19Pkv9P5OMCoL8lY0w=\t" }, { "testName": "POST too large", @@ -53,7 +59,8 @@ {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} ] }, - "expectedAuthorization": "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=6Q6PiTipLae6n4GsSIDTCJ54bEbHUBp+4MUXrbQCBoY=" + "expectedAuthorization": "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=6Q6PiTipLae6n4GsSIDTCJ54bEbHUBp+4MUXrbQCBoY=", + "expectedDataToSign": "POST\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t3\t\tiysZKJ78BqF0NvDrpv9Hc3pJBWC5f5apR4qUK/Qfo5k=\t" }, { "testName": "POST length equals max_body", @@ -65,7 +72,8 @@ {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} ] }, - "expectedAuthorization": "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=6Q6PiTipLae6n4GsSIDTCJ54bEbHUBp+4MUXrbQCBoY=" + "expectedAuthorization": "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=6Q6PiTipLae6n4GsSIDTCJ54bEbHUBp+4MUXrbQCBoY=", + "expectedDataToSign": "POST\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t3\t\tiysZKJ78BqF0NvDrpv9Hc3pJBWC5f5apR4qUK/Qfo5k=\t" }, { "testName": "POST empty body", @@ -77,7 +85,8 @@ {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} ] }, - "expectedAuthorization": "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=1gEDxeQGD5GovIkJJGcBaKnZ+VaPtrc4qBUHixjsPCQ=" + "expectedAuthorization": "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=1gEDxeQGD5GovIkJJGcBaKnZ+VaPtrc4qBUHixjsPCQ=", + "expectedDataToSign": "POST\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t6\t\t\t" }, { "testName": "Simple header signing with GET", @@ -89,7 +98,8 @@ {"X-Test1": "test-simple-header"} ] }, - "expectedAuthorization": "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=8F9AybcRw+PLxnvT+H0JRkjROrrUgsxJTnRXMzqvcwY=" + "expectedAuthorization": "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=8F9AybcRw+PLxnvT+H0JRkjROrrUgsxJTnRXMzqvcwY=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t4\tx-test1:test-simple-header\t\t" }, { "testName": "Header containing spaces", @@ -101,7 +111,8 @@ {"X-Test1": "\" test-header-with-spaces \""} ] }, - "expectedAuthorization": "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=ucq2AbjCNtobHfCTuS38fdkl5UDdWHZhQX46fYR8CqI=" + "expectedAuthorization": "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=ucq2AbjCNtobHfCTuS38fdkl5UDdWHZhQX46fYR8CqI=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t4\tx-test1:\" test-header-with-spaces \"\t\t" }, { "testName": "Header with leading and interior spaces", @@ -113,7 +124,7 @@ {"X-Test1": " first-thing second-thing"} ] }, - "failsWithMessage": "Invalid return character or leading space in header: X-Test1", + "failsWithMessage": "Invalid leading whitespace, reserved character(s), or returncharacter(s) in header value: ' first-thing second-thing'", "expectedAuthorization": "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=WtnneL539UadAAOJwnsXvPqT4Kt6z7HMgBEwAFpt3+c=" }, { @@ -128,7 +139,8 @@ {"X-Test3": "t3"} ] }, - "expectedAuthorization": "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=Wus73Nx8jOYM+kkBFF2q8D1EATRIMr0WLWwpLBgkBqY=" + "expectedAuthorization": "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=Wus73Nx8jOYM+kkBFF2q8D1EATRIMr0WLWwpLBgkBqY=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t4\tx-test1:t1\tx-test2:t2\tx-test3:t3\t\t" }, { "testName": "Extra header", @@ -143,7 +155,8 @@ {"X-Extra": "this won't be included"} ] }, - "expectedAuthorization": "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=Knd/jc0A5Ghhizjayr0AUUvl2MZjBpS3FDSzvtq4Ixc=" + "expectedAuthorization": "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=Knd/jc0A5Ghhizjayr0AUUvl2MZjBpS3FDSzvtq4Ixc=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t5\tx-test1:t1\tx-test2:t2\tx-test3:t3\t\t" }, { "testName": "PUT test", @@ -152,7 +165,33 @@ "path": "/testapi/v1/t6", "data": "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP" }, - "expectedAuthorization": "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=GNBWEYSEWOLtu+7dD52da2C39aX/Jchpon3K/AmBqBU=" + "expectedAuthorization": "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=GNBWEYSEWOLtu+7dD52da2C39aX/Jchpon3K/AmBqBU=", + "expectedDataToSign": "PUT\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/t6\t\t\t" + }, + { + "testName": "GET with query params", + "request": { + "method": "GET", + "path": "/testapi/v1/configs/111?from=12345&limit=200000", + "headers": [ + {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} + ] + }, + "expectedAuthorization": "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=XM+hsuSs6nuy/5eDRty1IjtVCAdr8xPFRAZ/b8RXDm8=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/configs/111?from=12345&limit=200000\t\t\t" + }, + { + "_comment": "signature must be different here than in 'GET with query params' test", + "testName": "GET with query params and separator in path", + "request": { + "method": "GET", + "path": "/testapi/v1/configs/111;222;333?from=12345&limit=200000", + "headers": [ + {"Host": "akaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net"} + ] + }, + "expectedAuthorization": "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=pmQF7Is2+O4r/mMojPR4yeF58BrempNNoBX5/DT0Fxs=", + "expectedDataToSign": "GET\thttps\takaa-baseurl-xxxxxxxxxxx-xxxxxxxxxxxxx.luna.akamaiapis.net\t/testapi/v1/configs/111;222;333?from=12345&limit=200000\t\t\t" } ] } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/edgegrid_python.egg-info/PKG-INFO new/edgegrid-python-1.3.1/edgegrid_python.egg-info/PKG-INFO --- old/edgegrid-python-1.2.1/edgegrid_python.egg-info/PKG-INFO 2021-10-11 09:39:22.000000000 +0200 +++ new/edgegrid-python-1.3.1/edgegrid_python.egg-info/PKG-INFO 2022-09-22 11:50:47.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: edgegrid-python -Version: 1.2.1 +Version: 1.3.1 Summary: {OPEN} client authentication protocol for python-requests Home-page: https://github.com/akamai/AkamaiOPEN-edgegrid-python Author: Jonathan Landis @@ -8,12 +8,8 @@ Maintainer: Akamai Developer Experience team Maintainer-email: dl-devexp-...@akamai.com License: Apache 2.0 -Platform: UNKNOWN Classifier: License :: OSI Approved :: Apache Software License Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Requires-Python: >=2.7.10 License-File: LICENSE - -UNKNOWN - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/edgegrid_python.egg-info/SOURCES.txt new/edgegrid-python-1.3.1/edgegrid_python.egg-info/SOURCES.txt --- old/edgegrid-python-1.2.1/edgegrid_python.egg-info/SOURCES.txt 2021-10-11 09:39:22.000000000 +0200 +++ new/edgegrid-python-1.3.1/edgegrid_python.egg-info/SOURCES.txt 2022-09-22 11:50:47.000000000 +0200 @@ -1,6 +1,6 @@ LICENSE MANIFEST.in -README.rst +README.md requirements.txt setup.py akamai/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/edgegrid_python.egg-info/requires.txt new/edgegrid-python-1.3.1/edgegrid_python.egg-info/requires.txt --- old/edgegrid-python-1.2.1/edgegrid_python.egg-info/requires.txt 2021-10-11 09:39:22.000000000 +0200 +++ new/edgegrid-python-1.3.1/edgegrid_python.egg-info/requires.txt 2022-09-22 11:50:47.000000000 +0200 @@ -1,4 +1,5 @@ requests>=2.3.0 +requests_toolbelt>=0.9.0 pyOpenSSL>=19.0.0 ndg-httpsclient pyasn1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/requirements.txt new/edgegrid-python-1.3.1/requirements.txt --- old/edgegrid-python-1.2.1/requirements.txt 2021-06-24 16:17:32.000000000 +0200 +++ new/edgegrid-python-1.3.1/requirements.txt 2022-09-08 12:49:34.000000000 +0200 @@ -1,4 +1,5 @@ requests>=2.3.0 +requests_toolbelt>=0.9.0 pyopenssl>=19.0.0 ndg-httpsclient pyasn1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/edgegrid-python-1.2.1/setup.py new/edgegrid-python-1.3.1/setup.py --- old/edgegrid-python-1.2.1/setup.py 2021-10-11 09:27:16.000000000 +0200 +++ new/edgegrid-python-1.3.1/setup.py 2022-09-22 11:39:50.000000000 +0200 @@ -1,7 +1,7 @@ from setuptools import setup, find_packages setup( name='edgegrid-python', - version='1.2.1', + version='1.3.1', description='{OPEN} client authentication protocol for python-requests', author='Jonathan Landis', author_email='jlan...@akamai.com', @@ -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',