Beispiel #1
0
def generate_presigned_url(self,
                           ClientMethod,
                           Params=None,
                           ExpiresIn=3600,
                           HttpMethod=None):
    """Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
        ``ClientMethod``.

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

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
        default, the http method is whatever is used in the method's model.

    :returns: The presigned url
    """
    client_method = ClientMethod
    params = Params
    if params is None:
        params = {}
    expires_in = ExpiresIn
    http_method = HttpMethod
    context = {'is_presign_request': True}

    request_signer = self._request_signer
    serializer = self._serializer

    try:
        operation_name = self._PY_TO_OP_NAME[client_method]
    except KeyError:
        raise UnknownClientMethodError(method_name=client_method)

    operation_model = self.meta.service_model.operation_model(operation_name)

    params = self._emit_api_params(params, operation_model, context)

    # Create a request dict based on the params to serialize.
    request_dict = serializer.serialize_to_request(params, operation_model)

    # Switch out the http method if user specified it.
    if http_method is not None:
        request_dict['method'] = http_method

    # Prepare the request dict by including the client's endpoint url.
    prepare_request_dict(request_dict,
                         endpoint_url=self.meta.endpoint_url,
                         context=context)

    # Generate the presigned url.
    return request_signer.generate_presigned_url(request_dict=request_dict,
                                                 expires_in=expires_in,
                                                 operation_name=operation_name)
Beispiel #2
0
def generate_presigned_url(self, ClientMethod, Params=None, ExpiresIn=3600,
                           HttpMethod=None):
    """Generate a presigned url given a client, its method, and arguments

    :type ClientMethod: string
    :param ClientMethod: The client method to presign for

    :type Params: dict
    :param Params: The parameters normally passed to
        ``ClientMethod``.

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

    :type HttpMethod: string
    :param HttpMethod: The http method to use on the generated url. By
        default, the http method is whatever is used in the method's model.

    :returns: The presigned url
    """
    client_method = ClientMethod
    params = Params
    if params is None:
        params = {}
    expires_in = ExpiresIn
    http_method = HttpMethod
    context = {
        'is_presign_request': True
    }

    request_signer = self._request_signer
    serializer = self._serializer

    try:
        operation_name = self._PY_TO_OP_NAME[client_method]
    except KeyError:
        raise UnknownClientMethodError(method_name=client_method)

    operation_model = self.meta.service_model.operation_model(
        operation_name)

    params = self._emit_api_params(params, operation_model, context)

    # Create a request dict based on the params to serialize.
    request_dict = serializer.serialize_to_request(
        params, operation_model)

    # Switch out the http method if user specified it.
    if http_method is not None:
        request_dict['method'] = http_method

    # Prepare the request dict by including the client's endpoint url.
    prepare_request_dict(
        request_dict, endpoint_url=self.meta.endpoint_url, context=context)

    # Generate the presigned url.
    return request_signer.generate_presigned_url(
        request_dict=request_dict, expires_in=expires_in,
        operation_name=operation_name)
Beispiel #3
0
    def _convert_to_request_dict(self,
                                 api_params,
                                 operation_model,
                                 context=None):
        # Given the API params provided by the user and the operation_model
        # we can serialize the request to a request_dict.
        operation_name = operation_model.name

        # Emit an event that allows users to modify the parameters at the
        # beginning of the method. It allows handlers to modify existing
        # parameters or return a new set of parameters to use.
        responses = self.meta.events.emit(
            'provide-client-params.{endpoint_prefix}.{operation_name}'.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            params=api_params,
            model=operation_model,
            context=context)
        api_params = first_non_none_response(responses, default=api_params)

        event_name = (
            'before-parameter-build.{endpoint_prefix}.{operation_name}')
        self.meta.events.emit(event_name.format(
            endpoint_prefix=self._service_model.endpoint_prefix,
            operation_name=operation_name),
                              params=api_params,
                              model=operation_model,
                              context=context)

        request_dict = self._serializer.serialize_to_request(
            api_params, operation_model)
        prepare_request_dict(request_dict,
                             endpoint_url=self._endpoint.host,
                             user_agent=self._client_config.user_agent)
        return request_dict
Beispiel #4
0
    def _convert_to_request_dict(self, api_params, operation_model):
        # Given the API params provided by the user and the operation_model
        # we can serialize the request to a request_dict.
        operation_name = operation_model.name

        # Emit an event that allows users to modify the parameters at the
        # beginning of the method. It allows handlers to modify existing
        # parameters or return a new set of parameters to use.
        responses = self.meta.events.emit(
            'provide-client-params.{endpoint_prefix}.{operation_name}'.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            params=api_params, model=operation_model)
        api_params = first_non_none_response(responses, default=api_params)

        event_name = (
            'before-parameter-build.{endpoint_prefix}.{operation_name}')
        self.meta.events.emit(
            event_name.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            params=api_params, model=operation_model)

        request_dict = self._serializer.serialize_to_request(
            api_params, operation_model)
        prepare_request_dict(request_dict, endpoint_url=self._endpoint.host,
                             user_agent=self._client_config.user_agent)
        self.meta.events.emit(
            'before-call.{endpoint_prefix}.{operation_name}'.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            model=operation_model, params=request_dict,
            request_signer=self._request_signer
        )
        return request_dict
 def prepare_base_request_dict(self, request_dict, endpoint_url=None,
                               user_agent=None):
     self.base_request_dict.update(request_dict)
     if user_agent is None:
         user_agent = self.user_agent
     if endpoint_url is None:
         endpoint_url = self.endpoint_url
     prepare_request_dict(self.base_request_dict, endpoint_url=endpoint_url,
                          user_agent=user_agent)
Beispiel #6
0
 def prepare_base_request_dict(self, request_dict, endpoint_url=None,
                               user_agent=None):
     self.base_request_dict.update(request_dict)
     if user_agent is None:
         user_agent = self.user_agent
     if endpoint_url is None:
         endpoint_url = self.endpoint_url
     prepare_request_dict(self.base_request_dict, endpoint_url=endpoint_url,
                          user_agent=user_agent)
Beispiel #7
0
 def _convert_to_request_dict(self, api_params, operation_model,
                              context=None):
     api_params = self._emit_api_params(
         api_params, operation_model, context)
     request_dict = self._serializer.serialize_to_request(
         api_params, operation_model)
     prepare_request_dict(request_dict, endpoint_url=self._endpoint.host,
                          user_agent=self._client_config.user_agent,
                          context=context)
     return request_dict
Beispiel #8
0
 async def _convert_to_request_dict(self, api_params, operation_model,
                                    context=None):
     api_params = await self._emit_api_params(
         api_params, operation_model, context)
     request_dict = self._serializer.serialize_to_request(
         api_params, operation_model)
     if not self._client_config.inject_host_prefix:
         request_dict.pop('host_prefix', None)
     prepare_request_dict(request_dict, endpoint_url=self._endpoint.host,
                          user_agent=self._client_config.user_agent,
                          context=context)
     return request_dict
Beispiel #9
0
def _botocore_parser_integration_test(service: str,
                                      action: str,
                                      headers: dict = None,
                                      expected: dict = None,
                                      **kwargs):
    # Load the appropriate service
    service = load_service(service)
    # Use the serializer from botocore to serialize the request params
    serializer = create_serializer(service.protocol)

    operation_model = service.operation_model(action)
    serialized_request = serializer.serialize_to_request(
        kwargs, operation_model)
    prepare_request_dict(serialized_request, "")
    split_url = urlsplit(serialized_request.get("url"))
    path = split_url.path
    query_string = split_url.query
    body = serialized_request["body"]
    # use custom headers (if provided), or headers from serialized request as default
    headers = serialized_request.get("headers") if headers is None else headers

    if service.protocol in ["query", "ec2"]:
        # Serialize the body as query parameter
        body = urlencode(serialized_request["body"])

    # Use our parser to parse the serialized body
    parser = create_parser(service)
    parsed_operation_model, parsed_request = parser.parse(
        HttpRequest(
            method=serialized_request.get("method") or "GET",
            path=unquote(path),
            query_string=to_str(query_string),
            headers=headers,
            body=body,
            raw_path=path,
        ))

    # Check if the determined operation_model is correct
    assert parsed_operation_model == operation_model

    # Check if the result is equal to the given "expected" dict or the kwargs (if "expected" has not been set)
    expected = expected or kwargs
    # The parser adds None for none-existing members on purpose. Remove those for the assert
    expected = {
        key: value
        for key, value in expected.items() if value is not None
    }
    parsed_request = {
        key: value
        for key, value in parsed_request.items() if value is not None
    }
    assert parsed_request == expected
Beispiel #10
0
 def _convert_to_request_dict(self,
                              api_params,
                              operation_model,
                              context=None):
     api_params = self._emit_api_params(api_params, operation_model,
                                        context)
     request_dict = self._serializer.serialize_to_request(
         api_params, operation_model)
     prepare_request_dict(request_dict,
                          endpoint_url=self._endpoint.host,
                          user_agent=self._client_config.user_agent,
                          context=context)
     return request_dict
Beispiel #11
0
def generate_db_auth_token(self, DBHostname, Port, DBUsername, Region=None):
    """Generates an auth token used to connect to a db with IAM credentials.

    :type DBHostname: str
    :param DBHostname: The hostname of the database to connect to.

    :type Port: int
    :param Port: The port number the database is listening on.

    :type DBUsername: str
    :param DBUsername: The username to log in as.

    :type Region: str
    :param Region: The region the database is in. If None, the client
        region will be used.

    :return: A presigned url which can be used as an auth token.
    """
    region = Region
    if region is None:
        region = self.meta.region_name

    params = {
        'Action': 'connect',
        'DBUser': DBUsername,
    }

    request_dict = {
        'url_path': '/',
        'query_string': '',
        'headers': {},
        'body': params,
        'method': 'GET'
    }

    # RDS requires that the scheme not be set when sent over. This can cause
    # issues when signing because the Python url parsing libraries follow
    # RFC 1808 closely, which states that a netloc must be introduced by `//`.
    # Otherwise the url is presumed to be relative, and thus the whole
    # netloc would be treated as a path component. To work around this we
    # introduce https here and remove it once we're done processing it.
    scheme = 'https://'
    endpoint_url = '%s%s:%s' % (scheme, DBHostname, Port)
    prepare_request_dict(request_dict, endpoint_url)
    presigned_url = self._request_signer.generate_presigned_url(
        operation_name='connect',
        request_dict=request_dict,
        region_name=region,
        expires_in=900,
        signing_name='rds-db')
    return presigned_url[len(scheme):]
Beispiel #12
0
def generate_db_auth_token(self, DBHostname, Port, DBUsername, Region=None):
    """Generates an auth token used to connect to a db with IAM credentials.

    :type DBHostname: str
    :param DBHostname: The hostname of the database to connect to.

    :type Port: int
    :param Port: The port number the database is listening on.

    :type DBUsername: str
    :param DBUsername: The username to log in as.

    :type Region: str
    :param Region: The region the database is in. If None, the client
        region will be used.

    :return: A presigned url which can be used as an auth token.
    """
    region = Region
    if region is None:
        region = self.meta.region_name

    params = {
        'Action': 'connect',
        'DBUser': DBUsername,
    }

    request_dict = {
        'url_path': '/',
        'query_string': '',
        'headers': {},
        'body': params,
        'method': 'GET'
    }

    # RDS requires that the scheme not be set when sent over. This can cause
    # issues when signing because the Python url parsing libraries follow
    # RFC 1808 closely, which states that a netloc must be introduced by `//`.
    # Otherwise the url is presumed to be relative, and thus the whole
    # netloc would be treated as a path component. To work around this we
    # introduce https here and remove it once we're done processing it.
    scheme = 'https://'
    endpoint_url = '%s%s:%s' % (scheme, DBHostname, Port)
    prepare_request_dict(request_dict, endpoint_url)
    presigned_url = self._request_signer.generate_presigned_url(
        operation_name='connect', request_dict=request_dict,
        region_name=region, expires_in=900, signing_name='rds-db'
    )
    return presigned_url[len(scheme):]
Beispiel #13
0
    def test_recreate_request(self):

        client = Lambda().client()
        operation_model = client._service_model.operation_model('Invoke')
        self.result = operation_model

        payload = {"name": "bbbbaaaa"}
        request_dict= {'url_path': '/2015-03-31/functions/temp_lambda_HL58KB/invocations',
                       'query_string': {},
                       'method': 'POST',
                       'headers': {},
                       'body': json.dumps(payload)}
        endpoint_url = 'https://lambda.eu-west-1.amazonaws.com'
        user_agent='Boto3/1.12.5 Python/3.8.1 Darwin/18.7.0 Botocore/1.15.5'

        from botocore.awsrequest import prepare_request_dict

        prepare_request_dict(request_dict=request_dict,endpoint_url=endpoint_url,user_agent=user_agent)
        request = client._endpoint.create_request(request_dict, operation_model)

        headers = {'User-Agent': b'Boto3/1.12.5 Python/3.8.1 Darwin/18.7.0 Botocore/1.15.5', 'X-Amz-Date': b'20200224T010440Z', 'Authorization': b'AWS4-HMAC-SHA256 Credential=AKIAURGGJDT3TXD5DCXK/20200224/eu-west-1/lambda/aws4_request, SignedHeaders=host;x-amz-date, Signature=3ea5c19cc097466202e71c4e3b4e306327709442138bfd6443b27a25cfd89c91', 'Content-Length': '15'}
        self.result = requests.post(request.url,json=payload,headers=request.headers).text
        #self.result = request.url
        #http_session = URLLib3Session()

        #self.result = http_session.send(request).text
        #self.result = request.headers.items()
        return
        from botocore.endpoint import Endpoint
        endpoint = Endpoint()
        self.params = { 'url_path': '/2015-03-31/functions/temp_lambda_HL58KB/invocations', 'query_string': {},
                        'method'  : 'POST',
                        'headers' : {'User-Agent': 'Boto3/1.12.5 Python/3.8.1 Darwin/18.7.0 Botocore/1.15.5'},
                        'body'    : b'{"name": "123"}',
                        'url'     : 'https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/temp_lambda_HL58KB/invocations',
                        'context' : {'client_region': 'eu-west-1',
                                    'client_config': None, 'has_streaming_input': True, 'auth_type': None}}
        #< botocore.config.Config object at0x10f5802e0 >
        self.result =42
Beispiel #14
0
    def _convert_to_request_dict(self, api_params, operation_model):
        # Given the API params provided by the user and the operation_model
        # we can serialize the request to a request_dict.
        operation_name = operation_model.name
        event_name = (
            'before-parameter-build.{endpoint_prefix}.{operation_name}')
        self.meta.events.emit(
            event_name.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            params=api_params, model=operation_model)

        request_dict = self._serializer.serialize_to_request(
            api_params, operation_model)
        prepare_request_dict(request_dict, endpoint_url=self._endpoint.host,
                             user_agent=self._client_config.user_agent)
        self.meta.events.emit(
            'before-call.{endpoint_prefix}.{operation_name}'.format(
                endpoint_prefix=self._service_model.endpoint_prefix,
                operation_name=operation_name),
            model=operation_model, params=request_dict,
            request_signer=self._request_signer
        )
        return request_dict
Beispiel #15
0
def generate_presigned_post(self,
                            Bucket,
                            Key,
                            Fields=None,
                            Conditions=None,
                            ExpiresIn=3600):
    """Builds the url and the form fields used for a presigned s3 post

    :type Bucket: string
    :param Bucket: The name of the bucket to presign the post to. Note that
        bucket related conditions should not be included in the
        ``conditions`` parameter.

    :type Key: string
    :param Key: Key name, optionally add ${filename} to the end to
        attach the submitted filename. Note that key related condtions and
        fields are filled out for you and should not be included in the
        ``fields`` or ``condtions`` parmater.

    :type Fields: dict
    :param Fields: A dictionary of prefilled form fields to build on top
        of. Elements that may be included are acl, Cache-Control,
        Content-Type, Content-Disposition, Content-Encoding, Expires,
        success_action_redirect, redirect, success_action_status,
        and x-amz-meta-.

        Note that if a particular element is included in the fields
        dictionary it will not be automatically added to the conditions
        list. You must specify a condition for the element as well.

    :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"},
         ["content-length-range", 2, 5],
         ["starts-with", "$success_action_redirect", ""]
        ]

        Conditions that are included may pertain to acl,
        content-length-range, Cache-Control, Content-Type,
        Content-Disposition, Content-Encoding, Expires,
        success_action_redirect, redirect, success_action_status,
        and/or x-amz-meta-.

        Note that if you include a condition, you must specify
        the a valid value in the fields dictionary as well. A value will
        not be added automatically to the fields dictionary based on the
        conditions.

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

    :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'}
        }
    """
    bucket = Bucket
    key = Key
    fields = Fields
    conditions = Conditions
    expires_in = ExpiresIn

    if fields is None:
        fields = {}

    if conditions is None:
        conditions = []

    post_presigner = S3PostPresigner(self._request_signer)
    serializer = self._serializer

    # We choose the CreateBucket operation model because its url gets
    # serialized to what a presign post requires.
    operation_model = self.meta.service_model.operation_model('CreateBucket')

    # Create a request dict based on the params to serialize.
    request_dict = serializer.serialize_to_request({'Bucket': bucket},
                                                   operation_model)

    # Prepare the request dict by including the client's endpoint url.
    prepare_request_dict(request_dict, endpoint_url=self.meta.endpoint_url)

    # Append that the bucket name to the list of conditions.
    conditions.append({'bucket': bucket})

    # If the key ends with filename, the only constraint that can be
    # imposed is if it starts with the specified prefix.
    if key.endswith('${filename}'):
        conditions.append(["starts-with", '$key', key[:-len('${filename}')]])
    else:
        conditions.append({'key': key})

    # Add the key to the fields.
    fields['key'] = key

    return post_presigner.generate_presigned_post(request_dict=request_dict,
                                                  fields=fields,
                                                  conditions=conditions,
                                                  expires_in=expires_in)
Beispiel #16
0
def _assert_endpoints_equal(actual, expected, endpoint):
    if 'host' not in expected:
        return
    prepare_request_dict(actual, endpoint)
    actual_host = urlsplit(actual['url']).netloc
    assert_equal(actual_host, expected['host'], 'Host')
Beispiel #17
0
def generate_presigned_post(self, Bucket, Key, Fields=None, Conditions=None,
                            ExpiresIn=3600):
    """Builds the url and the form fields used for a presigned s3 post

    :type Bucket: string
    :param Bucket: The name of the bucket to presign the post to. Note that
        bucket related conditions should not be included in the
        ``conditions`` parameter.

    :type Key: string
    :param Key: Key name, optionally add ${filename} to the end to
        attach the submitted filename. Note that key related condtions and
        fields are filled out for you and should not be included in the
        ``fields`` or ``condtions`` parmater.

    :type Fields: dict
    :param Fields: A dictionary of prefilled form fields to build on top
        of. Elements that may be included are acl, Cache-Control,
        Content-Type, Content-Disposition, Content-Encoding, Expires,
        success_action_redirect, redirect, success_action_status,
        and x-amz-meta-.

        Note that if a particular element is included in the fields
        dictionary it will not be automatically added to the conditions
        list. You must specify a condition for the element as well.

    :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"},
         ["content-length-range", 2, 5],
         ["starts-with", "$success_action_redirect", ""]
        ]

        Conditions that are included may pertain to acl,
        content-length-range, Cache-Control, Content-Type,
        Content-Disposition, Content-Encoding, Expires,
        success_action_redirect, redirect, success_action_status,
        and/or x-amz-meta-.

        Note that if you include a condition, you must specify
        the a valid value in the fields dictionary as well. A value will
        not be added automatically to the fields dictionary based on the
        conditions.

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

    :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'}
        }
    """
    bucket = Bucket
    key = Key
    fields = Fields
    conditions = Conditions
    expires_in = ExpiresIn

    if fields is None:
        fields = {}

    if conditions is None:
        conditions = []

    post_presigner = S3PostPresigner(self._request_signer)
    serializer = self._serializer

    # We choose the CreateBucket operation model because its url gets
    # serialized to what a presign post requires.
    operation_model = self.meta.service_model.operation_model(
        'CreateBucket')

    # Create a request dict based on the params to serialize.
    request_dict = serializer.serialize_to_request(
        {'Bucket': bucket}, operation_model)

    # Prepare the request dict by including the client's endpoint url.
    prepare_request_dict(
        request_dict, endpoint_url=self.meta.endpoint_url)

    # Append that the bucket name to the list of conditions.
    conditions.append({'bucket': bucket})

    # If the key ends with filename, the only constraint that can be
    # imposed is if it starts with the specified prefix.
    if key.endswith('${filename}'):
        conditions.append(["starts-with", '$key', key[:-len('${filename}')]])
    else:
        conditions.append({'key': key})

    # Add the key to the fields.
    fields['key'] = key

    return post_presigner.generate_presigned_post(
        request_dict=request_dict, fields=fields, conditions=conditions,
        expires_in=expires_in)
Beispiel #18
0
def _assert_endpoints_equal(actual, expected, endpoint):
    if 'host' not in expected:
        return
    prepare_request_dict(actual, endpoint)
    actual_host = urlsplit(actual['url']).netloc
    assert_equal(actual_host, expected['host'], 'Host')