def calc_signature(self, request, params): logger.debug("Calculating signature using v2 auth.") split = urlsplit(request.url) path = split.path if len(path) == 0: path = '/' string_to_sign = '%s\n%s\n%s\n' % (request.method, split.netloc, path) lhmac = hmac.new(self.credentials.secret_key.encode('utf-8'), digestmod=sha256) pairs = [] for key in sorted(params): # Any previous signature should not be a part of this # one, so we skip that particular key. This prevents # issues during retries. if key == 'Signature': continue value = six.text_type(params[key]) quoted_key = quote(key.encode('utf-8'), safe='') quoted_value = quote(value.encode('utf-8'), safe='-_~') pairs.append(f'{quoted_key}={quoted_value}') qs = '&'.join(pairs) string_to_sign += qs logger.debug('String to sign: %s', string_to_sign) lhmac.update(string_to_sign.encode('utf-8')) b64 = base64.b64encode(lhmac.digest()).strip().decode('utf-8') return (qs, b64)
def _canonical_query_string_params(self, params): l = [] for param in sorted(params): value = str(params[param]) l.append('%s=%s' % (quote(param, safe='-_.~'), quote(value, safe='-_.~'))) cqs = '&'.join(l) return cqs
def _canonical_query_string_params(self, params): # [(key, value), (key2, value2)] key_val_pairs = [] for key in params: value = str(params[key]) key_val_pairs.append( (quote(key, safe='-_.~'), quote(value, safe='-_.~'))) sorted_key_vals = [] # Sort by the URI-encoded key names, and in the case of # repeated keys, then sort by the value. for key, value in sorted(key_val_pairs): sorted_key_vals.append('%s=%s' % (key, value)) canonical_query_string = '&'.join(sorted_key_vals) return canonical_query_string
def add_recursion_detection_header(params, **kwargs): has_lambda_name = 'AWS_LAMBDA_FUNCTION_NAME' in os.environ trace_id = os.environ.get('_X_AMZ_TRACE_ID') if has_lambda_name and trace_id: headers = params['headers'] if 'X-Amzn-Trace-Id' not in headers: headers['X-Amzn-Trace-Id'] = quote(trace_id)
def percent_encode(input_str, safe=SAFE_CHARS): """Urlencodes a string. Whereas percent_encode_sequence handles taking a dict/sequence and producing a percent encoded string, this function deals only with taking a string (not a dict/sequence) and percent encoding it. """ if not isinstance(input_str, string_types): input_str = text_type(input_str) return quote(text_type(input_str).encode('utf-8'), safe=safe)
def percent_encode(input_str, safe=SAFE_CHARS): """Urlencodes a string. Whereas percent_encode_sequence handles taking a dict/sequence and producing a percent encoded string, this function deals only with taking a string (not a dict/sequence) and percent encoding it. If given the binary type, will simply URL encode it. If given the text type, will produce the binary type by UTF-8 encoding the text. If given something else, will convert it to the text type first. """ # If its not a binary or text string, make it a text string. if not isinstance(input_str, (six.binary_type, six.text_type)): input_str = six.text_type(input_str) # If it's not bytes, make it bytes by UTF-8 encoding it. if not isinstance(input_str, six.binary_type): input_str = input_str.encode('utf-8') return quote(input_str, safe=safe)
def test_cant_decode_quoted_jsondoc(self): value = quote('{"foo": "missing end quote}') converted_value = handlers.decode_quoted_jsondoc(value) self.assertEqual(converted_value, value)
def test_decode_quoted_jsondoc(self): value = quote('{"foo":"bar"}') converted_value = handlers.decode_quoted_jsondoc(value) self.assertEqual(converted_value, {'foo': 'bar'})
def _normalize_url_path(self, path): normalized_path = quote(normalize_url_path(path), safe='/~') return normalized_path