Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

INTEGRATION [PR#432 > development/8.2] VLTCLT-39: Update getAccounts to search by name #433

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions lib/IAMClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,15 @@ class VaultClient {
/**
* Get accounts using account ids, canonical ids or email addresses
*
* There are 2 signatures:
* - `getAccounts(accountIds, emailAddresses, canonicalIds, options, callback)`
* - `getAccounts(
* filter: { accountIds?, emailAddresses?, canonicalIds?, accountNames? },
* options, callback)`
*
* The last signature allows to add a new filter `accountNames`
* without messing with previous signature.
*
* @param {array|undefined} accountIds - Account ids, exclusive with
* emailAddresses and canonicalIds
* @param {array|undefined} emailAddresses - Email addresses, exclusive
Expand All @@ -465,22 +474,42 @@ class VaultClient {
* @param {object} options - Options
* @param {string} [options.reqUid] - Request uid
* @param {function} callback - Callback(err, result)
*
* @param {Object} filter - Contains the previous signature's first 3 params
* with additional `accountNames` field
*
* Note: do not use `accountNames` with vault2
*
* @return {undefined}
*/
getAccounts(accountIds, emailAddresses, canonicalIds, options, callback) {
let accountNames;
if (arguments.length === 3) {
// check and convert args from signature getAccounts(filter, options, callback)
const filter = accountIds;
/* eslint-disable-next-line no-param-reassign */
options = emailAddresses;
/* eslint-disable-next-line no-param-reassign */
callback = canonicalIds;
assert(filter && typeof filter === 'object' && !Array.isArray(filter),
'first arg (filter) must be an object containing one filter field');
assert(options && typeof options === 'object' && !Array.isArray(options),
'second arg (options) must be an object');
assert(callback && typeof callback === 'function',
'third arg (callback) must be a function');
({
/* eslint-disable-next-line no-param-reassign */
accountIds, emailAddresses, canonicalIds, accountNames
} = filter);
}
assert((accountIds && Array.isArray(accountIds)) || !accountIds,
'accountIds should be an array');
assert((emailAddresses && Array.isArray(emailAddresses))
|| !emailAddresses, 'emailAddresses should be an array');
assert((canonicalIds && Array.isArray(canonicalIds)) || !canonicalIds,
'canonicalIds should be an array');
if (
(accountIds && (emailAddresses || canonicalIds))
|| (emailAddresses && (accountIds || canonicalIds))
|| (canonicalIds && (accountIds || emailAddresses))) {
assert(false, 'accountIds, emailAddresses and canonicalIds '
+ 'ids are exclusive');
}
assert((accountNames && Array.isArray(accountNames)) || !accountNames,
'accountNames should be an array');
const data = {
Action: 'GetAccounts',
Version: '2010-05-08',
Expand All @@ -494,7 +523,13 @@ class VaultClient {
if (emailAddresses) {
data.emailAddresses = emailAddresses;
}

if (accountNames) {
data.accountNames = accountNames;
}
if (Object.values(data).length > 3) {
assert(false, 'accountIds, emailAddresses, canonicalIds '
+ 'and accountNames ids are exclusive');
}
const verb = this.useAuthenticatedAdminRoutes ? 'POST' : 'GET';

this.request(verb, '/', this.useAuthenticatedAdminRoutes, callback, data, options.reqUid, null);
Expand Down
100 changes: 100 additions & 0 deletions tests/unit/getAccounts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* eslint-disable operator-linebreak */
'use strict'; // eslint-disable-line

const assert = require('assert');
const IAMClient = require('../../lib/IAMClient.js');

Check failure on line 5 in tests/unit/getAccounts.js

View workflow job for this annotation

GitHub Actions / tests

Unexpected use of file extension "js" for "../../lib/IAMClient.js"

const accountIds = ['accountId1', 'accountId2'];
const canonicalIds = ['canId1', 'canId2'];
const emailAddresses = ['email1', 'email2'];
const accountNames = ['name1', 'name2'];
const opt = { reqUid: 'test.getAccounts.reqUid' };
const mockCB = () => {};

const expectedData = {
Action: 'GetAccounts',
Version: '2010-05-08',
};

describe('getAccounts', () => {
let client;
let spyArg = null;

beforeEach('spy on request', done => {
client = new IAMClient('127.0.0.1', 8500);
client.request = function spy(...args) {
spyArg = args;
};
done();
});

afterEach('reset spyArg', () => { spyArg = null; });

describe('should send request with regular function signature (5 args)', () => {
[
{ name: 'accountIds', args: [accountIds, null, null, opt, mockCB] },
{ name: 'emailAddresses', args: [null, emailAddresses, null, opt, mockCB] },
{ name: 'canonicalIds', args: [null, null, canonicalIds, opt, mockCB] },
].forEach(({ name, args }) => it(`for ${name}`, () => {
client.getAccounts(...args);
const [method, path, auth, cb, data, reqUid, contentType] = spyArg;
assert.strictEqual(method, 'GET');
assert.strictEqual(path, '/');
assert.strictEqual(auth, false);
assert.strictEqual(cb, mockCB);
assert.strictEqual(reqUid, opt.reqUid);
assert.strictEqual(contentType, null);
assert.deepStrictEqual(
data,
Object.assign({}, expectedData, { [name]: args[0] || args[1] || args[2] }),
);
}));
});

describe('should send request with new function signature (3args)', () => {
[
{ name: 'accountIds', args: [{ accountIds }, opt, mockCB] },
{ name: 'emailAddresses', args: [{ emailAddresses }, opt, mockCB] },
{ name: 'canonicalIds', args: [{ canonicalIds }, opt, mockCB] },
{ name: 'accountNames', args: [{ accountNames }, opt, mockCB] },
].forEach(({ name, args }) => it(`for ${name}`, () => {
client.getAccounts(...args);
const [method, path, auth, cb, data, reqUid, contentType] = spyArg;
assert.strictEqual(method, 'GET');
assert.strictEqual(path, '/');
assert.strictEqual(auth, false);
assert.strictEqual(cb, mockCB);
assert.strictEqual(reqUid, opt.reqUid);
assert.strictEqual(contentType, null);
assert.deepStrictEqual(
data,
Object.assign({}, expectedData, { [name]: Object.values(args[0])[0] }),
);
}));
});

describe('should throw with regular function signature (5args)', () => {
it('for all values set', () => {
assert.throws(() => client.getAccounts(accountIds, emailAddresses, canonicalIds, opt, mockCB),
assert.AssertionError);
});
});

describe('should throw with new function signature (3args)', () => {
it('for all values set', () => {
assert.throws(() => client.getAccounts(
{
accountIds, emailAddresses, canonicalIds, accountNames,
},
opt,
mockCB,
),
assert.AssertionError);
});

it('for wrong argument type', () => {
assert.throws(() => client.getAccounts(accountIds, opt, mockCB),
assert.AssertionError);
});
});
});
Loading