* WIP on user groups

* Minor changes to user credential prompt
This commit is contained in:
Bryan Ashby 2015-05-11 16:39:28 -06:00
parent ca3453ecfb
commit a7f9e3846e
8 changed files with 145 additions and 37 deletions

View File

@ -86,6 +86,7 @@ function getDefaultConfig() {
passwordMax : 128,
requireActivation : true, // require SysOp activation?
invalidUsernames : [],
defaultGroups : [ 'users' ]
},
defaults : {

View File

@ -70,4 +70,9 @@ function createInitialValues() {
'INSERT OR IGNORE INTO user_group ' +
'VALUES(1, "users");'
);
dbs.user.run(
'INSERT OR IGNORE INTO user_group ' +
'VALUES(2, "sysops");'
);
}

View File

@ -13,6 +13,10 @@ var _ = require('lodash');
exports.TextView = TextView;
function TextView(options) {
if(options.dimens) {
options.dimens.height = 1; // force height of 1 for TextView's & sub classes
}
View.call(this, options);
var self = this;
@ -36,8 +40,6 @@ function TextView(options) {
this.textMaskChar = options.textMaskChar;
}
this.dimens.height = 1;
this.drawText = function(s) {
//

View File

@ -3,6 +3,7 @@
var userDb = require('./database.js').dbs.user;
var Config = require('./config.js').config;
var userGroup = require('./user_group.js');
var crypto = require('crypto');
var assert = require('assert');
@ -116,6 +117,15 @@ User.prototype.authenticate = function(username, password, cb) {
cachedInfo.properties = allProps;
}
callback(err);
});
},
function initGroups(callback) {
userGroup.getGroupsForUser(cachedInfo.userId, function groupsLoaded(err, groups) {
if(!err) {
cachedInfo.groups = groups;
}
callback(err);
});
}
@ -125,6 +135,7 @@ User.prototype.authenticate = function(username, password, cb) {
self.userId = cachedInfo.userId;
self.username = cachedInfo.username;
self.properties = cachedInfo.properties;
self.groups = cachedInfo.groups;
self.authenticated = true;
}
@ -164,6 +175,8 @@ User.prototype.create = function(options, cb) {
// :TODO: set various defaults, e.g. default activation status, etc.
self.properties.account_status = Config.users.requireActivation ? User.AccountStatus.inactive : User.AccountStatus.active;
// :TODO: Set default groups from Config.users.defaultGroups[]
async.series(
[
function beginTransaction(callback) {
@ -203,6 +216,16 @@ User.prototype.create = function(options, cb) {
}
});
},
function setInitialGroupMembership(callback) {
userGroup.getGroupsByName(Config.users.defaultGroups, function defaultGroups(err, groups) {
if(err) {
callback(err);
} else {
self.groups = groups;
callback(null);
}
});
},
function saveAll(callback) {
self.persist(false, function persisted(err) {
callback(err);
@ -245,6 +268,11 @@ User.prototype.persist = function(useTransaction, cb) {
persistProperties(self, function persisted(err) {
callback(err);
});
},
function saveGroups(callback) {
userGroup.addUserToGroups(self.userId, self.groups, function groupsSaved(err) {
callback(err);
});
}
],
function complete(err) {
@ -452,34 +480,6 @@ function loadProperties(options, cb) {
});
}
function loadGroups(userId, cb) {
//
// user_group
// group_id | group_name
//
//
// user_group_member
// group_id | user_id
//
//
var sql = '';
var groups = {}; // id:name
userDb.each(sql, [ userId ], function dbRow(err, row) {
if(err) {
cb(err);
return;
} else {
//groups[row.group_id]
}
},
function complete() {
cb(null, groups);
});
}
/*function getProperties(userId, propNames, cb) {
var properties = {};

93
core/user_group.js Normal file
View File

@ -0,0 +1,93 @@
/* jslint node: true */
'use strict';
var userDb = require('./database.js').dbs.user;
var Config = require('./config.js').config;
var async = require('async');
var _ = require('lodash');
exports.getGroupsForUser = getGroupsForUser;
exports.getGroupsByName = getGroupsByName;
exports.addUserToGroup = addUserToGroup;
exports.addUserToGroups = addUserToGroups;
exports.removeUserFromGroup = removeUserFromGroup;
//
// user_group
// group_id | group_name
//
//
// user_group_member
// group_id | user_id
//
//
function getGroupsForUser(userId, cb) {
var sql =
'SELECT g.group_id, g.group_name ' +
'FROM user_group g, user_group_member gm ' +
'WHERE g.group_id = gm.group_id AND gm.user_id = ?;';
var groups = {}; // id:name
userDb.each(sql, [ userId ], function dbRow(err, row) {
if(err) {
cb(err);
return;
} else {
console.log(row);
//groups[row.group_id]
}
},
function complete() {
cb(null, groups);
});
}
function getGroupsByName(groupNames, cb) {
var sql =
'SELECT group_id, group_name ' +
'FROM user_group ' +
'WHERE group_name IN ("' + groupNames.join('","') + '");';
userDb.all(sql, function allRows(err, rows) {
if(err) {
cb(err);
return;
} else {
var groups = {};
rows.forEach(function row(r) {
groups[r.group_id] = r.group_name;
});
cb(null, groups);
}
});
}
function addUserToGroup(userId, groupId, cb) {
userDb.run(
'REPLACE INTO user_group_member (group_id, user_id) ' +
'VALUES(?, ?);',
[ groupId, userId ],
function complete(err) {
cb(err);
}
);
}
function addUserToGroups(userId, groups, cb) {
async.each(Object.keys(groups), function item(groupId, nextItem) {
addUserToGroup(userId, groupId, function added(err) {
nextItem(err);
});
}, function complete(err) {
cb(err);
});
}
function removeUserFromGroup(userId, groupId, cb) {
}

View File

@ -74,6 +74,7 @@ function submitApplication(callingMenu, formData, extraArgs) {
menuViewController.switchFocus(viewIds[0]);
} else {
// Seems legit!
// :TODO: All of this should be a system API, not a mod
var newUser = new user.User();
newUser.username = formData.value.username;
@ -87,6 +88,7 @@ function submitApplication(callingMenu, formData, extraArgs) {
email_address : formData.value.email,
web_address : formData.value.web,
// :TODO: This is set in User.create() -- proabbly don't need it here:
account_status : Config.users.requireActivation ? user.User.AccountStatus.inactive : user.User.AccountStatus.active,
// :TODO: Other defaults

View File

@ -56,7 +56,8 @@
"submit" : true,
"focus" : true,
// :TODO: need a good way to localize these ... Standard Orig->Lookup seems good.
"items" : [ "Login", "Apply", "Log Off" ]
"items" : [ "Login", "Apply", "Log Off" ],
"itemSpacing" : 1
}
},
"submit" : {

View File

@ -1,14 +1,18 @@
{
"userCredentials" : {
"art" : "USERCRED",
"art" : "usercred",
"mci" : {
"ET1" : {
"argName" : "username"
"argName" : "username",
"width" : 15,
"maxLength" : "@config:users.usernameMax"
},
"ET2" : {
"submit" : true,
"argName" : "password",
"password" : true
"submit" : true,
"argName" : "password",
"password" : true,
"width" : 15,
"maxLength" : "@config:users.passwordMax"
}
}
},