Skip to content

Commit

Permalink
[FEATURE] Allow overriding the aws service identifier in AwsSigv4Sign…
Browse files Browse the repository at this point in the history
…er (#333)

* [FEATURE] Allow overriding the aws service identifier in AwsSigv4Signer

Currently the service identifier is hard coded to es with no way to
override, this change allows for a user provided `service` option to
override the default.

defaulted the `opts` parameter to an empty object literal which allowed
for some type checking cleanup.

Signed-off-by: Lee Shepherd <bigwebguy@gmail.com>

* Update changelog for #333

Signed-off-by: Lee Shepherd <bigwebguy@gmail.com>

* Update planned test assertions

I swear I ran this test...

Signed-off-by: Lee Shepherd <bigwebguy@gmail.com>

Signed-off-by: Lee Shepherd <bigwebguy@gmail.com>
  • Loading branch information
bwg authored Nov 28, 2022
1 parent 9099a5c commit 2f840e5
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
## [Unreleased]
### Added
- Add release details to releasing.md ([319](https://github.com/opensearch-project/opensearch-js/pull/319))
- Allow overriding the aws service identifier in AwsSigv4Signer ([333](https://github.com/opensearch-project/opensearch-js/pull/333))
### Dependencies
### Changed
### Deprecated
Expand Down
11 changes: 7 additions & 4 deletions lib/aws/AwsSigv4Signer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,22 @@ const awsDefaultCredentialsProvider = () =>
});
});

function AwsSigv4Signer(opts) {
function AwsSigv4Signer(opts = {}) {
const credentialsState = {
credentials: null,
};
if (opts && (!opts.region || opts.region === null || opts.region === '')) {
if (!opts.region) {
throw new AwsSigv4SignerError('Region cannot be empty');
}
if (opts && typeof opts.getCredentials !== 'function') {
if (!opts.service) {
opts.service = 'es';
}
if (typeof opts.getCredentials !== 'function') {
opts.getCredentials = awsDefaultCredentialsProvider;
}

function buildSignedRequestObject(request = {}) {
request.service = 'es';
request.service = opts.service;
request.region = opts.region;
request.headers = request.headers || {};
request.headers['host'] = request.hostname;
Expand Down
58 changes: 49 additions & 9 deletions test/unit/lib/aws/awssigv4signer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const { Connection } = require('../../../../index');
const { Client, buildServer } = require('../../../utils');

test('Sign with SigV4', (t) => {
t.plan(2);
t.plan(3);

const mockCreds = {
accessKeyId: uuidv4(),
Expand Down Expand Up @@ -50,30 +50,70 @@ test('Sign with SigV4', (t) => {
const signedRequest = auth.buildSignedRequestObject(request);
t.hasProp(signedRequest.headers, 'X-Amz-Date');
t.hasProp(signedRequest.headers, 'Authorization');
t.same(signedRequest.service, 'es');
});

test('Sign with SigV4 failure (with empty region)', (t) => {
t.plan(2);
const mockCreds = {
accessKeyId: uuidv4(),
secretAccessKey: uuidv4(),
};

const mockRegions = [{ region: undefined }, { region: null }, { region: '' }, {}];

const AwsSigv4SignerOptions = {
getCredentials: () =>
new Promise((resolve) => {
setTimeout(() => resolve(mockCreds), 100);
}),
};

mockRegions.forEach((region) => {
try {
AwsSigv4Signer(Object.assign({}, AwsSigv4SignerOptions, region));
t.fail('Should fail');
} catch (err) {
t.ok(err instanceof AwsSigv4SignerError);
t.same(err.message, 'Region cannot be empty');
}
});

t.end();
});

test('Sign with SigV4 and provided service', (t) => {
t.plan(1);

const mockCreds = {
accessKeyId: uuidv4(),
secretAccessKey: uuidv4(),
};

const mockRegion = 'us-west-2';
const mockService = 'foo';

const AwsSigv4SignerOptions = {
getCredentials: () =>
new Promise((resolve) => {
setTimeout(() => resolve(mockCreds), 100);
}),
region: mockRegion,
service: mockService,
};

try {
AwsSigv4Signer(AwsSigv4SignerOptions);
t.fail('Should fail');
} catch (err) {
t.ok(err instanceof AwsSigv4SignerError);
t.same(err.message, 'Region cannot be empty');
}
const auth = AwsSigv4Signer(AwsSigv4SignerOptions);

const connection = new Connection({
url: new URL('https://localhost:9200'),
});

const request = connection.buildRequestObject({
path: '/hello',
method: 'GET',
});

const signedRequest = auth.buildSignedRequestObject(request);
t.same(signedRequest.service, mockService);
});

test('Sign with SigV4 using default getCredentials provider', (t) => {
Expand Down

0 comments on commit 2f840e5

Please sign in to comment.