33# EdgeGrid requests Auth handler
44#
55# Original author: Jonathan Landis <[email protected] > 6+ # Package maintainer: Akamai Developer Experience team <[email protected] > 67#
78# For more information visit https://developer.akamai.com
89
9- # Copyright 2014 Akamai Technologies, Inc. All Rights Reserved
10- #
10+ # Copyright 2021 Akamai Technologies, Inc. All Rights Reserved
11+ #
1112# Licensed under the Apache License, Version 2.0 (the "License");
1213# you may not use this file except in compliance with the License.
1314# You may obtain a copy of the License at
2021# See the License for the specific language governing permissions and
2122# limitations under the License.
2223
23- import requests
2424import logging
2525import uuid
2626import hashlib
3434
3535if sys .version_info [0 ] >= 3 :
3636 # python3
37- from urllib .parse import urlparse , parse_qsl , urlunparse
37+ from urllib .parse import urlparse
3838else :
3939 # python2.7
40- from urlparse import urlparse , parse_qsl , urlunparse
40+ from urlparse import urlparse
4141 import urllib3 .contrib .pyopenssl
4242 urllib3 .contrib .pyopenssl .inject_into_urllib3 ()
4343
4444logger = logging .getLogger (__name__ )
4545
46- __all__ = ['EdgeGridAuth' ]
46+ __all__ = ['EdgeGridAuth' ]
47+
4748
4849def eg_timestamp ():
4950 return strftime ('%Y%m%dT%H:%M:%S+0000' , gmtime ())
5051
52+
5153def new_nonce ():
5254 return uuid .uuid4 ()
5355
56+
5457def base64_hmac_sha256 (data , key ):
5558 return base64 .b64encode (
56- hmac .new (key .encode ('utf8' ), data .encode ('utf8' ), hashlib .sha256 ).digest ()
59+ hmac .new (
60+ key .encode ('utf8' ),
61+ data .encode ('utf8' ),
62+ hashlib .sha256 ).digest ()
5763 ).decode ('utf8' )
5864
65+
5966def base64_sha256 (data ):
6067 if isinstance (data , str ):
6168 data = data .encode ('utf8' )
6269 return base64 .b64encode (hashlib .sha256 (data ).digest ()).decode ('utf8' )
6370
71+
6472class EdgeGridAuth (AuthBase ):
6573 """A Requests authentication handler that provides Akamai {OPEN} EdgeGrid support.
6674
@@ -76,15 +84,15 @@ class EdgeGridAuth(AuthBase):
7684
7785 """
7886
79- def __init__ (self , client_token , client_secret , access_token ,
87+ def __init__ (self , client_token , client_secret , access_token ,
8088 headers_to_sign = None , max_body = 131072 ):
81- """Initialize authentication using the given parameters from the Luna Manage APIs
89+ """Initialize authentication using the given parameters from the Akamai OPEN APIs
8290 Interface:
8391
8492 :param client_token: Client token provided by "Credentials" ui
8593 :param client_secret: Client secret provided by "Credentials" ui
8694 :param access_token: Access token provided by "Authorizations" ui
87- :param headers_to_sign: An ordered list header names that will be included in
95+ :param headers_to_sign: An ordered list header names that will be included in
8896 the signature. This will be provided by specific APIs. (default [])
8997 :param max_body: Maximum content body size for POST requests. This will be provided by
9098 specific APIs. (default 131072)
@@ -94,7 +102,7 @@ def __init__(self, client_token, client_secret, access_token,
94102 self .client_secret = client_secret
95103 self .access_token = access_token
96104 if headers_to_sign :
97- self .headers_to_sign = [ h .lower () for h in headers_to_sign ]
105+ self .headers_to_sign = [h .lower () for h in headers_to_sign ]
98106 else :
99107 self .headers_to_sign = []
100108 self .max_body = max_body
@@ -103,15 +111,15 @@ def __init__(self, client_token, client_secret, access_token,
103111
104112 @staticmethod
105113 def from_edgerc (rcinput , section = 'default' ):
106- """Returns an EdgeGridAuth object from the configuration from the given section of the
114+ """Returns an EdgeGridAuth object from the configuration from the given section of the
107115 given edgerc file.
108116
109- :param filename: path to the edgerc file
110- :param section: the section to use (this is the [bracketed] part of the edgerc,
117+ :param rcinput: EdgeRc instance or path to the edgerc file
118+ :param section: the section to use (this is the [bracketed] part of the edgerc,
111119 default is 'default')
112120
113121 """
114- from .edgerc import EdgeRc
122+ from .edgerc import EdgeRc
115123 if isinstance (rcinput , EdgeRc ):
116124 rc = rcinput
117125 else :
@@ -149,11 +157,13 @@ def make_content_hash(self, r):
149157 logger .debug ("signing content: %s" , prepared_body )
150158 if len (prepared_body ) > self .max_body :
151159 logger .debug (
152- "data length %d is larger than maximum %d" ,
160+ "data length %d is larger than maximum %d" ,
153161 len (prepared_body ), self .max_body
154162 )
155163 prepared_body = prepared_body [0 :self .max_body ]
156- logger .debug ("data truncated to %d for computing the hash" , len (prepared_body ))
164+ logger .debug (
165+ "data truncated to %d for computing the hash" ,
166+ len (prepared_body ))
157167
158168 content_hash = base64_sha256 (prepared_body )
159169
@@ -173,7 +183,8 @@ def get_header_versions(self, header=None):
173183 akamai_cli_command = os .getenv ('AKAMAI_CLI_COMMAND' )
174184 akamai_cli_command_version = os .getenv ('AKAMAI_CLI_COMMAND_VERSION' )
175185 if akamai_cli_command and akamai_cli_command_version :
176- version_header += " AkamaiCLI-" + akamai_cli_command + "/" + akamai_cli_command_version
186+ version_header += " AkamaiCLI-" + akamai_cli_command + \
187+ "/" + akamai_cli_command_version
177188
178189 if version_header != '' :
179190 if 'User-Agent' not in header :
@@ -186,7 +197,7 @@ def get_header_versions(self, header=None):
186197 def make_data_to_sign (self , r , auth_header ):
187198 parsed_url = urlparse (r .url )
188199
189- if ( r .headers .get ('Host' , False ) ):
200+ if r .headers .get ('Host' , False ):
190201 netloc = r .headers ['Host' ]
191202 else :
192203 netloc = parsed_url .netloc
@@ -197,8 +208,10 @@ def make_data_to_sign(self, r, auth_header):
197208 r .method ,
198209 parsed_url .scheme ,
199210 netloc ,
200- # Note: relative URL constraints are handled by requests when it sets up 'r'
201- parsed_url .path + ('?' + parsed_url .query if parsed_url .query else "" ),
211+ # Note: relative URL constraints are handled by requests when it
212+ # sets up 'r'
213+ parsed_url .path + \
214+ ('?' + parsed_url .query if parsed_url .query else "" ),
202215 self .canonicalize_headers (r ),
203216 self .make_content_hash (r ),
204217 auth_header
@@ -208,7 +221,7 @@ def make_data_to_sign(self, r, auth_header):
208221
209222 def sign_request (self , r , timestamp , auth_header ):
210223 return base64_hmac_sha256 (
211- self .make_data_to_sign (r , auth_header ),
224+ self .make_data_to_sign (r , auth_header ),
212225 self .make_signing_key (timestamp )
213226 )
214227
@@ -219,7 +232,8 @@ def make_auth_header(self, r, timestamp, nonce):
219232 ('timestamp' , timestamp ),
220233 ('nonce' , nonce ),
221234 ]
222- auth_header = "EG1-HMAC-SHA256 " + ';' .join ([ "%s=%s" % kvp for kvp in kvps ]) + ';'
235+ auth_header = "EG1-HMAC-SHA256 " + \
236+ ';' .join (["%s=%s" % kvp for kvp in kvps ]) + ';'
223237 logger .debug ('unsigned authorization header: %s' , auth_header )
224238
225239 signed_auth_header = auth_header + \
0 commit comments