From 181bc2d10f3cf327bb046ed4552056184dbfcb46 Mon Sep 17 00:00:00 2001 From: benoit74 Date: Fri, 15 Jul 2016 20:06:19 +0200 Subject: [PATCH] Add support for S3.putBucketPolicy (#3) * Add support for S3.putBucketPolicy * Add support to s3.putBucketPolicy (documentation) * More coherent test case --- README.md | 19 ++++++ aws/s3.js | 31 ++++++++++ ...e_cloudformation_helper_functions.template | 60 +++++++++++++++++++ test/aws/s3.putBucketPolicy.template | 38 ++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 test/aws/s3.putBucketPolicy.template diff --git a/README.md b/README.md index 66c9485..a55684e 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,25 @@ S3PutObjectFunctionArn [s3.putObject.template](test/aws/s3.putObject.template) +### Put S3 Bucket Policy + +Mirrors the [S3.putBucketPolicy API method](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#putBucketPolicy-property). + +This will replace the existing policy if any is already configured. + +#### Parameters + +##### Bucket +The S3 bucket to put the policy + +##### Policy +The policy to put (it is a string containing a JSON description of the policy. All quotes in the policy must hence be escaped) + +#### Reference Output Name +S3PutBucketPolicyFunctionArn + +#### Example/Test Template +[s3.putBucketPolicy.template](test/aws/s3.putBucketPolicy.template) ### Subscribe to SNS topics diff --git a/aws/s3.js b/aws/s3.js index d855a58..a130282 100644 --- a/aws/s3.js +++ b/aws/s3.js @@ -47,3 +47,34 @@ exports.putObject = function(event, context) { handler = new PutObject(event, context); handler.handle(); } + +// Exposes the S3.putBucketPolicy API method +function PutBucketPolicy(event, context) { + base.Handler.call(this, event, context); +} +PutBucketPolicy.prototype = Object.create(base.Handler.prototype); +PutBucketPolicy.prototype.handleCreate = function() { + var p = this.event.ResourceProperties; + delete p.ServiceToken; + return s3.putBucketPolicyAsync(p) + .then(function() { + return { + BucketName : p.Bucket + } + }); +} +PutBucketPolicy.prototype.handleDelete = function(referencedData) { + return Promise.try(function() { + if(referencedData) { + return s3.deleteBucketPolicyAsync({ + Bucket : referencedData.BucketName + }); + } + }); +} +exports.putBucketPolicy = function(event, context) { + console.log(JSON.stringify(event)); + handler = new PutBucketPolicy(event, context); + handler.handle(); +} + diff --git a/create_cloudformation_helper_functions.template b/create_cloudformation_helper_functions.template index 8cc46b3..018aa39 100644 --- a/create_cloudformation_helper_functions.template +++ b/create_cloudformation_helper_functions.template @@ -329,6 +329,62 @@ "S3PutObjectFunctionRole" ] }, + "S3PutBucketPolicyFunctionRole": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Version" : "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { + "Service": [ "lambda.amazonaws.com" ] + }, + "Action": [ "sts:AssumeRole" ] + } + ] + }, + "ManagedPolicyArns": [ + { "Ref": "RoleBasePolicy" } + ], + "Policies": [ + { + "PolicyName": "S3PolicyWriter", + "PolicyDocument": { + "Version" : "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:ListBucket", + "s3:PutBucketPolicy", + "s3:DeleteBucketPolicy" + ], + "Resource": "*" + } + ] + } + } + ] + } + }, + "S3PutBucketPolicyFunction": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": "com.gilt.public.backoffice", + "S3Key": "lambda_functions/cloudformation-helpers.zip" + }, + "Description": "Used to put S3 bucket policy.", + "Handler": "aws/s3.putBucketPolicy", + "Role": {"Fn::GetAtt" : [ "S3PutBucketPolicyFunctionRole", "Arn" ] }, + "Runtime": "nodejs4.3", + "Timeout": 30 + }, + "DependsOn": [ + "S3PutBucketPolicyFunctionRole" + ] + }, "SnsSubscribeFunctionRole": { "Type": "AWS::IAM::Role", "Properties": { @@ -465,6 +521,10 @@ "Description": "The ARN of the S3PutObjectFunction, for use in other CloudFormation templates.", "Value": { "Fn::GetAtt" : ["S3PutObjectFunction", "Arn"] } }, + "S3PutBucketPolicyFunctionArn": { + "Description": "The ARN of the S3PutBucketPolicyFunction, for use in other CloudFormation templates.", + "Value": { "Fn::GetAtt" : ["S3PutBucketPolicyFunction", "Arn"] } + }, "SesCreateReceiptRuleFunctionArn": { "Description": "The ARN of the SesCreateReceiptRuleFunction, for use in other CloudFormation templates.", "Value": { "Fn::GetAtt" : ["SesCreateReceiptRuleFunction", "Arn"] } diff --git a/test/aws/s3.putBucketPolicy.template b/test/aws/s3.putBucketPolicy.template new file mode 100644 index 0000000..fa4a562 --- /dev/null +++ b/test/aws/s3.putBucketPolicy.template @@ -0,0 +1,38 @@ +{ + "AWSTemplateFormatVersion": "2010-09-09", + "Parameters": { + "CFHelperStackName": { + "Type": "String", + "Description": "The name of the stack where you installed the CloudFormation helper functions. See https://github.com/gilt/cloudformation-helpers." + } + }, + "Resources": { + "CFHelperStack": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": "https://s3.amazonaws.com/com.gilt.public.backoffice/cloudformation_templates/lookup_stack_outputs.template" + } + }, + "CFHelper": { + "Type": "Custom::CFHelper", + "Properties": { + "ServiceToken": { "Fn::GetAtt" : ["CFHelperStack", "Outputs.LookupStackOutputsArn"] }, + "StackName": { "Ref": "CFHelperStackName" } + }, + "DependsOn": [ + "CFHelperStack" + ] + }, + "S3PutBucketPolicy": { + "Type": "Custom::S3PutBucketPolicy", + "Properties": { + "ServiceToken": { "Fn::GetAtt" : ["CFHelper", "S3PutBucketPolicyFunctionArn"] }, + "Bucket": "my-test-bucket321", + "Policy": "{ \"Version\": \"2008-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"Service\": \"ses.amazonaws.com\" }, \"Action\": \"s3:PutObject\", \"Resource\": \"arn:aws:s3:::my-test-bucket321/*\" } ] }" + }, + "DependsOn": [ + "CFHelper" + ] + } + } +}