feat: bruno cli awsv4 auth support

This commit is contained in:
Anoop M D
2024-02-23 23:42:28 +05:30
parent 5fece08f4b
commit 43c873422f
7 changed files with 231 additions and 4 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@usebruno/cli",
"version": "1.9.0",
"version": "1.9.1",
"license": "MIT",
"main": "src/index.js",
"bin": {
@@ -24,9 +24,11 @@
"package.json"
],
"dependencies": {
"@aws-sdk/credential-providers": "^3.425.0",
"@usebruno/common": "0.1.0",
"@usebruno/js": "0.10.1",
"@usebruno/lang": "0.10.0",
"aws4-axios": "^3.3.0",
"axios": "^1.5.1",
"chai": "^4.3.7",
"chalk": "^3.0.0",

View File

@@ -0,0 +1,56 @@
const { fromIni } = require('@aws-sdk/credential-providers');
const { aws4Interceptor } = require('aws4-axios');
function isStrPresent(str) {
return str && str !== '' && str !== 'undefined';
}
async function resolveAwsV4Credentials(request) {
const awsv4 = request.awsv4config;
if (isStrPresent(awsv4.profileName)) {
try {
credentialsProvider = fromIni({
profile: awsv4.profileName
});
credentials = await credentialsProvider();
awsv4.accessKeyId = credentials.accessKeyId;
awsv4.secretAccessKey = credentials.secretAccessKey;
awsv4.sessionToken = credentials.sessionToken;
} catch {
console.error('Failed to fetch credentials from AWS profile.');
}
}
return awsv4;
}
function addAwsV4Interceptor(axiosInstance, request) {
if (!request.awsv4config) {
console.warn('No Auth Config found!');
return;
}
const awsv4 = request.awsv4config;
if (!isStrPresent(awsv4.accessKeyId) || !isStrPresent(awsv4.secretAccessKey)) {
console.warn('Required Auth Fields are not present');
return;
}
const interceptor = aws4Interceptor({
options: {
region: awsv4.region,
service: awsv4.service
},
credentials: {
accessKeyId: awsv4.accessKeyId,
secretAccessKey: awsv4.secretAccessKey,
sessionToken: awsv4.sessionToken
}
});
axiosInstance.interceptors.request.use(interceptor);
}
module.exports = {
addAwsV4Interceptor,
resolveAwsV4Credentials
};

View File

@@ -57,6 +57,17 @@ const prepareRequest = (request, collectionRoot) => {
};
}
if (request.auth.mode === 'awsv4') {
axiosRequest.awsv4config = {
accessKeyId: get(request, 'auth.awsv4.accessKeyId'),
secretAccessKey: get(request, 'auth.awsv4.secretAccessKey'),
sessionToken: get(request, 'auth.awsv4.sessionToken'),
service: get(request, 'auth.awsv4.service'),
region: get(request, 'auth.awsv4.region'),
profileName: get(request, 'auth.awsv4.profileName')
};
}
if (request.auth.mode === 'bearer') {
axiosRequest.headers['authorization'] = `Bearer ${get(request, 'auth.bearer.token')}`;
}

View File

@@ -15,6 +15,7 @@ const https = require('https');
const { HttpProxyAgent } = require('http-proxy-agent');
const { SocksProxyAgent } = require('socks-proxy-agent');
const { makeAxiosInstance } = require('../utils/axios-instance');
const { addAwsV4Interceptor, resolveAwsV4Credentials } = require('./awsv4auth-helper');
const { shouldUseProxy, PatchedHttpsProxyAgent } = require('../utils/proxy-util');
const protocolRegex = /^([-+\w]{1,25})(:?\/\/|:)/;
@@ -190,6 +191,12 @@ const runSingleRequest = async function (
// run request
const axiosInstance = makeAxiosInstance();
if (request.awsv4config) {
request.awsv4config = await resolveAwsV4Credentials(request);
addAwsV4Interceptor(axiosInstance, request);
delete request.awsv4config;
}
/** @type {import('axios').AxiosResponse} */
response = await axiosInstance(request);