From a04f82c0612794a190aa0de5056402e49e96171e Mon Sep 17 00:00:00 2001 From: Lucas <12496191+lucashuy@users.noreply.github.com> Date: Fri, 2 Jun 2023 15:51:00 -0700 Subject: [PATCH 1/4] Added authorizer project --- ...st_start_api_with_terraform_application.py | 23 +++++++++++++++++++ .../start_api/lambda_authorizers/app.py | 1 + 2 files changed, 24 insertions(+) diff --git a/tests/integration/local/start_api/test_start_api_with_terraform_application.py b/tests/integration/local/start_api/test_start_api_with_terraform_application.py index 59b088b54b..b7bbfd3b7a 100644 --- a/tests/integration/local/start_api/test_start_api_with_terraform_application.py +++ b/tests/integration/local/start_api/test_start_api_with_terraform_application.py @@ -54,3 +54,26 @@ def test_successful_request(self): self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), {"message": "hello world"}) + + +@skipIf( + not CI_OVERRIDE, + "Skip Terraform test cases unless running in CI", +) +@pytest.mark.flaky(reruns=3) +class TestStartApiTerraformApplicationV1LambdaAuthorizers(TerraformStartApiIntegrationBase): + terraform_application = "v1-lambda-authorizer" + + def setUp(self): + self.url = "http://127.0.0.1:{}".format(self.port) + + def test_invoke_authorizer(self): + response = requests.get(self.url + "/hello", timeout=300, headers={"myheader": "123"}) + + self.assertEqual(response.status_code, 200) + self.assertEqual(response.json(), {"message": "from authorizer"}) + + def test_fails_validation(self): + response = requests.get(self.url + "/hello", timeout=300, headers={"myheader": "not valid"}) + + self.assertEqual(response.status_code, 401) diff --git a/tests/integration/testdata/start_api/lambda_authorizers/app.py b/tests/integration/testdata/start_api/lambda_authorizers/app.py index cfd4b7c84e..10657a379f 100644 --- a/tests/integration/testdata/start_api/lambda_authorizers/app.py +++ b/tests/integration/testdata/start_api/lambda_authorizers/app.py @@ -96,6 +96,7 @@ def auth_handler(event, context): # context['obj'] = {'foo':'bar'} <- also invalid authResponse['context'] = context + print(authResponse) return authResponse From cfc62a7f29897fd3221f1c49c1db1f456d1dc3a9 Mon Sep 17 00:00:00 2001 From: Lucas <12496191+lucashuy@users.noreply.github.com> Date: Mon, 5 Jun 2023 16:15:20 -0700 Subject: [PATCH 2/4] Added project files --- .../v1-lambda-authorizer/lambda-functions.zip | Bin 0 -> 551 bytes .../terraform/v1-lambda-authorizer/main.tf | 75 ++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/lambda-functions.zip create mode 100644 tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf diff --git a/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/lambda-functions.zip b/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/lambda-functions.zip new file mode 100644 index 0000000000000000000000000000000000000000..36c26446344af50d1215621f24af2bff75856930 GIT binary patch literal 551 zcmWIWW@Zs#-~d9t+CyOsP@u%jz`)I*z>txcmy(lORIFD}85+XNz((kZ=$e!ogI`e0(%A72s5%DNMly7eVLnpV>iPE@R4oU3# zu^KoQ?CfWD~ErxLp0T@O^Yry3(yF zCr{n`dm?4$t2v=}=Y5O1>-L5}z?+?eUHjgqcwl&gVkf|xkx7IZ5p&3LpqPV!C5<2! X3Go=<&B_MS!U%+sKzawzLIwr^eU{QQ literal 0 HcmV?d00001 diff --git a/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf b/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf new file mode 100644 index 0000000000..6218a7470d --- /dev/null +++ b/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf @@ -0,0 +1,75 @@ +provider "aws" {} + +resource "aws_api_gateway_authorizer" "header_authorizer" { + name = "header_authorizer" + rest_api_id = aws_api_gateway_rest_api.api.id + authorizer_uri = aws_lambda_function.authorizer.invoke_arn + authorizer_credentials = aws_iam_role.invocation_role.arn + identity_source = "method.request.header.myheader" + identity_validation_expression = "^123$" +} + +resource "aws_lambda_function" "authorizer" { + filename = "lambda-functions.zip" + function_name = "authorizer" + role = aws_iam_role.invocation_role.arn + handler = "handlers.auth_handler" + runtime = "python3.8" + source_code_hash = filebase64sha256("lambda-functions.zip") +} + +resource "aws_lambda_function" "hello_endpoint" { + filename = "lambda-functions.zip" + function_name = "hello_lambda" + role = aws_iam_role.invocation_role.arn + handler = "handlers.hello_handler" + runtime = "python3.8" + source_code_hash = filebase64sha256("lambda-functions.zip") +} + +resource "aws_api_gateway_method" "get_hello" { + rest_api_id = aws_api_gateway_rest_api.api.id + resource_id = aws_api_gateway_resource.hello_resource.id + http_method = "GET" + authorizer_id = aws_api_gateway_authorizer.header_authorizer.id + authorization = "CUSTOM" +} + +resource "aws_api_gateway_resource" "hello_resource" { + rest_api_id = aws_api_gateway_rest_api.api.id + parent_id = aws_api_gateway_rest_api.api.root_resource_id + path_part = "hello" +} + +resource "aws_api_gateway_integration" "MyDemoIntegration" { + rest_api_id = aws_api_gateway_rest_api.api.id + resource_id = aws_api_gateway_resource.hello_resource.id + http_method = aws_api_gateway_method.get_hello.http_method + type = "AWS_PROXY" + content_handling = "CONVERT_TO_TEXT" + uri = aws_lambda_function.hello_endpoint.invoke_arn +} + +resource "aws_api_gateway_rest_api" "api" { + name = "api" +} + +resource "aws_iam_role" "invocation_role" { + name = "iam_lambda" + path = "/" + assume_role_policy = < Date: Tue, 6 Jun 2023 10:59:19 -0700 Subject: [PATCH 3/4] Removed extra print --- tests/integration/testdata/start_api/lambda_authorizers/app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/testdata/start_api/lambda_authorizers/app.py b/tests/integration/testdata/start_api/lambda_authorizers/app.py index 10657a379f..cfd4b7c84e 100644 --- a/tests/integration/testdata/start_api/lambda_authorizers/app.py +++ b/tests/integration/testdata/start_api/lambda_authorizers/app.py @@ -96,7 +96,6 @@ def auth_handler(event, context): # context['obj'] = {'foo':'bar'} <- also invalid authResponse['context'] = context - print(authResponse) return authResponse From f13fc3be554a39a813c8f97ba6385dcfcb7dfc0b Mon Sep 17 00:00:00 2001 From: Lucas <12496191+lucashuy@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:49:07 -0700 Subject: [PATCH 4/4] Add request based authorizer testing --- ...st_start_api_with_terraform_application.py | 27 ++++++-- .../terraform/v1-lambda-authorizer/main.tf | 64 +++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/tests/integration/local/start_api/test_start_api_with_terraform_application.py b/tests/integration/local/start_api/test_start_api_with_terraform_application.py index b7bbfd3b7a..fc991445b0 100644 --- a/tests/integration/local/start_api/test_start_api_with_terraform_application.py +++ b/tests/integration/local/start_api/test_start_api_with_terraform_application.py @@ -3,7 +3,7 @@ from pathlib import Path from typing import Optional from unittest import skipIf -from http.client import HTTPConnection +from parameterized import parameterized import pytest import requests @@ -67,13 +67,32 @@ class TestStartApiTerraformApplicationV1LambdaAuthorizers(TerraformStartApiInteg def setUp(self): self.url = "http://127.0.0.1:{}".format(self.port) - def test_invoke_authorizer(self): - response = requests.get(self.url + "/hello", timeout=300, headers={"myheader": "123"}) + @parameterized.expand( + [ + ("/hello", {"headers": {"myheader": "123"}}), + ("/hello-request", {"headers": {"myheader": "123"}, "params": {"mystring": "456"}}), + ("/hello-request-empty", {}), + ("/hello-request-empty", {"headers": {"foo": "bar"}}), + ] + ) + def test_invoke_authorizer(self, endpoint, parameters): + response = requests.get(self.url + endpoint, timeout=300, **parameters) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), {"message": "from authorizer"}) - def test_fails_validation(self): + @parameterized.expand( + [ + ("/hello", {"headers": {"blank": "invalid"}}), + ("/hello-request", {"headers": {"blank": "invalid"}, "params": {"blank": "invalid"}}), + ] + ) + def test_missing_authorizer_identity_source(self, endpoint, parameters): + response = requests.get(self.url + endpoint, timeout=300, **parameters) + + self.assertEqual(response.status_code, 401) + + def test_fails_token_header_validation_authorizer(self): response = requests.get(self.url + "/hello", timeout=300, headers={"myheader": "not valid"}) self.assertEqual(response.status_code, 401) diff --git a/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf b/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf index 6218a7470d..b3dcc7b51c 100644 --- a/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf +++ b/tests/integration/testdata/start_api/terraform/v1-lambda-authorizer/main.tf @@ -9,6 +9,24 @@ resource "aws_api_gateway_authorizer" "header_authorizer" { identity_validation_expression = "^123$" } +resource "aws_api_gateway_authorizer" "request_authorizer" { + name = "request_authorizer" + rest_api_id = aws_api_gateway_rest_api.api.id + authorizer_uri = aws_lambda_function.authorizer.invoke_arn + authorizer_credentials = aws_iam_role.invocation_role.arn + identity_source = "method.request.header.myheader, method.request.querystring.mystring" + type = "REQUEST" +} + +resource "aws_api_gateway_authorizer" "request_authorizer_empty" { + name = "request_authorizer" + rest_api_id = aws_api_gateway_rest_api.api.id + authorizer_uri = aws_lambda_function.authorizer.invoke_arn + authorizer_credentials = aws_iam_role.invocation_role.arn + identity_source = "" + type = "REQUEST" +} + resource "aws_lambda_function" "authorizer" { filename = "lambda-functions.zip" function_name = "authorizer" @@ -35,12 +53,40 @@ resource "aws_api_gateway_method" "get_hello" { authorization = "CUSTOM" } +resource "aws_api_gateway_method" "get_hello_request" { + rest_api_id = aws_api_gateway_rest_api.api.id + resource_id = aws_api_gateway_resource.hello_resource_request.id + http_method = "GET" + authorizer_id = aws_api_gateway_authorizer.request_authorizer.id + authorization = "CUSTOM" +} + +resource "aws_api_gateway_method" "get_hello_request_empty" { + rest_api_id = aws_api_gateway_rest_api.api.id + resource_id = aws_api_gateway_resource.hello_resource_request_empty.id + http_method = "GET" + authorizer_id = aws_api_gateway_authorizer.request_authorizer_empty.id + authorization = "CUSTOM" +} + resource "aws_api_gateway_resource" "hello_resource" { rest_api_id = aws_api_gateway_rest_api.api.id parent_id = aws_api_gateway_rest_api.api.root_resource_id path_part = "hello" } +resource "aws_api_gateway_resource" "hello_resource_request" { + rest_api_id = aws_api_gateway_rest_api.api.id + parent_id = aws_api_gateway_rest_api.api.root_resource_id + path_part = "hello-request" +} + +resource "aws_api_gateway_resource" "hello_resource_request_empty" { + rest_api_id = aws_api_gateway_rest_api.api.id + parent_id = aws_api_gateway_rest_api.api.root_resource_id + path_part = "hello-request-empty" +} + resource "aws_api_gateway_integration" "MyDemoIntegration" { rest_api_id = aws_api_gateway_rest_api.api.id resource_id = aws_api_gateway_resource.hello_resource.id @@ -50,6 +96,24 @@ resource "aws_api_gateway_integration" "MyDemoIntegration" { uri = aws_lambda_function.hello_endpoint.invoke_arn } +resource "aws_api_gateway_integration" "MyDemoIntegrationRequest" { + rest_api_id = aws_api_gateway_rest_api.api.id + resource_id = aws_api_gateway_resource.hello_resource_request.id + http_method = aws_api_gateway_method.get_hello_request.http_method + type = "AWS_PROXY" + content_handling = "CONVERT_TO_TEXT" + uri = aws_lambda_function.hello_endpoint.invoke_arn +} + +resource "aws_api_gateway_integration" "MyDemoIntegrationRequestEmpty" { + rest_api_id = aws_api_gateway_rest_api.api.id + resource_id = aws_api_gateway_resource.hello_resource_request_empty.id + http_method = aws_api_gateway_method.get_hello_request_empty.http_method + type = "AWS_PROXY" + content_handling = "CONVERT_TO_TEXT" + uri = aws_lambda_function.hello_endpoint.invoke_arn +} + resource "aws_api_gateway_rest_api" "api" { name = "api" }