Skip to content

Commit

Permalink
NC | NSFS | revoking --new_access_key and fixing access key update …
Browse files Browse the repository at this point in the history
…issues

1. revoking `--new_access_key`
2. fixing issue where `--regenerate` did not update the secret_key
3. fixing an issue where using `--access_key` without `--new_access_key` did not updated the symlink
4. updated the tests.

Signed-off-by: liranmauda <liran.mauda@gmail.com>
  • Loading branch information
liranmauda committed Jan 7, 2024
1 parent 20eb458 commit 578b7c0
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 144 deletions.
35 changes: 15 additions & 20 deletions src/cmd/manage_nsfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ Account Options:
# required for add, update, and delete
--access_key <key> (default none) Authenticate incoming requests for this access key only (default is no auth).
--new_access_key <key> (default none) Set a new access key for the account.
--regenerate (default none) When set and new_access_key is not set, will regenerate the access_key and secret_key
--config_root <dir> (default config.NSFS_NC_DEFAULT_CONF_DIR) Configuration files path for Noobaa standalon NSFS.
Expand Down Expand Up @@ -146,7 +145,7 @@ async function check_and_create_config_dirs() {
config_root,
buckets_dir_path,
accounts_dir_path,
access_keys_dir_path
access_keys_dir_path
];
for (const dir_path of pre_req_dirs) {
try {
Expand Down Expand Up @@ -399,23 +398,26 @@ function set_access_keys(argv, generate) {

async function fetch_account_data(argv, from_file) {
let data;
let generate_access_keys = true;
let access_keys = [{
access_key: undefined,
secret_key: undefined,
}];
let new_access_key;
const action = argv._[1] || '';
if (from_file) {
const fs_context = native_fs_utils.get_process_fs_context();
const raw_data = (await nb_native().fs.readFile(fs_context, from_file)).data;
data = JSON.parse(raw_data.toString());
}
if (action !== ACTIONS.LIST && action !== ACTIONS.STATUS) _validate_access_keys(argv);
let new_access_key = argv.new_access_key;
if (action === 'update') {
generate_access_keys = false;
if (argv.regenerate) {
const keys = set_access_keys(argv, true);
new_access_key = keys[0].access_key;
}
if (action === ACTIONS.ADD || action === ACTIONS.STATUS) {
access_keys = set_access_keys(argv, true);
} else if (action === ACTIONS.UPDATE) {
access_keys = set_access_keys(argv, Boolean(argv.regenerate));
new_access_key = access_keys[0].access_key;
access_keys[0].access_key = undefined; //Setting it as undefined so we can replace the symlink
}
if (action === 'delete') generate_access_keys = false;

if (!data) {
data = _.omitBy({
name: argv.name,
Expand All @@ -424,7 +426,7 @@ async function fetch_account_data(argv, from_file) {
wide: argv.wide,
new_name: argv.new_name,
new_access_key,
access_keys: set_access_keys(argv, generate_access_keys),
access_keys,
nsfs_account_config: {
distinguished_name: argv.user,
uid: !argv.user && argv.uid,
Expand Down Expand Up @@ -817,14 +819,7 @@ function _validate_access_keys(argv) {
check_numbers: true,
check_symbols: true,
})) throw_cli_error(ManageCLIError.AccountSecretKeyFlagComplexity);
// checking the complexity of new_access_key
if (!is_undefined(argv.new_access_key) && !string_utils.validate_complexity(argv.new_access_key, {
require_length: 20,
check_uppercase: true,
check_lowercase: false,
check_numbers: true,
check_symbols: false,
})) throw_cli_error(ManageCLIError.NewAccountAccessKeyFlagComplexity);

}

exports.main = main;
Expand Down
8 changes: 1 addition & 7 deletions src/manage_nsfs/manage_nsfs_cli_errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,6 @@ ManageCLIError.AccountAccessKeyFlagComplexity = Object.freeze({
http_code: 400,
});

ManageCLIError.NewAccountAccessKeyFlagComplexity = Object.freeze({
code: 'NewAccountAccessKeyFlagComplexity',
message: 'Account new access key length must be 20, and must contain uppercase and numbers',
http_code: 400,
});

ManageCLIError.MissingAccountNameFlag = Object.freeze({
code: 'MissingAccountNameFlag',
message: 'Account name is mandatory, please use the --name flag',
Expand All @@ -178,7 +172,7 @@ ManageCLIError.MissingAccountEmailFlag = Object.freeze({

ManageCLIError.MissingIdentifier = Object.freeze({
code: 'MissingIdentifier',
message: 'Account identifier is mandatory, please use the --acces_key or --name flag',
message: 'Account identifier is mandatory, please use the --access_key or --name flag',
http_code: 400,
});

Expand Down
52 changes: 41 additions & 11 deletions src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,29 +190,59 @@ describe('manage nsfs cli account flow', () => {
assert_account(account_symlink, new_account_details);
});

it('cli update account access_key', async () => {
it('cli account update name by name', async function() {
const { type, name } = defaults;
const new_access_key = 'GIGiFAnjaaE7OKD5N7hB';
const account_options = { config_root, name, new_access_key: new_access_key };
const new_name = 'account1_new_name'
const account_options = { config_root, name, new_name };
const action = nc_nsfs_manage_actions.UPDATE;
account_options.new_name = 'account1_new_name';
await exec_manage_cli(type, action, account_options);
let new_account_details = await read_config_file(config_root, accounts_schema_dir, new_name);
expect(new_account_details.name).toBe(new_name);
const access_key = new_account_details.access_keys[0].access_key;
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, access_key, true);
//fixing the new_account_details for compare.
new_account_details = { ...new_account_details, ...new_account_details.nsfs_account_config };
assert_account(account_symlink, new_account_details);
});

it('cli account update access key, secret_key & new_name by name', async function() {
const { type, name } = defaults;
const new_name = 'account1_new_name'
const access_key = 'GIGiFAnjaaE7OKD5N7hB';
const secret_key = 'U3AYaMpU3zRDcRFWmvzgQr9MoHIAsD+3oEXAMPLE';
const account_options = { config_root, name, new_name, access_key, secret_key };
const account_details = await read_config_file(config_root, accounts_schema_dir, name);
const action = nc_nsfs_manage_actions.UPDATE;
account_options.new_name = 'account1_new_name';
await exec_manage_cli(type, action, account_options);
let new_account_details = await read_config_file(config_root, accounts_schema_dir, name);
let new_account_details = await read_config_file(config_root, accounts_schema_dir, new_name);
expect(new_account_details.name).toBe(new_name);
expect(account_details.access_keys[0].access_key).not.toBe(new_account_details.access_keys[0].access_key);
expect(new_account_details.access_keys[0].access_key).toBe(new_access_key);
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, new_access_key, true);
expect(account_details.access_keys[0].secret_key).not.toBe(new_account_details.access_keys[0].secret_key);
expect(new_account_details.access_keys[0].access_key).toBe(access_key);
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, access_key, true);
//fixing the new_account_details for compare.
new_account_details = { ...new_account_details, ...new_account_details.nsfs_account_config };
assert_account(account_symlink, new_account_details);
});

it('should fail - cli update account new access_key wrong complexity', async () => {
it('cli update account access_key and secret_key using flags', async () => {
const { type, name } = defaults;
const new_access_key = 'new';
const account_options = { config_root, name, new_access_key: new_access_key };
const access_key = 'GIGiFAnjaaE7OKD5N7hB';
const secret_key = 'U3AYaMpU3zRDcRFWmvzgQr9MoHIAsD+3oEXAMPLE';
const account_options = { config_root, name, access_key, secret_key };
const account_details = await read_config_file(config_root, accounts_schema_dir, name);
const action = nc_nsfs_manage_actions.UPDATE;
const res = await exec_manage_cli(type, action, account_options);
expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.NewAccountAccessKeyFlagComplexity.message);
await exec_manage_cli(type, action, account_options);
let new_account_details = await read_config_file(config_root, accounts_schema_dir, name);
expect(account_details.access_keys[0].access_key).not.toBe(new_account_details.access_keys[0].access_key);
expect(account_details.access_keys[0].secret_key).not.toBe(new_account_details.access_keys[0].secret_key);
expect(new_account_details.access_keys[0].access_key).toBe(access_key);
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, access_key, true);
//fixing the new_account_details for compare.
new_account_details = { ...new_account_details, ...new_account_details.nsfs_account_config };
assert_account(account_symlink, new_account_details);
});

});
Expand Down
111 changes: 5 additions & 106 deletions src/test/unit_tests/test_nc_nsfs_cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ mocha.describe('manage_nsfs cli', function() {
try {
await fs_utils.create_fresh_path(bucket_path);
await fs_utils.file_must_exist(bucket_path);
await exec_manage_cli(type, action, { ...bucket_options, bucket_policy: invalid_bucket_policy});
await exec_manage_cli(type, action, { ...bucket_options, bucket_policy: invalid_bucket_policy });
assert.fail('should have failed with invalid bucket policy');
} catch (err) {
assert_error(err, ManageCLIError.MalformedPolicy);
Expand Down Expand Up @@ -432,27 +432,6 @@ mocha.describe('manage_nsfs cli', function() {
assert_response(action, type, account_list, expected_list, undefined, true);
});

mocha.it('cli account update uid by access key', async function() {
const action = nc_nsfs_manage_actions.UPDATE;
const update_options = {
config_root,
access_key: account_options.access_key,
secret_key: account_options.secret_key,
email: 'account2@noobaa.io',
uid: 222,
gid: 222
};
const update_response = await exec_manage_cli(type, action, update_options);
updating_options = { ...updating_options, ...update_options };
assert_response(action, type, update_response, updating_options);
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, access_key, true);
account_options = { ...account_options, ...update_options };
assert_account(account_symlink, account_options);
const account = await read_config_file(config_root, accounts_schema_dir, name);
assert_account(account, account_options);
await assert_config_file_permissions(config_root, accounts_schema_dir, name);
});

mocha.it('cli account update uid by name', async function() {
const action = nc_nsfs_manage_actions.UPDATE;
const update_options = {
Expand All @@ -475,64 +454,6 @@ mocha.describe('manage_nsfs cli', function() {
assert_account(account, account_options);
});

mocha.it('cli account update name by access key', async function() {
const action = nc_nsfs_manage_actions.UPDATE;
const update_options = {
config_root,
new_name: 'account1_new_name',
access_key: account_options.access_key,
secret_key: account_options.secret_key,
};
account_options.new_name = 'account1_new_name';
const update_response = await exec_manage_cli(type, action, update_options);
updating_options = { ...updating_options, name: update_options.new_name };
assert_response(action, type, update_response, updating_options);
account_options = { ...account_options, new_name: undefined, name: update_options.new_name };
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, access_key, true);
assert_account(account_symlink, account_options);
const account = await read_config_file(config_root, accounts_schema_dir, account_options.name);
assert_account(account, account_options);
});

mocha.it('cli account update access key by name', async function() {
const action = nc_nsfs_manage_actions.UPDATE;
const update_options = {
config_root,
new_access_key: 'BIGiFAnjaaE7OKD5N7hB',
name: account_options.name
};
const update_response = await exec_manage_cli(type, action, update_options);
updating_options = { ...updating_options, access_key: update_options.new_access_key };
assert_response(action, type, update_response, updating_options);
account_options = { ...account_options, new_access_key: undefined, access_key: update_options.new_access_key };
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, account_options.access_key, true);
assert_account(account_symlink, account_options);
const account = await read_config_file(config_root, accounts_schema_dir, account_options.name);
assert_account(account, account_options);
});

mocha.it('cli account update access key & new_name by name', async function() {
const action = nc_nsfs_manage_actions.UPDATE;
const update_options = {
config_root,
new_access_key: 'BIGiFAnjaaE6OGD5N7hB',
new_name: 'account2_new_name',
name: account_options.name
};
await exec_manage_cli(type, action, update_options);
account_options = {
...account_options,
new_access_key: undefined,
new_name: undefined,
access_key: update_options.new_access_key,
name: update_options.new_name
};
const account_symlink = await read_config_file(config_root, access_keys_schema_dir, account_options.access_key, true);
assert_account(account_symlink, account_options);
const account = await read_config_file(config_root, accounts_schema_dir, account_options.name);
assert_account(account, account_options);
});

mocha.it('cli account delete by name', async function() {
const action = nc_nsfs_manage_actions.DELETE;
const res = await exec_manage_cli(type, action, { config_root, name: account_options.name });
Expand Down Expand Up @@ -635,8 +556,10 @@ mocha.describe('manage_nsfs cli', function() {

mocha.it('cli account2 update - new_access_key already exists', async function() {
const action = nc_nsfs_manage_actions.UPDATE;
const options = { ...account2_options };
options.access_key = 'GIGiFAnjaaE7OKD5N7hA';
try {
await exec_manage_cli(type, action, { ...account2_options, new_access_key: 'GIGiFAnjaaE7OKD5N7hA' });
await exec_manage_cli(type, action, options);
assert.fail('should have failed with account access key already exists');
} catch (err) {
assert_error(err, ManageCLIError.AccountAccessKeyAlreadyExists);
Expand Down Expand Up @@ -685,32 +608,8 @@ mocha.describe('manage_nsfs cli', function() {
assert_account(account, account_options);
});

mocha.it('cli account delete by access key', async function() {
const action = nc_nsfs_manage_actions.DELETE;
const res = await exec_manage_cli(type, action, { config_root, access_key, secret_key });
assert_response(action, type, res);
try {
await read_config_file(config_root, access_keys_schema_dir, access_key, true);
throw new Error('cli account delete failed - account config file exists after deletion');
} catch (err) {
if (err.code !== 'ENOENT') {
throw new Error('cli account delete failed - read file failed with the following error - ', err.code);
}
}
try {
await read_config_file(config_root, accounts_schema_dir, account_options.name);
throw new Error('cli account delete failed - account config file exists after deletion');
} catch (err) {
if (err.code !== 'ENOENT') {
throw new Error('cli account delete failed - read file failed with the following error - ', err.code);
}
}
});

mocha.it('cli account delete by name', async function() {
let action = nc_nsfs_manage_actions.ADD;
await exec_manage_cli(type, action, account_options);
action = nc_nsfs_manage_actions.DELETE;
const action = nc_nsfs_manage_actions.DELETE;
const res = await exec_manage_cli(type, action, { config_root, name: account_options.name });
assert_response(action, type, res);
try {
Expand Down

0 comments on commit 578b7c0

Please sign in to comment.