N8N-4134 Add AWS cred testing and http custom calls with credentials (#3924)

*  Add Aws testing and http custom api
This commit is contained in:
agobrech
2022-08-23 19:02:32 +02:00
committed by GitHub
parent a85d565ffc
commit 5285fc1de6
10 changed files with 196 additions and 231 deletions

View File

@@ -1,4 +1,12 @@
import { ICredentialType, INodeProperties } from 'n8n-workflow';
import { Request, sign } from 'aws4';
import { ICredentialTestRequest, IHttpRequestMethods } from 'n8n-workflow';
import {
ICredentialDataDecryptedObject,
ICredentialType,
IDataObject,
IHttpRequestOptions,
INodeProperties,
} from 'n8n-workflow';
export const regions = [
{
@@ -259,4 +267,98 @@ export class Aws implements ICredentialType {
placeholder: 'https://s3.{region}.amazonaws.com',
},
];
async authenticate(
credentials: ICredentialDataDecryptedObject,
requestOptions: IHttpRequestOptions,
): Promise<IHttpRequestOptions> {
let endpoint;
let service = requestOptions.qs?.service;
let path = requestOptions.qs?.path;
const method = requestOptions.method;
const body = requestOptions.body;
let region = credentials.region;
const query = requestOptions.qs?.query as IDataObject;
if (!requestOptions.baseURL && !requestOptions.url) {
if (service === 'lambda' && credentials.lambdaEndpoint) {
endpoint = credentials.lambdaEndpoint;
} else if (service === 'sns' && credentials.snsEndpoint) {
endpoint = credentials.snsEndpoint;
} else if (service === 'sqs' && credentials.sqsEndpoint) {
endpoint = credentials.sqsEndpoint;
} else if (service === 's3' && credentials.s3Endpoint) {
endpoint = credentials.s3Endpoint;
} else if (service === 'ses' && credentials.sesEndpoint) {
endpoint = credentials.sesEndpoint;
} else if (service === 'rekognition' && credentials.rekognitionEndpoint) {
endpoint = credentials.rekognitionEndpoint;
} else if (service === 'sqs' && credentials.sqsEndpoint) {
endpoint = credentials.sqsEndpoint;
} else if (service) {
endpoint = `https://${service}.${credentials.region}.amazonaws.com`;
}
endpoint = new URL((endpoint as string).replace('{region}', credentials.region as string));
} else {
// If no endpoint is set, we try to decompose the path and use the default endpoint
const customUrl = new URL(requestOptions.baseURL! + requestOptions.url!);
service = customUrl.hostname.split('.')[0] as string;
region = customUrl.hostname.split('.')[1] as string;
if (service === 'sts') {
try {
customUrl.searchParams.set('Action', 'GetCallerIdentity');
customUrl.searchParams.append('Version', '2011-06-15');
} catch (err) {
console.log(err);
}
}
path = customUrl.pathname as string;
endpoint = customUrl;
}
if (service === 's3' && credentials.s3Endpoint) {
path = `${endpoint.pathname}?${queryToString(query).replace(/\+/g, '%2B')}`;
}
const signOpts = {
headers: requestOptions.headers,
host: endpoint.host,
method,
path,
body,
region,
} as Request;
const securityHeaders = {
accessKeyId: `${credentials.accessKeyId}`.trim(),
secretAccessKey: `${credentials.secretAccessKey}`.trim(),
sessionToken: credentials.temporaryCredentials
? `${credentials.sessionToken}`.trim()
: undefined,
};
try {
sign(signOpts, securityHeaders);
} catch (err) {
console.log(err);
}
const options: IHttpRequestOptions = {
headers: signOpts.headers,
method,
url: endpoint.origin + path,
body: signOpts.body,
};
return options;
}
test: ICredentialTestRequest = {
request: {
baseURL: '=https://sts.{{$credentials.region}}.amazonaws.com',
url: '?Action=GetCallerIdentity&Version=2011-06-15',
method: 'POST',
},
};
}
function queryToString(params: IDataObject) {
return Object.keys(params)
.map((key) => key + '=' + params[key])
.join('&');
}