def test_region_required_for_sigv4(self): self.signer = RequestSigner(ServiceId('service_name'), None, 'signing_name', 'v4', self.credentials, self.emitter) with self.assertRaises(NoRegionError): self.signer.sign('operation_name', self.request)
def test_presigned_url_throws_unsupported_signature_error(self): request_dict = { 'headers': {}, 'url': 'https://s3.amazonaws.com/mybucket/myobject', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } self.signer = RequestSigner(ServiceId('service_name'), 'region_name', 'signing_name', 'foo', self.credentials, self.emitter) with self.assertRaises(UnsupportedSignatureVersionError): self.signer.generate_presigned_url(request_dict, operation_name='foo')
def setUp(self): super(TestS3PostPresigner, self).setUp() self.request_signer = RequestSigner(ServiceId('service_name'), 'region_name', 'signing_name', 's3v4', self.credentials, self.emitter) self.signer = S3PostPresigner(self.request_signer) self.request_dict = { 'headers': {}, 'url': 'https://s3.amazonaws.com/mybucket', 'body': b'', 'url_path': '/', 'method': 'POST', 'context': {} } self.auth = mock.Mock() self.auth.REQUIRES_REGION = True self.add_auth = mock.Mock() self.auth.return_value.add_auth = self.add_auth self.fixed_credentials = self.credentials.get_frozen_credentials() self.datetime_patch = mock.patch('ibm_botocore.signers.datetime') self.datetime_mock = self.datetime_patch.start() self.fixed_date = datetime.datetime(2014, 3, 10, 17, 2, 55, 0) self.fixed_delta = datetime.timedelta(seconds=3600) self.datetime_mock.datetime.utcnow.return_value = self.fixed_date self.datetime_mock.timedelta.return_value = self.fixed_delta
def test_destination_region_always_changed(self): # If the user provides a destination region, we will still # override the DesinationRegion with the region_name from # the endpoint object. actual_region = 'us-west-1' operation_model = mock.Mock() operation_model.name = 'CopySnapshot' credentials = Credentials('key', 'secret') event_emitter = HierarchicalEmitter() request_signer = RequestSigner(ServiceId('ec2'), actual_region, 'ec2', 'v4', credentials, event_emitter) request_dict = {} params = { 'SourceRegion': 'us-west-2', 'DestinationRegion': 'us-east-1' } request_dict['body'] = params request_dict['url'] = 'https://ec2.us-west-1.amazonaws.com' request_dict['method'] = 'POST' request_dict['headers'] = {} request_dict['context'] = {} # The user provides us-east-1, but we will override this to # endpoint.region_name, of 'us-west-1' in this case. handlers.inject_presigned_url_ec2(request_dict, request_signer, operation_model) self.assertIn('https://ec2.us-west-2.amazonaws.com?', params['PresignedUrl']) # Always use the DestinationRegion from the endpoint, regardless of # whatever value the user provides. self.assertEqual(params['DestinationRegion'], actual_region)
def test_no_credentials_case_is_forwarded_to_signer(self): # If no credentials are given to the RequestSigner, we should # forward that fact on to the Auth class and let them handle # the error (which they already do). self.credentials = None self.signer = RequestSigner(ServiceId('service_name'), 'region_name', 'signing_name', 'v4', self.credentials, self.emitter) auth_cls = mock.Mock() with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': auth_cls}): self.signer.get_auth_instance('service_name', 'region_name', 'v4') auth_cls.assert_called_with( service_name='service_name', region_name='region_name', credentials=None, )
def setUp(self): self.credentials = Credentials('key', 'secret') self.emitter = mock.Mock() self.emitter.emit_until_response.return_value = (None, None) self.signer = RequestSigner(ServiceId('service_name'), 'region_name', 'signing_name', 'v4', self.credentials, self.emitter) self.fixed_credentials = self.credentials.get_frozen_credentials()
def get_client_args(self, service_model, region_name, is_secure, endpoint_url, verify, credentials, scoped_config, client_config, endpoint_bridge): final_args = self.compute_client_args( service_model, client_config, endpoint_bridge, region_name, endpoint_url, is_secure, scoped_config) service_name = final_args['service_name'] # noqa parameter_validation = final_args['parameter_validation'] endpoint_config = final_args['endpoint_config'] protocol = final_args['protocol'] config_kwargs = final_args['config_kwargs'] s3_config = final_args['s3_config'] partition = endpoint_config['metadata'].get('partition', None) socket_options = final_args['socket_options'] signing_region = endpoint_config['signing_region'] endpoint_region_name = endpoint_config['region_name'] event_emitter = copy.copy(self._event_emitter) signer = RequestSigner( service_model.service_id, signing_region, endpoint_config['signing_name'], endpoint_config['signature_version'], credentials, event_emitter ) config_kwargs['s3'] = s3_config new_config = Config(**config_kwargs) endpoint_creator = EndpointCreator(event_emitter) endpoint = endpoint_creator.create_endpoint( service_model, region_name=endpoint_region_name, endpoint_url=endpoint_config['endpoint_url'], verify=verify, response_parser_factory=self._response_parser_factory, max_pool_connections=new_config.max_pool_connections, proxies=new_config.proxies, timeout=(new_config.connect_timeout, new_config.read_timeout), socket_options=socket_options, client_cert=new_config.client_cert, proxies_config=new_config.proxies_config) serializer = ibm_botocore.serialize.create_serializer( protocol, parameter_validation) response_parser = ibm_botocore.parsers.create_parser(protocol) return { 'serializer': serializer, 'endpoint': endpoint, 'response_parser': response_parser, 'event_emitter': event_emitter, 'request_signer': signer, 'service_model': service_model, 'loader': self._loader, 'client_config': new_config, 'partition': partition, 'exceptions_factory': self._exceptions_factory }
def test_adds_md5_when_s3v2(self): credentials = Credentials('key', 'secret') request_signer = RequestSigner( 's3', 'us-east-1', 's3', 's3', credentials, mock.Mock()) request_dict = {'body': b'bar', 'url': 'https://s3.us-east-1.amazonaws.com', 'method': 'PUT', 'headers': {}} context = self.get_context() handlers.conditionally_calculate_md5( request_dict, request_signer=request_signer, context=context) self.assertTrue('Content-MD5' in request_dict['headers'])
def test_signer_with_refreshable_credentials_gets_credential_set(self): class FakeCredentials(Credentials): def get_frozen_credentials(self): return ReadOnlyCredentials('foo', 'bar', 'baz') self.credentials = FakeCredentials('a', 'b', 'c') self.signer = RequestSigner( 'service_name', 'region_name', 'signing_name', 'v4', self.credentials, self.emitter) auth_cls = mock.Mock() with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': auth_cls}): auth = self.signer.get_auth('service_name', 'region_name') self.assertEqual(auth, auth_cls.return_value) # Note we're called with 'foo', 'bar', 'baz', and *not* # 'a', 'b', 'c'. auth_cls.assert_called_with( credentials=ReadOnlyCredentials('foo', 'bar', 'baz'), service_name='service_name', region_name='region_name')
def test_add_md5_raises_error_when_md5_unavailable(self): credentials = Credentials('key', 'secret') request_signer = RequestSigner( 's3', 'us-east-1', 's3', 's3', credentials, mock.Mock()) request_dict = {'body': b'bar', 'url': 'https://s3.us-east-1.amazonaws.com', 'method': 'PUT', 'headers': {}} self.set_md5_available(False) with self.assertRaises(MD5UnavailableError): handlers.calculate_md5( request_dict, request_signer=request_signer)
def test_conditional_does_not_add_when_md5_unavailable(self): credentials = Credentials('key', 'secret') request_signer = RequestSigner( 's3', 'us-east-1', 's3', 's3', credentials, mock.Mock()) request_dict = {'body': b'bar', 'url': 'https://s3.us-east-1.amazonaws.com', 'method': 'PUT', 'headers': {}} context = self.get_context() self.set_md5_available(False) with mock.patch('ibm_botocore.handlers.MD5_AVAILABLE', False): handlers.conditionally_calculate_md5( request_dict, request_signer=request_signer, context=context) self.assertFalse('Content-MD5' in request_dict['headers'])
def test_dest_region_removed(self): operation_model = mock.Mock() operation_model.name = 'CopyDBSnapshot' credentials = Credentials('key', 'secret') event_emitter = HierarchicalEmitter() request_signer = RequestSigner(ServiceId('rds'), 'us-east-1', 'rds', 'v4', credentials, event_emitter) request_dict = {} params = {'SourceRegion': 'us-west-2'} request_dict['body'] = params request_dict['url'] = 'https://rds.us-east-1.amazonaws.com' request_dict['method'] = 'POST' request_dict['headers'] = {} request_dict['context'] = {} handlers.inject_presigned_url_rds(params=request_dict, request_signer=request_signer, model=operation_model) self.assertNotIn('DestinationRegion', params)
class TestSigner(BaseSignerTest): def test_region_name(self): self.assertEqual(self.signer.region_name, 'region_name') def test_signature_version(self): self.assertEqual(self.signer.signature_version, 'v4') def test_signing_name(self): self.assertEqual(self.signer.signing_name, 'signing_name') def test_region_required_for_sigv4(self): self.signer = RequestSigner(ServiceId('service_name'), None, 'signing_name', 'v4', self.credentials, self.emitter) with self.assertRaises(NoRegionError): self.signer.sign('operation_name', self.request) def test_get_auth(self): auth_cls = mock.Mock() with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': auth_cls}): auth = self.signer.get_auth('service_name', 'region_name') self.assertEqual(auth, auth_cls.return_value) auth_cls.assert_called_with(credentials=self.fixed_credentials, service_name='service_name', region_name='region_name') def test_get_auth_signature_override(self): auth_cls = mock.Mock() with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4-custom': auth_cls}): auth = self.signer.get_auth('service_name', 'region_name', signature_version='v4-custom') self.assertEqual(auth, auth_cls.return_value) auth_cls.assert_called_with(credentials=self.fixed_credentials, service_name='service_name', region_name='region_name') def test_get_auth_bad_override(self): with self.assertRaises(UnknownSignatureVersionError): self.signer.get_auth('service_name', 'region_name', signature_version='bad') def test_emits_choose_signer(self): with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': mock.Mock()}): self.signer.sign('operation_name', self.request) self.emitter.emit_until_response.assert_called_with( 'choose-signer.service_name.operation_name', signing_name='signing_name', region_name='region_name', signature_version='v4', context=mock.ANY) def test_choose_signer_override(self): auth = mock.Mock() auth.REQUIRES_REGION = False self.emitter.emit_until_response.return_value = (None, 'custom') with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'custom': auth}): self.signer.sign('operation_name', self.request) auth.assert_called_with(credentials=self.fixed_credentials) auth.return_value.add_auth.assert_called_with(self.request) def test_emits_before_sign(self): with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': mock.Mock()}): self.signer.sign('operation_name', self.request) self.emitter.emit.assert_called_with( 'before-sign.service_name.operation_name', request=self.request, signing_name='signing_name', region_name='region_name', signature_version='v4', request_signer=self.signer, operation_name='operation_name') def test_disable_signing(self): # Returning ibm_botocore.UNSIGNED from choose-signer disables signing! auth = mock.Mock() self.emitter.emit_until_response.return_value = (None, ibm_botocore.UNSIGNED) with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': auth}): self.signer.sign('operation_name', self.request) auth.assert_not_called() def test_generate_url_emits_choose_signer(self): request_dict = { 'headers': {}, 'url': 'https://foo.com', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': mock.Mock()}): self.signer.generate_presigned_url(request_dict, 'operation_name') self.emitter.emit_until_response.assert_called_with( 'choose-signer.service_name.operation_name', signing_name='signing_name', region_name='region_name', signature_version='v4-query', context=mock.ANY) def test_choose_signer_passes_context(self): self.request.context = {'foo': 'bar'} with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': mock.Mock()}): self.signer.sign('operation_name', self.request) self.emitter.emit_until_response.assert_called_with( 'choose-signer.service_name.operation_name', signing_name='signing_name', region_name='region_name', signature_version='v4', context={'foo': 'bar'}) def test_generate_url_choose_signer_override(self): request_dict = { 'headers': {}, 'url': 'https://foo.com', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } auth = mock.Mock() auth.REQUIRES_REGION = False self.emitter.emit_until_response.return_value = (None, 'custom') auth_types_map = {'custom': mock.Mock(), 'custom-query': auth} with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types_map): self.signer.generate_presigned_url(request_dict, 'operation_name') auth.assert_called_with(credentials=self.fixed_credentials, expires=3600) def test_generate_url_unsigned(self): request_dict = { 'headers': {}, 'url': 'https://foo.com', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } self.emitter.emit_until_response.return_value = (None, ibm_botocore.UNSIGNED) url = self.signer.generate_presigned_url(request_dict, 'operation_name') self.assertEqual(url, 'https://foo.com') def test_generate_presigned_url(self): auth = mock.Mock() auth.REQUIRES_REGION = True request_dict = { 'headers': {}, 'url': 'https://foo.com', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4-query': auth}): presigned_url = self.signer.generate_presigned_url( request_dict, operation_name='operation_name') auth.assert_called_with(credentials=self.fixed_credentials, region_name='region_name', service_name='signing_name', expires=3600) self.assertEqual(presigned_url, 'https://foo.com') def test_generate_presigned_url_with_region_override(self): auth = mock.Mock() auth.REQUIRES_REGION = True request_dict = { 'headers': {}, 'url': 'https://foo.com', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4-query': auth}): presigned_url = self.signer.generate_presigned_url( request_dict, operation_name='operation_name', region_name='us-west-2') auth.assert_called_with(credentials=self.fixed_credentials, region_name='us-west-2', service_name='signing_name', expires=3600) self.assertEqual(presigned_url, 'https://foo.com') def test_generate_presigned_url_with_exipres_in(self): auth = mock.Mock() auth.REQUIRES_REGION = True request_dict = { 'headers': {}, 'url': 'https://foo.com', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4-query': auth}): presigned_url = self.signer.generate_presigned_url( request_dict, operation_name='operation_name', expires_in=900) auth.assert_called_with(credentials=self.fixed_credentials, region_name='region_name', expires=900, service_name='signing_name') self.assertEqual(presigned_url, 'https://foo.com') def test_presigned_url_throws_unsupported_signature_error(self): request_dict = { 'headers': {}, 'url': 'https://s3.amazonaws.com/mybucket/myobject', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } self.signer = RequestSigner(ServiceId('service_name'), 'region_name', 'signing_name', 'foo', self.credentials, self.emitter) with self.assertRaises(UnsupportedSignatureVersionError): self.signer.generate_presigned_url(request_dict, operation_name='foo') def test_signer_with_refreshable_credentials_gets_credential_set(self): class FakeCredentials(Credentials): def get_frozen_credentials(self): return ReadOnlyCredentials('foo', 'bar', 'baz') self.credentials = FakeCredentials('a', 'b', 'c') self.signer = RequestSigner(ServiceId('service_name'), 'region_name', 'signing_name', 'v4', self.credentials, self.emitter) auth_cls = mock.Mock() with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': auth_cls}): auth = self.signer.get_auth('service_name', 'region_name') self.assertEqual(auth, auth_cls.return_value) # Note we're called with 'foo', 'bar', 'baz', and *not* # 'a', 'b', 'c'. auth_cls.assert_called_with(credentials=ReadOnlyCredentials( 'foo', 'bar', 'baz'), service_name='service_name', region_name='region_name') def test_no_credentials_case_is_forwarded_to_signer(self): # If no credentials are given to the RequestSigner, we should # forward that fact on to the Auth class and let them handle # the error (which they already do). self.credentials = None self.signer = RequestSigner(ServiceId('service_name'), 'region_name', 'signing_name', 'v4', self.credentials, self.emitter) auth_cls = mock.Mock() with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4': auth_cls}): auth = self.signer.get_auth_instance('service_name', 'region_name', 'v4') auth_cls.assert_called_with( service_name='service_name', region_name='region_name', credentials=None, ) def test_sign_with_signing_type_standard(self): auth = mock.Mock() post_auth = mock.Mock() query_auth = mock.Mock() auth_types = { 'v4-presign-post': post_auth, 'v4-query': query_auth, 'v4': auth } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request, signing_type='standard') self.assertFalse(post_auth.called) self.assertFalse(query_auth.called) auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='signing_name', region_name='region_name') def test_sign_with_signing_type_presign_url(self): auth = mock.Mock() post_auth = mock.Mock() query_auth = mock.Mock() auth_types = { 'v4-presign-post': post_auth, 'v4-query': query_auth, 'v4': auth } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request, signing_type='presign-url') self.assertFalse(post_auth.called) self.assertFalse(auth.called) query_auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='signing_name', region_name='region_name') def test_sign_with_signing_type_presign_post(self): auth = mock.Mock() post_auth = mock.Mock() query_auth = mock.Mock() auth_types = { 'v4-presign-post': post_auth, 'v4-query': query_auth, 'v4': auth } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request, signing_type='presign-post') self.assertFalse(auth.called) self.assertFalse(query_auth.called) post_auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='signing_name', region_name='region_name') def test_sign_with_region_name(self): auth = mock.Mock() auth_types = {'v4': auth} with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request, region_name='foo') auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='signing_name', region_name='foo') def test_sign_override_region_from_context(self): auth = mock.Mock() auth_types = {'v4': auth} self.request.context = {'signing': {'region': 'my-override-region'}} with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request) auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='signing_name', region_name='my-override-region') def test_sign_with_region_name_overrides_context(self): auth = mock.Mock() auth_types = {'v4': auth} self.request.context = {'signing': {'region': 'context-override'}} with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request, region_name='param-override') auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='signing_name', region_name='param-override') def test_sign_with_expires_in(self): auth = mock.Mock() auth_types = {'v4': auth} with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request, expires_in=2) auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='signing_name', region_name='region_name', expires=2) def test_sign_with_custom_signing_name(self): auth = mock.Mock() auth_types = {'v4': auth} with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): self.signer.sign('operation_name', self.request, signing_name='foo') auth.assert_called_with(credentials=ReadOnlyCredentials( 'key', 'secret', None), service_name='foo', region_name='region_name') def test_presign_with_custom_signing_name(self): auth = mock.Mock() auth.REQUIRES_REGION = True request_dict = { 'headers': {}, 'url': 'https://foo.com', 'body': b'', 'url_path': '/', 'method': 'GET', 'context': {} } with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, {'v4-query': auth}): presigned_url = self.signer.generate_presigned_url( request_dict, operation_name='operation_name', signing_name='foo') auth.assert_called_with(credentials=self.fixed_credentials, region_name='region_name', expires=3600, service_name='foo') self.assertEqual(presigned_url, 'https://foo.com') def test_unknown_signer_raises_unknown_on_standard(self): auth = mock.Mock() auth_types = {'v4': auth} self.emitter.emit_until_response.return_value = (None, 'custom') with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): with self.assertRaises(UnknownSignatureVersionError): self.signer.sign('operation_name', self.request, signing_type='standard') def test_unknown_signer_raises_unsupported_when_not_standard(self): auth = mock.Mock() auth_types = {'v4': auth} self.emitter.emit_until_response.return_value = (None, 'custom') with mock.patch.dict(ibm_botocore.auth.AUTH_TYPE_MAPS, auth_types): with self.assertRaises(UnsupportedSignatureVersionError): self.signer.sign('operation_name', self.request, signing_type='presign-url') with self.assertRaises(UnsupportedSignatureVersionError): self.signer.sign('operation_name', self.request, signing_type='presign-post')