mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
parent
911288e695
commit
7de0216976
@ -54,6 +54,7 @@ function needsPermission(permission) {
|
|||||||
if (permissions.hasPermission(req.authInfo.scope,permission)) {
|
if (permissions.hasPermission(req.authInfo.scope,permission)) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
log.audit({event: "permission.fail"},req);
|
||||||
return res.send(401);
|
return res.send(401);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -93,6 +94,7 @@ function revoke(req,res) {
|
|||||||
var token = req.body.token;
|
var token = req.body.token;
|
||||||
// TODO: audit log
|
// TODO: audit log
|
||||||
Tokens.revoke(token).then(function() {
|
Tokens.revoke(token).then(function() {
|
||||||
|
log.audit({event: "auth.login.revoke"},req);
|
||||||
res.send(200);
|
res.send(200);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,8 @@ var Users = require("./users");
|
|||||||
var Clients = require("./clients");
|
var Clients = require("./clients");
|
||||||
var permissions = require("./permissions");
|
var permissions = require("./permissions");
|
||||||
|
|
||||||
|
var log = require("../../log");
|
||||||
|
|
||||||
var bearerStrategy = function (accessToken, done) {
|
var bearerStrategy = function (accessToken, done) {
|
||||||
// is this a valid token?
|
// is this a valid token?
|
||||||
Tokens.get(accessToken).then(function(token) {
|
Tokens.get(accessToken).then(function(token) {
|
||||||
@ -34,10 +36,12 @@ var bearerStrategy = function (accessToken, done) {
|
|||||||
if (user) {
|
if (user) {
|
||||||
done(null,user,{scope:token.scope});
|
done(null,user,{scope:token.scope});
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "auth.invalid-token"});
|
||||||
done(null,false);
|
done(null,false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "auth.invalid-token"});
|
||||||
done(null,false);
|
done(null,false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -49,6 +53,7 @@ var clientPasswordStrategy = function(clientId, clientSecret, done) {
|
|||||||
if (client && client.secret == clientSecret) {
|
if (client && client.secret == clientSecret) {
|
||||||
done(null,client);
|
done(null,client);
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "auth.invalid-client",client:clientId});
|
||||||
done(null,false);
|
done(null,false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -73,7 +78,7 @@ var passwordTokenExchange = function(client, username, password, scope, done) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (attemptCount > 5) {
|
if (attemptCount > 5) {
|
||||||
// TODO: audit log
|
log.audit({event: "auth.login.fail.too-many-attempts",username:username,client:client.id});
|
||||||
done(new Error("Too many login attempts. Wait 10 minutes and try again"),false);
|
done(new Error("Too many login attempts. Wait 10 minutes and try again"),false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -85,14 +90,15 @@ var passwordTokenExchange = function(client, username, password, scope, done) {
|
|||||||
return logEntry.user !== username;
|
return logEntry.user !== username;
|
||||||
});
|
});
|
||||||
Tokens.create(username,client.id,scope).then(function(tokens) {
|
Tokens.create(username,client.id,scope).then(function(tokens) {
|
||||||
// TODO: audit log
|
log.audit({event: "auth.login",username:username,client:client.id,scope:scope});
|
||||||
done(null,tokens.accessToken,null,{expires_in:tokens.expires_in});
|
done(null,tokens.accessToken,null,{expires_in:tokens.expires_in});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "auth.login.fail.permissions",username:username,client:client.id,scope:scope});
|
||||||
done(null,false);
|
done(null,false);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: audit log
|
log.audit({event: "auth.login.fail.credentials",username:username,client:client.id,scope:scope});
|
||||||
done(null,false);
|
done(null,false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -24,11 +24,13 @@ var settings = require("../settings");
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
get: function(req,res) {
|
get: function(req,res) {
|
||||||
|
log.audit({event: "flows.get"},req);
|
||||||
res.json(redNodes.getFlows());
|
res.json(redNodes.getFlows());
|
||||||
},
|
},
|
||||||
post: function(req,res) {
|
post: function(req,res) {
|
||||||
var flows = req.body;
|
var flows = req.body;
|
||||||
var deploymentType = req.get("Node-RED-Deployment-Type")||"full";
|
var deploymentType = req.get("Node-RED-Deployment-Type")||"full";
|
||||||
|
log.audit({event: "flows.set",type:deploymentType},req);
|
||||||
redNodes.setFlows(flows,deploymentType).then(function() {
|
redNodes.setFlows(flows,deploymentType).then(function() {
|
||||||
res.send(204);
|
res.send(204);
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
|
@ -67,7 +67,7 @@ function init(adminApp,storage) {
|
|||||||
auth.getToken,
|
auth.getToken,
|
||||||
auth.errorHandler
|
auth.errorHandler
|
||||||
);
|
);
|
||||||
adminApp.post("/auth/revoke",auth.revoke);
|
adminApp.post("/auth/revoke",needsPermission(""),auth.revoke);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flows
|
// Flows
|
||||||
|
@ -24,6 +24,7 @@ function createLibrary(type) {
|
|||||||
redApp.get(new RegExp("/library/"+type+"($|\/(.*))"),needsPermission("library.read"),function(req,res) {
|
redApp.get(new RegExp("/library/"+type+"($|\/(.*))"),needsPermission("library.read"),function(req,res) {
|
||||||
var path = req.params[1]||"";
|
var path = req.params[1]||"";
|
||||||
storage.getLibraryEntry(type,path).then(function(result) {
|
storage.getLibraryEntry(type,path).then(function(result) {
|
||||||
|
log.audit({event: "library.get",type:type},req);
|
||||||
if (typeof result === "string") {
|
if (typeof result === "string") {
|
||||||
res.writeHead(200, {'Content-Type': 'text/plain'});
|
res.writeHead(200, {'Content-Type': 'text/plain'});
|
||||||
res.write(result);
|
res.write(result);
|
||||||
@ -35,10 +36,12 @@ function createLibrary(type) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
log.warn("Error loading library entry '"+path+"' : "+err);
|
log.warn("Error loading library entry '"+path+"' : "+err);
|
||||||
if (err.message.indexOf('forbidden') === 0) {
|
if (err.message.indexOf('forbidden') === 0) {
|
||||||
|
log.audit({event: "library.get",type:type,error:"forbidden"},req);
|
||||||
res.send(403);
|
res.send(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.audit({event: "library.get",type:type,error:"not_found"},req);
|
||||||
res.send(404);
|
res.send(404);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -50,13 +53,16 @@ function createLibrary(type) {
|
|||||||
delete meta.text;
|
delete meta.text;
|
||||||
|
|
||||||
storage.saveLibraryEntry(type,path,meta,text).then(function() {
|
storage.saveLibraryEntry(type,path,meta,text).then(function() {
|
||||||
|
log.audit({event: "library.set",type:type},req);
|
||||||
res.send(204);
|
res.send(204);
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
log.warn("Error saving library entry '"+path+"' : "+err);
|
log.warn("Error saving library entry '"+path+"' : "+err);
|
||||||
if (err.message.indexOf('forbidden') === 0) {
|
if (err.message.indexOf('forbidden') === 0) {
|
||||||
|
log.audit({event: "library.set",type:type,error:"forbidden"},req);
|
||||||
res.send(403);
|
res.send(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
log.audit({event: "library.set",type:type,error:"unexpected_error",message:err.toString()},req);
|
||||||
res.json(500,{error:"unexpected_error", message:err.toString()});
|
res.json(500,{error:"unexpected_error", message:err.toString()});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -70,36 +76,43 @@ module.exports = {
|
|||||||
|
|
||||||
getAll: function(req,res) {
|
getAll: function(req,res) {
|
||||||
storage.getAllFlows().then(function(flows) {
|
storage.getAllFlows().then(function(flows) {
|
||||||
|
log.audit({event: "library.get.all",type:"flow"},req);
|
||||||
res.json(flows);
|
res.json(flows);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
get: function(req,res) {
|
get: function(req,res) {
|
||||||
storage.getFlow(req.params[0]).then(function(data) {
|
storage.getFlow(req.params[0]).then(function(data) {
|
||||||
// data is already a JSON string
|
// data is already a JSON string
|
||||||
|
log.audit({event: "library.get",type:"flow",path:req.params[0]},req);
|
||||||
res.set('Content-Type', 'application/json');
|
res.set('Content-Type', 'application/json');
|
||||||
res.send(data);
|
res.send(data);
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
log.warn("Error loading flow '"+req.params[0]+"' : "+err);
|
log.warn("Error loading flow '"+req.params[0]+"' : "+err);
|
||||||
if (err.message.indexOf('forbidden') === 0) {
|
if (err.message.indexOf('forbidden') === 0) {
|
||||||
|
log.audit({event: "library.get",type:"flow",path:req.params[0],error:"forbidden"},req);
|
||||||
res.send(403);
|
res.send(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
log.audit({event: "library.get",type:"flow",path:req.params[0],error:"not_found"},req);
|
||||||
res.send(404);
|
res.send(404);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
post: function(req,res) {
|
post: function(req,res) {
|
||||||
var flow = JSON.stringify(req.body);
|
var flow = JSON.stringify(req.body);
|
||||||
storage.saveFlow(req.params[0],flow).then(function() {
|
storage.saveFlow(req.params[0],flow).then(function() {
|
||||||
|
log.audit({event: "library.set",type:"flow",path:req.params[0]},req);
|
||||||
res.send(204);
|
res.send(204);
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
log.warn("Error loading flow '"+req.params[0]+"' : "+err);
|
log.warn("Error loading flow '"+req.params[0]+"' : "+err);
|
||||||
if (err.message.indexOf('forbidden') === 0) {
|
if (err.message.indexOf('forbidden') === 0) {
|
||||||
|
log.audit({event: "library.set",type:"flow",path:req.params[0],error:"forbidden"},req);
|
||||||
res.send(403);
|
res.send(403);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res.send(500);
|
log.audit({event: "library.set",type:"flow",path:req.params[0],error:"unexpected_error",message:err.toString()},req);
|
||||||
|
res.send(500,{error:"unexpected_error", message:err.toString()});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,17 @@ var settings = require("../settings");
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
getAll: function(req,res) {
|
getAll: function(req,res) {
|
||||||
if (req.get("accept") == "application/json") {
|
if (req.get("accept") == "application/json") {
|
||||||
|
log.audit({event: "nodes.list.get"},req);
|
||||||
res.json(redNodes.getNodeList());
|
res.json(redNodes.getNodeList());
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "nodes.configs.get"},req);
|
||||||
res.send(redNodes.getNodeConfigs());
|
res.send(redNodes.getNodeConfigs());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
post: function(req,res) {
|
post: function(req,res) {
|
||||||
if (!settings.available()) {
|
if (!settings.available()) {
|
||||||
|
log.audit({event: "nodes.install",error:"settings_unavailable"},req);
|
||||||
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -45,20 +48,25 @@ module.exports = {
|
|||||||
if (node.module) {
|
if (node.module) {
|
||||||
var module = redNodes.getModuleInfo(node.module);
|
var module = redNodes.getModuleInfo(node.module);
|
||||||
if (module) {
|
if (module) {
|
||||||
|
log.audit({event: "nodes.install",module:node.module,error:"module_already_loaded"},req);
|
||||||
res.json(400,{error:"module_already_loaded", message:"Module already loaded"});
|
res.json(400,{error:"module_already_loaded", message:"Module already loaded"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
promise = server.installModule(node.module);
|
promise = server.installModule(node.module);
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "nodes.install",module:node.module,error:"invalid_request"},req);
|
||||||
res.json(400,{error:"invalid_request", message:"Invalid request"});
|
res.json(400,{error:"invalid_request", message:"Invalid request"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
promise.then(function(info) {
|
promise.then(function(info) {
|
||||||
|
log.audit({event: "nodes.install",module:node.module},req);
|
||||||
res.json(redNodes.getModuleInfo(node.module));
|
res.json(redNodes.getModuleInfo(node.module));
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
if (err.code === 404) {
|
if (err.code === 404) {
|
||||||
|
log.audit({event: "nodes.install",module:node.module,error:"not_found"},req);
|
||||||
res.send(404);
|
res.send(404);
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "nodes.install",module:node.module,error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -66,6 +74,7 @@ module.exports = {
|
|||||||
|
|
||||||
delete: function(req,res) {
|
delete: function(req,res) {
|
||||||
if (!settings.available()) {
|
if (!settings.available()) {
|
||||||
|
log.audit({event: "nodes.remove",error:"settings_unavailable"},req);
|
||||||
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -74,6 +83,7 @@ module.exports = {
|
|||||||
var promise = null;
|
var promise = null;
|
||||||
var module = redNodes.getModuleInfo(mod);
|
var module = redNodes.getModuleInfo(mod);
|
||||||
if (!module) {
|
if (!module) {
|
||||||
|
log.audit({event: "nodes.remove",module:mod,error:"not_found"},req);
|
||||||
res.send(404);
|
res.send(404);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -81,11 +91,14 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
promise.then(function() {
|
promise.then(function() {
|
||||||
|
log.audit({event: "nodes.remove",module:mod},req);
|
||||||
res.send(204);
|
res.send(204);
|
||||||
}).otherwise(function(err) {
|
}).otherwise(function(err) {
|
||||||
|
log.audit({event: "nodes.remove",module:mod,error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
||||||
});
|
});
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
log.audit({event: "nodes.remove",module:mod,error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -96,35 +109,46 @@ module.exports = {
|
|||||||
if (req.get("accept") === "application/json") {
|
if (req.get("accept") === "application/json") {
|
||||||
result = redNodes.getNodeInfo(id);
|
result = redNodes.getNodeInfo(id);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
log.audit({event: "nodes.info.get",id:id},req);
|
||||||
delete result.loaded;
|
delete result.loaded;
|
||||||
|
res.send(result);
|
||||||
|
} else {
|
||||||
|
log.audit({event: "nodes.info.get",id:id,error:"not_found"},req);
|
||||||
|
res.send(404);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result = redNodes.getNodeConfig(id);
|
result = redNodes.getNodeConfig(id);
|
||||||
}
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
log.audit({event: "nodes.config.get",id:id},req);
|
||||||
res.send(result);
|
res.send(result);
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "nodes.config.get",id:id,error:"not_found"},req);
|
||||||
res.send(404);
|
res.send(404);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getModule: function(req,res) {
|
getModule: function(req,res) {
|
||||||
var module = req.params.mod;
|
var module = req.params.mod;
|
||||||
var result = redNodes.getModuleInfo(module);
|
var result = redNodes.getModuleInfo(module);
|
||||||
if (result) {
|
if (result) {
|
||||||
|
log.audit({event: "nodes.module.get",module:module},req);
|
||||||
res.json(result);
|
res.json(result);
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "nodes.module.get",module:module,error:"not_found"},req);
|
||||||
res.send(404);
|
res.send(404);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
putSet: function(req,res) {
|
putSet: function(req,res) {
|
||||||
if (!settings.available()) {
|
if (!settings.available()) {
|
||||||
|
log.audit({event: "nodes.info.set",error:"settings_unavailable"},req);
|
||||||
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var body = req.body;
|
var body = req.body;
|
||||||
if (!body.hasOwnProperty("enabled")) {
|
if (!body.hasOwnProperty("enabled")) {
|
||||||
|
log.audit({event: "nodes.info.set",error:"invalid_request"},req);
|
||||||
res.json(400,{error:"invalid_request", message:"Invalid request"});
|
res.json(400,{error:"invalid_request", message:"Invalid request"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -133,23 +157,29 @@ module.exports = {
|
|||||||
var node = redNodes.getNodeInfo(id);
|
var node = redNodes.getNodeInfo(id);
|
||||||
var info;
|
var info;
|
||||||
if (!node) {
|
if (!node) {
|
||||||
|
log.audit({event: "nodes.info.set",id:id,error:"not_found"},req);
|
||||||
res.send(404);
|
res.send(404);
|
||||||
} else {
|
} else {
|
||||||
delete node.loaded;
|
delete node.loaded;
|
||||||
res.json(putNode(node, body.enabled));
|
var result = putNode(node, body.enabled);
|
||||||
|
log.audit({event: "nodes.info.set",id:id,enabled:body.enabled},req);
|
||||||
|
res.json(result);
|
||||||
}
|
}
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
log.audit({event: "nodes.info.set",id:id,enabled:body.enabled,error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
putModule: function(req,res) {
|
putModule: function(req,res) {
|
||||||
if (!settings.available()) {
|
if (!settings.available()) {
|
||||||
|
log.audit({event: "nodes.module.set",error:"settings_unavailable"},req);
|
||||||
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
res.json(400,{error:"settings_unavailable", message:"Settings unavailable"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var body = req.body;
|
var body = req.body;
|
||||||
if (!body.hasOwnProperty("enabled")) {
|
if (!body.hasOwnProperty("enabled")) {
|
||||||
|
log.audit({event: "nodes.module.set",error:"invalid_request"},req);
|
||||||
res.json(400,{error:"invalid_request", message:"Invalid request"});
|
res.json(400,{error:"invalid_request", message:"Invalid request"});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -157,6 +187,7 @@ module.exports = {
|
|||||||
var mod = req.params.mod;
|
var mod = req.params.mod;
|
||||||
var module = redNodes.getModuleInfo(mod);
|
var module = redNodes.getModuleInfo(mod);
|
||||||
if (!module) {
|
if (!module) {
|
||||||
|
log.audit({event: "nodes.module.set",module:mod,error:"not_found"},req);
|
||||||
return res.send(404);
|
return res.send(404);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,6 +215,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
res.json(redNodes.getModuleInfo(mod));
|
res.json(redNodes.getModuleInfo(mod));
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
|
log.audit({event: "nodes.module.set",module:mod,enabled:body.enabled,error:err.code||"unexpected_error",message:err.toString()},req);
|
||||||
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
res.json(400,{error:err.code||"unexpected_error", message:err.toString()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ function start() {
|
|||||||
wsServer = new ws.Server({server:server,path:path});
|
wsServer = new ws.Server({server:server,path:path});
|
||||||
|
|
||||||
wsServer.on('connection',function(ws) {
|
wsServer.on('connection',function(ws) {
|
||||||
|
log.audit({event: "comms.open"});
|
||||||
var pendingAuth = (settings.adminAuth != null);
|
var pendingAuth = (settings.adminAuth != null);
|
||||||
if (!pendingAuth) {
|
if (!pendingAuth) {
|
||||||
activeConnections.push(ws);
|
activeConnections.push(ws);
|
||||||
@ -55,6 +56,7 @@ function start() {
|
|||||||
pendingConnections.push(ws);
|
pendingConnections.push(ws);
|
||||||
}
|
}
|
||||||
ws.on('close',function() {
|
ws.on('close',function() {
|
||||||
|
log.audit({event: "comms.close",user:ws.user});
|
||||||
removeActiveConnection(ws);
|
removeActiveConnection(ws);
|
||||||
removePendingConnection(ws);
|
removePendingConnection(ws);
|
||||||
});
|
});
|
||||||
@ -88,19 +90,25 @@ function start() {
|
|||||||
if (client) {
|
if (client) {
|
||||||
Users.get(client.user).then(function(user) {
|
Users.get(client.user).then(function(user) {
|
||||||
if (user) {
|
if (user) {
|
||||||
|
ws.user = user;
|
||||||
|
log.audit({event: "comms.auth",user:ws.user});
|
||||||
completeConnection(client.scope,true);
|
completeConnection(client.scope,true);
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "comms.auth.fail"});
|
||||||
completeConnection(null,false);
|
completeConnection(null,false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "comms.auth.fail"});
|
||||||
completeConnection(null,false);
|
completeConnection(null,false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (anonymousUser) {
|
if (anonymousUser) {
|
||||||
|
log.audit({event: "comms.auth",user:anonymousUser});
|
||||||
completeConnection(anonymousUser.permissions,false);
|
completeConnection(anonymousUser.permissions,false);
|
||||||
} else {
|
} else {
|
||||||
|
log.audit({event: "comms.auth.fail"});
|
||||||
completeConnection(null,false);
|
completeConnection(null,false);
|
||||||
}
|
}
|
||||||
//TODO: duplicated code - pull non-auth message handling out
|
//TODO: duplicated code - pull non-auth message handling out
|
||||||
|
27
red/log.js
27
red/log.js
@ -25,6 +25,7 @@ var levels = {
|
|||||||
info: 40,
|
info: 40,
|
||||||
debug: 50,
|
debug: 50,
|
||||||
trace: 60,
|
trace: 60,
|
||||||
|
audit: 98,
|
||||||
metric: 99
|
metric: 99
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,6 +36,7 @@ var levelNames = {
|
|||||||
40: "info",
|
40: "info",
|
||||||
50: "debug",
|
50: "debug",
|
||||||
60: "trace",
|
60: "trace",
|
||||||
|
98: "audit",
|
||||||
99: "metric"
|
99: "metric"
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -45,7 +47,10 @@ var metricsEnabled = false;
|
|||||||
var LogHandler = function(settings) {
|
var LogHandler = function(settings) {
|
||||||
this.logLevel = settings ? levels[settings.level]||levels.info : levels.info;
|
this.logLevel = settings ? levels[settings.level]||levels.info : levels.info;
|
||||||
this.metricsOn = settings ? settings.metrics||false : false;
|
this.metricsOn = settings ? settings.metrics||false : false;
|
||||||
metricsEnabled = this.metricsOn;
|
this.auditOn = settings ? settings.audit||false : false;
|
||||||
|
|
||||||
|
metricsEnabled = metricsEnabled || this.metricsOn;
|
||||||
|
|
||||||
this.handler = (settings && settings.handler) ? settings.handler(settings) : consoleLogger;
|
this.handler = (settings && settings.handler) ? settings.handler(settings) : consoleLogger;
|
||||||
this.on("log",function(msg) {
|
this.on("log",function(msg) {
|
||||||
if (this.shouldReportMessage(msg.level)) {
|
if (this.shouldReportMessage(msg.level)) {
|
||||||
@ -56,12 +61,14 @@ var LogHandler = function(settings) {
|
|||||||
util.inherits(LogHandler, EventEmitter);
|
util.inherits(LogHandler, EventEmitter);
|
||||||
|
|
||||||
LogHandler.prototype.shouldReportMessage = function(msglevel) {
|
LogHandler.prototype.shouldReportMessage = function(msglevel) {
|
||||||
return msglevel <= this.logLevel || (msglevel == log.METRIC && this.metricsOn);
|
return msglevel <= this.logLevel ||
|
||||||
|
(msglevel == log.METRIC && this.metricsOn) ||
|
||||||
|
(msglevel == log.AUDIT && this.auditOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
var consoleLogger = function(msg) {
|
var consoleLogger = function(msg) {
|
||||||
if (msg.level == log.METRIC) {
|
if (msg.level == log.METRIC || msg.level == log.AUDIT) {
|
||||||
util.log("[metric] "+JSON.stringify(msg));
|
util.log("["+levelNames[msg.level]+"] "+JSON.stringify(msg));
|
||||||
} else {
|
} else {
|
||||||
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg);
|
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg);
|
||||||
}
|
}
|
||||||
@ -74,9 +81,11 @@ var log = module.exports = {
|
|||||||
INFO: 40,
|
INFO: 40,
|
||||||
DEBUG: 50,
|
DEBUG: 50,
|
||||||
TRACE: 60,
|
TRACE: 60,
|
||||||
|
AUDIT: 98,
|
||||||
METRIC: 99,
|
METRIC: 99,
|
||||||
|
|
||||||
init: function(settings) {
|
init: function(settings) {
|
||||||
|
metricsEnabled = false;
|
||||||
logHandlers = [];
|
logHandlers = [];
|
||||||
var loggerSettings = {};
|
var loggerSettings = {};
|
||||||
if (settings.logging) {
|
if (settings.logging) {
|
||||||
@ -122,5 +131,15 @@ var log = module.exports = {
|
|||||||
},
|
},
|
||||||
metric: function() {
|
metric: function() {
|
||||||
return metricsEnabled;
|
return metricsEnabled;
|
||||||
|
},
|
||||||
|
|
||||||
|
audit: function(msg,req) {
|
||||||
|
msg.level = log.AUDIT;
|
||||||
|
if (req) {
|
||||||
|
msg.user = req.user;
|
||||||
|
msg.path = req.path;
|
||||||
|
msg.ip = (req.headers && req.headers['x-forwarded-for']) || (req.connection && req.connection.remoteAddress) || undefined;
|
||||||
|
}
|
||||||
|
log.log(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user