diff --git a/bin/cli/cmds/user_management.js b/bin/cli/cmds/user_management.js index 2f1d0cf..c9abc10 100644 --- a/bin/cli/cmds/user_management.js +++ b/bin/cli/cmds/user_management.js @@ -5,7 +5,7 @@ */ module.exports = { - 'command': 'user [pass] [mail] [group] [data...]', + 'command': 'user [data...]', 'description': 'add, get, update or remove an user', 'actionDependencies': ['vorpal'], 'action': (actionDependencies) => { @@ -15,39 +15,82 @@ module.exports = { let action = args.action.toLowerCase(); let profile = { user: args.nick, - pass: (args.pass) ? global['app'].modules.auth.generateHash(args.pass) : "-", + pass: null, mail: null, group: 0 }; - if(!args.mail) profile.mail = profile.user; - if(args.mail) profile.mail = args.mail; - if(args.group) profile.group = args.group; + // add a new user if(action === 'add') { + if(Array.isArray(args.data) && args.data.length >= 1) { + // set data + profile.pass = global['modules'].auth.generateHash(args.data[0]); + if(args.data.length >= 2) profile.mail = args.data[1]; + if(args.data.length >= 3) profile.group = args.data[2]; - global['app'].modules.database.getUser([profile.user, profile.mail], (err, rep) => { - if(err) vorpal.log("ERR: While finding user"); - else { - if (!rep) { - global['app'].modules.database.addUser(profile.user, profile.mail, profile.pass, profile.group, (errAdd, repAdd) => { - if(errAdd) vorpal.log("ERR: While adding user"); - else vorpal.log("Reply: "+rep); - }); - } else { - vorpal.log("User exists: "); - vorpal.log(rep); + // haystack verifying + let haystack = profile.user; + if(typeof profile.mail !== 'undefined' && profile.mail !== null) haystack = [profile.user, profile.mail]; + + // query user by haystack + global['modules'].database.getUser(haystack, (err, rep) => { + if(err) { + global['logs'].error("ERR: While finding user"); + global['logs'].error(err); } - } - }); + else { + // no users exist, add user + if (!rep) { + global['modules'].database.addUser(profile.user, (profile.mail || ''), profile.pass, profile.group, (errAdd, repAdd) => { + if(errAdd) { + global['logs'].error("ERR: While adding user"); + global['logs'].error(errAdd); + } + else vorpal.log("Reply: "+repAdd); + }); + // user already exists + } else { + vorpal.log("User exists: "); + vorpal.log(rep); + } + } + }); + // missing data + } else { + global['logs'].log("No data is present or is missing. Please see:"); + global['logs'].log("$ user help add"); + cb(); + } + // query users } else if(action === 'get') { - global['app'].modules.database.getUser([profile.user, profile.mail], (err, rep) => { - if(rep) { - vorpal.log("User exists: "); - vorpal.log(rep); - } else { - vorpal.log("User "+profile.user+" / "+profile.mail+" doesn't exist."); - } - }); + // wildcard catch-all + if(profile.user === '*') { + global['modules'].database.getUsers((err, rep) => { + if(rep) { + global['logs'].log(rep); + } + if(err) { + global['logs'].error('$ user get *'); + global['logs'].error(err); + } + }); + } else { + // query users by first input + global['modules'].database.getUser(profile.user, (err, rep) => { + if(rep) { + global['logs'].log("User exists: "); + global['logs'].log(rep); + } else { + global['logs'].warn("User "+profile.user+" doesn't exist."); + } + if(err) { + global['logs'].error('$ user get '+profile.user); + global['logs'].error(err); + } + }); + } + + // update users, just one field } else if(action === 'update') { if(args.data.length < 2) vorpal.log("No data supplied."); else { @@ -56,18 +99,62 @@ module.exports = { vorpal.log("Field: "+field+"; Param: "+param); } } else if(action === 'remove' || action === 'delete') { - global['app'].modules.database.getUser([profile.user, profile.mail], (err, rep) => { + // haystack + let haystack = profile.user; + if(typeof profile.mail !== 'undefined' && profile.mail !== null) haystack = [profile.user, profile.mail]; + + global['modules'].database.getUser(haystack, (err, rep) => { if(rep) { vorpal.log("User exists. Deleting him."); - vorpal.log(rep); - global['app'].modules.database.delUser(rep.email, (errDel, repDel) => { - if(repDel) vorpal.log("Deleted user."); - else vorpal.log("ERR: While deleting user."); + global['logs'].debug(rep); + global['modules'].database.delUser(rep[0].email, (errDel, repDel) => { + if(repDel) { + vorpal.log("Deleted user."); + global['logs'].debug(repDel); + } + else { + vorpal.log("ERR: While deleting user."); + global['logs'].debug(errDel); + } }); } }); - } else if(action === 'genpass') { - vorpal.log(profile.pass); + } else if(action === 'help') { + if(args.nick === 'add') { + vorpal.log("user add [group]"); + vorpal.log(": user nickname"); + vorpal.log(": will be hashed ASAP"); + vorpal.log(": format: user@example.tld"); + vorpal.log("[group]: not needed; only Numbers; group id"); + + vorpal.log("---"); + + vorpal.log("returning 0 or 1 and printing errors"); + } else if(args.nick === 'get') { + vorpal.log("user get "); + vorpal.log(": searching both in both; format: foobar OR user@example.tld"); + + vorpal.log("---"); + vorpal.log("user get * - to get all users"); + vorpal.log("printing JSON-object of user data"); + } else if(args.nick === 'update') { + vorpal.log("user update "); + vorpal.log(": user nickname"); + vorpal.log(": string"); + vorpal.log(": mixed data; will be converted to Boolean, Number or String"); + + vorpal.log("---"); + + vorpal.log("returning 0 or 1 and printing errors"); + vorpal.log("printing JSON-object of updated user data"); + } else if(args.nick === 'remove' || args.nick === 'delete') { + vorpal.log("user remove|delete "); + vorpal.log(": user nickname"); + + vorpal.log("---"); + + vorpal.log("returning 0 or 1 and printing errors"); + } } cb(); diff --git a/bin/database/models.js b/bin/database/models.js index 9391fc0..7ab6629 100644 --- a/bin/database/models.js +++ b/bin/database/models.js @@ -46,7 +46,7 @@ models.user = new Schema({ // group models.group = new Schema({ - name: String, // recognizable application name; ex. "Administration" + name: String, // recognizable group name; ex. "Administration" created: {type: Date, default: Date.now}, roles: {type: String, default: ""} // roles; separated by commas "a,b,a.b,c.*,d.z.*" }); @@ -61,16 +61,16 @@ models.application = new Schema({ // activities models.activity = new Schema({ - userId: Schema.Types.ObjectId, + userId: Schema.Types.ObjectId, // reference to user date: { type: Date, default: Date.now}, - uri: { type: String, default: ""}, - state: { type: Boolean, default: false } + uri: { type: String, default: ""}, // full path url e.g. http://localhost/activity_url?a=s + state: { type: Boolean, default: false } // successed or failed }); // used authcodes models.authCode = new Schema({ - applicationId: Schema.Types.ObjectId, - userId: Schema.Types.ObjectId, + applicationId: Schema.Types.ObjectId, // reference to application + userId: Schema.Types.ObjectId, // reference to user token: String, // generated token, only usable in combination with userId and applicationId timestamp: { type: Date, default: Date.now } }); diff --git a/bin/database/module.js b/bin/database/module.js index 0c337de..6cc0a81 100644 --- a/bin/database/module.js +++ b/bin/database/module.js @@ -46,29 +46,28 @@ global['gds'].db.on('error', (data) => { /** * Adds User to Database * @author Ruben Meyer - * @param {String} firstname First name - * @param {String} lastname Last name - * @param {String} email E-Mail - * @param {String} password hashed PW + * @param {String} nick nickname + * @param {String} email email + * @param {String} passhash hashed password * @param {Number} group Group id (normally 0 -> user) * @param {Function} callback Callback function (error, reply) */ -methods.addUser = (nick, email, pass, group, callback) => { +methods.addUser = (nick, email, passhash, group, callback) => { if(typeof callback !== 'function') callback = function() {}; - if(typeof nick !== 'string') return callback(new TypeError('nick is not a string::database.addUser('+nick+','+email+','+pass+','+group+',callback)', module.filename)); - if(typeof email !== 'string') return callback(new TypeError('email is not a string::database.addUser('+nick+','+email+','+pass+','+group+',callback)', module.filename)); - if(typeof pass !== 'string') return callback(new TypeError('pass is not a string::database.addUser('+nick+','+email+','+pass+','+group+',callback)', module.filename)); - if(isNaN(group)) return callback(new TypeError('group is not a number::database.addUser('+nick+','+email+','+pass+','+group+',callback)', module.filename)); + if(typeof nick !== 'string') return callback(new TypeError('nick is not a string::database.addUser('+nick+','+email+','+passhash+','+group+',callback)', module.filename)); + if(typeof email !== 'string') return callback(new TypeError('email is not a string::database.addUser('+nick+','+email+','+passhash+','+group+',callback)', module.filename)); + if(typeof passhash !== 'string') return callback(new TypeError('passhash is not a string::database.addUser('+nick+','+email+','+passhash+','+group+',callback)', module.filename)); + if(isNaN(group)) return callback(new TypeError('group is not a number::database.addUser('+nick+','+email+','+passhash+','+group+',callback)', module.filename)); - var User = models.user; + let userModel = models.user; - let tempUser = new User(); - tempUser.nickname = nick; - tempUser.email = email; - tempUser.passhash = pass; - tempUser.group = group; + let user = new userModel(); + user.nickname = nick; + user.email = email; + user.passhash = passhash; + user.group = group; - tempUser.save((err) => { + user.save((err) => { if(!err) callback(null, 1); else callback(err); }); @@ -86,11 +85,12 @@ methods.delUser = (haystack, callback) => { if(typeof callback !== 'function') callback = function() {}; if(typeof haystack !== 'string') return callback(new TypeError('haystack is not a string::database.delUser('+haystack+',callback)', module.filename)); - var User = models.user; + let userModel = models.user; - User.find().or([{nickname: haystack}, {email: haystack}]) - .then((users) => { + userModel.findOneAndDelete().or([{nickname: haystack}, {email: haystack}]) + .then((rep) => { // TODO delete user + global['logs'].debug('deleted user: '+haystack); callback(null, 1); }).catch((err) => { callback(err); @@ -99,7 +99,28 @@ methods.delUser = (haystack, callback) => { /** - * gets entry by email + * get all users + * @author Ruben Meyer + * @param {Function} callback Callback function (reply -> Array users) + */ +methods.getUsers = (callback) => { + if(typeof callback !== 'function') callback = function() {}; + + let userModel = models.user; + + userModel.find({}) + .then((users) => { + if(users.length > 0) + return callback(null, users); + else + return callback(null, false); + }).catch((err) => { + return callback(err); + }); +}; + +/** + * query users by email, nickname or rememberme token * @author Ruben Meyer * @param {String|String[]} haystack email or nick * @param {Function} callback Callback function (reply -> Array users) @@ -108,7 +129,7 @@ methods.getUser = (haystack, callback) => { if(typeof callback !== 'function') callback = function() {}; if(typeof haystack !== 'string' && typeof haystack !== 'object') return callback(new TypeError('email or nickname is not a string|object::database.getUser('+haystack+',callback)', module.filename)); - var User = models.user; + let userModel = models.user; let or = []; if(typeof haystack === 'string') { @@ -125,7 +146,7 @@ methods.getUser = (haystack, callback) => { } } - User.find().or(or) + userModel.find().or(or) .then((users) => { if(users.length > 0) return callback(null, users); @@ -144,13 +165,13 @@ methods.getUser = (haystack, callback) => { * @param {Object} obj data * @param {Function} callback Callback function */ -methods.updateUserProfile = (id, obj, callback) => { +methods.updateUser = (id, obj, callback) => { if(typeof callback !== 'function') callback = function() {}; - if(typeof id !== 'string') return callback(new TypeError('id is not a string::database.updateUserProfile('+id+','+JSON.stringify(obj)+',callback)', module.filename)); - if(typeof obj !== 'object') return callback(new TypeError('obj is not an object::database.updateUserProfile('+id+','+JSON.stringify(obj)+',callback)', module.filename)); + if(typeof id !== 'string') return callback(new TypeError('id is not a string::database.updateUser('+id+','+JSON.stringify(obj)+',callback)', module.filename)); + if(typeof obj !== 'object') return callback(new TypeError('obj is not an object::database.updateUser('+id+','+JSON.stringify(obj)+',callback)', module.filename)); - var User = models.user; - User.findByIdAndUpdate(id, obj, (err, data) => { + let userModel = models.user; + userModel.findByIdAndUpdate(id, obj, (err, data) => { if(err) callback(err); else callback(null, data); }); @@ -161,11 +182,12 @@ methods.updateUserProfile = (id, obj, callback) => { /** * updates data based on login * @author Ruben Meyer + * @TODO UPDATE METHOD; PROBABLY OUTDATED * @param {Number} id User ID - * @param {Object} options options JSON -> remember + * @param {Object} data data JSON -> remember * @param {Function} callback Callback function (date => 'Login Date', token => 'RememberMe Cookie Token') */ -methods.updateNewAction = (id, options, callback) => { +methods.addActivity = (id, data, callback) => { if(typeof callback !== 'function') callback = function() {}; if(typeof id !== 'string') return callback(new TypeError('id is not a string::database.updateNewAction('+id+','+JSON.stringify(options)+',callback)', module.filename)); if(typeof options !== 'object' && options !== null) return callback(new TypeError('obj is not an object::database.updateUserProfile('+id+','+JSON.stringify(obj)+',callback)', module.filename)); @@ -331,8 +353,8 @@ methods.verifyAppCall = (obj, callback) => { methods.userCount = (callback) => { if(typeof callback !== 'function') callback = function() {}; - var User = models.user; - User.countDocuments({}, (err, count) => { + let userModel = models.user; + userModel.countDocuments({}, (err, count) => { callback((err) ? err : count); }); };