Exemple #1
0
 def _create_prepared_request(self, params, operation_model):
     request = create_request_object(params)
     self._sign_request(request)
     prepared_request = self.client._endpoint.prepare_request(request)
     if self._extra_headers is not None:
         prepared_request.headers.update(self._extra_headers)
     return prepared_request
Exemple #2
0
    def generate_presigned_url(self, request_dict, operation_name,
                               expires_in=3600, region_name=None,
                               signing_name=None):
        """Generates a presigned url

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type operation_name: str
        :param operation_name: The operation being signed.

        :type expires_in: int
        :param expires_in: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

        :type region_name: string
        :param region_name: The region name to sign the presigned url.

        :type signing_name: str
        :param signing_name: The name to use for the service when signing.

        :returns: The presigned url
        """
        request = create_request_object(request_dict)
        self.sign(operation_name, request, region_name,
                  'presign-url', expires_in, signing_name)

        request.prepare()
        return request.url
Exemple #3
0
 def test_create_request_object(self):
     request = create_request_object(self.request_dict)
     self.assertEqual(request.method, self.request_dict['method'])
     self.assertEqual(request.url, self.request_dict['url'])
     self.assertEqual(request.data, self.request_dict['body'])
     self.assertEqual(request.context, self.request_dict['context'])
     self.assertIn('User-Agent', request.headers)
Exemple #4
0
    def generate_presigned_url(self,
                               request_dict,
                               operation_name,
                               expires_in=3600,
                               region_name=None):
        """Generates a presigned url

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type operation_name: str
        :param operation_name: The operation being signed.

        :type expires_in: int
        :param expires_in: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

        :type region_name: string
        :param region_name: The region name to sign the presigned url.

        :returns: The presigned url
        """
        request = create_request_object(request_dict)
        self.sign(operation_name, request, region_name, 'presign-url',
                  expires_in)

        request.prepare()
        return request.url
Exemple #5
0
 def test_enable_disable_callbacks_only_ever_registered_once(self):
     body = CallbackEnablingBody()
     request = create_request_object({
         'method': 'PUT',
         'url': 'https://s3.amazonaws.com',
         'body': body,
         'headers': {},
         'context': {}
     })
     # Create two TransferManager's using the same client
     TransferManager(self.client)
     TransferManager(self.client)
     self.client.meta.events.emit('request-created.s3',
                                  request=request,
                                  operation_name='PutObject')
     # The client should have only have the enable/disable callback
     # handlers registered once depite being used for two different
     # TransferManagers.
     self.assertEqual(
         body.enable_callback_call_count, 1,
         'The enable_callback() should have only ever been registered once')
     self.assertEqual(
         body.disable_callback_call_count, 1,
         'The disable_callback() should have only ever been registered '
         'once')
Exemple #6
0
def authenticate_presign_url_signv2(method, path, headers, data, url, query_params, request_dict):

    # Calculating Signature
    aws_request = create_request_object(request_dict)
    credentials = Credentials(access_key=TEST_AWS_ACCESS_KEY_ID, secret_key=TEST_AWS_SECRET_ACCESS_KEY)
    auth = HmacV1QueryAuth(credentials=credentials, expires=query_params['Expires'][0])
    split = urlsplit(aws_request.url)
    string_to_sign = auth.get_string_to_sign(method=method, split=split, headers=aws_request.headers)
    signature = auth.get_signature(string_to_sign=string_to_sign)

    # Comparing the signature in url with signature we calculated
    query_sig = urlparse.unquote(query_params['Signature'][0])
    if query_sig != signature:

        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string='SignatureDoesNotMatch',
            aws_access_token=TEST_AWS_ACCESS_KEY_ID,
            string_to_sign=string_to_sign,
            signature=signature,
            message='The request signature we calculated does not match the signature you provided. \
                    Check your key and signing method.')

    # Checking whether the url is expired or not
    if int(query_params['Expires'][0]) < time.time():
        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string='AccessDenied',
            message='Request has expired',
            expires=query_params['Expires'][0]
        )
Exemple #7
0
 def test_create_request_object(self):
     request = create_request_object(self.request_dict)
     self.assertEqual(request.method, self.request_dict['method'])
     self.assertEqual(request.url, self.request_dict['url'])
     self.assertEqual(request.data, self.request_dict['body'])
     self.assertEqual(request.context, self.request_dict['context'])
     self.assertIn('User-Agent', request.headers)
Exemple #8
0
def authenticate_presign_url_signv4(method, path, headers, data, url, query_params, request_dict):

    # Calculating Signature
    aws_request = create_request_object(request_dict)
    ReadOnlyCredentials = namedtuple('ReadOnlyCredentials',
                                 ['access_key', 'secret_key', 'token'])
    credentials = ReadOnlyCredentials(TEST_AWS_ACCESS_KEY_ID, TEST_AWS_SECRET_ACCESS_KEY, None)
    region = query_params['X-Amz-Credential'][0].split('/')[2]
    signer = S3SigV4QueryAuth(credentials, 's3', region, expires=int(query_params['X-Amz-Expires'][0]))
    signature = signer.add_auth(aws_request, query_params['X-Amz-Date'][0])

    expiration_time = datetime.datetime.strptime(query_params['X-Amz-Date'][0], '%Y%m%dT%H%M%SZ') + \
        datetime.timedelta(seconds=int(query_params['X-Amz-Expires'][0]))

    # Comparing the signature in url with signature we calculated
    query_sig = urlparse.unquote(query_params['X-Amz-Signature'][0])
    if query_sig != signature:

        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string='SignatureDoesNotMatch',
            aws_access_token=TEST_AWS_ACCESS_KEY_ID,
            signature=signature,
            message='The request signature we calculated does not match the signature you provided. \
                    Check your key and signing method.')

    # Checking whether the url is expired or not
    if expiration_time < datetime.datetime.utcnow():
        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string='AccessDenied',
            message='Request has expired',
            expires=query_params['X-Amz-Expires'][0]
        )
Exemple #9
0
 def create_request(self, params, operation_model=None):
     request = create_request_object(params)
     if operation_model:
         event_name = "request-created.{endpoint_prefix}.{op_name}".format(
             endpoint_prefix=self._endpoint_prefix, op_name=operation_model.name
         )
         self._event_emitter.emit(event_name, request=request, operation_name=operation_model.name)
     prepared_request = self.prepare_request(request)
     return prepared_request
Exemple #10
0
 def create_request(self, params, operation_model=None):
     request = create_request_object(params)
     if operation_model:
         event_name = 'request-created.{endpoint_prefix}.{op_name}'.format(
             endpoint_prefix=self._endpoint_prefix,
             op_name=operation_model.name)
         self._event_emitter.emit(event_name, request=request,
                                  operation_name=operation_model.name)
     prepared_request = self.prepare_request(request)
     return prepared_request
Exemple #11
0
def authenticate_presign_url_signv4(method, path, headers, data, url, query_params, request_dict):

    is_presign_valid = False
    for port in PORT_REPLACEMENT:
        match = re.match(HOST_COMBINATION_REGEX, urlparse.urlparse(request_dict['url']).netloc)
        if match and match.group(2):
            request_dict['url'] = request_dict['url'].replace('%s' % match.group(2), '%s' % port)
        else:
            request_dict['url'] = '%s:%s' % (request_dict['url'], port)

        # Calculating Signature
        aws_request = create_request_object(request_dict)
        ReadOnlyCredentials = namedtuple('ReadOnlyCredentials',
                                ['access_key', 'secret_key', 'token'])
        credentials = ReadOnlyCredentials(TEST_AWS_ACCESS_KEY_ID, TEST_AWS_SECRET_ACCESS_KEY,
            query_params.get('X-Amz-Security-Token', None))
        region = query_params['X-Amz-Credential'][0].split('/')[2]
        signer = S3SigV4QueryAuth(credentials, 's3', region, expires=int(query_params['X-Amz-Expires'][0]))
        signature = signer.add_auth(aws_request, query_params['X-Amz-Date'][0])

        expiration_time = datetime.datetime.strptime(query_params['X-Amz-Date'][0], '%Y%m%dT%H%M%SZ') + \
            datetime.timedelta(seconds=int(query_params['X-Amz-Expires'][0]))

        # Comparing the signature in url with signature we calculated
        query_sig = urlparse.unquote(query_params['X-Amz-Signature'][0])
        if query_sig == signature:
            is_presign_valid = True
            break

    # Comparing the signature in url with signature we calculated
    if config.S3_SKIP_SIGNATURE_VALIDATION:
        if not is_presign_valid:
            LOGGER.warning('Signatures do not match, but not raising an error, as S3_SKIP_SIGNATURE_VALIDATION=1')
        signature = query_sig
        is_presign_valid = True

    if not is_presign_valid:

        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string='SignatureDoesNotMatch',
            aws_access_token=TEST_AWS_ACCESS_KEY_ID,
            signature=signature,
            message='The request signature we calculated does not match the signature you provided. \
                    Check your key and signing method.')

    # Checking whether the url is expired or not
    if expiration_time < datetime.datetime.utcnow():
        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string='AccessDenied',
            message='Request has expired',
            expires=query_params['X-Amz-Expires'][0]
        )
Exemple #12
0
def authenticate_presign_url_signv2(method, path, headers, data, url,
                                    query_params, request_dict):

    # Calculating Signature
    aws_request = create_request_object(request_dict)
    credentials = Credentials(
        access_key=TEST_AWS_ACCESS_KEY_ID,
        secret_key=TEST_AWS_SECRET_ACCESS_KEY,
        token=query_params.get("X-Amz-Security-Token", None),
    )
    auth = HmacV1QueryAuth(credentials=credentials,
                           expires=query_params["Expires"][0])
    split = urlsplit(aws_request.url)
    string_to_sign = auth.get_string_to_sign(method=method,
                                             split=split,
                                             headers=aws_request.headers)
    signature = auth.get_signature(string_to_sign=string_to_sign)

    # Comparing the signature in url with signature we calculated
    query_sig = urlparse.unquote(query_params["Signature"][0])
    if config.S3_SKIP_SIGNATURE_VALIDATION:
        if query_sig != signature:
            LOGGER.warning(
                "Signatures do not match, but not raising an error, as S3_SKIP_SIGNATURE_VALIDATION=1"
            )
        signature = query_sig

    if query_sig != signature:

        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string="SignatureDoesNotMatch",
            aws_access_token=TEST_AWS_ACCESS_KEY_ID,
            string_to_sign=string_to_sign,
            signature=signature,
            message=
            "The request signature we calculated does not match the signature you provided. \
                    Check your key and signing method.",
        )

    # Checking whether the url is expired or not
    if int(query_params["Expires"][0]) < time.time():
        if config.S3_SKIP_SIGNATURE_VALIDATION:
            LOGGER.warning(
                "Signature is expired, but not raising an error, as S3_SKIP_SIGNATURE_VALIDATION=1"
            )
        else:
            return requests_error_response_xml_signature_calculation(
                code=403,
                code_string="AccessDenied",
                message="Request has expired",
                expires=query_params["Expires"][0],
            )
Exemple #13
0
 def create_request(self, params, operation_model=None):
     request = create_request_object(params)
     if operation_model:
         request.stream_output = any([
             operation_model.has_streaming_output,
             operation_model.has_event_stream_output
         ])
         event_name = 'request-created.{endpoint_prefix}.{op_name}'.format(
             endpoint_prefix=self._endpoint_prefix,
             op_name=operation_model.name)
         self._event_emitter.emit(event_name, request=request,
                                  operation_name=operation_model.name)
     prepared_request = self.prepare_request(request)
     return prepared_request
Exemple #14
0
    def generate_presigned_url(self,
                               request_dict,
                               expires_in=3600,
                               region_name=None):
        """Generates a presigned url

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type expires_in: int
        :param expires_in: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

        :type region_name: string
        :param region_name: The region name to sign the presigned url.

        :returns: The presigned url
        """
        if region_name is None:
            region_name = self._region_name
        query_prefix = '-query'
        signature_version = self._signature_version
        if not signature_version.endswith(query_prefix):
            signature_version += query_prefix

        kwargs = {
            'signing_name': self._signing_name,
            'region_name': region_name,
            'signature_version': signature_version,
            'expires': expires_in
        }

        signature_type = signature_version.split('-', 1)[0]
        try:
            auth = self.get_auth_instance(**kwargs)
        except UnknownSignatureVersionError:
            raise UnsupportedSignatureVersionError(
                signature_version=signature_type)

        request = create_request_object(request_dict)

        # Fix s3 host for s3 sigv2 bucket names
        fix_s3_host(request, signature_type, region_name)

        auth.add_auth(request)
        request.prepare()

        return request.url
 def create_request(self, params, operation_model=None):
     request = create_request_object(params)
     if operation_model:
         request.stream_output = any([
             operation_model.has_streaming_output,
             operation_model.has_event_stream_output
         ])
         service_id = operation_model.service_model.service_id.hyphenize()
         event_name = 'request-created.{service_id}.{op_name}'.format(
             service_id=service_id, op_name=operation_model.name)
         self._event_emitter.emit(event_name,
                                  request=request,
                                  operation_name=operation_model.name)
     prepared_request = self.prepare_request(request)
     return prepared_request
Exemple #16
0
 def create_request(self, params, operation_model=None):
     request = create_request_object(params)
     if operation_model:
         request.stream_output = any([
             operation_model.has_streaming_output,
             operation_model.has_event_stream_output
         ])
         service_id = operation_model.service_model.service_id.hyphenize()
         event_name = 'request-created.{service_id}.{op_name}'.format(
             service_id=service_id,
             op_name=operation_model.name)
         self._event_emitter.emit(event_name, request=request,
                                  operation_name=operation_model.name)
     prepared_request = self.prepare_request(request)
     return prepared_request
Exemple #17
0
    def generate_presigned_url(self, request_dict, expires_in=3600,
                               region_name=None):
        """Generates a presigned url

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type expires_in: int
        :param expires_in: The number of seconds the presigned url is valid
            for. By default it expires in an hour (3600 seconds)

        :type region_name: string
        :param region_name: The region name to sign the presigned url.

        :returns: The presigned url
        """
        if region_name is None:
            region_name = self._region_name
        query_prefix = '-query'
        signature_version = self._signature_version
        if not signature_version.endswith(query_prefix):
            signature_version += query_prefix

        kwargs = {'signing_name': self._signing_name,
                  'region_name': region_name,
                  'signature_version': signature_version,
                  'expires': expires_in}

        signature_type = signature_version.split('-', 1)[0]
        try:
            auth = self.get_auth(**kwargs)
        except UnknownSignatureVersionError:
            raise UnsupportedSignatureVersionError(
                signature_version=signature_type)

        request = create_request_object(request_dict)

        # Fix s3 host for s3 sigv2 bucket names
        fix_s3_host(request, signature_type, region_name)

        auth.add_auth(request)
        request.prepare()

        return request.url
def test_service_router_works_for_every_service(
    service: ServiceModel, operation: OperationModel, caplog
):
    caplog.set_level("CRITICAL", "botocore")

    # Create a dummy request for the service router
    client = _client(service.service_name)
    request_context = {
        "client_region": client.meta.region_name,
        "client_config": client.meta.config,
        "has_streaming_input": operation.has_streaming_input,
        "auth_type": operation.auth_type,
    }
    request_args = _create_dummy_request_args(operation)
    request_dict = client._convert_to_request_dict(request_args, operation, request_context)
    request_object = create_request_object(request_dict)
    client._request_signer.sign(operation.name, request_object)
    request: Request = _botocore_request_to_localstack_request(request_object)

    # Execute the service router
    detected_service_name = determine_aws_service_name(request)

    # Make sure the detected service is the same as the one we generated the request for
    assert service.service_name == detected_service_name
Exemple #19
0
 def test_enable_disable_callbacks_only_ever_registered_once(self):
     body = CallbackEnablingBody()
     request = create_request_object({
         'method': 'PUT',
         'url': 'https://s3.amazonaws.com',
         'body': body,
         'headers': {},
         'context': {}
     })
     # Create two TransferManager's using the same client
     TransferManager(self.client)
     TransferManager(self.client)
     self.client.meta.events.emit(
         'request-created.s3', request=request, operation_name='PutObject')
     # The client should have only have the enable/disable callback
     # handlers registered once depite being used for two different
     # TransferManagers.
     self.assertEqual(
         body.enable_callback_call_count, 1,
         'The enable_callback() should have only ever been registered once')
     self.assertEqual(
         body.disable_callback_call_count, 1,
         'The disable_callback() should have only ever been registered '
         'once')
Exemple #20
0
    def generate_presigned_post(self, request_dict, fields=None,
                                conditions=None, expires_in=3600,
                                region_name=None):
        """Generates the url and the form fields used for a presigned s3 post

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type fields: dict
        :param fields: A dictionary of prefilled form fields to build on top
            of.

        :type conditions: list
        :param conditions: A list of conditions to include in the policy. Each
            element can be either a list or a structure. For example:
            [
             {"acl": "public-read"},
             {"bucket": "mybucket"},
             ["starts-with", "$key", "mykey"]
            ]

        :type expires_in: int
        :param expires_in: The number of seconds the presigned post is valid
            for.

        :type region_name: string
        :param region_name: The region name to sign the presigned post to.

        :rtype: dict
        :returns: A dictionary with two elements: ``url`` and ``fields``.
            Url is the url to post to. Fields is a dictionary filled with
            the form fields and respective values to use when submitting the
            post. For example:

            {'url': 'https://mybucket.s3.amazonaws.com
             'fields': {'acl': 'public-read',
                        'key': 'mykey',
                        'signature': 'mysignature',
                        'policy': 'mybase64 encoded policy'}
            }
        """
        if fields is None:
            fields = {}

        if conditions is None:
            conditions = []

        if region_name is None:
            region_name = self._request_signer.region_name

        # Create the policy for the post.
        policy = {}

        # Create an expiration date for the policy
        datetime_now = datetime.datetime.utcnow()
        expire_date = datetime_now + datetime.timedelta(seconds=expires_in)
        policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601)

        # Append all of the conditions that the user supplied.
        policy['conditions'] = []
        for condition in conditions:
            policy['conditions'].append(condition)

        # Obtain the appropriate signer.
        query_prefix = '-presign-post'
        signature_version = self._request_signer.signature_version
        if not signature_version.endswith(query_prefix):
            signature_version += query_prefix

        kwargs = {'signing_name': self._request_signer.signing_name,
                  'region_name': region_name,
                  'signature_version': signature_version}

        signature_type = signature_version.split('-', 1)[0]

        try:
            auth = self._request_signer.get_auth(**kwargs)
        except UnknownSignatureVersionError:
            raise UnsupportedSignatureVersionError(
                signature_version=signature_type)

        # Store the policy and the fields in the request for signing
        request = create_request_object(request_dict)
        request.context['s3-presign-post-fields'] = fields
        request.context['s3-presign-post-policy'] = policy

        auth.add_auth(request)

        # Fix s3 host for s3 sigv2 bucket names
        fix_s3_host(request, signature_type, region_name)
        # Return the url and the fields for th form to post.
        return {'url': request.url, 'fields': fields}
Exemple #21
0
def authenticate_presign_url_signv4(method, path, headers, data, url, query_params, request_dict):
    is_presign_valid = False
    for port in PORT_REPLACEMENT:
        match = re.match(HOST_COMBINATION_REGEX, urlparse.urlparse(request_dict["url"]).netloc)
        if match and match.group(2):
            request_dict["url"] = request_dict["url"].replace("%s" % match.group(2), "%s" % port)
        else:
            request_dict["url"] = "%s:%s" % (request_dict["url"], port)

        # Calculating Signature
        aws_request = create_request_object(request_dict)
        ReadOnlyCredentials = namedtuple(
            "ReadOnlyCredentials", ["access_key", "secret_key", "token"]
        )
        credentials = ReadOnlyCredentials(
            TEST_AWS_ACCESS_KEY_ID,
            TEST_AWS_SECRET_ACCESS_KEY,
            query_params.get("X-Amz-Security-Token", None),
        )
        region = query_params["X-Amz-Credential"][0].split("/")[2]
        signer = S3SigV4QueryAuth(
            credentials, "s3", region, expires=int(query_params["X-Amz-Expires"][0])
        )
        signature = signer.add_auth(aws_request, query_params["X-Amz-Date"][0])

        expiration_time = datetime.datetime.strptime(
            query_params["X-Amz-Date"][0], "%Y%m%dT%H%M%SZ"
        ) + datetime.timedelta(seconds=int(query_params["X-Amz-Expires"][0]))
        expiration_time = expiration_time.replace(tzinfo=datetime.timezone.utc)

        # Comparing the signature in url with signature we calculated
        query_sig = urlparse.unquote(query_params["X-Amz-Signature"][0])
        if query_sig == signature:
            is_presign_valid = True
            break

    # Comparing the signature in url with signature we calculated
    if config.S3_SKIP_SIGNATURE_VALIDATION:
        if not is_presign_valid:
            LOGGER.warning(
                "Signatures do not match, but not raising an error, as S3_SKIP_SIGNATURE_VALIDATION=1"
            )
        signature = query_sig
        is_presign_valid = True

    if not is_presign_valid:
        return requests_error_response_xml_signature_calculation(
            code=403,
            code_string="SignatureDoesNotMatch",
            aws_access_token=TEST_AWS_ACCESS_KEY_ID,
            signature=signature,
            message="The request signature we calculated does not match the signature you provided. \
                    Check your key and signing method.",
        )

    # Checking whether the url is expired or not
    if is_expired(expiration_time):
        if config.S3_SKIP_SIGNATURE_VALIDATION:
            LOGGER.warning(
                "Signature is expired, but not raising an error, as S3_SKIP_SIGNATURE_VALIDATION=1"
            )
        else:
            return requests_error_response_xml_signature_calculation(
                code=403,
                code_string="AccessDenied",
                message="Request has expired",
                expires=query_params["X-Amz-Expires"][0],
            )
Exemple #22
0
    def generate_presigned_post(self,
                                request_dict,
                                fields=None,
                                conditions=None,
                                expires_in=3600,
                                region_name=None):
        """Generates the url and the form fields used for a presigned s3 post

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type fields: dict
        :param fields: A dictionary of prefilled form fields to build on top
            of.

        :type conditions: list
        :param conditions: A list of conditions to include in the policy. Each
            element can be either a list or a structure. For example:
            [
             {"acl": "public-read"},
             {"bucket": "mybucket"},
             ["starts-with", "$key", "mykey"]
            ]

        :type expires_in: int
        :param expires_in: The number of seconds the presigned post is valid
            for.

        :type region_name: string
        :param region_name: The region name to sign the presigned post to.

        :rtype: dict
        :returns: A dictionary with two elements: ``url`` and ``fields``.
            Url is the url to post to. Fields is a dictionary filled with
            the form fields and respective values to use when submitting the
            post. For example:

            {'url': 'https://mybucket.s3.amazonaws.com
             'fields': {'acl': 'public-read',
                        'key': 'mykey',
                        'signature': 'mysignature',
                        'policy': 'mybase64 encoded policy'}
            }
        """
        if fields is None:
            fields = {}

        if conditions is None:
            conditions = []

        if region_name is None:
            region_name = self._request_signer.region_name

        # Create the policy for the post.
        policy = {}

        # Create an expiration date for the policy
        datetime_now = datetime.datetime.utcnow()
        expire_date = datetime_now + datetime.timedelta(seconds=expires_in)
        policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601)

        # Append all of the conditions that the user supplied.
        policy['conditions'] = []
        for condition in conditions:
            policy['conditions'].append(condition)

        # Obtain the appropriate signer.
        query_prefix = '-presign-post'
        signature_version = self._request_signer.signature_version
        if not signature_version.endswith(query_prefix):
            signature_version += query_prefix

        kwargs = {
            'signing_name': self._request_signer.signing_name,
            'region_name': region_name,
            'signature_version': signature_version
        }

        signature_type = signature_version.split('-', 1)[0]

        try:
            auth = self._request_signer.get_auth_instance(**kwargs)
        except UnknownSignatureVersionError:
            raise UnsupportedSignatureVersionError(
                signature_version=signature_type)

        # Store the policy and the fields in the request for signing
        request = create_request_object(request_dict)
        request.context['s3-presign-post-fields'] = fields
        request.context['s3-presign-post-policy'] = policy

        auth.add_auth(request)

        # Fix s3 host for s3 sigv2 bucket names
        fix_s3_host(request, signature_type, region_name)
        # Return the url and the fields for th form to post.
        return {'url': request.url, 'fields': fields}
Exemple #23
0
    def generate_presigned_post(self,
                                request_dict,
                                fields=None,
                                conditions=None,
                                expires_in=3600,
                                region_name=None):
        """Generates the url and the form fields used for a presigned s3 post

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type fields: dict
        :param fields: A dictionary of prefilled form fields to build on top
            of.

        :type conditions: list
        :param conditions: A list of conditions to include in the policy. Each
            element can be either a list or a structure. For example:
            [
             {"acl": "public-read"},
             {"bucket": "mybucket"},
             ["starts-with", "$key", "mykey"]
            ]

        :type expires_in: int
        :param expires_in: The number of seconds the presigned post is valid
            for.

        :type region_name: string
        :param region_name: The region name to sign the presigned post to.

        :rtype: dict
        :returns: A dictionary with two elements: ``url`` and ``fields``.
            Url is the url to post to. Fields is a dictionary filled with
            the form fields and respective values to use when submitting the
            post. For example:

            {'url': 'https://mybucket.s3.amazonaws.com
             'fields': {'acl': 'public-read',
                        'key': 'mykey',
                        'signature': 'mysignature',
                        'policy': 'mybase64 encoded policy'}
            }
        """
        if fields is None:
            fields = {}

        if conditions is None:
            conditions = []

        # Create the policy for the post.
        policy = {}

        # Create an expiration date for the policy
        datetime_now = datetime.datetime.utcnow()
        expire_date = datetime_now + datetime.timedelta(seconds=expires_in)
        policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601)

        # Append all of the conditions that the user supplied.
        policy['conditions'] = []
        for condition in conditions:
            policy['conditions'].append(condition)

        # Store the policy and the fields in the request for signing
        request = create_request_object(request_dict)
        request.context['s3-presign-post-fields'] = fields
        request.context['s3-presign-post-policy'] = policy

        self._request_signer.sign('PutObject', request, region_name,
                                  'presign-post')
        # Return the url and the fields for th form to post.
        return {'url': request.url, 'fields': fields}
Exemple #24
0
    def generate_presigned_post(self, request_dict, fields=None,
                                conditions=None, expires_in=3600,
                                region_name=None):
        """Generates the url and the form fields used for a presigned s3 post

        :type request_dict: dict
        :param request_dict: The prepared request dictionary returned by
            ``botocore.awsrequest.prepare_request_dict()``

        :type fields: dict
        :param fields: A dictionary of prefilled form fields to build on top
            of.

        :type conditions: list
        :param conditions: A list of conditions to include in the policy. Each
            element can be either a list or a structure. For example:
            [
             {"acl": "public-read"},
             {"bucket": "mybucket"},
             ["starts-with", "$key", "mykey"]
            ]

        :type expires_in: int
        :param expires_in: The number of seconds the presigned post is valid
            for.

        :type region_name: string
        :param region_name: The region name to sign the presigned post to.

        :rtype: dict
        :returns: A dictionary with two elements: ``url`` and ``fields``.
            Url is the url to post to. Fields is a dictionary filled with
            the form fields and respective values to use when submitting the
            post. For example:

            {'url': 'https://mybucket.s3.amazonaws.com
             'fields': {'acl': 'public-read',
                        'key': 'mykey',
                        'signature': 'mysignature',
                        'policy': 'mybase64 encoded policy'}
            }
        """
        if fields is None:
            fields = {}

        if conditions is None:
            conditions = []

        # Create the policy for the post.
        policy = {}

        # Create an expiration date for the policy
        datetime_now = datetime.datetime.utcnow()
        expire_date = datetime_now + datetime.timedelta(seconds=expires_in)
        policy['expiration'] = expire_date.strftime(botocore.auth.ISO8601)

        # Append all of the conditions that the user supplied.
        policy['conditions'] = []
        for condition in conditions:
            policy['conditions'].append(condition)

        # Store the policy and the fields in the request for signing
        request = create_request_object(request_dict)
        request.context['s3-presign-post-fields'] = fields
        request.context['s3-presign-post-policy'] = policy

        self._request_signer.sign(
            'PutObject', request, region_name, 'presign-post')
        # Return the url and the fields for th form to post.
        return {'url': request.url, 'fields': fields}