Added mesh and user notes

This commit is contained in:
Ylian Saint-Hilaire 2018-04-16 11:57:42 -07:00
parent ff1478c48a
commit e90878364f
4 changed files with 89 additions and 35 deletions

2
db.js
View File

@ -99,7 +99,7 @@ module.exports.CreateDB = function (args, datapath) {
obj.StoreEvent = function (ids, source, event) { obj.file.insert(event); } obj.StoreEvent = function (ids, source, event) { obj.file.insert(event); }
obj.GetEvents = function (ids, domain, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }, func) } } obj.GetEvents = function (ids, domain, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }, func) } }
obj.GetEventsWithLimit = function (ids, domain, limit, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit, func); } } obj.GetEventsWithLimit = function (ids, domain, limit, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit).exec(func); } else { obj.file.find({ type: 'event', domain: domain, ids: { $in: ids } }, { type: 0, _id: 0, domain: 0, ids: 0, node: 0 }).sort({ time: -1 }).limit(limit, func); } }
obj.RemoveMesh = function (id) { obj.file.remove({ mesh: id }, { multi: true }); obj.file.remove({ _id: id }); } obj.RemoveMesh = function (id) { obj.file.remove({ mesh: id }, { multi: true }); obj.file.remove({ _id: id }); obj.file.remove({ _id: 'nt' + id }); }
obj.RemoveAllEvents = function (domain) { obj.file.remove({ type: 'event', domain: domain }, { multi: true }); } obj.RemoveAllEvents = function (domain) { obj.file.remove({ type: 'event', domain: domain }, { multi: true }); }
obj.MakeSiteAdmin = function (username, domain) { obj.Get('user/' + domain + '/' + username, function (err, docs) { if (docs.length == 1) { docs[0].siteadmin = 0xFFFFFFFF; obj.Set(docs[0]); } }); } obj.MakeSiteAdmin = function (username, domain) { obj.Get('user/' + domain + '/' + username, function (err, docs) { if (docs.length == 1) { docs[0].siteadmin = 0xFFFFFFFF; obj.Set(docs[0]); } }); }
obj.DeleteDomain = function (domain, func) { obj.file.remove({ domain: domain }, { multi: true }, func); } obj.DeleteDomain = function (domain, func) { obj.file.remove({ domain: domain }, { multi: true }, func); }

View File

@ -1021,49 +1021,101 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
case 'setNotes': case 'setNotes':
{ {
// Argument validation // Argument validation
if (obj.common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid if (obj.common.validateString(command.id, 1, 1024) == false) break; // Check id
if ((command.nodeid.split('/').length != 3) || (command.nodeid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain var splitid = command.id.split('/');
if ((splitid.length != 3) || (splitid[1] != domain.id)) return; // Invalid domain, operation only valid for current domain
var idtype = splitid[0];
if ((idtype != 'user') && (idtype != 'mesh') && (idtype != 'node')) return;
// Check if this user has rights on this nodeid to set notes if (idtype == 'node') {
obj.db.Get(command.nodeid, function (err, nodes) { // TODO: Make a NodeRights(user) method that also does not do a db call if agent is connected (???) // Check if this user has rights on this id to set notes
if (nodes.length == 1) { obj.db.Get(command.id, function (err, nodes) { // TODO: Make a NodeRights(user) method that also does not do a db call if agent is connected (???)
var meshlinks = user.links[nodes[0].meshid]; if (nodes.length == 1) {
if ((meshlinks) && (meshlinks.rights) && (meshlinks.rights & obj.parent.MESHRIGHT_SETNOTES != 0)) { var meshlinks = user.links[nodes[0].meshid];
// Set the node's notes if ((meshlinks) && (meshlinks.rights) && (meshlinks.rights & obj.parent.MESHRIGHT_SETNOTES != 0)) {
if (obj.common.validateString(command.notes, 1) == false) { // Set the id's notes
obj.db.Remove('nt' + command.nodeid); // Delete the note for this node if (obj.common.validateString(command.notes, 1) == false) {
} else { obj.db.Remove('nt' + command.id); // Delete the note for this node
obj.db.Set({ _id: 'nt' + command.nodeid, value: command.notes }); // Set the note for this node } else {
obj.db.Set({ _id: 'nt' + command.id, value: command.notes }); // Set the note for this node
}
} }
} }
});
} else if (idtype == 'mesh') {
// Get the mesh for this device
var mesh = obj.parent.meshes[command.id];
if (mesh) {
// Check if this user has rights to do this
if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; }
// Set the id's notes
if (obj.common.validateString(command.notes, 1) == false) {
obj.db.Remove('nt' + command.id); // Delete the note for this node
} else {
obj.db.Set({ _id: 'nt' + command.id, value: command.notes }); // Set the note for this node
}
} }
}); } else if ((idtype == 'user') && ((user.siteadmin & 2) != 0)) {
// Set the id's notes
if (obj.common.validateString(command.notes, 1) == false) {
obj.db.Remove('nt' + command.id); // Delete the note for this node
} else {
obj.db.Set({ _id: 'nt' + command.id, value: command.notes }); // Set the note for this node
}
}
break; break;
} }
case 'getNotes': case 'getNotes':
{ {
// Argument validation // Argument validation
if (obj.common.validateString(command.nodeid, 1, 1024) == false) break; // Check nodeid if (obj.common.validateString(command.id, 1, 1024) == false) break; // Check id
if ((command.nodeid.split('/').length != 3) || (command.nodeid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain var splitid = command.id.split('/');
if ((splitid.length != 3) || (splitid[1] != domain.id)) return; // Invalid domain, operation only valid for current domain
var idtype = splitid[0];
if ((idtype != 'user') && (idtype != 'mesh') && (idtype != 'node')) return;
// Get the device if (idtype == 'node') {
obj.db.Get(command.nodeid, function (err, nodes) { // Get the device
if (nodes.length != 1) { ws.send(JSON.stringify({ action: 'getnetworkinfo', nodeid: command.nodeid, netif: null })); return; } obj.db.Get(command.id, function (err, nodes) {
var node = nodes[0]; if (nodes.length != 1) return;
var node = nodes[0];
// Get the mesh for this device
var mesh = obj.parent.meshes[node.meshid];
if (mesh) {
// Check if this user has rights to do this
if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; }
// Get the notes about this node
obj.db.Get('nt' + command.id, function (err, notes) {
if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; }
ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value }));
});
}
});
} else if (idtype == 'mesh') {
// Get the mesh for this device // Get the mesh for this device
var mesh = obj.parent.meshes[node.meshid]; var mesh = obj.parent.meshes[command.id];
if (mesh) { if (mesh) {
// Check if this user has rights to do this // Check if this user has rights to do this
if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; } if (mesh.links[user._id] == null || (mesh.links[user._id].rights == 0)) { return; }
// Get the notes about this node // Get the notes about this node
obj.db.Get('nt' + command.nodeid, function (err, notes) { obj.db.Get('nt' + command.id, function (err, notes) {
if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', nodeid: command.nodeid, notes: null })); return; } if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; }
ws.send(JSON.stringify({ action: 'getNotes', nodeid: command.nodeid, notes: notes[0].value })); ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value }));
}); });
} }
}); } else if ((idtype == 'user') && ((user.siteadmin & 2) != 0)) {
// Get the notes about this node
obj.db.Get('nt' + command.id, function (err, notes) {
if (notes.length != 1) { ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: null })); return; }
ws.send(JSON.stringify({ action: 'getNotes', id: command.id, notes: notes[0].value }));
});
}
break; break;
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.1.6-k", "version": "0.1.6-l",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -1092,7 +1092,7 @@
} }
case 'getNotes':{ case 'getNotes':{
var n = Q('d2devNotes'); var n = Q('d2devNotes');
if (n && (message.nodeid == n.attributes['nodeid'].value)) { if (n && (message.id == decodeURIComponent(n.attributes['noteid'].value))) {
if (message.notes) { QH('d2devNotes', decodeURIComponent(message.notes)); } else { QH('d2devNotes', ''); } if (message.notes) { QH('d2devNotes', decodeURIComponent(message.notes)); } else { QH('d2devNotes', ''); }
var ro = n.attributes['ro'].value == 'true'; var ro = n.attributes['ro'].value == 'true';
if (ro == false) { // If we have permissions, set read/write on this note. if (ro == false) { // If we have permissions, set read/write on this note.
@ -2817,7 +2817,7 @@
x += '</table><br />'; x += '</table><br />';
// Show action button, only show if we have permissions 4, 8, 64 // Show action button, only show if we have permissions 4, 8, 64
if ((meshrights & 76) != 0) { x += '<input type=button value=Actions title="Perform power actions on the device" onclick=deviceActionFunction() />'; } if ((meshrights & 76) != 0) { x += '<input type=button value=Actions title="Perform power actions on the device" onclick=deviceActionFunction() />'; }
x += '<input type=button value=Notes title="View notes about this device" onclick=deviceNotesFunction(' + ((meshrights & 128) == 0) + ',"' + node._id + '") />'; x += '<input type=button value=Notes title="View notes about this device" onclick=showNotes(' + ((meshrights & 128) == 0) + ',"' + encodeURIComponent(node._id) + '") />';
QH('p10html', x); QH('p10html', x);
// Show node last 7 days timeline // Show node last 7 days timeline
@ -2898,13 +2898,13 @@
go(panel); go(panel);
} }
function deviceNotesFunction(readonly, nodeid) { function showNotes(readonly, noteid) {
if (xxdialogMode) return; if (xxdialogMode) return;
setDialogMode(2, "Device Notes", 2, deviceNotesFunctionEx, '<textarea id=d2devNotes ro=' + readonly + ' nodeid=' + nodeid + ' readonly style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea>', nodeid); setDialogMode(2, "Notes", 2, showNotesEx, '<textarea id=d2devNotes ro=' + readonly + ' noteid=' + noteid + ' readonly style=background-color:#fcf3cf;width:100%;height:200px;resize:none;overflow-y:scroll></textarea><span style=font-size:10px>Notes can be viewed and changed by other administrators.<span>', noteid);
meshserver.send({ action: 'getNotes', nodeid: nodeid }); meshserver.send({ action: 'getNotes', id: decodeURIComponent(noteid) });
} }
function deviceNotesFunctionEx(buttons, tag) { meshserver.send({ action: 'setNotes', nodeid: tag, notes: encodeURIComponent(Q('d2devNotes').value) }); } function showNotesEx(buttons, tag) { meshserver.send({ action: 'setNotes', id: decodeURIComponent(tag), notes: encodeURIComponent(Q('d2devNotes').value) }); }
function deviceActionFunction() { function deviceActionFunction() {
var meshrights = meshes[currentNode.meshid].links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights; var meshrights = meshes[currentNode.meshid].links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights;
@ -4452,7 +4452,9 @@
x += addHtmlValue('Type', meshtype); x += addHtmlValue('Type', meshtype);
x += addHtmlValue('Identifier', currentMesh._id.split('/')[2]); x += addHtmlValue('Identifier', currentMesh._id.split('/')[2]);
x += '<br>'; x += '<br><input type=button value=Notes title="View notes about this mesh" onclick=showNotes(false,"' + encodeURIComponent(currentMesh._id) + '") />';
x += '<br><br>';
var currentMeshLinks = currentMesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()]; var currentMeshLinks = currentMesh.links['user/{{{domain}}}/' + userinfo.name.toLowerCase()];
if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<a onclick=p20showAddMeshUserDialog() style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> Add User</a>'; } if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<a onclick=p20showAddMeshUserDialog() style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> Add User</a>'; }
@ -4550,7 +4552,7 @@
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshagentconsole>Mesh Agent Console<br>'; x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshagentconsole>Mesh Agent Console<br>';
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshserverfiles>Server Files<br>'; x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20meshserverfiles>Server Files<br>';
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20wakedevices>Wake Devices<br>'; x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20wakedevices>Wake Devices<br>';
x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editnotes>Edit Notes<br>'; x += '<input type=checkbox onchange=p20validateAddMeshUserDialog() id=p20editnotes>Edit Device Notes<br>';
x += '</div>'; x += '</div>';
setDialogMode(2, "Add User to Mesh", 3, p20showAddMeshUserDialogEx, x); setDialogMode(2, "Add User to Mesh", 3, p20showAddMeshUserDialogEx, x);
p20validateAddMeshUserDialog(); p20validateAddMeshUserDialog();
@ -5068,7 +5070,7 @@
x += '</table></div><br />'; x += '</table></div><br />';
// Add action buttons // Add action buttons
//x += '<input type=button value=Notes title="View notes about this user" onclick=userNotesFunction("' + userid + '") />'; x += '<input type=button value=Notes title="View notes about this user" onclick=showNotes(false,"' + userid + '") />';
if (!self && (activeSessions > 0)) { x += '<input type=button value=Notify title="Send user notification" onclick=showUserAlertDialog(event,"' + userid + '") />'; } if (!self && (activeSessions > 0)) { x += '<input type=button value=Notify title="Send user notification" onclick=showUserAlertDialog(event,"' + userid + '") />'; }
// Setup the panel // Setup the panel