Skip to content

Commit 9206af9

Browse files
committed
feat: allow private for sns, dynamodb, kinesis, and s3
1 parent 81f49fa commit 9206af9

File tree

4 files changed

+466
-0
lines changed

4 files changed

+466
-0
lines changed

lib/package/dynamodb/compileMethodsToDynamodb.test.js

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,117 @@ describe('#compileMethodsToDynamodb()', () => {
825825
})
826826
})
827827
})
828+
829+
describe('#private', () => {
830+
it('should create corresponding resources when a dynamodb proxy is given with private', () => {
831+
serverlessApigatewayServiceProxy.validated = {
832+
events: [
833+
{
834+
serviceName: 'dynamodb',
835+
http: {
836+
path: 'dynamodb',
837+
method: 'post',
838+
action: 'PutItem',
839+
tableName: {
840+
Ref: 'MyTable'
841+
},
842+
key: 'key',
843+
private: true,
844+
auth: { authorizationType: 'NONE' }
845+
}
846+
}
847+
]
848+
}
849+
serverlessApigatewayServiceProxy.apiGatewayRestApiLogicalId = 'ApiGatewayRestApi'
850+
serverlessApigatewayServiceProxy.apiGatewayResources = {
851+
dynamodb: {
852+
name: 'dynamodb',
853+
resourceLogicalId: 'ApiGatewayResourceDynamodb'
854+
}
855+
}
856+
857+
serverlessApigatewayServiceProxy.compileMethodsToDynamodb()
858+
expect(serverless.service.provider.compiledCloudFormationTemplate.Resources).to.deep.equal({
859+
ApiGatewayMethoddynamodbPost: {
860+
Type: 'AWS::ApiGateway::Method',
861+
Properties: {
862+
HttpMethod: 'POST',
863+
RequestParameters: {},
864+
AuthorizationScopes: undefined,
865+
AuthorizerId: undefined,
866+
AuthorizationType: 'NONE',
867+
ApiKeyRequired: true,
868+
ResourceId: { Ref: 'ApiGatewayResourceDynamodb' },
869+
RestApiId: { Ref: 'ApiGatewayRestApi' },
870+
Integration: {
871+
IntegrationHttpMethod: 'POST',
872+
Type: 'AWS',
873+
Credentials: { 'Fn::GetAtt': ['ApigatewayToDynamodbRole', 'Arn'] },
874+
Uri: {
875+
'Fn::Sub': [
876+
'arn:aws:apigateway:${AWS::Region}:dynamodb:action/${action}',
877+
{ action: 'PutItem' }
878+
]
879+
},
880+
PassthroughBehavior: 'NEVER',
881+
RequestTemplates: {
882+
'application/json': {
883+
'Fn::Sub': [
884+
'{"TableName": "${TableName}","Item": {\n #set ($body = $util.parseJson($input.body))\n #foreach( $key in $body.keySet())\n #set ($item = $body.get($key))\n #foreach( $type in $item.keySet())\n "$key":{"$type" : "$item.get($type)"}\n #if($foreach.hasNext()),#end\n #end\n #if($foreach.hasNext()),#end\n #end\n }\n }',
885+
{ TableName: { Ref: 'MyTable' } }
886+
]
887+
},
888+
'application/x-www-form-urlencoded': {
889+
'Fn::Sub': [
890+
'{"TableName": "${TableName}","Item": {\n #set ($body = $util.parseJson($input.body))\n #foreach( $key in $body.keySet())\n #set ($item = $body.get($key))\n #foreach( $type in $item.keySet())\n "$key":{"$type" : "$item.get($type)"}\n #if($foreach.hasNext()),#end\n #end\n #if($foreach.hasNext()),#end\n #end\n }\n }',
891+
{ TableName: { Ref: 'MyTable' } }
892+
]
893+
}
894+
},
895+
IntegrationResponses: [
896+
{
897+
StatusCode: 200,
898+
SelectionPattern: '2\\d{2}',
899+
ResponseParameters: {},
900+
ResponseTemplates: {}
901+
},
902+
{
903+
StatusCode: 400,
904+
SelectionPattern: '4\\d{2}',
905+
ResponseParameters: {},
906+
ResponseTemplates: {}
907+
},
908+
{
909+
StatusCode: 500,
910+
SelectionPattern: '5\\d{2}',
911+
ResponseParameters: {},
912+
ResponseTemplates: {}
913+
}
914+
]
915+
},
916+
MethodResponses: [
917+
{
918+
ResponseParameters: {},
919+
ResponseModels: {},
920+
StatusCode: 200
921+
},
922+
{
923+
ResponseParameters: {},
924+
ResponseModels: {},
925+
StatusCode: 400
926+
},
927+
{
928+
ResponseParameters: {},
929+
ResponseModels: {},
930+
StatusCode: 500
931+
}
932+
]
933+
}
934+
}
935+
})
936+
})
937+
})
938+
828939
describe('#authorization', () => {
829940
const testAuthorization = (auth) => {
830941
const param = {

lib/package/kinesis/compileMethodsToKinesis.test.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,118 @@ describe('#compileMethodsToKinesis()', () => {
249249
})
250250
})
251251

252+
it('should create corresponding resources when kinesis proxies are given with private', () => {
253+
serverlessApigatewayServiceProxy.validated = {
254+
events: [
255+
{
256+
serviceName: 'kinesis',
257+
http: {
258+
streamName: 'myStream',
259+
path: 'kinesis',
260+
method: 'post',
261+
auth: {
262+
authorizationType: 'NONE'
263+
},
264+
private: true
265+
}
266+
}
267+
]
268+
}
269+
serverlessApigatewayServiceProxy.apiGatewayRestApiLogicalId = 'ApiGatewayRestApi'
270+
serverlessApigatewayServiceProxy.apiGatewayResources = {
271+
kinesis: {
272+
name: 'kinesis',
273+
resourceLogicalId: 'ApiGatewayResourceKinesis'
274+
}
275+
}
276+
277+
serverlessApigatewayServiceProxy.compileMethodsToKinesis()
278+
279+
expect(serverless.service.provider.compiledCloudFormationTemplate.Resources).to.deep.equal({
280+
ApiGatewayMethodkinesisPost: {
281+
Type: 'AWS::ApiGateway::Method',
282+
Properties: {
283+
HttpMethod: 'POST',
284+
RequestParameters: {},
285+
AuthorizationType: 'NONE',
286+
AuthorizerId: undefined,
287+
AuthorizationScopes: undefined,
288+
ApiKeyRequired: true,
289+
ResourceId: { Ref: 'ApiGatewayResourceKinesis' },
290+
RestApiId: { Ref: 'ApiGatewayRestApi' },
291+
Integration: {
292+
IntegrationHttpMethod: 'POST',
293+
Type: 'AWS',
294+
Credentials: { 'Fn::GetAtt': ['ApigatewayToKinesisRole', 'Arn'] },
295+
Uri: {
296+
'Fn::Sub': 'arn:aws:apigateway:${AWS::Region}:kinesis:action/PutRecord'
297+
},
298+
PassthroughBehavior: 'NEVER',
299+
RequestTemplates: {
300+
'application/json': {
301+
'Fn::Sub': [
302+
'{"StreamName":"${StreamName}","Data":"${Data}","PartitionKey":"${PartitionKey}"}',
303+
{
304+
StreamName: 'myStream',
305+
Data: '$util.base64Encode($input.body)',
306+
PartitionKey: '$context.requestId'
307+
}
308+
]
309+
},
310+
'application/x-www-form-urlencoded': {
311+
'Fn::Sub': [
312+
'{"StreamName":"${StreamName}","Data":"${Data}","PartitionKey":"${PartitionKey}"}',
313+
{
314+
StreamName: 'myStream',
315+
Data: '$util.base64Encode($input.body)',
316+
PartitionKey: '$context.requestId'
317+
}
318+
]
319+
}
320+
},
321+
IntegrationResponses: [
322+
{
323+
StatusCode: 200,
324+
SelectionPattern: 200,
325+
ResponseParameters: {},
326+
ResponseTemplates: {}
327+
},
328+
{
329+
StatusCode: 400,
330+
SelectionPattern: 400,
331+
ResponseParameters: {},
332+
ResponseTemplates: {}
333+
},
334+
{
335+
StatusCode: 500,
336+
SelectionPattern: 500,
337+
ResponseParameters: {},
338+
ResponseTemplates: {}
339+
}
340+
]
341+
},
342+
MethodResponses: [
343+
{
344+
ResponseParameters: {},
345+
ResponseModels: {},
346+
StatusCode: 200
347+
},
348+
{
349+
ResponseParameters: {},
350+
ResponseModels: {},
351+
StatusCode: 400
352+
},
353+
{
354+
ResponseParameters: {},
355+
ResponseModels: {},
356+
StatusCode: 500
357+
}
358+
]
359+
}
360+
}
361+
})
362+
})
363+
252364
it('should return the default template for application/json when one is not given', () => {
253365
const httpWithoutRequestTemplate = {
254366
path: 'foo/bar1',

lib/package/s3/compileMethodsToS3.test.js

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,124 @@ describe('#compileMethodsToS3()', () => {
472472
})
473473
})
474474

475+
it('should create corresponding resources when a s3 proxy is given with private', () => {
476+
serverlessApigatewayServiceProxy.validated = {
477+
events: [
478+
{
479+
serviceName: 's3',
480+
http: {
481+
path: 's3',
482+
method: 'post',
483+
bucket: {
484+
Ref: 'MyBucket'
485+
},
486+
action: 'PutObject',
487+
key: {
488+
pathParam: 'key'
489+
},
490+
private: true,
491+
auth: { authorizationType: 'NONE' }
492+
}
493+
}
494+
]
495+
}
496+
serverlessApigatewayServiceProxy.apiGatewayRestApiLogicalId = 'ApiGatewayRestApi'
497+
serverlessApigatewayServiceProxy.apiGatewayResources = {
498+
s3: {
499+
name: 's3',
500+
resourceLogicalId: 'ApiGatewayResourceS3'
501+
}
502+
}
503+
504+
serverlessApigatewayServiceProxy.compileMethodsToS3()
505+
expect(serverless.service.provider.compiledCloudFormationTemplate.Resources).to.deep.equal({
506+
ApiGatewayMethods3Post: {
507+
Type: 'AWS::ApiGateway::Method',
508+
Properties: {
509+
HttpMethod: 'POST',
510+
RequestParameters: {
511+
'method.request.header.Content-Type': true,
512+
'method.request.path.key': true
513+
},
514+
AuthorizationType: 'NONE',
515+
AuthorizationScopes: undefined,
516+
AuthorizerId: undefined,
517+
ApiKeyRequired: true,
518+
ResourceId: { Ref: 'ApiGatewayResourceS3' },
519+
RestApiId: { Ref: 'ApiGatewayRestApi' },
520+
Integration: {
521+
Type: 'AWS',
522+
IntegrationHttpMethod: 'PUT',
523+
Credentials: { 'Fn::GetAtt': ['ApigatewayToS3Role', 'Arn'] },
524+
Uri: {
525+
'Fn::Sub': ['arn:aws:apigateway:${AWS::Region}:s3:path/{bucket}/{object}', {}]
526+
},
527+
PassthroughBehavior: 'WHEN_NO_MATCH',
528+
RequestParameters: {
529+
'integration.request.header.Content-Type': 'method.request.header.Content-Type',
530+
'integration.request.header.x-amz-acl': "'authenticated-read'",
531+
'integration.request.path.bucket': {
532+
'Fn::Sub': [
533+
"'${bucket}'",
534+
{
535+
bucket: {
536+
Ref: 'MyBucket'
537+
}
538+
}
539+
]
540+
},
541+
'integration.request.path.object': 'method.request.path.key'
542+
},
543+
IntegrationResponses: [
544+
{
545+
StatusCode: 400,
546+
SelectionPattern: '4\\d{2}',
547+
ResponseParameters: {},
548+
ResponseTemplates: {}
549+
},
550+
{
551+
StatusCode: 500,
552+
SelectionPattern: '5\\d{2}',
553+
ResponseParameters: {},
554+
ResponseTemplates: {}
555+
},
556+
{
557+
StatusCode: 200,
558+
SelectionPattern: '2\\d{2}',
559+
ResponseParameters: {
560+
'method.response.header.Content-Type': 'integration.response.header.Content-Type',
561+
'method.response.header.Content-Length':
562+
'integration.response.header.Content-Length'
563+
},
564+
ResponseTemplates: {}
565+
}
566+
]
567+
},
568+
MethodResponses: [
569+
{
570+
ResponseParameters: {
571+
'method.response.header.Content-Type': true,
572+
'method.response.header.Content-Length': true
573+
},
574+
ResponseModels: {},
575+
StatusCode: 200
576+
},
577+
{
578+
ResponseParameters: {},
579+
ResponseModels: {},
580+
StatusCode: 400
581+
},
582+
{
583+
ResponseParameters: {},
584+
ResponseModels: {},
585+
StatusCode: 500
586+
}
587+
]
588+
}
589+
}
590+
})
591+
})
592+
475593
const testAuthorization = (auth) => {
476594
const http = {
477595
path: 's3',

0 commit comments

Comments
 (0)