diff --git a/core/oputil/oputil_help.js b/core/oputil/oputil_help.js index 0d132445..c3767c92 100644 --- a/core/oputil/oputil_help.js +++ b/core/oputil/oputil_help.js @@ -59,6 +59,15 @@ Actions: group USERNAME [+|-]GROUP Adds (+) or removes (-) user from a group + list [FILTER] List users with optional FILTER. + + Valid filters: + all : All users (default). + disabled : Disabled users. + inactive : Inactive users. + active : Active (regular) users. + locked : Locked users. + info arguments: --security Include security information in output diff --git a/core/oputil/oputil_user.js b/core/oputil/oputil_user.js index 78ea08ca..376ee166 100644 --- a/core/oputil/oputil_user.js +++ b/core/oputil/oputil_user.js @@ -460,6 +460,64 @@ function twoFactorAuthOTP(user) { ); } +function listUsers() { + // oputil user list [disabled|inactive|active|locked|all] + // :TODO: --after TIMESTAMP (new users) + // :TODO: --sort name|id + let listWhat; + if (argv._.length > 2) { + listWhat = argv._[argv._.length - 1]; + } else { + listWhat = 'all'; + } + + const User = require('../../core/user'); + if (![ 'all' ].concat(Object.keys(User.AccountStatus)).includes(listWhat)) { + return printUsageAndSetExitCode(getHelpFor('User'), ExitCodes.ERROR); + } + + async.waterfall( + [ + (callback) => { + const UserProps = require('../../core/user_property'); + + const userListOpts = { + properties : [ + UserProps.AccountStatus, + ], + }; + + User.getUserList(userListOpts, (err, userList) => { + if (err) { + return callback(err); + } + + if ('all' === listWhat) { + return callback(null, userList); + } + + const accountStatusFilter = User.AccountStatus[listWhat].toString(); + + return callback(null, userList.filter(user => { + return user[UserProps.AccountStatus] === accountStatusFilter; + })); + }); + }, + (userList, callback) => { + userList.forEach(user => { + + console.info(`${user.userId}: ${user.userName}`); + }); + }, + ], + err => { + if(err) { + return console.error(err.reason ? err.reason : err.message); + } + } + ); +} + function handleUserCommand() { function errUsage() { return printUsageAndSetExitCode(getHelpFor('User'), ExitCodes.ERROR); @@ -470,20 +528,25 @@ function handleUserCommand() { } const action = argv._[1]; - const usernameIdx = [ - 'pw', 'pass', 'passwd', 'password', - 'group', - 'mv', 'rename', - '2fa-otp', 'otp' - ].includes(action) ? argv._.length - 2 : argv._.length - 1; - const userName = argv._[usernameIdx]; + const userRequired = ![ 'list' ].includes(action); - if(!userName) { + let userName; + if (userRequired) { + const usernameIdx = [ + 'pw', 'pass', 'passwd', 'password', + 'group', + 'mv', 'rename', + '2fa-otp', 'otp' + ].includes(action) ? argv._.length - 2 : argv._.length - 1; + userName = argv._[usernameIdx]; + } + + if(!userName && userRequired) { return errUsage(); } initAndGetUser(userName, (err, user) => { - if(err) { + if(userName && err) { process.exitCode = ExitCodes.ERROR; return console.error(err.message); } @@ -512,6 +575,7 @@ function handleUserCommand() { '2fa-otp' : twoFactorAuthOTP, otp : twoFactorAuthOTP, + list : listUsers, }[action] || errUsage)(user, action); }); } \ No newline at end of file