def test_simple_request(self): url = urlsplit('http://localhost:9000/hello') expected_signed_headers = ['x-amz-content-sha256', 'x-amz-date'] expected_request_array = ['PUT', '/hello', '', 'x-amz-content-sha256:' + empty_hash, 'x-amz-date:dateString', '', ';'.join(expected_signed_headers), empty_hash] expected_request = '\n'.join(expected_request_array) actual_request = generate_canonical_request('PUT', url, {'X-Amz-Date': 'dateString', 'X-Amz-Content-Sha256': empty_hash}, empty_hash) eq_(expected_request, actual_request)
def test_simple_request(self): url = urlsplit('http://localhost:9000/hello') expected_signed_headers = ['x-amz-content-sha256', 'x-amz-date'] expected_request_array = ['PUT', '/hello', '', 'x-amz-content-sha256:' + empty_hash, 'x-amz-date:dateString', '', ';'.join(expected_signed_headers), empty_hash] headers_to_sign = FoldCaseDict({'X-Amz-Date': 'dateString', 'X-Amz-Content-Sha256': empty_hash}) expected_request = '\n'.join(expected_request_array) actual_request = generate_canonical_request('PUT', url, headers_to_sign, expected_signed_headers, empty_hash) eq_(expected_request, actual_request)
def test_simple_request(self): url = urlsplit("http://localhost:9000/hello") expected_signed_headers = ["x-amz-content-sha256", "x-amz-date"] expected_request_array = [ "PUT", "/hello", "", "x-amz-content-sha256:" + empty_hash, "x-amz-date:dateString", "", ";".join(expected_signed_headers), empty_hash, ] expected_request = "\n".join(expected_request_array) actual_request = generate_canonical_request( "PUT", url, {"X-Amz-Date": "dateString", "X-Amz-Content-Sha256": empty_hash}, empty_hash ) eq_(expected_request, actual_request)
def test_request_with_query(self): url = urlsplit('http://localhost:9000/hello?c=d&e=f&a=b') expected_signed_headers = ['x-amz-content-sha256', 'x-amz-date'] expected_request_array = ['PUT', '/hello', 'a=b&c=d&e=f', 'x-amz-content-sha256:' + empty_hash, 'x-amz-date:dateString', '', ';'.join(expected_signed_headers), empty_hash] expected_request = '\n'.join(expected_request_array) actual_request = generate_canonical_request('PUT', url, {'X-Amz-Date': 'dateString', ' x-Amz-Content-sha256\t': '\t' + empty_hash + ' '}, empty_hash) eq_(expected_request, actual_request)
def test_request_with_query(self): url = urlsplit('http://localhost:9000/hello?c=d&e=f&a=b') expected_signed_headers = ['x-amz-content-sha256', 'x-amz-date'] expected_request_array = ['PUT', '/hello', 'c=d&e=f&a=b', 'x-amz-content-sha256:' + empty_hash, 'x-amz-date:dateString', '', ';'.join(expected_signed_headers), empty_hash] expected_request = '\n'.join(expected_request_array) headers_to_sign = FoldCaseDict({'X-Amz-Date': 'dateString', 'X-Amz-Content-Sha256': empty_hash}) actual_request = generate_canonical_request('PUT', url, headers_to_sign, expected_signed_headers, empty_hash) eq_(expected_request, actual_request)
def sregistry_presign_v4( method, url, credentials, content_hash_hex, region=None, headers=None, expires=None, response_headers=None, ): """ Calculates signature version '4' for regular presigned URLs. :param method: Method to be presigned examples 'PUT', 'GET'. :param url: URL to be presigned. :param credentials: Credentials object with your AWS s3 account info. :param region: region of the bucket, it is optional. :param headers: any additional HTTP request headers to be presigned, it is optional. :param expires: final expiration of the generated URL. Maximum is 7days. :param response_headers: Specify additional query string parameters. :param content_hash_hex: sha256sum of the object. """ # Validate input arguments. if not credentials.get().access_key or not credentials.get().secret_key: raise InvalidArgumentError("Invalid access_key and secret_key.") if region is None: region = MINIO_REGION if headers is None: headers = {} # 7 days if expires is None: expires = "604800" request_date = datetime.utcnow() parsed_url = urlsplit(url) host = remove_default_port(parsed_url) headers["Host"] = host iso8601Date = request_date.strftime("%Y%m%dT%H%M%SZ") headers_to_sign = headers # Construct queries. query = {} query["X-Amz-Algorithm"] = _SIGN_V4_ALGORITHM query["X-Amz-Credential"] = generate_credential_string( credentials.get().access_key, request_date, region) query["X-Amz-Date"] = iso8601Date query["X-Amz-Expires"] = str(expires) if credentials.get().session_token is not None: query["X-Amz-Security-Token"] = credentials.get().session_token signed_headers = get_signed_headers(headers_to_sign) query["X-Amz-SignedHeaders"] = ";".join(signed_headers) if response_headers is not None: query.update(response_headers) # URL components. url_components = [parsed_url.geturl()] if query is not None: ordered_query = collections.OrderedDict(sorted(query.items())) query_components = [] for component_key in ordered_query: single_component = [component_key] if ordered_query[component_key] is not None: single_component.append("=") single_component.append( queryencode(ordered_query[component_key])) else: single_component.append("=") query_components.append("".join(single_component)) query_string = "&".join(query_components) if query_string: url_components.append("?") url_components.append(query_string) new_url = "".join(url_components) # new url constructor block ends. new_parsed_url = urlsplit(new_url) canonical_request = generate_canonical_request(method, new_parsed_url, headers_to_sign, signed_headers, content_hash_hex) string_to_sign = generate_string_to_sign(request_date, region, canonical_request) signing_key = generate_signing_key(request_date, region, credentials.get().secret_key) signature = hmac.new(signing_key, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest() new_parsed_url = urlsplit(new_url + "&X-Amz-Signature=" + signature) return new_parsed_url.geturl()