diff --git a/samtranslator/model/api/http_api_generator.py b/samtranslator/model/api/http_api_generator.py index 6f251fef9..ffcbdb023 100644 --- a/samtranslator/model/api/http_api_generator.py +++ b/samtranslator/model/api/http_api_generator.py @@ -308,11 +308,16 @@ def _construct_basepath_mappings(self, basepaths, http_api): invalid_regex = r"[^0-9a-zA-Z\/\-\_]+" if re.search(invalid_regex, path) is not None: raise InvalidResourceException(self.logical_id, "Invalid Basepath name provided.") - # ignore leading and trailing `/` in the path name - m = re.search(r"[a-zA-Z0-9]+[\-\_]?[a-zA-Z0-9]+", path) - path = m.string[m.start(0) : m.end(0)] - if path is None: - raise InvalidResourceException(self.logical_id, "Invalid Basepath name provided.") + + if path == "/": + path = "" + else: + # ignore leading and trailing `/` in the path name + m = re.search(r"[a-zA-Z0-9]+[\-\_]?[a-zA-Z0-9]+", path) + path = m.string[m.start(0) : m.end(0)] + if path is None: + raise InvalidResourceException(self.logical_id, "Invalid Basepath name provided.") + logical_id = "{}{}{}".format(self.logical_id, re.sub(r"[\-\_]+", "", path), "ApiMapping") basepath_mapping = ApiGatewayV2ApiMapping(logical_id, attributes=self.passthrough_resource_attributes) basepath_mapping.DomainName = ref(self.domain.get("ApiDomainName")) diff --git a/samtranslator/open_api/open_api.py b/samtranslator/open_api/open_api.py index 40bea55f9..cadd105e9 100644 --- a/samtranslator/open_api/open_api.py +++ b/samtranslator/open_api/open_api.py @@ -334,6 +334,14 @@ def set_path_default_authorizer(self, path, default_authorizer, authorizers, api if normalized_method_name != "options": normalized_method_name = self._normalize_method_name(method_name) # It is possible that the method could have two definitions in a Fn::If block. + if normalized_method_name not in self.get_path(path): + raise InvalidDocumentException( + [ + InvalidTemplateException( + "Could not find {} in {} within DefinitionBody.".format(normalized_method_name, path) + ) + ] + ) for method_definition in self.get_method_contents(self.get_path(path)[normalized_method_name]): # If no integration given, then we don't need to process this definition (could be AWS::NoValue) if not self.method_definition_has_integration(method_definition): diff --git a/tests/model/api/test_http_api_generator.py b/tests/model/api/test_http_api_generator.py index c9656d050..404dd7f41 100644 --- a/tests/model/api/test_http_api_generator.py +++ b/tests/model/api/test_http_api_generator.py @@ -237,14 +237,14 @@ def test_basepaths(self): self.kwargs["domain"] = { "DomainName": "example.com", "CertificateArn": "some-url", - "BasePath": ["one-1", "two_2", "three"], + "BasePath": ["one-1", "two_2", "three", "/"], "Route53": {"HostedZoneId": "xyz", "HostedZoneName": "abc", "IpV6": True}, } http_api = HttpApiGenerator(**self.kwargs)._construct_http_api() domain, basepath, route = HttpApiGenerator(**self.kwargs)._construct_api_domain(http_api) self.assertIsNotNone(domain, None) self.assertIsNotNone(basepath, None) - self.assertEqual(len(basepath), 3) + self.assertEqual(len(basepath), 4) self.assertIsNotNone(route, None) self.assertEqual(route.HostedZoneName, None) self.assertEqual(route.HostedZoneId, "xyz") diff --git a/tests/translator/input/error_implicit_http_api_auth_any_method.yaml b/tests/translator/input/error_implicit_http_api_auth_any_method.yaml new file mode 100644 index 000000000..c5b848610 --- /dev/null +++ b/tests/translator/input/error_implicit_http_api_auth_any_method.yaml @@ -0,0 +1,24 @@ +Resources: + SomeHttpApi: + Type: AWS::Serverless::HttpApi + Properties: + DefinitionBody: + paths: + "/{domain}": + any: + responses: {} + "/{domain/}{id}": + any: + responses: {} + openapi: 3.0.1 + Auth: + Authorizers: + OAuth2Authorizer: + AuthorizationScopes: + - email + JwtConfiguration: + audience: + - randomnumber + issuer: https://some/issuer + IdentitySource: "$request.headers.Authorization" + DefaultAuthorizer: OAuth2Authorizer \ No newline at end of file diff --git a/tests/translator/output/error_implicit_http_api_auth_any_method.json b/tests/translator/output/error_implicit_http_api_auth_any_method.json new file mode 100644 index 000000000..7064fdf5b --- /dev/null +++ b/tests/translator/output/error_implicit_http_api_auth_any_method.json @@ -0,0 +1,3 @@ +{ + "errorMessage": "Invalid Serverless Application Specification document. Number of errors found: 1. Structure of the SAM template is invalid. Could not find x-amazon-apigateway-any-method in /{domain} within DefinitionBody." +} \ No newline at end of file diff --git a/tests/translator/test_translator.py b/tests/translator/test_translator.py index 76f3f291d..db19ce446 100644 --- a/tests/translator/test_translator.py +++ b/tests/translator/test_translator.py @@ -658,6 +658,7 @@ def _generate_new_deployment_hash(self, logical_id, dict_to_hash, rest_api_to_sw "error_httpapi_mtls_configuration_invalid_field", "error_httpapi_mtls_configuration_invalid_type", "error_resource_policy_not_dict", + "error_implicit_http_api_auth_any_method", ], ) @patch("boto3.session.Session.region_name", "ap-southeast-1")