Skip to content

Commit 69e29e1

Browse files
authored
Merge pull request #9259 from naveenpaul1/iam_accesskey
IAM_NOOBAA | IAM create access key
2 parents a566cda + 7775968 commit 69e29e1

File tree

4 files changed

+256
-58
lines changed

4 files changed

+256
-58
lines changed

src/api/common_api.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,8 @@ module.exports = {
932932
properties: {
933933
access_key: { $ref: '#/definitions/access_key' },
934934
secret_key: { $ref: '#/definitions/secret_key' },
935+
deactivated: { type: 'boolean' },
936+
creation_date: { idate: true, },
935937
}
936938
},
937939

src/sdk/accountspace_nb.js

Lines changed: 132 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ const SensitiveString = require('../util/sensitive_string');
66
const account_util = require('../util/account_util');
77
const iam_utils = require('../endpoint/iam/iam_utils');
88
const dbg = require('../util/debug_module')(__filename);
9-
const system_store = require('..//server/system_services/system_store').get_instance();
10-
// const { account_cache } = require('./object_sdk');
119
const IamError = require('../endpoint/iam/iam_errors').IamError;
12-
const { IAM_ACTIONS, IAM_DEFAULT_PATH, IAM_SPLIT_CHARACTERS } = require('../endpoint/iam/iam_constants');
13-
10+
const system_store = require('..//server/system_services/system_store').get_instance();
11+
const { IAM_ACTIONS, IAM_DEFAULT_PATH, ACCESS_KEY_STATUS_ENUM,
12+
IAM_SPLIT_CHARACTERS } = require('../endpoint/iam/iam_constants');
1413

1514
/*
1615
TODO: DISCUSS:
@@ -49,7 +48,7 @@ class AccountSpaceNB {
4948
{ username: params.username, path: params.iam_path });
5049
account_util._check_username_already_exists(action, params, requesting_account);
5150
const iam_arn = iam_utils.create_arn_for_user(requesting_account._id.toString(), params.username, params.iam_path);
52-
const account_name = account_util.populate_username(params.username, requesting_account.name.unwrap());
51+
const account_name = account_util.get_account_name_from_username(params.username, requesting_account.name.unwrap());
5352
const req = {
5453
rpc_params: {
5554
name: account_name,
@@ -88,7 +87,7 @@ class AccountSpaceNB {
8887
async get_user(params, account_sdk) {
8988
const action = IAM_ACTIONS.GET_USER;
9089
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
91-
const account_name = account_util.populate_username(params.username, requesting_account.name.unwrap());
90+
const account_name = account_util.get_account_name_from_username(params.username, requesting_account.name.unwrap());
9291
const requested_account = system_store.get_account_by_email(account_name);
9392
account_util._check_if_requesting_account_is_root_account(action, requesting_account,
9493
{ username: params.username, iam_path: params.iam_path });
@@ -102,17 +101,17 @@ class AccountSpaceNB {
102101
username: account_util.get_iam_username(requested_account.name.unwrap()),
103102
arn: requested_account.iam_arn,
104103
// TODO: GAP Need to save created date
105-
create_date: new Date(),
104+
create_date: Date.now(),
106105
// TODO: Dates missing : GAP
107-
password_last_used: new Date(),
106+
password_last_used: Date.now(),
108107
};
109108
return reply;
110109
}
111110

112111
async update_user(params, account_sdk) {
113112
const action = IAM_ACTIONS.UPDATE_USER;
114113
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
115-
const username = account_util.populate_username(params.username, requesting_account.name.unwrap());
114+
const username = account_util.get_account_name_from_username(params.username, requesting_account.name.unwrap());
116115
account_util._check_if_requesting_account_is_root_account(action, requesting_account,
117116
{ username: params.username, iam_path: params.iam_path });
118117
account_util._check_if_account_exists(action, username);
@@ -156,15 +155,12 @@ class AccountSpaceNB {
156155

157156
async delete_user(params, account_sdk) {
158157
const action = IAM_ACTIONS.DELETE_USER;
159-
// GAP - we do not have the user iam_path at this point (error message)
160-
//const requesting_account = account_sdk.requesting_account;
161158
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
162-
const username = account_util.populate_username(params.username, requesting_account.name.unwrap());
159+
const username = account_util.get_account_name_from_username(params.username, requesting_account.name.unwrap());
163160
account_util._check_if_requesting_account_is_root_account(action, requesting_account, { username: params.username });
164161
account_util._check_if_account_exists(action, username);
165162
const requested_account = system_store.get_account_by_email(username);
166163
account_util._check_if_requested_account_is_root_account_or_IAM_user(action, requesting_account, requested_account);
167-
//const root_account = system_store.get_account_by_email(requesting_account.email);
168164
account_util._check_if_requested_is_owned_by_root_account(action, requesting_account, requested_account);
169165
// TODO: DELETE INLINE POLICY : Manually
170166
// TODO: DELETE ACCESS KEY : manually
@@ -181,7 +177,6 @@ class AccountSpaceNB {
181177

182178
async list_users(params, account_sdk) {
183179
const action = IAM_ACTIONS.LIST_USERS;
184-
//const requesting_account = account_sdk.requesting_account;
185180
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
186181
account_util._check_if_requesting_account_is_root_account(action, requesting_account, { });
187182
const is_truncated = false; // GAP - no pagination at this point
@@ -201,8 +196,8 @@ class AccountSpaceNB {
201196
username: iam_user.name.unwrap().split(IAM_SPLIT_CHARACTERS)[0],
202197
arn: iam_user.iam_arn,
203198
// TODO: GAP Need to save created date
204-
create_date: new Date(),
205-
// TODO: GAP Miising password_last_used
199+
create_date: Date.now(),
200+
// TODO: GAP missing password_last_used
206201
password_last_used: Date.now(), // GAP
207202
};
208203
return member;
@@ -217,39 +212,121 @@ class AccountSpaceNB {
217212
/////////////////////////////////
218213

219214
async create_access_key(params, account_sdk) {
220-
// TODO
221-
dbg.log0('AccountSpaceNB.create_access_key:', params);
222-
const { code, http_code, type } = IamError.NotImplemented;
223-
throw new IamError({ code, message: 'NotImplemented', http_code, type });
215+
const action = IAM_ACTIONS.CREATE_ACCESS_KEY;
216+
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
217+
const requested_account = validate_and_return_requested_account(params, action, requesting_account, account_sdk);
218+
const account_email = params.username ? new SensitiveString(`${params.username}:${requesting_account.name.unwrap()}`) :
219+
account_sdk.requesting_account.email;
220+
account_util._check_number_of_access_key_array(action, requested_account);
221+
const req = {
222+
rpc_params: {
223+
email: account_email,
224+
is_iam: true,
225+
},
226+
account: requesting_account,
227+
};
228+
// CORE CHANGES PENDING - START
229+
let iam_access_key;
230+
try {
231+
iam_access_key = await account_util.generate_account_keys(req);
232+
} catch (err) {
233+
dbg.error(`AccountSpaceNB.${action} error: `, err);
234+
const message_with_details = `Create accesskey failed for the user with name ${account_util.get_iam_username(account_email.unwrap())}.`;
235+
const { code, http_code, type } = IamError.InternalFailure;
236+
throw new IamError({ code, message: message_with_details, http_code, type });
237+
}
238+
239+
// CORE CHANGES PENDING - STOP
240+
241+
return {
242+
username: params.username,
243+
access_key: iam_access_key.access_key.unwrap(),
244+
create_date: iam_access_key.creation_date,
245+
status: ACCESS_KEY_STATUS_ENUM.ACTIVE,
246+
secret_key: iam_access_key.secret_key.unwrap(),
247+
};
224248
}
225249

226250
async get_access_key_last_used(params, account_sdk) {
227-
dbg.log0('AccountSpaceNB.get_access_key_last_used:', params);
228-
const { code, http_code, type } = IamError.NotImplemented;
229-
throw new IamError({ code, message: 'NotImplemented', http_code, type });
251+
const action = IAM_ACTIONS.GET_ACCESS_KEY_LAST_USED;
252+
const dummy_region = 'us-west-2';
253+
const dummy_service_name = 's3';
254+
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
255+
account_util._check_access_key_belongs_to_account(action, requesting_account, params.access_key);
256+
// TODO: Need to return valid last_used_date date, Low priority.
257+
const username = account_util._returned_username(requesting_account, requesting_account.name.unwrap(), false);
258+
return {
259+
region: dummy_region, // GAP
260+
last_used_date: Date.now(), // GAP
261+
service_name: dummy_service_name, // GAP
262+
username: username ? account_util.get_iam_username(username) : undefined,
263+
};
230264
}
231265

232266
async update_access_key(params, account_sdk) {
233-
dbg.log0('AccountSpaceNB.update_access_key:', params);
234-
const { code, http_code, type } = IamError.NotImplemented;
235-
throw new IamError({ code, message: 'NotImplemented', http_code, type });
267+
const action = IAM_ACTIONS.UPDATE_ACCESS_KEY;
268+
const access_key_id = params.access_key;
269+
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
270+
const requested_account = validate_and_return_requested_account(params, action, requesting_account, account_sdk);
271+
account_util._check_access_key_belongs_to_account(action, requested_account, access_key_id);
272+
273+
const updating_access_key_obj = _.find(requested_account.access_keys,
274+
access_key => access_key.access_key.unwrap() === access_key_id);
275+
if (account_util._get_access_key_status(updating_access_key_obj.deactivated) === params.status) {
276+
dbg.log0(`AccountSpaceNB.${action} status was not change, not updating the database`);
277+
return;
278+
}
279+
const filtered_access_keys = account_util.get_non_updating_access_key(requested_account, access_key_id);
280+
updating_access_key_obj.deactivated = account_util._check_access_key_is_deactivated(params.status);
281+
updating_access_key_obj.secret_key = system_store.master_key_manager
282+
.encrypt_sensitive_string_with_master_key_id(updating_access_key_obj.secret_key, requested_account.master_key_id._id);
283+
filtered_access_keys.push(updating_access_key_obj);
284+
285+
await system_store.make_changes({
286+
update: {
287+
accounts: [{
288+
_id: requested_account._id,
289+
$set: { access_keys: filtered_access_keys }
290+
}]
291+
}
292+
});
293+
// TODO : clean account cache
236294
}
237295

238296
async delete_access_key(params, account_sdk) {
239-
dbg.log0('AccountSpaceNB.delete_access_key:', params);
240-
const { code, http_code, type } = IamError.NotImplemented;
241-
throw new IamError({ code, message: 'NotImplemented', http_code, type });
297+
const action = IAM_ACTIONS.DELETE_ACCESS_KEY;
298+
const access_key_id = params.access_key;
299+
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
300+
301+
const requested_account = validate_and_return_requested_account(params, action, requesting_account, account_sdk);
302+
account_util._check_access_key_belongs_to_account(action, requested_account, access_key_id);
303+
// Filter out the deleting access key from the access key list and save remaining accesskey.
304+
const filtered_access_keys = account_util.get_non_updating_access_key(requested_account, access_key_id);
305+
const updates = {
306+
access_keys: filtered_access_keys,
307+
};
308+
await system_store.make_changes({
309+
update: {
310+
accounts: [{
311+
_id: requested_account._id,
312+
$set: _.omitBy(updates, _.isUndefined),
313+
}]
314+
}
315+
});
316+
// TODO : clean account cache
242317
}
243318

244319
async list_access_keys(params, account_sdk) {
245-
dbg.log0('AccountSpaceNB.list_access_keys:', params);
246-
const { code, http_code, type } = IamError.NotImplemented;
247-
throw new IamError({ code, message: 'NotImplemented', http_code, type });
248-
}
320+
const action = IAM_ACTIONS.LIST_ACCESS_KEYS;
321+
const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
322+
const requested_account = validate_and_return_requested_account(params, action, requesting_account, account_sdk);
249323

250-
////////////////////
251-
// POLICY METHODS //
252-
////////////////////
324+
const is_truncated = false; // // GAP - no pagination at this point
325+
let members = account_util._list_access_keys_from_account(requesting_account, requested_account, false);
326+
members = members.sort((a, b) => a.access_key.localeCompare(b.access_key));
327+
return { members, is_truncated,
328+
username: account_util._returned_username(requesting_account, requested_account.name.unwrap(), false) };
329+
}
253330

254331
async put_user_policy(params, account_sdk) {
255332
dbg.log0('AccountSpaceNB.put_user_policy:', params);
@@ -276,5 +353,24 @@ class AccountSpaceNB {
276353
}
277354
}
278355

356+
357+
function validate_and_return_requested_account(params, action, requesting_account, account_sdk) {
358+
const on_itself = !params.username;
359+
let requested_account;
360+
if (on_itself) {
361+
// When accesskeyt API called without specific username, action on the same requesting account.
362+
// So in that case requesting account and requested account is same.
363+
requested_account = requesting_account;
364+
} else {
365+
const account_email = account_util.get_account_name_from_username(params.username, requesting_account.name.unwrap());
366+
account_util._check_if_account_exists(action, account_email);
367+
requested_account = system_store.get_account_by_email(account_email);
368+
account_util._check_if_requesting_account_is_root_account(action, requesting_account, { username: params.username });
369+
account_util._check_if_requested_account_is_root_account_or_IAM_user(action, requesting_account, requested_account);
370+
account_util._check_if_requested_is_owned_by_root_account(action, requesting_account, requested_account);
371+
}
372+
return requested_account;
373+
}
374+
279375
// EXPORTS
280376
module.exports = AccountSpaceNB;

src/server/system_services/schemas/account_schema.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ module.exports = {
4747
properties: {
4848
access_key: { $ref: 'common_api#/definitions/access_key' },
4949
secret_key: { $ref: 'common_api#/definitions/secret_key' },
50+
deactivated: { type: 'boolean' },
51+
creation_date: { idate: true },
5052
}
5153
}
5254
},

0 commit comments

Comments
 (0)