Completed user access rights removal feature, #3065
Ylian Saint-Hilaire committed
Aug 27, 2021 at 14:42 UTC
41ecece9a9f172bbafa68ded5209f372af0c3713
6 files changed
+104
-30
agents/meshcore.js
+1
@@ -874,6 +874,7 @@ function handleServerCommand(data) {
874
case 'msg': {
875
switch (data.type) {
876
case 'console': { // Process a console command
877
+ if ((typeof data.rights != 'number') || ((data.rights & 16) == 0)) break; // Check console rights
878
if (data.value && data.sessionid) {
879
MeshServerLogEx(17, [data.value], "Processing console command: " + data.value, data);
880
var args = splitArgs(data.value);
agents/recoverycore.js
+1
@@ -911,6 +911,7 @@ require('MeshAgent').AddCommandHandler(function (data) {
911
{
912
switch (data.type) {
913
case 'console': { // Process a console command
914
+ if ((typeof data.rights != 'number') || ((data.rights & 16) == 0)) break; // Check console rights
915
if (data.value && data.sessionid) {
916
var args = splitArgs(data.value);
917
processConsoleCommand(args[0].toLowerCase(), parseArgs(args), data.rights, data.sessionid);
meshuser.js
+2
-2
@@ -4313,7 +4313,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4313
4314
// Get the node and the rights for this node
4315
parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
4316
- if ((rights & MESHRIGHT_AGENTCONSOLE) == 0) return;
4316
+ if ((rights & MESHRIGHT_REMOTECONTROL) == 0) return;
4317
4318
// Ask for clipboard data from agent
4319
var agent = parent.wsagents[node._id];
@@ -4326,7 +4326,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4326
4327
// Get the node and the rights for this node
4328
parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
4329
- if ((rights & MESHRIGHT_AGENTCONSOLE) == 0) return;
4329
+ if ((rights & MESHRIGHT_REMOTECONTROL) == 0) return;
4330
4331
// Send clipboard data to the agent
4332
var agent = parent.wsagents[node._id];
views/default-mobile.handlebars
+32
-9
@@ -3549,7 +3549,7 @@
3549
3550
if ((currentDevicePanel != 5) &&
3551
(currentNode != null) &&
3552
- ((meshrights & 8) || (meshrights & 256)) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 65536) == 0)) &&
3552
+ ((meshrights & 8) || (meshrights & 256)) && ((meshrights == 0xFFFFFFFF) || ((meshrights & 512) == 0)) &&
3553
(((currentNode.agent == null) && ((typeof currentNode.intelamt.sku !== 'number') || ((currentNode.intelamt.sku & 8) != 0))) || (currentNode.agent && (currentNode.agent.caps & 2)))
3554
) { menus.push({ n: "Terminal", f: 'setupDeviceMenu(5)' }); }
3555
@@ -6359,6 +6359,28 @@
6359
// These must match server
6360
//
6361
6362
+ // Remove user rights
6363
+ function removeUserRights(rights, userid) {
6364
+ if ((userid != userinfo._id) || (userinfo.removeRights == null)) return rights;
6365
+ var add = 0, substract = 0;
6366
+ if ((userinfo.removeRights & 0x00010000) != 0) { add += 0x00010000; } // No Desktop
6367
+ if ((userinfo.removeRights & 0x00000100) != 0) { add += 0x00000100; } // Desktop View Only
6368
+ if ((userinfo.removeRights & 0x00000200) != 0) { add += 0x00000200; } // No Terminal
6369
+ if ((userinfo.removeRights & 0x00000400) != 0) { add += 0x00000400; } // No Files
6370
+ if ((userinfo.removeRights & 0x00000010) != 0) { substract += 0x00000010; } // No Console
6371
+ if (rights != 0xFFFFFFFF) {
6372
+ // If not administrator, add and subsctract restrictions
6373
+ rights |= add;
6374
+ rights &= (0xFFFFFFFF - substract);
6375
+ } else {
6376
+ // If administrator for a device group, start with permissions and add and subsctract restrictions
6377
+ rights = 1 + 2 + 4 + 8 + 32 + 64 + 128 + 16384 + 32768 + 131072 + 262144 + 524288 + 1048576;
6378
+ rights |= add;
6379
+ rights &= (0xFFFFFFFF - substract);
6380
+ }
6381
+ return rights;
6382
+ }
6383
+
6384
// Get the right of a user on a given device group
6385
function GetMeshRights(mesh, userid) {
6386
if (mesh == null) { return 0; }
@@ -6367,12 +6389,12 @@
6389
if ((mesh == null) || (mesh.links == null)) { return 0; }
6390
6391
// Check if super user
6370
- if (userinfo.manageAllDeviceGroups && (userid == userinfo._id)) return 0xFFFFFFFF;
6392
+ if (serverinfo.manageAllDeviceGroups && (userid == userinfo._id)) return removeUserRights(0xFFFFFFFF, userid);
6393
6394
// Check device group link permission
6395
var rights = 0, r = mesh.links[userid];
6396
if (r != null) {
6375
- if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device group link, stop here.
6397
+ if (r.rights == 0xFFFFFFFF) { return removeUserRights(0xFFFFFFFF, userid); } // User has full rights thru a device group link, stop here.
6398
rights = r.rights;
6399
}
6400
@@ -6384,14 +6406,14 @@
6406
if (i.startsWith('ugrp/')) {
6407
r = mesh.links[i];
6408
if (r != null) {
6387
- if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a user group, stop here.
6409
+ if (r.rights == 0xFFFFFFFF) { return removeUserRights(0xFFFFFFFF, userid); } // User has full rights thru a user group, stop here.
6410
rights |= r.rights; // TODO: Deal with reverse permissions
6411
}
6412
}
6413
}
6414
}
6415
6394
- return rights;
6416
+ return removeUserRights(rights, userid);
6417
}
6418
6419
// Returns true if the user can view the given device group
@@ -6403,7 +6425,7 @@
6425
if (mesh.links[userid] != null) { return true; } // User has visilibity thru a direct link
6426
6427
// Check if user user
6406
- if (userinfo.manageAllDeviceGroups && (userid == userinfo._id)) return true;
6428
+ if (serverinfo.manageAllDeviceGroups && (userid == userinfo._id)) return true;
6429
6430
// Check permissions thru user groups
6431
var user = null;
@@ -6423,8 +6445,7 @@
6445
if (userid == null) { userid = userinfo._id; }
6446
if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } }
6447
var r = GetMeshRights(node.meshid, userid);
6426
- if (r == 0xFFFFFFFF) return r;
6427
- var user = null;
6448
+ if (r == 0xFFFFFFFF) return removeUserRights(r, userid);
6449
6450
// Check direct device rights using device data
6451
if ((node.links != null) && (node.links[userid] != null)) { r |= node.links[userid].rights; } // TODO: Deal with reverse permissions
@@ -6438,6 +6459,7 @@
6459
6460
// Check direct device rights using user data
6461
/*
6462
+ var user = null;
6463
if (userid == userinfo._id) { user = userinfo; } else { if (users != null) { user = users[userid]; } }
6464
if ((user != null) && (user.links != null)) {
6465
var r2 = user.links[node._id];
@@ -6447,7 +6469,7 @@
6469
}
6470
}
6471
*/
6450
- return r;
6472
+ return removeUserRights(r, userid);
6473
}
6474
6475
// Return true if the device is visible to the user
@@ -6468,6 +6490,7 @@
6490
return false;
6491
}
6492
6493
+
6494
//
6495
// Generic Methods
6496
//
views/default.handlebars
+31
-7
@@ -2807,10 +2807,12 @@
2807
if (userinfo._id == message.event.account._id) {
2808
var newsiteadmin = message.event.account.siteadmin?message.event.account.siteadmin:0;
2809
var oldsiteadmin = userinfo.siteadmin?userinfo.siteadmin:0;
2810
+ var newRemoveRights = message.event.account.removeRights?message.event.account.removeRights:0;
2811
+ var oldRemoveRights = userinfo.removeRights?userinfo.removeRights:0;
2812
if ((message.event.account.quota != userinfo.quota) || (((userinfo.siteadmin & 8) == 0) && ((message.event.account.siteadmin & 8) != 0))) { meshserver.send({ action: 'files' }); }
2813
var oldgroups = userinfo.groups;
2814
userinfo = message.event.account;
2813
- if ((oldsiteadmin != newsiteadmin) || (message.event.accountImageChange == 1)) { // If the site admin permission or user image has changed...
2815
+ if ((oldsiteadmin != newsiteadmin) || (oldRemoveRights != newRemoveRights) || (message.event.accountImageChange == 1)) { // If the site admin permission or user image has changed...
2816
if (message.event.accountImageChange == 1) { userinfo.accountImageRnd = Math.floor(Math.random() * 9999999999); }
2817
updateSiteAdmin();
2818
}
@@ -15819,6 +15821,28 @@
15821
// These must match server
15822
//
15823
15824
+ // Remove user rights
15825
+ function removeUserRights(rights, userid) {
15826
+ if ((userid != userinfo._id) || (userinfo.removeRights == null)) return rights;
15827
+ var add = 0, substract = 0;
15828
+ if ((userinfo.removeRights & 0x00010000) != 0) { add += 0x00010000; } // No Desktop
15829
+ if ((userinfo.removeRights & 0x00000100) != 0) { add += 0x00000100; } // Desktop View Only
15830
+ if ((userinfo.removeRights & 0x00000200) != 0) { add += 0x00000200; } // No Terminal
15831
+ if ((userinfo.removeRights & 0x00000400) != 0) { add += 0x00000400; } // No Files
15832
+ if ((userinfo.removeRights & 0x00000010) != 0) { substract += 0x00000010; } // No Console
15833
+ if (rights != 0xFFFFFFFF) {
15834
+ // If not administrator, add and subsctract restrictions
15835
+ rights |= add;
15836
+ rights &= (0xFFFFFFFF - substract);
15837
+ } else {
15838
+ // If administrator for a device group, start with permissions and add and subsctract restrictions
15839
+ rights = 1 + 2 + 4 + 8 + 32 + 64 + 128 + 16384 + 32768 + 131072 + 262144 + 524288 + 1048576;
15840
+ rights |= add;
15841
+ rights &= (0xFFFFFFFF - substract);
15842
+ }
15843
+ return rights;
15844
+ }
15845
+
15846
// Get the right of a user on a given device group
15847
function GetMeshRights(mesh, userid) {
15848
if (mesh == null) { return 0; }
@@ -15827,12 +15851,12 @@
15851
if ((mesh == null) || (mesh.links == null)) { return 0; }
15852
15853
// Check if super user
15830
- if (serverinfo.manageAllDeviceGroups && (userid == userinfo._id)) return 0xFFFFFFFF;
15854
+ if (serverinfo.manageAllDeviceGroups && (userid == userinfo._id)) return removeUserRights(0xFFFFFFFF, userid);
15855
15856
// Check device group link permission
15857
var rights = 0, r = mesh.links[userid];
15858
if (r != null) {
15835
- if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a device group link, stop here.
15859
+ if (r.rights == 0xFFFFFFFF) { return removeUserRights(0xFFFFFFFF, userid); } // User has full rights thru a device group link, stop here.
15860
rights = r.rights;
15861
}
15862
@@ -15844,14 +15868,14 @@
15868
if (i.startsWith('ugrp/')) {
15869
r = mesh.links[i];
15870
if (r != null) {
15847
- if (r.rights == 0xFFFFFFFF) { return 0xFFFFFFFF; } // User has full rights thru a user group, stop here.
15871
+ if (r.rights == 0xFFFFFFFF) { return removeUserRights(0xFFFFFFFF, userid); } // User has full rights thru a user group, stop here.
15872
rights |= r.rights; // TODO: Deal with reverse permissions
15873
}
15874
}
15875
}
15876
}
15877
15854
- return rights;
15878
+ return removeUserRights(rights, userid);
15879
}
15880
15881
// Returns true if the user can view the given device group
@@ -15883,7 +15907,7 @@
15907
if (userid == null) { userid = userinfo._id; }
15908
if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } }
15909
var r = GetMeshRights(node.meshid, userid);
15886
- if (r == 0xFFFFFFFF) return r;
15910
+ if (r == 0xFFFFFFFF) return removeUserRights(r, userid);
15911
15912
// Check direct device rights using device data
15913
if ((node.links != null) && (node.links[userid] != null)) { r |= node.links[userid].rights; } // TODO: Deal with reverse permissions
@@ -15907,7 +15931,7 @@
15931
}
15932
}
15933
*/
15910
- return r;
15934
+ return removeUserRights(r, userid);
15935
}
15936
15937
// Return true if the device is visible to the user
webserver.js
+37
-12
@@ -6799,6 +6799,28 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6799
// Access Control Functions
6800
//
6801
6802
+ // Remove user rights
6803
+ function removeUserRights(rights, user) {
6804
+ if (user.removeRights == null) return rights;
6805
+ var add = 0, substract = 0;
6806
+ if ((user.removeRights & 0x00010000) != 0) { add += 0x00010000; } // No Desktop
6807
+ if ((user.removeRights & 0x00000100) != 0) { add += 0x00000100; } // Desktop View Only
6808
+ if ((user.removeRights & 0x00000200) != 0) { add += 0x00000200; } // No Terminal
6809
+ if ((user.removeRights & 0x00000400) != 0) { add += 0x00000400; } // No Files
6810
+ if ((user.removeRights & 0x00000010) != 0) { substract += 0x00000010; } // No Console
6811
+ if (rights != 0xFFFFFFFF) {
6812
+ // If not administrator, add and subsctract restrictions
6813
+ rights |= add;
6814
+ rights &= (0xFFFFFFFF - substract);
6815
+ } else {
6816
+ // If administrator for a device group, start with permissions and add and subsctract restrictions
6817
+ rights = 1 + 2 + 4 + 8 + 32 + 64 + 128 + 16384 + 32768 + 131072 + 262144 + 524288 + 1048576;
6818
+ rights |= add;
6819
+ rights &= (0xFFFFFFFF - substract);
6820
+ }
6821
+ return rights;
6822
+ }
6823
+
6824
// Return the node and rights for a given nodeid
6825
obj.GetNodeWithRights = function (domain, user, nodeid, func) {
6826
// Perform user pre-validation
@@ -6818,7 +6840,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6840
6841
// This is a super user that can see all device groups for a given domain
6842
if ((user.siteadmin == 0xFFFFFFFF) && (parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0) && (nodes[0].domain == user.domain)) {
6821
- func(nodes[0], 0xFFFFFFFF, true); return;
6843
+ func(nodes[0], removeUserRights(0xFFFFFFFF, user), true); return;
6844
}
6845
6846
// If no links, stop here.
@@ -6827,7 +6849,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6849
// Check device link
6850
var rights = 0, visible = false, r = user.links[nodeid];
6851
if (r != null) {
6830
- if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a device link, stop here.
6852
+ if (r.rights == 0xFFFFFFFF) { func(nodes[0], removeUserRights(0xFFFFFFFF, user), true); return; } // User has full rights thru a device link, stop here.
6853
rights |= r.rights;
6854
visible = true;
6855
}
@@ -6835,7 +6857,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6857
// Check device group link
6858
r = user.links[nodes[0].meshid];
6859
if (r != null) {
6838
- if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a device group link, stop here.
6860
+ if (r.rights == 0xFFFFFFFF) { func(nodes[0], removeUserRights(0xFFFFFFFF, user), true); return; } // User has full rights thru a device group link, stop here.
6861
rights |= r.rights;
6862
visible = true;
6863
}
@@ -6847,13 +6869,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6869
if (g && (g.links != null)) {
6870
r = g.links[nodes[0].meshid];
6871
if (r != null) {
6850
- if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a user group link, stop here.
6872
+ if (r.rights == 0xFFFFFFFF) { func(nodes[0], removeUserRights(0xFFFFFFFF, user), true); return; } // User has full rights thru a user group link, stop here.
6873
rights |= r.rights; // TODO: Deal with reverse rights
6874
visible = true;
6875
}
6876
r = g.links[nodeid];
6877
if (r != null) {
6856
- if (r.rights == 0xFFFFFFFF) { func(nodes[0], 0xFFFFFFFF, true); return; } // User has full rights thru a user group direct link, stop here.
6878
+ if (r.rights == 0xFFFFFFFF) { func(nodes[0], removeUserRights(0xFFFFFFFF, user), true); return; } // User has full rights thru a user group direct link, stop here.
6879
rights |= r.rights; // TODO: Deal with reverse rights
6880
visible = true;
6881
}
@@ -6861,6 +6883,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6883
}
6884
}
6885
6886
+ // Remove any user rights
6887
+ rights = removeUserRights(rights, user);
6888
+
6889
// Return the rights we found
6890
func(nodes[0], rights, visible);
6891
});
@@ -6954,7 +6979,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6979
} else return 0;
6980
6981
// Check if this is a super user that can see all device groups for a given domain
6957
- if ((user.siteadmin == 0xFFFFFFFF) && (parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0) && (meshid.startsWith('mesh/' + user.domain + '/'))) { return 0xFFFFFFFF; }
6982
+ if ((user.siteadmin == 0xFFFFFFFF) && (parent.config.settings.managealldevicegroups.indexOf(user._id) >= 0) && (meshid.startsWith('mesh/' + user.domain + '/'))) { return removeUserRights(0xFFFFFFFF, user); }
6983
6984
// Check direct user to device group permissions
6985
if (user.links == null) return 0;
@@ -6962,7 +6987,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6987
r = user.links[meshid];
6988
if (r != null) {
6989
var rights = r.rights;
6965
- if (rights == 0xFFFFFFFF) { return rights; } // If the user has full access thru direct link, stop here.
6990
+ if (rights == 0xFFFFFFFF) { return removeUserRights(rights, user); } // If the user has full access thru direct link, stop here.
6991
}
6992
6993
// Check if we are part of any user groups that would give this user more access.
@@ -6973,7 +6998,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
6998
r = g.links[meshid];
6999
if (r != null) {
7000
if (r.rights == 0xFFFFFFFF) {
6976
- return r.rights; // If the user hash full access thru a user group link, stop here.
7001
+ return removeUserRights(r.rights, user); // If the user hash full access thru a user group link, stop here.
7002
} else {
7003
rights |= r.rights; // Add to existing rights (TODO: Deal with reverse rights)
7004
}
@@ -6983,7 +7008,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
7008
}
7009
}
7010
6986
- return rights;
7011
+ return removeUserRights(rights, user);
7012
}
7013
7014
// Returns true if the user can view the given device group
@@ -7022,11 +7047,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
7047
if (typeof user == 'string') { user = obj.users[user]; }
7048
if (user == null) { return 0; }
7049
var r = obj.GetMeshRights(user, mesh);
7025
- if (r == 0xFFFFFFFF) return r;
7050
+ if (r == 0xFFFFFFFF) return removeUserRights(r, user);
7051
7052
// Check direct device rights using device data
7053
if ((user.links != null) && (user.links[nodeid] != null)) { r |= user.links[nodeid].rights; } // TODO: Deal with reverse permissions
7029
- if (r == 0xFFFFFFFF) return r;
7054
+ if (r == 0xFFFFFFFF) return removeUserRights(r, user);
7055
7056
// Check direct device rights thru a user group
7057
for (var i in user.links) {
@@ -7036,7 +7061,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
7061
}
7062
}
7063
7039
- return r;
7064
+ return removeUserRights(r, user);
7065
}
7066
7067
// Returns a list of displatch targets for a given mesh