diff --git a/src/manage_nsfs/manage_nsfs_cli_errors.js b/src/manage_nsfs/manage_nsfs_cli_errors.js index 505ace007c..9b5c0a2f95 100644 --- a/src/manage_nsfs/manage_nsfs_cli_errors.js +++ b/src/manage_nsfs/manage_nsfs_cli_errors.js @@ -193,15 +193,15 @@ ManageCLIError.MissingAccountAccessKeyFlag = Object.freeze({ http_code: 400, }); -ManageCLIError.AccountSecretKeyFlagComplexity = Object.freeze({ - code: 'AccountSecretKeyFlagComplexity', - message: 'Account secret length must be 40, and must contain uppercase, lowercase, numbers and symbols', +ManageCLIError.InvalidAccountSecretKeyFlag = Object.freeze({ + code: 'InvalidAccountSecretKeyFlag', + message: 'Account secret length must be 40, and must contain only alpha-numeric chars, "+", "/"', http_code: 400, }); -ManageCLIError.AccountAccessKeyFlagComplexity = Object.freeze({ - code: 'AccountAccessKeyFlagComplexity', - message: 'Account access key length must be 20, and must contain uppercase and numbers', +ManageCLIError.InvalidAccountAccessKeyFlag = Object.freeze({ + code: 'InvalidAccountAccessKeyFlag', + message: 'Account access key length must be 20, and must contain only alpha-numeric chars', http_code: 400, }); diff --git a/src/manage_nsfs/manage_nsfs_validations.js b/src/manage_nsfs/manage_nsfs_validations.js index 85d71685ab..0b64156f7c 100644 --- a/src/manage_nsfs/manage_nsfs_validations.js +++ b/src/manage_nsfs/manage_nsfs_validations.js @@ -316,23 +316,15 @@ function _validate_access_keys(access_key, secret_key) { if (!_.isUndefined(secret_key) && _.isUndefined(access_key)) { throw_cli_error(ManageCLIError.MissingAccountAccessKeyFlag); } - // checking the complexity of access_key - if (!_.isUndefined(access_key) && !string_utils.validate_complexity(access_key, { - require_length: 20, - check_uppercase: true, - check_lowercase: false, - check_numbers: true, - check_symbols: false, - })) throw_cli_error(ManageCLIError.AccountAccessKeyFlagComplexity); - // checking the complexity of secret_key - if (!_.isUndefined(secret_key) && !string_utils.validate_complexity(secret_key, { - require_length: 40, - check_uppercase: true, - check_lowercase: true, - check_numbers: true, - check_symbols: true, - })) throw_cli_error(ManageCLIError.AccountSecretKeyFlagComplexity); + // checking access_key length=20 and contains only alphanumeric chars + if (access_key && !string_utils.access_key_regexp.test(access_key)) { + throw_cli_error(ManageCLIError.InvalidAccountAccessKeyFlag); + } + // checking secret_key length=40 and contains only alphanumeric chars and +/ + if (secret_key && !string_utils.secret_key_regexp.test(secret_key)) { + throw_cli_error(ManageCLIError.InvalidAccountSecretKeyFlag); + } } /** diff --git a/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js b/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js index 822e41f91a..77b33beeb2 100644 --- a/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js +++ b/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js @@ -107,20 +107,36 @@ describe('manage nsfs cli account flow', () => { assert_account(account_symlink, account_options); }); - it('should fail - cli update account access_key wrong complexity', async () => { + it('should fail - cli update account invalid access_key - invalid size', async () => { const { type, secret_key, name, new_buckets_path, uid, gid } = defaults; const account_options = { config_root, access_key: 'abc', secret_key, name, new_buckets_path, uid, gid }; const action = ACTIONS.UPDATE; const res = await exec_manage_cli(type, action, account_options); - expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.AccountAccessKeyFlagComplexity.message); + expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.InvalidAccountAccessKeyFlag.message); }); - it('should fail - cli update account secret_key wrong complexity', async () => { + it('should fail - cli update account invalid access_key - contains "+" ', async () => { + const { type, secret_key, name, new_buckets_path, uid, gid } = defaults; + const account_options = { config_root, access_key: 'abc+abc+abc+abc+abc+', secret_key, name, new_buckets_path, uid, gid }; + const action = ACTIONS.UPDATE; + const res = await exec_manage_cli(type, action, account_options); + expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.InvalidAccountAccessKeyFlag.message); + }); + + it('should fail - cli update account invalid secret_key - invalid size', async () => { const { type, access_key, name, new_buckets_path, uid, gid } = defaults; const account_options = { config_root, access_key, secret_key: 'abc', name, new_buckets_path, uid, gid }; const action = ACTIONS.UPDATE; const res = await exec_manage_cli(type, action, account_options); - expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.AccountSecretKeyFlagComplexity.message); + expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.InvalidAccountSecretKeyFlag.message); + }); + + it('should fail - cli update account invalid secret_key - contains @', async () => { + const { type, access_key, name, new_buckets_path, uid, gid } = defaults; + const account_options = { config_root, access_key, secret_key: 'abcaabcabcabc@abcabcabc@abcabcabc@abcabc', name, new_buckets_path, uid, gid }; + const action = ACTIONS.UPDATE; + const res = await exec_manage_cli(type, action, account_options); + expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.InvalidAccountSecretKeyFlag.message); }); it('should fail - cli create account integer uid and gid', async () => { @@ -1137,7 +1153,7 @@ describe('manage nsfs cli account flow', () => { const command_flags = {config_root, from_file: path_to_option_json_file_name}; // create the account const res = await exec_manage_cli(type, action, command_flags); - expect(JSON.parse(res.stdout).error.code).toBe(ManageCLIError.AccountAccessKeyFlagComplexity.code); + expect(JSON.parse(res.stdout).error.code).toBe(ManageCLIError.InvalidAccountAccessKeyFlag.code); }); it('should fail - cli create account using from_file with additional flags (name)', async () => { diff --git a/src/util/string_utils.js b/src/util/string_utils.js index 9cbe87ceb8..156c959db8 100644 --- a/src/util/string_utils.js +++ b/src/util/string_utils.js @@ -8,10 +8,8 @@ const crypto = require('crypto'); const ALPHA_NUMERIC_CHARSET = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; const email_regexp = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; const escape_regexp = /[\\^$.*+?()[\]{}|]/g; -const uppercase_regexp = /[A-Z]/; -const lowercase_regexp = /[a-z]/; -const numbers_regexp = /\d/; -const symbols_regexp = /[!@#$%^&*(),.?":+-{}|<>]/; +const access_key_regexp = /^[a-zA-Z0-9]{20}$/; +const secret_key_regexp = /^[a-zA-Z0-9+/]{40}$/; function crypto_random_string(len, charset = ALPHA_NUMERIC_CHARSET) { // In order to not favor any specific chars over others we limit the maximum random value @@ -148,99 +146,6 @@ function escape_reg_exp(str) { return str.replace(escape_regexp, '\\$&'); } -/** - * - * @param {string} string - * @param {number} require_length - */ -function validate_length(string, require_length) { - if (string.length !== require_length) { - return false; - } - return true; -} - -/** - * @param {string} string - * @param {boolean} check_uppercase - */ -function validate_uppercase(string, check_uppercase) { - const uppercase_test = uppercase_regexp.test(string); - if (check_uppercase && !uppercase_test) { - return false; - } - return true; -} - -/** - * @param {string} string - * @param {boolean} check_lowercase - */ -function validate_lowercase(string, check_lowercase) { - const lowercase_test = lowercase_regexp.test(string); - if (check_lowercase && !lowercase_test) { - return false; - } - return true; -} - -/** - * @param {string} string - * @param {boolean} check_numbers - */ -function validate_numbers(string, check_numbers) { - const numbers_test = numbers_regexp.test(string); - if (check_numbers && !numbers_test) { - return false; - } - return true; -} - -/** - * @param {string} string - * @param {boolean} check_symbols - */ -function validate_symbols(string, check_symbols) { - const symbols_test = symbols_regexp.test(string); - if (check_symbols && !symbols_test) { - return false; - } - return true; -} - - -/** - * validate_complexity will validate the complexity of a string - * - * @param {string} string - * @param {{ - * require_length?: number, - * check_uppercase?: boolean, - * check_lowercase?: boolean, - * check_numbers?: boolean, - * check_symbols?: boolean, - * }} options - Options for complexity validation. - * - * @returns {boolean} - */ -function validate_complexity(string, options = {}) { - const { - require_length = 20, - check_uppercase = true, - check_lowercase = true, - check_numbers = true, - check_symbols = true, - } = options; - - return ( - validate_length(string, require_length) && - validate_uppercase(string, check_uppercase) && - validate_lowercase(string, check_lowercase) && - validate_numbers(string, check_numbers) && - validate_symbols(string, check_symbols) - ); -} - exports.ALPHA_NUMERIC_CHARSET = ALPHA_NUMERIC_CHARSET; exports.crypto_random_string = crypto_random_string; exports.left_pad_zeros = left_pad_zeros; @@ -249,9 +154,5 @@ exports.rolling_hash = rolling_hash; exports.equal_case_insensitive = equal_case_insensitive; exports.is_email_address = is_email_address; exports.escape_reg_exp = escape_reg_exp; -exports.validate_length = validate_length; -exports.validate_uppercase = validate_uppercase; -exports.validate_lowercase = validate_lowercase; -exports.validate_numbers = validate_numbers; -exports.validate_symbols = validate_symbols; -exports.validate_complexity = validate_complexity; +exports.access_key_regexp = access_key_regexp; +exports.secret_key_regexp = secret_key_regexp;