Skip to content

Commit

Permalink
fix: fix lambda permission for API path parameters (#992)
Browse files Browse the repository at this point in the history
  • Loading branch information
53ningen authored and jlhood committed Jul 26, 2019
1 parent 7fd10a7 commit 5f886df
Show file tree
Hide file tree
Showing 7 changed files with 428 additions and 1 deletion.
2 changes: 1 addition & 1 deletion samtranslator/model/eventsources/push.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ def _get_permission(self, resources_to_link, stage, suffix):
if not stage or not suffix:
raise RuntimeError("Could not add permission to lambda function.")

path = path.replace('{proxy+}', '*')
path = re.sub(r'{([a-zA-Z0-9._-]+|proxy\+)}', '*', path)
method = '*' if self.Method.lower() == 'any' else self.Method.upper()

api_id = self.RestApiId
Expand Down
30 changes: 30 additions & 0 deletions tests/model/eventsources/test_api_event_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,36 @@ def test_get_permission_with_trailing_slash(self):

self.assertEqual(arn, "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/foo")

@patch("boto3.session.Session.region_name", "eu-west-2")
def test_get_permission_with_path_parameter(self):
self.api_event_source.Path = "/foo/{userId}/bar"
cfn = self.api_event_source.to_cloudformation(function=self.func, explicit_api={})

perm = cfn[0]
self.assertIsInstance(perm, LambdaPermission)

try:
arn = self._extract_path_from_arn("{}PermissionTest".format(self.logical_id), perm)
except AttributeError:
self.fail("Permission class isn't valid")

self.assertEqual(arn, "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/foo/*/bar")

@patch("boto3.session.Session.region_name", "eu-west-2")
def test_get_permission_with_proxy_resource(self):
self.api_event_source.Path = "/foo/{proxy+}"
cfn = self.api_event_source.to_cloudformation(function=self.func, explicit_api={})

perm = cfn[0]
self.assertIsInstance(perm, LambdaPermission)

try:
arn = self._extract_path_from_arn("{}PermissionTest".format(self.logical_id), perm)
except AttributeError:
self.fail("Permission class isn't valid")

self.assertEqual(arn, "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/foo/*")

@patch("boto3.session.Session.region_name", "eu-west-2")
def test_get_permission_with_just_slash(self):
self.api_event_source.Path = "/"
Expand Down
20 changes: 20 additions & 0 deletions tests/translator/input/api_with_path_parameters.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Resources:
HtmlFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://sam-demo-bucket/member_portal.zip
Handler: index.gethtml
Runtime: nodejs4.3
Events:
GetHtml:
Type: Api
Properties:
RestApiId: HtmlApi
Path: /{prameter}/resources
Method: get

HtmlApi:
Type: AWS::Serverless::Api
Properties:
StageName: Prod
DefinitionUri: s3://sam-demo-bucket/webpage_swagger.json
120 changes: 120 additions & 0 deletions tests/translator/output/api_with_path_parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"Resources": {
"HtmlFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"ManagedPolicyArns": [
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
]
}
}
},
"HtmlApiProdStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "HtmlApiDeploymentf117c932f7"
},
"RestApiId": {
"Ref": "HtmlApi"
},
"StageName": "Prod"
}
},
"HtmlFunctionGetHtmlPermissionProd": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"Principal": "apigateway.amazonaws.com",
"FunctionName": {
"Ref": "HtmlFunction"
},
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources",
{
"__Stage__": "Prod",
"__ApiId__": "HtmlApi"
}
]
}
}
},
"HtmlFunctionGetHtmlPermissionTest": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"Principal": "apigateway.amazonaws.com",
"FunctionName": {
"Ref": "HtmlFunction"
},
"SourceArn": {
"Fn::Sub": [
"arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources",
{
"__Stage__": "*",
"__ApiId__": "HtmlApi"
}
]
}
}
},
"HtmlApiDeploymentf117c932f7": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289",
"StageName": "Stage"
}
},
"HtmlApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"BodyS3Location": {
"Bucket": "sam-demo-bucket",
"Key": "webpage_swagger.json"
}
}
},
"HtmlFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "member_portal.zip"
},
"Handler": "index.gethtml",
"Role": {
"Fn::GetAtt": [
"HtmlFunctionRole",
"Arn"
]
},
"Runtime": "nodejs4.3",
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
]
}
}
}
}
128 changes: 128 additions & 0 deletions tests/translator/output/aws-cn/api_with_path_parameters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
{
"Resources": {
"HtmlFunctionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"ManagedPolicyArns": [
"arn:aws-cn:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
],
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"sts:AssumeRole"
],
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
}
}
]
}
}
},
"HtmlApiProdStage": {
"Type": "AWS::ApiGateway::Stage",
"Properties": {
"DeploymentId": {
"Ref": "HtmlApiDeploymentf117c932f7"
},
"RestApiId": {
"Ref": "HtmlApi"
},
"StageName": "Prod"
}
},
"HtmlFunctionGetHtmlPermissionProd": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"Principal": "apigateway.amazonaws.com",
"FunctionName": {
"Ref": "HtmlFunction"
},
"SourceArn": {
"Fn::Sub": [
"arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources",
{
"__Stage__": "Prod",
"__ApiId__": "HtmlApi"
}
]
}
}
},
"HtmlFunctionGetHtmlPermissionTest": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"Action": "lambda:invokeFunction",
"Principal": "apigateway.amazonaws.com",
"FunctionName": {
"Ref": "HtmlFunction"
},
"SourceArn": {
"Fn::Sub": [
"arn:aws-cn:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/*/resources",
{
"__Stage__": "*",
"__ApiId__": "HtmlApi"
}
]
}
}
},
"HtmlApiDeploymentf117c932f7": {
"Type": "AWS::ApiGateway::Deployment",
"Properties": {
"RestApiId": {
"Ref": "HtmlApi"
},
"Description": "RestApi deployment id: f117c932f75cfa87d23dfed64e9430d0081ef289",
"StageName": "Stage"
}
},
"HtmlApi": {
"Type": "AWS::ApiGateway::RestApi",
"Properties": {
"EndpointConfiguration": {
"Types": [
"REGIONAL"
]
},
"BodyS3Location": {
"Bucket": "sam-demo-bucket",
"Key": "webpage_swagger.json"
},
"Parameters": {
"endpointConfigurationTypes": "REGIONAL"
}
}
},
"HtmlFunction": {
"Type": "AWS::Lambda::Function",
"Properties": {
"Code": {
"S3Bucket": "sam-demo-bucket",
"S3Key": "member_portal.zip"
},
"Handler": "index.gethtml",
"Role": {
"Fn::GetAtt": [
"HtmlFunctionRole",
"Arn"
]
},
"Runtime": "nodejs4.3",
"Tags": [
{
"Value": "SAM",
"Key": "lambda:createdBy"
}
]
}
}
}
}
Loading

0 comments on commit 5f886df

Please sign in to comment.