diff --git a/coffee/components-manager.coffee b/coffee/components-manager.coffee
index 612c730..384bc69 100644
--- a/coffee/components-manager.coffee
+++ b/coffee/components-manager.coffee
@@ -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
diff --git a/coffee/engine.coffee b/coffee/engine.coffee
index 9342284..61bcef6 100644
--- a/coffee/engine.coffee
+++ b/coffee/engine.coffee
@@ -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
diff --git a/coffee/persistence.coffee b/coffee/persistence.coffee
index 9ad5015..613d7c2 100644
--- a/coffee/persistence.coffee
+++ b/coffee/persistence.coffee
@@ -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
diff --git a/coffee/request-handler.coffee b/coffee/request-handler.coffee
index 3f6a39c..748d76f 100644
--- a/coffee/request-handler.coffee
+++ b/coffee/request-handler.coffee
@@ -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!'
diff --git a/config/users.json b/config/users.json
index 12616d9..2646e5d 100644
--- a/config/users.json
+++ b/config/users.json
@@ -1,10 +1,12 @@
{
"admin": {
"password": "7407946a7a90b037ba5e825040f184a142161e4c61d81feb83ec8c7f011a99b0d77f39c9170c3231e1003c5cf859c69bd93043b095feff5cce6f6d45ec513764",
- "roles": [ "admin" ]
+ "roles": [
+ "admin"
+ ]
},
"dominic": {
"password": "2d51496fbe5b6d3e98e22d68140609eaedd64de457b2f75c346a4a98f87928eac11ea2be747709ae7a2f5b177af09a60a8dbf14bf703e0cb9b147fc0a3e3a064",
- "roles": [ "admin" ]
+ "roles": []
}
-}
+}
\ No newline at end of file
diff --git a/js/components-manager.js b/js/components-manager.js
index b5daeca..b24f8cf 100644
--- a/js/components-manager.js
+++ b/js/components-manager.js
@@ -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 = [];
diff --git a/js/engine.js b/js/engine.js
index 4366ed1..fccb8d6 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -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];
diff --git a/js/persistence.js b/js/persistence.js
index c0e2dbb..2ff4e38 100644
--- a/js/persistence.js
+++ b/js/persistence.js
@@ -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);
diff --git a/js/request-handler.js b/js/request-handler.js
index d46dd29..cac23d3 100644
--- a/js/request-handler.js
+++ b/js/request-handler.js
@@ -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 {
diff --git a/testing/files/testObjects.json b/testing/files/testObjects.json
index 5bb808f..3f75f77 100644
--- a/testing/files/testObjects.json
+++ b/testing/files/testObjects.json
@@ -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" ]
}
}
diff --git a/webpages/handlers/coffee/admin.coffee b/webpages/handlers/coffee/admin.coffee
index a7d29b7..916838c 100644
--- a/webpages/handlers/coffee/admin.coffee
+++ b/webpages/handlers/coffee/admin.coffee
@@ -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
diff --git a/webpages/handlers/coffee/forge_rule.coffee b/webpages/handlers/coffee/forge_rule.coffee
index 6d0eb93..a4b6801 100644
--- a/webpages/handlers/coffee/forge_rule.coffee
+++ b/webpages/handlers/coffee/forge_rule.coffee
@@ -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
diff --git a/webpages/handlers/js/admin.js b/webpages/handlers/js/admin.js
index bb5fcec..12abbb9 100644
--- a/webpages/handlers/js/admin.js
+++ b/webpages/handlers/js/admin.js
@@ -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);
diff --git a/webpages/handlers/js/forge_rule.js b/webpages/handlers/js/forge_rule.js
index f55b2d1..8bb5c39 100644
--- a/webpages/handlers/js/forge_rule.js
+++ b/webpages/handlers/js/forge_rule.js
@@ -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++) {
diff --git a/webpages/handlers/remote-scripts/admin.html b/webpages/handlers/remote-scripts/admin.html
new file mode 100644
index 0000000..bd7e515
--- /dev/null
+++ b/webpages/handlers/remote-scripts/admin.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/webpages/handlers/templates/admin.html b/webpages/handlers/templates/admin.html
index 5f2b539..d2107fd 100644
--- a/webpages/handlers/templates/admin.html
+++ b/webpages/handlers/templates/admin.html
@@ -1,2 +1,6 @@
-
\ No newline at end of file
+
+
+