def _create_request_object(self, operation, params): user_agent = self.session.user_agent() params['headers']['User-Agent'] = user_agent uri = self.build_uri(operation, params) uri = urljoin(self.host, uri) payload = None if params['payload']: payload = params['payload'].getvalue() if payload is None: request = AWSRequest(method=operation.http['method'], url=uri, headers=params['headers']) else: request = AWSRequest(method=operation.http['method'], url=uri, headers=params['headers'], data=payload) return request
def setUp(self): self.credentials = botocore.credentials.Credentials(access_key='foo', secret_key='bar', token='baz') self.auth = botocore.auth.S3SigV4Auth(self.credentials, 'ec2', 'eu-central-1') self.request = AWSRequest(data=six.BytesIO(b"foo bar baz")) self.request.method = 'PUT' self.request.url = 'https://s3.eu-central-1.amazonaws.com/'
def test_operation_params_before_auth_params(self): # The spec is picky about this. request = AWSRequest() request.method = 'GET' request.url = 'https://ec2.us-east-1.amazonaws.com/?Action=MyOperation' self.auth.add_auth(request) # Verify auth params come after the existing params. self.assertIn( '?Action=MyOperation&X-Amz', request.url)
def _create_request_object(self, operation, params): params['Action'] = operation.name params['Version'] = self.service.api_version user_agent = self.session.user_agent() request = AWSRequest(method='POST', url=self.host, data=params, headers={'User-Agent': user_agent}) return request
def test_operation_params_before_auth_params_in_body(self): request = AWSRequest() request.method = 'GET' request.url = 'https://ec2.us-east-1.amazonaws.com/' request.data = {'Action': 'MyOperation'} self.auth.add_auth(request) # Same situation, the params from request.data come before the auth # params in the query string. self.assertIn('?Action=MyOperation&X-Amz', request.url)
def setUp(self): super(TestSigV4Resign, self).setUp() self.credentials = botocore.credentials.Credentials( access_key='foo', secret_key='bar', token='baz') self.auth = botocore.auth.SigV4Auth(self.credentials, 'ec2', 'us-west-2') self.request = AWSRequest() self.request.method = 'PUT' self.request.url = 'https://ec2.amazonaws.com/'
def test_switch_host_with_param(self): request = AWSRequest() url = 'https://machinelearning.us-east-1.amazonaws.com' new_endpoint = 'https://my-custom-endpoint.amazonaws.com' data = '{"PredictEndpoint":"%s"}' % new_endpoint request.data = data.encode('utf-8') request.url = url handlers.switch_host_with_param(request, 'PredictEndpoint') self.assertEqual(request.url, new_endpoint)
def send_to_es(self, path, method="GET", payload={}): """Low-level POST data to Amazon Elasticsearch Service generating a Sigv4 signed request Args: path (str): path to send to ES method (str, optional): HTTP method default:GET payload (dict, optional): additional payload used during POST or PUT Returns: dict: json answer converted in dict Raises: #: Error during ES communication ES_Exception: Description """ if not path.startswith("/"): path = "/" + path es_region = self.cfg["es_endpoint"].split(".")[1] headers = { "Host": self.cfg["es_endpoint"], "Content-Type": "application/json" } # send to ES with exponential backoff retries = 0 while retries < int(self.cfg["es_max_retry"]): if retries > 0: seconds = (2**retries) * .1 time.sleep(seconds) req = AWSRequest( method=method, url="https://{}{}".format( self.cfg["es_endpoint"], quote(path)), data=json.dumps(payload), params={"format": "json"}, headers=headers) credential_resolver = create_credential_resolver(get_session()) credentials = credential_resolver.load_credentials() SigV4Auth(credentials, 'es', es_region).add_auth(req) try: preq = req.prepare() session = Session() res = session.send(preq) if res.status_code >= 200 and res.status_code <= 299: return json.loads(res.content) else: raise ES_Exception(res.status_code, res._content) except ES_Exception as e: if (e.status_code >= 500) and (e.status_code <= 599): retries += 1 # Candidate for retry else: raise # Stop retrying, re-raise exception
def sign(request, *, aws_session, region, service): aws_request = AWSRequest( method=request.method.upper(), url=to_canonical_url(request.url), data=request.body, ) credentials = aws_session.get_credentials() SigV4Auth(credentials, service, region).add_auth(request) request.headers.update(**aws_request.headers.items())
def test_signature_with_date_headers(self): request = AWSRequest() request.headers = {'Date': 'Thu, 17 Nov 2005 18:49:58 GMT'} request.url = 'https://route53.amazonaws.com' self.auth.add_auth(request) self.assertEqual( request.headers['X-Amzn-Authorization'], ('AWS3-HTTPS AWSAccessKeyId=access_key,Algorithm=HmacSHA256,' 'Signature=M245fo86nVKI8rLpH4HgWs841sBTUKuwciiTpjMDgPs='))
def _sign_headers(self, method, url, headers={}): # Hijack botocore's machinery to sign the request. This is a complicated # process that involves reformatting the request data according to specific # rules, and we don't want to implement that ourselves. # This code will need to be modified if we ever need to send requests # with data. request = AWSRequest(method=method, url=url, headers=headers) S3SigV4Auth(self._credentials, "s3", self._region).add_auth(request) return dict(request.headers.items())
def test_discover_endpoint_fails(self): request = AWSRequest() request.context = {'discovery': {'identifiers': {}}} request.url = 'old.com' self.manager.describe_endpoint.return_value = None self.handler.discover_endpoint(request, 'TestOperation') self.assertEqual(request.url, 'old.com') self.manager.describe_endpoint.assert_called_with( Operation='TestOperation', Identifiers={})
def get_enabled_rules(self) -> List[Dict[str, Any]]: """Gets information for all enabled rules.""" request = AWSRequest(method='GET', url=self.url + '/enabled', params={'type': 'RULE'}) self.signer.add_auth(request) prepped_request = request.prepare() response = requests.get(prepped_request.url, headers=prepped_request.headers) response.raise_for_status() return response.json()['policies']
def test_payload_is_bytes_type(self): request = AWSRequest() request.data = u'\u2713'.encode('utf-8') request.url = 'https://amazonaws.com' auth = self.create_signer() payload = auth.payload(request) self.assertEqual( payload, '1dabba21cdad44541f6b15796f8d22978fc7ea10c46aeceeeeb66c23b3ac7604')
def test_blacklist_expect_headers(self): request = AWSRequest() request.url = 'https://s3.amazonaws.com/bucket/foo' request.method = 'PUT' request.headers['expect'] = '100-Continue' credentials = botocore.credentials.Credentials('access_key', 'secret_key') auth = botocore.auth.S3SigV4Auth(credentials, 's3', 'us-east-1') auth.add_auth(request) self.assertNotIn('expect', request.headers['Authorization'])
def test_signature_is_not_normalized(self): request = AWSRequest() request.url = 'https://s3.amazonaws.com/bucket/foo/./bar/../bar' request.method = 'GET' credentials = botocore.credentials.Credentials('access_key', 'secret_key') auth = botocore.auth.S3SigV4Auth(credentials, 's3', 'us-east-1') auth.add_auth(request) self.assertTrue( request.headers['Authorization'].startswith('AWS4-HMAC-SHA256'))
def sign_botocore(): request = AWSRequest( "POST", URL_STRING, data=json.dumps(PAYLOAD, separators=(",", ":")).encode("utf-8"), ) emitter = HierarchicalEmitter() RequestSigner( ServiceId(SERVICE_NAME), REGION, SERVICE_NAME, "v4", CREDENTIALS, emitter ).sign(ACTION, request)
def test_content_sha256_set_if_payload_signing_disabled(self): request = AWSRequest() request.data = six.BytesIO(u'\u2713'.encode('utf-8')) request.url = 'https://amazonaws.com' request.context['payload_signing_enabled'] = False request.method = 'PUT' auth = self.create_signer() auth.add_auth(request) sha_header = request.headers['X-Amz-Content-SHA256'] self.assertEqual(sha_header, 'UNSIGNED-PAYLOAD')
def post_data_to_es(payload, region, creds, host, path, method='POST', proto='https://'): '''Post data to ES endpoint with SigV4 signed http headers''' req = AWSRequest(method=method, url=proto + host + urllib.quote(path), data=payload, headers={'Host': host, 'Content-Type' : 'application/json'}) SigV4Auth(creds, 'es', region).add_auth(req) http_session = BotocoreHTTPSession() res = http_session.send(req.prepare()) if res.status_code >= 200 and res.status_code <= 299: return res._content else: raise ES_Exception(res.status_code, res._content)
def _test_blacklist_header(self, header, value): request = AWSRequest() request.url = 'https://s3.amazonaws.com/bucket/foo' request.method = 'PUT' request.headers[header] = value credentials = botocore.credentials.Credentials('access_key', 'secret_key') auth = botocore.auth.S3SigV4Auth(credentials, 's3', 'us-east-1') auth.add_auth(request) self.assertNotIn(header, request.headers['Authorization'])
def test_virtual_host_style_for_make_bucket(self): request = AWSRequest(method='PUT', headers={}, url='https://foo.amazonaws.com/bucket') region_name = 'us-west-2' signature_version = 's3' switch_to_virtual_host_style(request=request, signature_version=signature_version, region_name=region_name) self.assertEqual(request.url, 'https://bucket.foo.amazonaws.com/')
def test_presign_content_type_form_encoded_not_signed(self): request = AWSRequest() request.method = 'GET' request.url = 'https://myservice.us-east-1.amazonaws.com/' request.headers['Content-Type'] = ( 'application/x-www-form-urlencoded; charset=utf-8') self.auth.add_auth(request) query_string = self.get_parsed_query_string(request) signed_headers = query_string.get('X-Amz-SignedHeaders') self.assertNotIn('content-type', signed_headers)
def test_presign_with_security_token(self): self.credentials.token = 'security-token' auth = botocore.auth.S3SigV4QueryAuth( self.credentials, self.service_name, self.region_name, expires=60) request = AWSRequest() request.method = 'GET' request.url = 'https://ec2.us-east-1.amazonaws.com/' auth.add_auth(request) query_string = self.get_parsed_query_string(request) self.assertEqual( query_string['X-Amz-Security-Token'], 'security-token')
def get_uri(prefix, uri): try: session = URLLib3Session() r = session.send(AWSRequest('GET', uri).prepare()) if r.status_code == 200: return r.text else: raise ResourceLoadingError("received non 200 status code of %s" % (r.status_code)) except Exception as e: raise ResourceLoadingError('Unable to retrieve %s: %s' % (uri, e))
def test_throws_invalid_dns_name_error(self): request = AWSRequest( method='PUT', headers={}, url='https://foo.amazonaws.com/mybucket.foo/key.txt') region_name = 'us-west-2' signature_version = 's3' with self.assertRaises(InvalidDNSNameError): switch_to_virtual_host_style(request=request, signature_version=signature_version, region_name=region_name)
def _create_aws_request(self): signed_headers = self._get_string_between( "SignedHeaders=", ",", self._headers["Authorization"] ).split(";") headers = self._create_headers_for_aws_request(signed_headers, self._headers) request = AWSRequest( method=self._method, url=self._path, data=self._data, headers=headers ) request.context["timestamp"] = headers["X-Amz-Date"] return request
def test_fix_s3_host_initial(self): endpoint = mock.Mock(region_name='us-west-2') request = AWSRequest( method='PUT', headers={}, url='https://s3-us-west-2.amazonaws.com/bucket/key.txt') auth = mock.Mock() handlers.fix_s3_host('foo', endpoint, request, auth) self.assertEqual(request.url, 'https://bucket.s3.amazonaws.com/key.txt') self.assertEqual(request.auth_path, '/bucket/key.txt')
def __call__(self, r): url = urlparse(r.url) path = url.path or '/' qs = url.query and '?%s' % url.query or '' safe_url = url.scheme + '://' + url.netloc.split(':')[0] + path + qs request = AWSRequest( method=r.method.upper(), url=safe_url, data=r.body) SigV4Auth( self.credentials, self.service, self.region).add_auth(request) r.headers.update(dict(request.headers.items())) return r
def text(self, input_text, session_attributes=None): """Input text will be passed to your lex bot""" url = self.url + 'text' payload = json.dumps({ "inputText": input_text, "sessionAttributes": session_attributes }) request = AWSRequest(method="POST", url=url, data=payload) SigV4Auth(self.creds, 'lex', self.region).add_auth(request) return self.session.send(request.prepare()).json()
def setUp(self): self.request = AWSRequest(url='http://example.com') self.prepared_request = AWSPreparedRequest(self.request) self.har_request = HarRequest({ 'url': 'http://example.com', 'method': 'GET', 'cookies': {}, 'headers': {}, 'queryString': [], 'postData': {'mimeType': ''}, })