admin command newuser added

This commit is contained in:
Dominic Bosch 2014-04-21 14:42:26 +02:00
parent bc999b6012
commit d7c09e2e2e
16 changed files with 221 additions and 69 deletions

View file

@ -50,14 +50,14 @@ exports.addRuleListener = ( eh ) =>
eventEmitter.addListener 'rule', eh
# Fetch all active rules per user
db.getAllActivatedRuleIdsPerUser ( err, objUsers ) ->
db.getAllActivatedRuleIdsPerUser ( err, objUsers ) =>
# Go through all rules of each user
fGoThroughUsers = ( user, rules ) ->
fGoThroughUsers = ( user, rules ) =>
# Fetch the rules object for each rule in each user
fFetchRule = ( userName ) ->
( rule ) ->
fFetchRule = ( userName ) =>
( rule ) =>
db.getRule rule, ( err, strRule ) =>
try
oRule = JSON.parse strRule

View file

@ -124,13 +124,14 @@ updateActionModules = ( updatedRuleId ) =>
fRequired = ( actionName ) ->
for action in oUser[updatedRuleId].rule.actions
# Since the event is in the format 'module -> function' we need to split the string
if (action.split ' -> ')[0] is actionName
if (action.split ' -> ')[ 0 ] is actionName
return true
false
# Go thorugh all loaded action modules and check whether the action is still required
for action of oUser[updatedRuleId].rule.actions
delete oUser[updatedRuleId].actions[action] if not fRequired action
if oUser[updatedRuleId]
for action of oUser[updatedRuleId].rule.actions
delete oUser[updatedRuleId].actions[action] if not fRequired action
fRemoveNotRequired oUser for name, oUser of listUserRules
@ -142,7 +143,7 @@ updateActionModules = ( updatedRuleId ) =>
# Load the action invoker module if it was part of the updated rule or if it's new
fAddIfNewOrNotExisting = ( actionName ) =>
moduleName = (actionName.split ' -> ')[0]
moduleName = (actionName.split ' -> ')[ 0 ]
if not oMyRule.actions[moduleName] or oMyRule.rule.id is updatedRuleId
db.actionInvokers.getModule moduleName, ( err, obj ) =>
if obj

View file

@ -624,9 +624,10 @@ exports.storeUser = ( objUser ) =>
if objUser and objUser.username and objUser.password
@db.sadd 'users', objUser.username,
replyHandler "sadd 'users' -> '#{ objUser.username }'"
objUser.password = objUser.password
@db.hmset "user:#{ objUser.username }", objUser,
replyHandler "hmset 'user:#{ objUser.username }' -> [objUser]"
@db.hset "user:#{ objUser.username }", "roles", JSON.stringify( objUser.roles ),
replyHandler "hset 'user:#{ objUser.username }' field 'roles' -> [objUser]"
else
@log.warn new Error 'DB | username or password was missing'
@ -649,7 +650,10 @@ Fetch a user by id and pass it to cb(err, obj).
###
exports.getUser = ( userId, cb ) =>
@log.info "DB | getUser: '#{ userId }'"
@db.hgetall "user:#{ userId }", cb
@db.hgetall "user:#{ userId }", ( err, obj ) =>
try
obj.roles = JSON.parse obj.roles
cb err, obj
###
Deletes a user and all his associated linked and active rules.
@ -708,6 +712,7 @@ exports.loginUser = ( userId, password, cb ) =>
else if obj and obj.password
if pw is obj.password
@log.info "DB | User '#{ obj.username }' logged in!"
obj.roles = JSON.parse obj.roles
cb null, obj
else
cb (new Error 'Wrong credentials!'), null

View file

@ -25,7 +25,9 @@ qs = require 'querystring'
# [crypto-js](https://github.com/evanvosberg/crypto-js)
mustache = require 'mustache'
crypto = require 'crypto-js'
pathUsers = path.resolve __dirname, '..', 'config', 'users.json'
# Prepare the user command handlers which are invoked via HTTP requests.
dirHandlers = path.resolve __dirname, '..', 'webpages', 'handlers'
exports = module.exports = ( args ) =>
@ -42,10 +44,53 @@ exports = module.exports = ( args ) =>
message: 'Shutting down... BYE!'
setTimeout args[ 'shutdown-function' ], 500
cb null, data
newuser: ( obj, cb ) ->
data =
code: 200
message: 'User stored thank you!'
if obj.username and obj.password
if obj.roles
try
roles = JSON.parse obj.roles
catch err
@log 'RH | error parsing newuser roles: ' + err.message
roles = []
else
roles = []
oUser =
username: obj.username
password: obj.password
roles: roles
db.storeUser oUser
fPersistNewUser = ( username, password, roles ) ->
( err, data ) ->
users = JSON.parse data
users[ username ] =
password: password
roles: roles
fs.writeFile pathUsers, JSON.stringify( users, undefined, 2 ), 'utf8', ( err ) ->
if err
@log.error "RH | Unable to write new user file! "
@log.error err
# {
# "admin": {
# "password": "7407946a7a90b037ba5e825040f184a142161e4c61d81feb83ec8c7f011a99b0d77f39c9170c3231e1003c5cf859c69bd93043b095feff5cce6f6d45ec513764",
# "roles": ["admin"]
# }
# }
# {"admin":{"password":"7407946a7a90b037ba5e825040f184a142161e4c61d81feb83ec8c7f011a99b0d77f39c9170c3231e1003c5cf859c69bd93043b095feff5cce6f6d45ec513764","roles":["admin"]},"dominic":{"password":"2d51496fbe5b6d3e98e22d68140609eaedd64de457b2f75c346a4a98f87928eac11ea2be747709ae7a2f5b177af09a60a8dbf14bf703e0cb9b147fc0a3e3a064","roles":[]}}
fs.readFile pathUsers, 'utf8', fPersistNewUser obj.username, obj.password, roles
else
data.code = 401
data.message = 'Missing parameter for this command'
cb null, data
db args
# Load the standard users from the user config file
users = JSON.parse fs.readFileSync path.resolve __dirname, '..', 'config', 'users.json'
users = JSON.parse fs.readFileSync pathUsers, 'utf8'
fStoreUser = ( username, oUser ) ->
oUser.username = username
db.storeUser oUser
@ -280,9 +325,9 @@ exports.handleAdmin = ( req, resp ) ->
if not req.session.user
page = 'login'
#TODO isAdmin should come from the db role
else if req.session.user.isAdmin isnt "true"
else if req.session.user.roles.indexOf( "admin" ) is -1
page = 'login'
msg = 'You need to be admin!'
msg = 'You need to be admin for this page!'
else
page = 'admin'
renderPage page, req, resp, msg
@ -299,19 +344,26 @@ objects.*
###
exports.handleAdminCommand = ( req, resp ) =>
if req.session and
req.session.user and
req.session.user.isAdmin is "true"
req.session.user and
req.session.user.roles.indexOf( "admin" ) > -1
body = ''
req.on 'data', ( data ) ->
body += data
req.on 'end', =>
obj = qs.parse body
@log.info 'RH | Received admin request: ' + obj.command
if obj.command and @objAdminCmds[obj.command]
@objAdminCmds[obj.command] obj, ( err, obj ) ->
resp.send obj.code, obj
else
arrCmd = obj.command.split( ' ' )
if not arrCmd[ 0 ] or not @objAdminCmds[ arrCmd[ 0 ] ]
resp.send 404, 'Command unknown!'
else
arrParams = arrCmd.slice 1
oParams = {}
for keyVal in arrParams
arrKV = keyVal.split ":"
if arrKV.length is 2
oParams[ arrKV[ 0 ] ] = arrKV[ 1 ]
@objAdminCmds[ arrCmd[ 0 ] ] oParams, ( err, obj ) ->
resp.send obj.code, obj
else
resp.send 401, 'You need to be logged in as admin!'

View file

@ -1,10 +1,12 @@
{
"admin": {
"password": "7407946a7a90b037ba5e825040f184a142161e4c61d81feb83ec8c7f011a99b0d77f39c9170c3231e1003c5cf859c69bd93043b095feff5cce6f6d45ec513764",
"roles": [ "admin" ]
"roles": [
"admin"
]
},
"dominic": {
"password": "2d51496fbe5b6d3e98e22d68140609eaedd64de457b2f75c346a4a98f87928eac11ea2be747709ae7a2f5b177af09a60a8dbf14bf703e0cb9b147fc0a3e3a064",
"roles": [ "admin" ]
"roles": []
}
}
}

View file

@ -61,24 +61,22 @@ Components Manager
var fFetchRule, rule, _i, _len, _results;
fFetchRule = function(userName) {
return function(rule) {
return db.getRule(rule, (function(_this) {
return function(err, strRule) {
var oRule;
try {
oRule = JSON.parse(strRule);
db.resetLog(userName, oRule.id);
db.appendLog(userName, oRule.id, "INIT", "Rule '" + oRule.id + "' initialized. Interval set to " + oRule.event_interval + " minutes");
return eventEmitter.emit('rule', {
event: 'init',
user: userName,
rule: oRule
});
} catch (_error) {
err = _error;
return _this.log.warn("CM | There's an invalid rule in the system: " + strRule);
}
};
})(this));
return db.getRule(rule, function(err, strRule) {
var oRule;
try {
oRule = JSON.parse(strRule);
db.resetLog(userName, oRule.id);
db.appendLog(userName, oRule.id, "INIT", "Rule '" + oRule.id + "' initialized. Interval set to " + oRule.event_interval + " minutes");
return eventEmitter.emit('rule', {
event: 'init',
user: userName,
rule: oRule
});
} catch (_error) {
err = _error;
return _this.log.warn("CM | There's an invalid rule in the system: " + strRule);
}
});
};
};
_results = [];

View file

@ -142,15 +142,17 @@ Engine
}
return false;
};
_results = [];
for (action in oUser[updatedRuleId].rule.actions) {
if (!fRequired(action)) {
_results.push(delete oUser[updatedRuleId].actions[action]);
} else {
_results.push(void 0);
if (oUser[updatedRuleId]) {
_results = [];
for (action in oUser[updatedRuleId].rule.actions) {
if (!fRequired(action)) {
_results.push(delete oUser[updatedRuleId].actions[action]);
} else {
_results.push(void 0);
}
}
return _results;
}
return _results;
};
for (name in listUserRules) {
oUser = listUserRules[name];

View file

@ -839,8 +839,8 @@ Persistence
_this.log.info("DB | storeUser: '" + objUser.username + "'");
if (objUser && objUser.username && objUser.password) {
_this.db.sadd('users', objUser.username, replyHandler("sadd 'users' -> '" + objUser.username + "'"));
objUser.password = objUser.password;
return _this.db.hmset("user:" + objUser.username, objUser, replyHandler("hmset 'user:" + objUser.username + "' -> [objUser]"));
_this.db.hmset("user:" + objUser.username, objUser, replyHandler("hmset 'user:" + objUser.username + "' -> [objUser]"));
return _this.db.hset("user:" + objUser.username, "roles", JSON.stringify(objUser.roles), replyHandler("hset 'user:" + objUser.username + "' field 'roles' -> [objUser]"));
} else {
return _this.log.warn(new Error('DB | username or password was missing'));
}
@ -874,7 +874,12 @@ Persistence
exports.getUser = (function(_this) {
return function(userId, cb) {
_this.log.info("DB | getUser: '" + userId + "'");
return _this.db.hgetall("user:" + userId, cb);
return _this.db.hgetall("user:" + userId, function(err, obj) {
try {
obj.roles = JSON.parse(obj.roles);
} catch (_error) {}
return cb(err, obj);
});
};
})(this);
@ -957,6 +962,7 @@ Persistence
} else if (obj && obj.password) {
if (pw === obj.password) {
_this.log.info("DB | User '" + obj.username + "' logged in!");
obj.roles = JSON.parse(obj.roles);
return cb(null, obj);
} else {
return cb(new Error('Wrong credentials!'), null);

View file

@ -11,7 +11,7 @@ Request Handler
*/
(function() {
var crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, qs, renderPage;
var crypto, db, dirHandlers, exports, fs, getHandlerPath, getRemoteScripts, getScript, getTemplate, mustache, path, pathUsers, qs, renderPage;
db = require('./persistence');
@ -25,6 +25,8 @@ Request Handler
crypto = require('crypto-js');
pathUsers = path.resolve(__dirname, '..', 'config', 'users.json');
dirHandlers = path.resolve(__dirname, '..', 'webpages', 'handlers');
exports = module.exports = (function(_this) {
@ -41,10 +43,57 @@ Request Handler
};
setTimeout(args['shutdown-function'], 500);
return cb(null, data);
},
newuser: function(obj, cb) {
var data, err, fPersistNewUser, oUser, roles;
data = {
code: 200,
message: 'User stored thank you!'
};
if (obj.username && obj.password) {
if (obj.roles) {
try {
roles = JSON.parse(obj.roles);
} catch (_error) {
err = _error;
this.log('RH | error parsing newuser roles: ' + err.message);
roles = [];
}
} else {
roles = [];
}
oUser = {
username: obj.username,
password: obj.password,
roles: roles
};
db.storeUser(oUser);
fPersistNewUser = function(username, password, roles) {
return function(err, data) {
var users;
users = JSON.parse(data);
users[username] = {
password: password,
roles: roles
};
return fs.writeFile(pathUsers, JSON.stringify(users, void 0, 2), 'utf8', function(err) {
if (err) {
this.log.error("RH | Unable to write new user file! ");
return this.log.error(err);
}
});
};
};
fs.readFile(pathUsers, 'utf8', fPersistNewUser(obj.username, obj.password, roles));
} else {
data.code = 401;
data.message = 'Missing parameter for this command';
}
return cb(null, data);
}
};
db(args);
users = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', 'config', 'users.json')));
users = JSON.parse(fs.readFileSync(pathUsers, 'utf8'));
fStoreUser = function(username, oUser) {
oUser.username = username;
return db.storeUser(oUser);
@ -329,9 +378,9 @@ Request Handler
var msg, page;
if (!req.session.user) {
page = 'login';
} else if (req.session.user.isAdmin !== "true") {
} else if (req.session.user.roles.indexOf("admin") === -1) {
page = 'login';
msg = 'You need to be admin!';
msg = 'You need to be admin for this page!';
} else {
page = 'admin';
}
@ -353,21 +402,31 @@ Request Handler
exports.handleAdminCommand = (function(_this) {
return function(req, resp) {
var body;
if (req.session && req.session.user && req.session.user.isAdmin === "true") {
if (req.session && req.session.user && req.session.user.roles.indexOf("admin") > -1) {
body = '';
req.on('data', function(data) {
return body += data;
});
return req.on('end', function() {
var obj;
var arrCmd, arrKV, arrParams, keyVal, oParams, obj, _i, _len;
obj = qs.parse(body);
_this.log.info('RH | Received admin request: ' + obj.command);
if (obj.command && _this.objAdminCmds[obj.command]) {
return _this.objAdminCmds[obj.command](obj, function(err, obj) {
arrCmd = obj.command.split(' ');
if (!arrCmd[0] || !_this.objAdminCmds[arrCmd[0]]) {
return resp.send(404, 'Command unknown!');
} else {
arrParams = arrCmd.slice(1);
oParams = {};
for (_i = 0, _len = arrParams.length; _i < _len; _i++) {
keyVal = arrParams[_i];
arrKV = keyVal.split(":");
if (arrKV.length === 2) {
oParams[arrKV[0]] = arrKV[1];
}
}
return _this.objAdminCmds[arrCmd[0]](oParams, function(err, obj) {
return resp.send(obj.code, obj);
});
} else {
return resp.send(404, 'Command unknown!');
}
});
} else {

View file

@ -111,17 +111,18 @@
"users": {
"userOne": {
"username": "tester-1",
"password": "password-1"
"password": "password-1",
"roles": []
},
"userTwo": {
"username": "tester-2",
"password": "password-2"
"password": "password-2",
"roles": []
},
"userAdmin": {
"username": "tester-admin",
"password": "password-admin",
"roles": [ "admin" ],
"isAdmin": true
"roles": [ "admin" ]
}
}

View file

@ -2,6 +2,11 @@
fOnLoad = () ->
document.title = 'Administrate'
$( '#pagetitle' ).text 'Hi {{{user.username}}}, issue your commands please:'
if not window.CryptoJS
$( '#info' ).attr 'class', 'error'
$( '#info' ).text 'CryptoJS library missing! Are you connected to the internet?'
$( '#but_submit' ).click () ->
data =
command: $( '#inp_command' ).val()
@ -19,4 +24,9 @@ fOnLoad = () ->
window.location.href = 'admin'
setTimeout fDelayed, 500
$( '#inp_password' ).keyup () ->
hp = CryptoJS.SHA3 $( this ).val(),
outputLength: 512
$( '#display_hash' ).text hp.toString()
window.addEventListener 'load', fOnLoad, true

View file

@ -514,7 +514,7 @@ fOnLoad = () ->
$( '#event_interval' ).val oRule.event_interval
# Conditions
editor.setValue JSON.stringify oRule.conditions
editor.setValue JSON.stringify oRule.conditions, undefined, 2
# Actions
for action in oRule.actions

View file

@ -5,7 +5,11 @@
fOnLoad = function() {
document.title = 'Administrate';
$('#pagetitle').text('Hi {{{user.username}}}, issue your commands please:');
return $('#but_submit').click(function() {
if (!window.CryptoJS) {
$('#info').attr('class', 'error');
$('#info').text('CryptoJS library missing! Are you connected to the internet?');
}
$('#but_submit').click(function() {
var data;
data = {
command: $('#inp_command').val()
@ -28,6 +32,13 @@
return setTimeout(fDelayed, 500);
});
});
return $('#inp_password').keyup(function() {
var hp;
hp = CryptoJS.SHA3($(this).val(), {
outputLength: 512
});
return $('#display_hash').text(hp.toString());
});
};
window.addEventListener('load', fOnLoad, true);

View file

@ -666,7 +666,7 @@
}
$('#input_event').val(oRule.event);
$('#event_interval').val(oRule.event_interval);
editor.setValue(JSON.stringify(oRule.conditions));
editor.setValue(JSON.stringify(oRule.conditions, void 0, 2));
_ref = oRule.actions;
_results = [];
for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) {

View file

@ -0,0 +1 @@
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha3.js"></script>

View file

@ -1,2 +1,6 @@
<input type="text" id="inp_command" style="width:300px" />
<button type="button" id="but_submit">command</button>
<button type="button" id="but_submit">command</button>
<br><br>
<h3>Get your password hashed:</h3>
<input type="password" id="inp_password" style="width:300px" />
<div id="display_hash" style="font-size:10px" />