Ejemplo n.º 1
0
def build_api_endpoint(
    current_request: Request, request_path: str, query_params: Optional[Dict] = None
) -> str:
    logger.info(f"Enter build_api_endpoint for {request_path}")
    request_dict = current_request.to_dict()

    context = request_dict["context"]
    stage = context["stage"]
    api_domain = context["domainName"]
    api_id = context["apiId"]

    if query_params is not None:
        if "api_id" in query_params:
            # replace api value with current api id
            query_params["api_id"] = api_id

        if "stage" in query_params:
            query_params["stage"] = stage

    if query_params is not None:
        url = f"https://{api_domain}/{stage}/{request_path.strip('/')}/?"
        url = url + urlencode(query_params)
    else:
        url = f"https://{api_domain}/{stage}/{request_path.strip('/')}"

    logger.info(f"Exit build_api_endpoint: {url}")
    return url
Ejemplo n.º 2
0
    def test_lazy_listeners(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
        )

        def command_handler(ack):
            ack()

        def say_it(say):
            say("Done!")

        app.command("/hello-world")(ack=command_handler, lazy=[say_it])

        input = (
            "token=verification_token"
            "&team_id=T111"
            "&team_domain=test-domain"
            "&channel_id=C111"
            "&channel_name=random"
            "&user_id=W111"
            "&user_name=primary-owner"
            "&command=%2Fhello-world"
            "&text=Hi"
            "&enterprise_id=E111"
            "&enterprise_name=Org+Name"
            "&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT111%2F111%2Fxxxxx"
            "&trigger_id=111.111.xxx")
        timestamp, body = str(int(time())), input

        chalice_app = Chalice(app_name="bolt-python-chalice")
        slack_handler = ChaliceSlackRequestHandler(app=app,
                                                   chalice=chalice_app)

        headers = self.build_headers(timestamp, body)
        headers["x-slack-bolt-lazy-only"] = "1"
        headers["x-slack-bolt-lazy-function-name"] = "say_it"

        request: Request = Request({
            "requestContext": {
                "httpMethod": "NONE",
                "resourcePath": "/slack/events",
            },
            "multiValueQueryStringParameters": {},
            "pathParameters": {},
            "context": {},
            "stageVariables": None,
            "isBase64Encoded": False,
            "body": body,
            "headers": headers,
        })
        response: Response = slack_handler.handle(request)
        assert response.status_code == 200
        assert self.mock_received_requests["/auth.test"] == 1
        assert self.mock_received_requests["/chat.postMessage"] == 1
Ejemplo n.º 3
0
def test_http_request_to_dict_is_json_serializable(http_request_kwargs):
    # We have to do some slight pre-preocessing here
    # to maintain preconditions.  If the
    # is_base64_encoded arg is True, we'll
    # base64 encode the body.  We assume API Gateway
    # upholds this precondition.
    is_base64_encoded = http_request_kwargs['is_base64_encoded']
    if is_base64_encoded:
        # Confirmed that if you send an empty body,
        # API Gateway will always say the body is *not*
        # base64 encoded.
        assume(http_request_kwargs['body'] is not None)
        body = base64.b64encode(http_request_kwargs['body'].encode('utf-8'))
        http_request_kwargs['body'] = body.decode('ascii')

    request = Request(**http_request_kwargs)
    assert isinstance(request.raw_body, bytes)
    request_dict = request.to_dict()
    # We should always be able to dump the request dict
    # to JSON.
    assert json.dumps(request_dict, default=handle_decimals)
Ejemplo n.º 4
0
def www_request_of(data: Dict[Text, Text], headers=None):
    merged = {"token": "foobar123", "channel_name": "privategroup"}
    merged.update(data)
    body = "&".join(f"{quote(k)}={quote(v)}" for k, v in merged.items())
    return Request(query_params={},
                   headers=headers or {},
                   uri_params={},
                   method="POST",
                   body=body.encode("utf-8"),
                   context={},
                   stage_vars={},
                   is_base64_encoded=False)
Ejemplo n.º 5
0
def test_http_request_to_dict_is_json_serializable(http_request_kwargs):
    # We have to do some slight pre-preocessing here
    # to maintain preconditions.  If the
    # is_base64_encoded arg is True, we'll
    # base64 encode the body.  We assume API Gateway
    # upholds this precondition.
    is_base64_encoded = http_request_kwargs['is_base64_encoded']
    if is_base64_encoded:
        # Confirmed that if you send an empty body,
        # API Gateway will always say the body is *not*
        # base64 encoded.
        assume(http_request_kwargs['body'] is not None)
        body = base64.b64encode(
            http_request_kwargs['body'].encode('utf-8'))
        http_request_kwargs['body'] = body.decode('ascii')

    request = Request(**http_request_kwargs)
    assert isinstance(request.raw_body, bytes)
    request_dict = request.to_dict()
    # We should always be able to dump the request dict
    # to JSON.
    assert json.dumps(request_dict, default=handle_decimals)
Ejemplo n.º 6
0
def test_url_build():

    mock_rq = Request({
        "multiValueQueryStringParameters": None,
        "headers": {
            "a": "b",
            "c": "d"
        },
        "pathParameters": None,
        "body": None,
        "stageVariables": None,
        "requestContext": {
            "resourcePath": None,
            "httpMethod": None,
            "stage": MOCK_STAGE,
            "domainName": MOCK_DOMAIN,
            "apiId": MOCK_API_ID,
        },
    })
    request_dict = mock_rq.to_dict()
    # print(request_dict.keys())
    context = request_dict["context"]
    # print(context)
    stage = context["stage"]
    assert stage == MOCK_STAGE
    # print(stage)
    api_domain = context["domainName"]
    # print(api_domain)
    assert api_domain == MOCK_DOMAIN
    api_id = context["apiId"]
    # print(api_id)
    assert api_id == MOCK_API_ID
    # build url
    url = build_api_endpoint(mock_rq, "/")
    # Is the url valid?
    result = parse.urlparse(url)
    # print(result)
    assert result is not None
Ejemplo n.º 7
0
    def handle(self, request: Request):
        body: str = request.raw_body.decode(
            "utf-8") if request.raw_body else ""
        self.logger.debug(
            f"Incoming request: {request.to_dict()}, body: {body}")

        method = request.method
        if method is None:
            return not_found()
        if method == "GET":
            if self.app.oauth_flow is not None:
                oauth_flow: OAuthFlow = self.app.oauth_flow
                bolt_req: BoltRequest = to_bolt_request(request, body)
                query = bolt_req.query
                is_callback = query is not None and (
                    (_first_value(query, "code") is not None
                     and _first_value(query, "state") is not None)
                    or _first_value(query, "error") is not None)
                if is_callback:
                    bolt_resp = oauth_flow.handle_callback(bolt_req)
                    return to_chalice_response(bolt_resp)
                else:
                    bolt_resp = oauth_flow.handle_installation(bolt_req)
                    return to_chalice_response(bolt_resp)
        elif method == "POST":
            bolt_req: BoltRequest = to_bolt_request(request, body)
            # https://docs.aws.amazon.com/lambda/latest/dg/python-context.html
            aws_lambda_function_name = self.chalice.lambda_context.function_name
            bolt_req.context[
                "aws_lambda_function_name"] = aws_lambda_function_name
            bolt_req.context["chalice_request"] = request.to_dict()
            bolt_resp = self.app.dispatch(bolt_req)
            aws_response = to_chalice_response(bolt_resp)
            return aws_response
        elif method == "NONE":
            bolt_req: BoltRequest = to_bolt_request(request, body)
            bolt_resp = self.app.dispatch(bolt_req)
            aws_response = to_chalice_response(bolt_resp)
            return aws_response

        return not_found()