forked from frankleonrose/api-gateway-auth-plugin
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ApiGatewayAuthExtension.js
94 lines (80 loc) · 2.65 KB
/
ApiGatewayAuthExtension.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*jshint node:true, esversion:6, multistr:true, eqnull:true */
'use strict';
/**
* Adds the posibility to configure AWS_IAM for your API Gateway endpoints
* and "Invoke with caller credentials"
*
* Usage:
*
* myFuncGetItem:
* handler: myFunc.get
* name: ${self:provider.stage}-myFunc-get-item
* memorySize: 128
* events:
* - http:
* method: GET
* path: mypath
* cors: true
* useIAMAuth: true
* invokeWithCallerCredentials: true
*/
class ApiGatewayAuthExtension {
constructor(serverless, options) {
this.serverless = serverless;
this.options = options;
this.hooks = {
'deploy:compileEvents': this._compileEvents.bind(this)
};
}
_capitalizeAlphaNumericPath(path) {
path = path.toLowerCase();
path = path.replace(/-/g, 'Dash');
path = path.replace(/\{(.*)\}/g, '$1Var');
path = path.replace(/[^0-9A-Za-z]/g, '');
path = path.charAt(0).toUpperCase() + path.slice(1);
return path;
}
_compileEvents() {
const tmp = this.serverless.service.provider.compiledCloudFormationTemplate;
const resources = tmp.Resources;
const iamFunctions = this.serverless.service.custom.useApiGatewayIAMAuthForLambdaFunctions;
this.serverless.service.getAllFunctions().forEach((functionName) => {
const functionObject = this.serverless.service.functions[functionName];
functionObject.events.forEach(event => {
if (!event.http) {return;}
if (event.http.useIAMAuth || event.http.invokeWithCallerCredentials) {
let path;
let method;
if (typeof event.http === 'object') {
path = event.http.path;
method = event.http.method;
} else if (typeof event.http === 'string') {
path = event.http.split(' ')[1];
method = event.http.split(' ')[0];
}
const resourcesArray = path.split('/');
const normalizedResourceName = resourcesArray.map(this._capitalizeAlphaNumericPath).join('');
const normalizedMethod = method[0].toUpperCase() + method.substr(1).toLowerCase();
const methodName = `ApiGatewayMethod${normalizedResourceName}${normalizedMethod}`;
if (event.http.useIAMAuth)
{
try{
resources[methodName].Properties.AuthorizationType = 'AWS_IAM';
} catch (e) {
throw new Error("api-gateway-auth-plugin: bad methodName: "+ methodName);
}
}
if (event.http.invokeWithCallerCredentials)
{
try{
resources[methodName].Properties.Integration.Credentials = 'arn:aws:iam::*:user/*';
} catch (e) {
throw new Error("api-gateway-auth-plugin: bad methodName: "+ methodName);
}
}
}
});
});
}
}
module.exports = ApiGatewayAuthExtension;