Skip to content
Open
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
7 changes: 1 addition & 6 deletions src/endpoint/iam/iam_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,6 @@ function check_iam_path_was_set(iam_path) {
return iam_path && iam_path !== iam_constants.IAM_DEFAULT_PATH;
}

function get_iam_username(requested_account_name) {
return requested_account_name.split(iam_constants.IAM_SPLIT_CHARACTERS)[0];
}

/**
* _create_detailed_message_for_iam_user_access_in_s3 returns a detailed message with details needed for user who
* tried to perform S3 operation
Expand All @@ -77,7 +73,7 @@ function get_iam_username(requested_account_name) {
function _create_detailed_message_for_iam_user_access_in_s3(user_account, method, resource_arn) {
const owner_account_id = get_owner_account_id(user_account);
const arn_for_requesting_account = create_arn_for_user(owner_account_id,
get_iam_username(user_account.name.unwrap()), user_account.iam_path);
user_account.name.unwrap(), user_account.iam_path);
const full_action_name = Array.isArray(method) && method.length > 1 ? method[1] : method; // special case for get_object_attributes

const message_start = `User: ${arn_for_requesting_account} is not authorized to perform: ${full_action_name} `;
Expand Down Expand Up @@ -863,7 +859,6 @@ exports.create_arn_for_user = create_arn_for_user;
exports.create_arn_for_root = create_arn_for_root;
exports.get_action_message_title = get_action_message_title;
exports.check_iam_path_was_set = check_iam_path_was_set;
exports.get_iam_username = get_iam_username;
exports.parse_max_items = parse_max_items;
exports.validate_params = validate_params;
exports.validate_iam_path = validate_iam_path;
Expand Down
33 changes: 26 additions & 7 deletions src/sdk/accountspace_fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -794,15 +794,34 @@ class AccountSpaceFS {
}

async _check_username_already_exists(action, params, requesting_account) {
const owner_account_id = this._get_owner_account_argument(requesting_account, params);
const owner_account_id = this._get_owner_account_argument(requesting_account);
const username = params.username;
const name_exists = await this.config_fs.is_account_exists_by_name(username, owner_account_id);
if (name_exists) {
dbg.error(`AccountSpaceFS.${action} username already exists`, username);
const message_with_details = `User with name ${username} already exists.`;
const { code, http_code, type } = IamError.EntityAlreadyExists;
throw new IamError({ code, message: message_with_details, http_code, type });
const file_name_exists = await this.config_fs.is_account_exists_by_name(username, owner_account_id);
if (file_name_exists) {
this._throw_error_if_account_already_exists(action, username);
}
const is_username_lowercase_exists_under_owner = await this._check_if_account_exists_under_the_owner(
requesting_account, username);
if (is_username_lowercase_exists_under_owner) {
this._throw_error_if_account_already_exists(action, username);
}
}

_throw_error_if_account_already_exists(action, username) {
dbg.error(`AccountSpaceFS.${action} username already exists`, username);
const message_with_details = `User with name ${username} already exists.`;
const { code, http_code, type } = IamError.EntityAlreadyExists;
throw new IamError({ code, message: message_with_details, http_code, type });
}

async _check_if_account_exists_under_the_owner(requesting_account, username) {
const members = await this._list_config_files_for_users(requesting_account, undefined);
for (const member of members) {
if (member.username.toLowerCase() === username.toLowerCase()) {
return true;
}
}
return false;
}

async _copy_data_from_requesting_account_to_account_config(action, requesting_account, params) {
Expand Down
6 changes: 3 additions & 3 deletions src/sdk/accountspace_nb.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ class AccountSpaceNB {
async create_user(params, account_sdk) {

const requesting_account = system_store.get_account_by_email(account_sdk.requesting_account.email);
const account_name = account_util.get_account_name_from_username(params.username, requesting_account._id.toString());
const account_email_wrapped = account_util.get_account_email_from_username(params.username, requesting_account._id.toString());
const req = {
name: account_name,
email: account_name,
name: params.username, // actual username saved
email: account_email_wrapped, // unique email generated from username lowercase and root account id
has_login: false,
s3_access: true,
allow_bucket_creation: true,
Expand Down
73 changes: 40 additions & 33 deletions src/server/system_services/account_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ const check_new_azure_connection_timeout = 20 * 1000;
*
*/
async function create_account(req) {
const action = IAM_ACTIONS.CREATE_USER;
let iam_arn;
if (req.rpc_params.owner) {
const user_name = account_util.get_iam_username(req.rpc_params.email.unwrap());
const action = IAM_ACTIONS.CREATE_USER;
const username = req.rpc_params.name.unwrap();
account_util._check_if_requesting_account_is_root_account(action, req.account,
{ username: user_name, path: req.rpc_params.iam_path });
account_util._check_username_already_exists(action, req.rpc_params.email, user_name);
iam_arn = iam_utils.create_arn_for_user(req.account._id.toString(), user_name,
req.rpc_params.iam_path || IAM_DEFAULT_PATH);
{ username: username, path: req.rpc_params.iam_path });
account_util._check_username_already_exists(action, req.rpc_params.email, username);
iam_arn = iam_utils.create_arn_for_user(req.account._id.toString(), username,
req.rpc_params.iam_path || IAM_DEFAULT_PATH);
} else {
account_util.validate_create_account_permissions(req);
account_util.validate_create_account_params(req);
Expand Down Expand Up @@ -1207,7 +1207,7 @@ async function get_user(req) {
const action = IAM_ACTIONS.GET_USER;
const requesting_account = req.account;
const requested_account = account_util.validate_and_return_requested_account(req.rpc_params, action, requesting_account);
const username = account_util.get_iam_username(req.rpc_params.username || requested_account.name.unwrap());
const username = requested_account.name.unwrap();
const iam_arn = iam_utils.create_arn_for_user(requesting_account._id.toString(), username,
requested_account.iam_path || IAM_DEFAULT_PATH);
const tags = account_util.get_sorted_list_tags_for_user(requested_account.tagging);
Expand All @@ -1228,25 +1228,32 @@ async function update_user(req) {

const action = IAM_ACTIONS.UPDATE_USER;
const requesting_account = system_store.get_account_by_email(req.account.email);
const old_username = account_util.get_account_name_from_username(req.rpc_params.username, requesting_account._id.toString());
const old_account_email_wrapped = account_util.get_account_email_from_username(
req.rpc_params.username, requesting_account._id.toString());
account_util._check_if_requesting_account_is_root_account(action, requesting_account,
{ username: req.rpc_params.username, iam_path: req.rpc_params.new_iam_path });
account_util._check_if_account_exists(action, old_username);
const requested_account = system_store.get_account_by_email(old_username);
account_util._check_if_account_exists(action, old_account_email_wrapped, req.rpc_params.username);
const requested_account = system_store.get_account_by_email(old_account_email_wrapped);
let iam_path = requested_account.iam_path;
let user_name = account_util.get_iam_username(requested_account.name.unwrap());
let user_name = req.rpc_params.username;
// Change to complete user name
const new_username = account_util.get_account_name_from_username(req.rpc_params.new_username, requesting_account._id.toString());
account_util._check_username_already_exists(action, new_username, req.rpc_params.new_username);
const is_username_update = req.rpc_params.new_username !== undefined &&
req.rpc_params.new_username !== req.rpc_params.username;
if (is_username_update) {
const new_account_email_wrapped = account_util.get_account_email_from_username(
req.rpc_params.new_username,
requesting_account._id.toString());
account_util._check_username_already_exists(action, new_account_email_wrapped, req.rpc_params.new_username);
}
account_util._check_if_requested_account_is_root_account_or_IAM_user(action, requesting_account, requested_account);
account_util._check_if_requested_is_owned_by_root_account(action, requesting_account, requested_account);
if (req.rpc_params.new_iam_path) iam_path = req.rpc_params.new_iam_path;
if (req.rpc_params.new_username) user_name = req.rpc_params.new_username;
const iam_arn = iam_utils.create_arn_for_user(requesting_account._id.toString(), user_name, iam_path);
const new_account_name = account_util.get_account_name_from_username(user_name, requesting_account._id.toString());
const new_account_email_wrapped = account_util.get_account_email_from_username(user_name, requesting_account._id.toString());
const updates = {
name: new_account_name,
email: new_account_name,
name: user_name,
email: new_account_email_wrapped,
iam_path: iam_path,
};
await system_store.make_changes({
Expand All @@ -1270,10 +1277,10 @@ async function delete_user(req) {

const action = IAM_ACTIONS.DELETE_USER;
const requesting_account = req.account;
const username = account_util.get_account_name_from_username(req.rpc_params.username, requesting_account._id.toString());
const account_email_wrapped = account_util.get_account_email_from_username(req.rpc_params.username, requesting_account._id.toString());
account_util._check_if_requesting_account_is_root_account(action, requesting_account, { username: req.rpc_params.username });
account_util._check_if_account_exists(action, username);
const requested_account = system_store.get_account_by_email(username);
account_util._check_if_account_exists(action, account_email_wrapped, req.rpc_params.username);
const requested_account = system_store.get_account_by_email(account_email_wrapped);
account_util._check_if_requested_account_is_root_account_or_IAM_user(action, requesting_account, requested_account);
account_util._check_if_requested_is_owned_by_root_account(action, requesting_account, requested_account);
account_util._check_if_user_does_not_have_resources_before_deletion(action, requested_account);
Expand All @@ -1295,7 +1302,7 @@ async function list_users(req) {
return owner_account_id === requesting_account._id.toString();
});
let members = _.map(requesting_account_iam_users, function(iam_user) {
const iam_username = account_util.get_iam_username(iam_user.name.unwrap());
const iam_username = iam_user.name.unwrap();
const iam_path = iam_user.iam_path || IAM_DEFAULT_PATH;
let member;
// Check the iam_path_prefix and add only those satify the iam_path if exists
Expand Down Expand Up @@ -1330,12 +1337,12 @@ async function create_access_key(req) {
iam_access_key = await account_util.generate_account_keys(account_req);
} catch (err) {
dbg.error(`AccountSpaceNB.${action} error: `, err);
const message_with_details = `Create accesskey failed for the user with name ${account_util.get_iam_username(requested_account.email.unwrap())}.`;
const message_with_details = `Create accesskey failed for the user with name ${requested_account.name.unwrap()}.`;
throw new RpcError('INTERNAL_FAILURE', message_with_details, 500);
}

return {
username: account_util.get_iam_username(requested_account.name.unwrap()),
username: requested_account.name.unwrap(),
access_key: iam_access_key.access_key.unwrap(),
create_date: iam_access_key.creation_date,
status: ACCESS_KEY_STATUS_ENUM.ACTIVE,
Expand Down Expand Up @@ -1387,16 +1394,16 @@ async function update_access_key(req) {
async function get_access_key_last_used(req) {
const action = IAM_ACTIONS.GET_ACCESS_KEY_LAST_USED;
const requesting_account = req.account;
const requested_account = account_util.validate_and_return_requested_account(req.rpc_params, action, requesting_account);
const dummy_region = 'us-west-2';
const dummy_service_name = 's3';
account_util._check_access_key_belongs_to_account(action, requesting_account, req.rpc_params.access_key);
// TODO: Need to return valid last_used_date date, Low priority.
const username = account_util._returned_username(requesting_account, requesting_account.name.unwrap(), false);
return {
region: dummy_region, // GAP
last_used_date: Date.now(), // GAP
service_name: dummy_service_name, // GAP
username: username ? account_util.get_iam_username(username) : undefined,
username: requested_account.name.unwrap(),
};
}

Expand Down Expand Up @@ -1425,12 +1432,12 @@ async function delete_access_key(req) {
async function tag_user(req) {
const action = IAM_ACTIONS.TAG_USER;
const requesting_account = req.account;
const username = account_util.get_account_name_from_username(req.rpc_params.username, requesting_account._id.toString());
const account_email_wrapped = account_util.get_account_email_from_username(req.rpc_params.username, requesting_account._id.toString());

account_util._check_if_requesting_account_is_root_account(action, requesting_account, { username: req.rpc_params.username });
account_util._check_if_account_exists(action, username);
account_util._check_if_account_exists(action, account_email_wrapped, req.rpc_params.username);

const requested_account = system_store.get_account_by_email(username);
const requested_account = system_store.get_account_by_email(account_email_wrapped);
account_util._check_if_requested_account_is_root_account_or_IAM_user(action, requesting_account, requested_account);
account_util._check_if_requested_is_owned_by_root_account(action, requesting_account, requested_account);

Expand Down Expand Up @@ -1467,12 +1474,12 @@ async function tag_user(req) {
async function untag_user(req) {
const action = IAM_ACTIONS.UNTAG_USER;
const requesting_account = req.account;
const username = account_util.get_account_name_from_username(req.rpc_params.username, requesting_account._id.toString());
const account_email_wrapped = account_util.get_account_email_from_username(req.rpc_params.username, requesting_account._id.toString());

account_util._check_if_requesting_account_is_root_account(action, requesting_account, { username: req.rpc_params.username });
account_util._check_if_account_exists(action, username);
account_util._check_if_account_exists(action, account_email_wrapped, req.rpc_params.username);

const requested_account = system_store.get_account_by_email(username);
const requested_account = system_store.get_account_by_email(account_email_wrapped);
account_util._check_if_requested_account_is_root_account_or_IAM_user(action, requesting_account, requested_account);
account_util._check_if_requested_is_owned_by_root_account(action, requesting_account, requested_account);

Expand All @@ -1496,12 +1503,12 @@ async function untag_user(req) {
async function list_user_tags(req) {
const action = IAM_ACTIONS.LIST_USER_TAGS;
const requesting_account = req.account;
const username = account_util.get_account_name_from_username(req.rpc_params.username, requesting_account._id.toString());
const account_email_wrapped = account_util.get_account_email_from_username(req.rpc_params.username, requesting_account._id.toString());

account_util._check_if_requesting_account_is_root_account(action, requesting_account, { username: req.rpc_params.username });
account_util._check_if_account_exists(action, username);
account_util._check_if_account_exists(action, account_email_wrapped, req.rpc_params.username);

const requested_account = system_store.get_account_by_email(username);
const requested_account = system_store.get_account_by_email(account_email_wrapped);
account_util._check_if_requested_account_is_root_account_or_IAM_user(action, requesting_account, requested_account);
account_util._check_if_requested_is_owned_by_root_account(action, requesting_account, requested_account);

Expand Down
2 changes: 1 addition & 1 deletion src/server/system_services/bucket_server.js
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ async function account_exists_by_principal_arn(principal_as_string) {
} else if (arn_sufix && arn_sufix.startsWith(user_sufix)) {
const arn_path_parts = principal_as_string.split('/');
const iam_user_name = arn_path_parts[arn_path_parts.length - 1].trim();
return system_store.get_account_by_email(new SensitiveString(`${iam_user_name}:${account_id}`));
return system_store.get_account_by_email(new SensitiveString(`${iam_user_name.toLowerCase()}:${account_id}`));
} //else {
// wrong principal ARN should not return anything.
//}
Expand Down
Loading