Allow complete removal of My Server tab for a specific domain.
Ylian Saint-Hilaire committed
Oct 5, 2020 at 16:47 UTC
4f8aca10481737c97b031084eb91eb77b1a74b81
5 files changed
+39
-19
meshcentral-config-schema.json
+1
-1
@@ -176,7 +176,7 @@
176
"description": "https url when to get the TLS certificate that MeshAgent's will see when connecting to this server. This setting is used when a reverse proxy like NGINX is used in front of MeshCentral."
177
},
178
"myServer": {
179
- "type": "object",
179
+ "type": [ "object", "boolean" ],
180
"additionalProperties": false,
181
"properties": {
182
"Backup": { "type": "boolean", "default": true, "description": "Allows administrators to backup the server from the My Server tab." },
meshctrl.js
+16
-3
@@ -338,6 +338,7 @@ if (args['_'].length == 0) {
338
console.log(" --group [groupname] - Filter by group name (or --id).");
339
console.log(" --count - Only return the device count.");
340
console.log(" --json - Show result as JSON.");
341
+ console.log(" --csv - Show result as comma seperated values.");
342
break;
343
}
344
case 'listusersofdevicegroup': {
@@ -1442,7 +1443,19 @@ function serverConnect() {
1443
if ((data.result != null) && (data.result != 'ok')) {
1444
console.log(data.result);
1445
} else {
1445
- if (args.count) {
1446
+ if (args.csv) {
1447
+ // Return a flat list
1448
+ var nodecount = 0;
1449
+ for (var i in data.nodes) {
1450
+ var devicesInMesh = data.nodes[i];
1451
+ for (var j in devicesInMesh) {
1452
+ var n = devicesInMesh[j];
1453
+ nodecount++;
1454
+ console.log('\"' + settings.xmeshes[i]._id.split('/')[2] + '\",\"' + settings.xmeshes[i].name.split('\"').join('') + '\",\"' + n._id.split('/')[2] + '\",\"' + n.name.split('\"').join('') + '\",' + (n.icon ? n.icon : 0) + ',' + (n.conn ? n.conn : 0) + ',' + (n.pwr ? n.pwr : 0));
1455
+ }
1456
+ }
1457
+ if (nodecount == 0) { console.log('None'); }
1458
+ } else if (args.count) {
1459
// Return how many devices are in this group
1460
var nodes = [];
1461
for (var i in data.nodes) { var devicesInMesh = data.nodes[i]; for (var j in devicesInMesh) { nodes.push(devicesInMesh[j]); } }
@@ -1457,12 +1470,12 @@ function serverConnect() {
1470
var nodecount = 0;
1471
for (var i in data.nodes) {
1472
var devicesInMesh = data.nodes[i];
1460
- if (settings.xmeshes) { console.log('\r\nDevice group: \"' + settings.xmeshes[i].name + '\"'); }
1473
+ if (settings.xmeshes) { console.log('\r\nDevice group: \"' + settings.xmeshes[i].name.split('\"').join('') + '\"'); }
1474
console.log('id, name, icon, conn, pwr, ip\r\n-----------------------------');
1475
for (var j in devicesInMesh) {
1476
var n = devicesInMesh[j];
1477
nodecount++;
1465
- console.log(n._id.split('/')[2] + ', \"' + n.name + '\", ' + (n.icon ? n.icon : 0) + ', ' + (n.conn ? n.conn : 0) + ', ' + (n.pwr ? n.pwr : 0));
1478
+ console.log('\"' + n._id.split('/')[2] + '\", \"' + n.name.split('\"', '') + '\", ' + (n.icon ? n.icon : 0) + ', ' + (n.conn ? n.conn : 0) + ', ' + (n.pwr ? n.pwr : 0));
1479
}
1480
}
1481
if (nodecount == 0) { console.log('None'); }
meshuser.js
+14
-8
@@ -472,7 +472,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
472
473
if (user.siteadmin === SITERIGHT_ADMIN) {
474
// Check if tracing is allowed for this domain
475
- if ((domain.myserver == null) || (domain.myserver.trace === true)) {
475
+ if ((domain.myserver !== false) && ((domain.myserver == null) || (domain.myserver.trace === true))) {
476
// Send server tracing information
477
try { ws.send(JSON.stringify({ action: 'traceinfo', traceSources: parent.parent.debugRemoteSources })); } catch (ex) { }
478
}
@@ -550,6 +550,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
550
}
551
case 'servertimelinestats':
552
{
553
+ // Only accept if the "My Server" tab is allowed for this domain
554
+ if (domain.myserver === false) break;
555
+
556
if ((user.siteadmin & 21) == 0) return; // Only site administrators with "site backup" or "site restore" or "site update" permissions can use this.
557
if (common.validateInt(command.hours, 0, 24 * 30) == false) return;
558
db.GetServerStats(command.hours, function (err, docs) {
@@ -561,6 +564,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
564
}
565
case 'serverstats':
566
{
567
+ // Only accept if the "My Server" tab is allowed for this domain
568
+ if (domain.myserver === false) break;
569
+
570
if ((user.siteadmin & 21) == 0) return; // Only site administrators with "site backup" or "site restore" or "site update" permissions can use this.
571
if (common.validateInt(command.interval, 1000, 1000000) == false) {
572
// Clear the timer
@@ -839,8 +845,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
845
// This is a server console message, only process this if full administrator
846
if (user.siteadmin != SITERIGHT_ADMIN) break;
847
842
- // Only accept is the console is allowed for this domain
843
- if ((domain.myserver != null) && (domain.myserver.console !== true)) break;
848
+ // Only accept if the console is allowed for this domain
849
+ if ((domain.myserver === false) || ((domain.myserver != null) && (domain.myserver.console !== true))) break;
850
851
var r = '';
852
var cmdargs = splitArgs(command.value);
@@ -2639,7 +2645,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2645
{
2646
// Check the server version
2647
if ((user.siteadmin & 16) == 0) break;
2642
- if ((domain.myserver != null) && (domain.myserver.upgrade !== true)) break;
2648
+ if ((domain.myserver === false) || ((domain.myserver != null) && (domain.myserver.upgrade !== true))) break;
2649
//parent.parent.getLatestServerVersion(function (currentVersion, latestVersion) { try { ws.send(JSON.stringify({ action: 'serverversion', current: currentVersion, latest: latestVersion })); } catch (ex) { } });
2650
parent.parent.getServerTags(function (tags, err) { try { ws.send(JSON.stringify({ action: 'serverversion', tags: tags })); } catch (ex) { } });
2651
break;
@@ -2648,7 +2654,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2654
{
2655
// Perform server update
2656
if ((user.siteadmin & 16) == 0) break;
2651
- if ((domain.myserver != null) && (domain.myserver.upgrade !== true)) break;
2657
+ if ((domain.myserver === false) || ((domain.myserver != null) && (domain.myserver.upgrade !== true))) break;
2658
if ((command.version != null) && (typeof command.version != 'string')) break;
2659
parent.parent.performServerUpdate(command.version);
2660
break;
@@ -2657,7 +2663,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2663
{
2664
// Load the server error log
2665
if ((user.siteadmin & 16) == 0) break;
2660
- if ((domain.myserver != null) && (domain.myserver.errorlog !== true)) break;
2666
+ if ((domain.myserver === false) || ((domain.myserver != null) && (domain.myserver.errorlog !== true))) break;
2667
fs.readFile(parent.parent.getConfigFilePath('mesherrors.txt'), 'utf8', function (err, data) { try { ws.send(JSON.stringify({ action: 'servererrors', data: data })); } catch (ex) { } });
2668
break;
2669
}
@@ -4555,8 +4561,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
4561
break;
4562
}
4563
case 'traceinfo': {
4558
- // Only accept is the tracing is allowed for this domain
4559
- if ((domain.myserver != null) && (domain.myserver.trace !== true)) break;
4564
+ // Only accept if the tracing tab is allowed for this domain
4565
+ if ((domain.myserver === false) || ((domain.myserver != null) && (domain.myserver.trace !== true))) break;
4566
4567
if ((user.siteadmin === SITERIGHT_ADMIN) && (typeof command.traceSources == 'object')) {
4568
parent.parent.debugRemoteSources = command.traceSources;
views/default.handlebars
+1
-1
@@ -1833,7 +1833,7 @@
1833
//QV('p2AccountImage', ((features & 4) == 0) && (serverinfo.domainauth == false)); // If account actions are not visible, also remove the image on that panel
1834
QV('p2AccountImage', !accountSettingsLocked)
1835
QV('p2ServerActions', (siteRights & 21) && ((serverFeatures & 15) != 0));
1836
- QV('LeftMenuMyServer', siteRights & 21); // 16 + 4 + 1
1836
+ QV('LeftMenuMyServer', (siteRights & 21) && ((serverFeatures & 64) != 0)); // 16 + 4 + 1
1837
QV('MainMenuMyServer', siteRights & 21);
1838
QV('p2ServerActionsBackup', (siteRights & 1) && ((serverFeatures & 1) != 0));
1839
QV('p2ServerActionsRestore', (siteRights & 4) && ((serverFeatures & 2) != 0));
webserver.js
+7
-6
@@ -2371,8 +2371,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2371
if (domain.customui != null) { customui = encodeURIComponent(JSON.stringify(domain.customui)); }
2372
2373
// Server features
2374
- var serverFeatures = 63;
2375
- if (domain.myserver) {
2374
+ var serverFeatures = 127;
2375
+ if (domain.myserver === false) { serverFeatures = 0; } // 64 = Show "My Server" tab
2376
+ else if (typeof domain.myserver == 'object') {
2377
if (domain.myserver.backup !== true) { serverFeatures -= 1; } // Disallow simple server backups
2378
if (domain.myserver.restore !== true) { serverFeatures -= 2; } // Disallow simple server restore
2379
if (domain.myserver.upgrade !== true) { serverFeatures -= 4; } // Disallow server upgrade
@@ -4063,7 +4064,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4064
if (domain == null) { return; }
4065
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
4066
if ((!req.session) || (req.session == null) || (!req.session.userid)) { res.sendStatus(401); return; }
4066
- if ((domain.myserver != null) && (domain.myserver.backup !== true)) { res.sendStatus(401); return; }
4067
+ if ((domain.myserver === false) || ((domain.myserver != null) && (domain.myserver.backup !== true))) { res.sendStatus(401); return; }
4068
4069
var user = obj.users[req.session.userid];
4070
if ((user == null) || ((user.siteadmin & 1) == 0)) { res.sendStatus(401); return; } // Check if we have server backup rights
@@ -4092,7 +4093,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4093
const domain = checkUserIpAddress(req, res);
4094
if (domain == null) { return; }
4095
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
4095
- if ((domain.myserver != null) && (domain.myserver.restore !== true)) { res.sendStatus(401); return; }
4096
+ if ((domain.myserver === false) || ((domain.myserver != null) && (domain.myserver.restore !== true))) { res.sendStatus(401); return; }
4097
4098
var authUserid = null;
4099
if ((req.session != null) && (typeof req.session.userid == 'string')) { authUserid = req.session.userid; }
@@ -4818,8 +4819,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
4819
obj.app.get(url, handleRootRequest);
4820
obj.app.post(url, handleRootPostRequest);
4821
obj.app.get(url + 'refresh.ashx', function (req, res) { res.sendStatus(200); });
4821
- if ((domain.myserver == null) || (domain.myserver.backup === true)) { obj.app.get(url + 'backup.zip', handleBackupRequest); }
4822
- if ((domain.myserver == null) || (domain.myserver.restore === true)) { obj.app.post(url + 'restoreserver.ashx', handleRestoreRequest); }
4822
+ if ((domain.myserver !== false) && ((domain.myserver == null) || (domain.myserver.backup === true))) { obj.app.get(url + 'backup.zip', handleBackupRequest); }
4823
+ if ((domain.myserver !== false) && ((domain.myserver == null) || (domain.myserver.restore === true))) { obj.app.post(url + 'restoreserver.ashx', handleRestoreRequest); }
4824
obj.app.get(url + 'terms', handleTermsRequest);
4825
obj.app.get(url + 'xterm', handleXTermRequest);
4826
obj.app.post(url + 'login', handleLoginRequest);