Skip to content

Commit 436b3d7

Browse files
authored
Merge pull request #8920 from shirady/iam-add-empty-list
NC | IAM | Return Empty List On Unimplemented Operations (`list-group-for-user`)
2 parents af53218 + 43ff894 commit 436b3d7

File tree

4 files changed

+103
-1
lines changed

4 files changed

+103
-1
lines changed

docs/design/iam.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ Here attached a diagram with all the accounts that we have in our system:
126126
- IAM DeleteAccessKey: AccessKeyId, UserName
127127
- IAM ListAccessKeys: UserName (not supported: Marker, MaxItems)
128128

129+
### Other
130+
- IAM ListGroupsForUser - would always return empty list (to check that the user exists it runs GetUser).
131+
129132
### Configuration Directory Components With users
130133
If account creates a user its config file will be created under identities/<user-id>.identity.json and under the account will be created `users/` directory and inside it it will link to the config.
131134
Example:

src/endpoint/iam/iam_rest.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const ACTIONS = Object.freeze({
3434
'UpdateAccessKey': 'update_access_key',
3535
'DeleteAccessKey': 'delete_access_key',
3636
'ListAccessKeys': 'list_access_keys',
37+
'ListGroupsForUser': 'list_groups_for_user',
3738
});
3839

3940
// notice: shows all methods as method post
@@ -50,6 +51,8 @@ const IAM_OPS = js_utils.deep_freeze({
5051
post_update_access_key: require('./ops/iam_update_access_key'),
5152
post_delete_access_key: require('./ops/iam_delete_access_key'),
5253
post_list_access_keys: require('./ops/iam_list_access_keys'),
54+
// other (currently ops that return empty just not to fail them)
55+
post_list_groups_for_user: require('./ops/iam_list_groups_for_user.js'),
5356
});
5457

5558
async function iam_rest(req, res) {
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* Copyright (C) 2024 NooBaa */
2+
'use strict';
3+
4+
const dbg = require('../../../util/debug_module')(__filename);
5+
const { CONTENT_TYPE_APP_FORM_URLENCODED } = require('../../../util/http_utils');
6+
const iam_utils = require('../iam_utils');
7+
const iam_constants = require('../iam_constants');
8+
9+
/**
10+
* https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListGroupsForUser.html
11+
*/
12+
async function list_groups_for_user(req, res) {
13+
14+
const params = {
15+
username: req.body.user_name,
16+
};
17+
18+
dbg.log1('To check that we have the user we will run the IAM GET USER', params);
19+
iam_utils.validate_params(iam_constants.IAM_ACTIONS.GET_USER, params);
20+
await req.account_sdk.get_user(params);
21+
22+
dbg.log1('IAM LIST GROUPS FOR USER (returns empty list on every request)', params);
23+
24+
return {
25+
ListGroupsForUserResponse: {
26+
ListGroupsForUserResult: {
27+
Groups: [],
28+
IsTruncated: false,
29+
},
30+
ResponseMetadata: {
31+
RequestId: req.request_id,
32+
}
33+
},
34+
};
35+
}
36+
37+
module.exports = {
38+
handler: list_groups_for_user,
39+
body: {
40+
type: CONTENT_TYPE_APP_FORM_URLENCODED,
41+
},
42+
reply: {
43+
type: 'xml',
44+
},
45+
};

src/test/unit_tests/test_nc_iam_basic_integration.js

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ const { TMP_PATH, generate_nsfs_account, get_new_buckets_path_by_test_env, gener
1111
get_coretest_path } = require('../system_tests/test_utils');
1212
const { ListUsersCommand, CreateUserCommand, GetUserCommand, UpdateUserCommand, DeleteUserCommand,
1313
ListAccessKeysCommand, CreateAccessKeyCommand, GetAccessKeyLastUsedCommand,
14-
UpdateAccessKeyCommand, DeleteAccessKeyCommand } = require('@aws-sdk/client-iam');
14+
UpdateAccessKeyCommand, DeleteAccessKeyCommand,
15+
ListGroupsForUserCommand } = require('@aws-sdk/client-iam');
1516
const { ACCESS_KEY_STATUS_ENUM } = require('../../endpoint/iam/iam_constants');
17+
const IamError = require('../../endpoint/iam/iam_errors').IamError;
18+
1619

1720
const coretest_path = get_coretest_path();
1821
const coretest = require(coretest_path);
@@ -229,6 +232,54 @@ mocha.describe('IAM basic integration tests - happy path', async function() {
229232
_check_status_code_ok(response);
230233
});
231234
});
235+
236+
mocha.describe('IAM other APIs (currently returns empty value)', async function() {
237+
const username3 = 'Emi';
238+
239+
mocha.before(async () => {
240+
// create a user
241+
const input = {
242+
UserName: username3
243+
};
244+
const command = new CreateUserCommand(input);
245+
const response = await iam_account.send(command);
246+
_check_status_code_ok(response);
247+
});
248+
249+
mocha.after(async () => {
250+
// delete a user
251+
const input = {
252+
UserName: username3
253+
};
254+
const command = new DeleteUserCommand(input);
255+
const response = await iam_account.send(command);
256+
_check_status_code_ok(response);
257+
});
258+
259+
mocha.it('list groups for non existing user - should throw an error', async function() {
260+
try {
261+
const input = {
262+
UserName: 'non-existing-user'
263+
};
264+
const command = new ListGroupsForUserCommand(input);
265+
await iam_account.send(command);
266+
assert.fail('list groups for non existing user - should throw an error');
267+
} catch (err) {
268+
const err_code = err.Error.Code;
269+
assert.equal(err_code, IamError.NoSuchEntity.code);
270+
}
271+
});
272+
273+
mocha.it('list groups for user - should be empty', async function() {
274+
const input = {
275+
UserName: username3
276+
};
277+
const command = new ListGroupsForUserCommand(input);
278+
const response = await iam_account.send(command);
279+
_check_status_code_ok(response);
280+
assert.equal(response.Groups.length, 0);
281+
});
282+
});
232283
});
233284

234285
/**

0 commit comments

Comments
 (0)