Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions samtranslator/model/api/http_api_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Comment on lines +315 to +317
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since we are just ignoring the leading and trailing /, I think we can simplify the code as

path = path.strip('/')

...

if not path:
    raise ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, it does look better, however even with this i won't be able to get rid of the if else as i would still have to check if path is "" before I do re.search. so I don't think it will be that useful.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear from reading the code what path is, and why it's reassigned to in such a way (e.g. foo-bar-baz becomes foo-bar... why?).

If it's generating a logical ID from an arbitrary string, we should refactor in such a way; it seems to be a fairly generic use-case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I am not sure about the reason behind creating logical_id like this. But we can try to understand where we use the logical id further and modify the logic accordingly.

I will merge this PR for now and can track this later.

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"))
Expand Down
8 changes: 8 additions & 0 deletions samtranslator/open_api/open_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
4 changes: 2 additions & 2 deletions tests/model/api/test_http_api_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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."
}
1 change: 1 addition & 0 deletions tests/translator/test_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down