Added function handlers for agentdisconnect and addmeshuser
Noah Zalev committed
Jan 8, 2022 at 11:55 UTC
fe4d426bdb9b062834c882d40d238505a7405d9a
1 file changed
+146
-146
meshuser.js
+146
-146
@@ -2171,139 +2171,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
2171
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'editmesh', responseid: command.responseid, result: 'ok' })); } catch (ex) { } }
2172
break;
2173
}
2174
- case 'addmeshuser':
2175
- {
2176
- var err = null, mesh, meshIdSplit;
2177
- if (typeof command.userid == 'string') { command.userids = [command.userid]; }
2178
-
2179
- // Resolve the device group name if needed
2180
- if ((typeof command.meshname == 'string') && (command.meshid == null)) {
2181
- for (var i in parent.meshes) {
2182
- var m = parent.meshes[i];
2183
- if ((m.mtype == 2) && (m.name == command.meshname) && parent.IsMeshViewable(user, m)) {
2184
- if (command.meshid == null) { command.meshid = m._id; } else { err = 'Duplicate device groups found'; }
2185
- }
2186
- }
2187
- }
2188
-
2189
- var selfMeshRights = 0;
2190
- try {
2191
- if (common.validateString(command.meshid, 1, 1024) == false) { err = 'Invalid groupid'; } // Check the meshid
2192
- else if (common.validateInt(command.meshadmin) == false) { err = 'Invalid group rights'; } // Mesh rights must be an integer
2193
- else if ((common.validateStrArray(command.usernames, 1, 64) == false) && (common.validateStrArray(command.userids, 1, 128) == false)) { err = 'Invalid usernames'; } // Username is between 1 and 64 characters
2194
- else {
2195
- if (command.meshid.indexOf('/') == -1) { command.meshid = 'mesh/' + domain.id + '/' + command.meshid; }
2196
- mesh = parent.meshes[command.meshid];
2197
- meshIdSplit = command.meshid.split('/');
2198
- if (mesh == null) { err = 'Unknown group'; }
2199
- else if (((selfMeshRights = parent.GetMeshRights(user, mesh)) & MESHRIGHT_MANAGEUSERS) == 0) { err = 'Permission denied'; }
2200
- else if ((meshIdSplit.length != 3) || (meshIdSplit[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
2201
- }
2202
- } catch (ex) { err = 'Validation exception: ' + ex; }
2203
-
2204
- // Handle any errors
2205
- if (err != null) {
2206
- if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: err })); } catch (ex) { } }
2207
- break;
2208
- }
2209
-
2210
- // Convert user names to userid's
2211
- if (command.userids == null) {
2212
- command.userids = [];
2213
- for (var i in command.usernames) {
2214
- if (parent.users['user/' + domain.id + '/' + command.usernames[i].toLowerCase()] != null) { command.userids.push('user/' + domain.id + '/' + command.usernames[i].toLowerCase()); }
2215
- else if (parent.users['user/' + domain.id + '/' + command.usernames[i]] != null) { command.userids.push('user/' + domain.id + '/' + command.usernames[i]); }
2216
- }
2217
- }
2218
- var unknownUsers = [], successCount = 0, failCount = 0, msgs = [];
2219
- for (var i in command.userids) {
2220
- // Check if the user exists
2221
- var newuserid = command.userids[i], newuser = null;
2222
- if (newuserid.startsWith('user/')) { newuser = parent.users[newuserid]; }
2223
- else if (newuserid.startsWith('ugrp/')) { newuser = parent.userGroups[newuserid]; }
2224
-
2225
- // Search for a user name in that windows domain is the username starts with *\
2226
- if ((newuser == null) && (newuserid.startsWith('user/' + domain.id + '/*\\')) == true) {
2227
- var search = newuserid.split('/')[2].substring(1);
2228
- for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == domain.id)) { newuser = parent.users[i]; command.userids[i] = newuserid = parent.users[i]._id; break; } }
2229
- }
2230
-
2231
- // Make sure this user is in the same domain as the device group
2232
- if (meshIdSplit[1] != newuserid.split('/')[1]) { msgs.push("Mismatch domains"); continue; }
2233
-
2234
- if (newuser != null) {
2235
- // Can't add or modify self
2236
- if (newuserid == obj.user._id) { msgs.push("Can't change self"); continue; }
2237
-
2238
- var targetMeshRights = 0;
2239
- if ((newuser.links != null) && (newuser.links[command.meshid] != null) && (newuser.links[command.meshid].rights != null)) { targetMeshRights = newuser.links[command.meshid].rights; }
2240
- if ((targetMeshRights === MESHRIGHT_ADMIN) && (selfMeshRights != MESHRIGHT_ADMIN)) { msgs.push("Can't change rights of device group administrator"); continue; } // A non-admin can't kick out an admin
2241
-
2242
- if (command.remove === true) {
2243
- // Remove mesh from user or user group
2244
- delete newuser.links[command.meshid];
2245
- } else {
2246
- // Adjust rights since we can't add more rights that we have outself for MESHRIGHT_MANAGEUSERS
2247
- if ((selfMeshRights != MESHRIGHT_ADMIN) && (command.meshadmin == MESHRIGHT_ADMIN)) { msgs.push("Can't set device group administrator, if not administrator"); continue; }
2248
- if (((selfMeshRights & 2) == 0) && ((command.meshadmin & 2) != 0) && ((targetMeshRights & 2) == 0)) { command.meshadmin -= 2; }
2249
-
2250
- // Add mesh to user or user group
2251
- if (newuser.links == null) { newuser.links = {}; }
2252
- if (newuser.links[command.meshid]) { newuser.links[command.meshid].rights = command.meshadmin; } else { newuser.links[command.meshid] = { rights: command.meshadmin }; }
2253
- }
2254
- if (newuserid.startsWith('user/')) { db.SetUser(newuser); }
2255
- else if (newuserid.startsWith('ugrp/')) { db.Set(newuser); }
2256
- parent.parent.DispatchEvent([newuser._id], obj, 'resubscribe');
2257
-
2258
- if (newuserid.startsWith('user/')) {
2259
- // Notify user change
2260
- var targets = ['*', 'server-users', user._id, newuser._id];
2261
- var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(newuser), action: 'accountchange', msgid: 78, msgArgs: [newuser.name], msg: 'Device group membership changed: ' + newuser.name, domain: domain.id };
2262
- if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
2263
- parent.parent.DispatchEvent(targets, obj, event);
2264
- } else if (newuserid.startsWith('ugrp/')) {
2265
- // Notify user group change
2266
- var targets = ['*', 'server-ugroups', user._id, newuser._id];
2267
- var event = { etype: 'ugrp', username: user.name, ugrpid: newuser._id, name: newuser.name, desc: newuser.desc, action: 'usergroupchange', links: newuser.links, msgid: 79, msgArgs: [newuser.name], msg: 'User group changed: ' + newuser.name, domain: domain.id };
2268
- if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
2269
- parent.parent.DispatchEvent(targets, obj, event);
2270
- }
2271
-
2272
- var event;
2273
- if (command.remove === true) {
2274
- // Remove userid from the mesh
2275
- delete mesh.links[newuserid];
2276
- db.Set(mesh);
2277
- event = { etype: 'mesh', username: newuser.name, userid: user._id, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + newuser.name + ' from device group ' + mesh.name, domain: domain.id, invite: mesh.invite };
2278
- } else {
2279
- // Add userid to the mesh
2280
- mesh.links[newuserid] = { name: newuser.name, rights: command.meshadmin };
2281
- db.Set(mesh);
2282
- event = { etype: 'mesh', username: newuser.name, userid: user._id, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Added user ' + newuser.name + ' to device group ' + mesh.name, domain: domain.id, invite: mesh.invite };
2283
- }
2284
-
2285
- // Notify mesh change
2286
- if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
2287
- parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(mesh, [user._id, newuserid]), obj, event);
2288
- if (command.remove === true) { msgs.push("Removed user " + newuserid.split('/')[2]); } else { msgs.push("Added user " + newuserid.split('/')[2]); }
2289
- successCount++;
2290
- } else {
2291
- msgs.push("Unknown user " + newuserid.split('/')[2]);
2292
- unknownUsers.push(newuserid.split('/')[2]);
2293
- failCount++;
2294
- }
2295
- }
2296
-
2297
- if ((successCount == 0) && (failCount == 0)) { msgs.push("Nothing done"); }
2298
-
2299
- if (unknownUsers.length > 0) {
2300
- // Send error back, user not found.
2301
- displayNotificationMessage('User' + ((unknownUsers.length > 1) ? 's' : '') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', "Device Group", 'ServerNotify', 5, (unknownUsers.length > 1) ? 16 : 15, [EscapeHtml(unknownUsers.join(', '))]);
2302
- }
2303
-
2304
- if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: msgs.join(', '), success: successCount, failed: failCount })); } catch (ex) { } }
2305
- break;
2306
- }
2174
case 'adddeviceuser': {
2175
if (typeof command.userid == 'string') { command.userids = [command.userid]; }
2176
var err = null, nodeIdSplit;
@@ -3321,19 +3188,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
3188
}
3189
break;
3190
}
3324
- case 'agentdisconnect':
3325
- {
3326
- if (common.validateInt(command.disconnectMode) == false) return; // Check disconnect mode
3327
-
3328
- // Get the node and the rights for this node
3329
- parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
3330
- if ((node == null) || (((rights & MESHRIGHT_AGENTCONSOLE) == 0) && (user.siteadmin != SITERIGHT_ADMIN))) return;
3331
-
3332
- // Force mesh agent disconnection
3333
- parent.forceMeshAgentDisconnect(user, domain, node._id, command.disconnectMode);
3334
- });
3335
- break;
3336
- }
3191
case 'close':
3192
{
3193
// Close the web socket session
@@ -5328,9 +5182,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5182
}
5183
5184
const serverCommands = {
5185
+ 'addmeshuser': serverCommandAddMeshUser,
5186
'adduser': serverCommandAddUser,
5187
'adduserbatch': serverCommandAddUserBatch,
5188
'addusertousergroup': serverCommandAddUserToUserGroup,
5189
+ 'agentdisconnect': serverCommandAgentDisconnect,
5190
'authcookie': serverCommandAuthCookie,
5191
'changeemail': serverCommandChangeEmail,
5192
'changelang': serverCommandChangeLang,
@@ -5416,6 +5272,138 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5272
'webstats': [serverUserCommandWebStats, ""]
5273
};
5274
5275
+ function serverCommandAddMeshUser(command) {
5276
+ var err = null, mesh, meshIdSplit;
5277
+ if (typeof command.userid == 'string') { command.userids = [command.userid]; }
5278
+
5279
+ // Resolve the device group name if needed
5280
+ if ((typeof command.meshname == 'string') && (command.meshid == null)) {
5281
+ for (var i in parent.meshes) {
5282
+ var m = parent.meshes[i];
5283
+ if ((m.mtype == 2) && (m.name == command.meshname) && parent.IsMeshViewable(user, m)) {
5284
+ if (command.meshid == null) { command.meshid = m._id; } else { err = 'Duplicate device groups found'; }
5285
+ }
5286
+ }
5287
+ }
5288
+
5289
+ var selfMeshRights = 0;
5290
+ try {
5291
+ if (common.validateString(command.meshid, 1, 1024) == false) { err = 'Invalid groupid'; } // Check the meshid
5292
+ else if (common.validateInt(command.meshadmin) == false) { err = 'Invalid group rights'; } // Mesh rights must be an integer
5293
+ else if ((common.validateStrArray(command.usernames, 1, 64) == false) && (common.validateStrArray(command.userids, 1, 128) == false)) { err = 'Invalid usernames'; } // Username is between 1 and 64 characters
5294
+ else {
5295
+ if (command.meshid.indexOf('/') == -1) { command.meshid = 'mesh/' + domain.id + '/' + command.meshid; }
5296
+ mesh = parent.meshes[command.meshid];
5297
+ meshIdSplit = command.meshid.split('/');
5298
+ if (mesh == null) { err = 'Unknown group'; }
5299
+ else if (((selfMeshRights = parent.GetMeshRights(user, mesh)) & MESHRIGHT_MANAGEUSERS) == 0) { err = 'Permission denied'; }
5300
+ else if ((meshIdSplit.length != 3) || (meshIdSplit[1] != domain.id)) { err = 'Invalid domain'; } // Invalid domain, operation only valid for current domain
5301
+ }
5302
+ } catch (ex) { err = 'Validation exception: ' + ex; }
5303
+
5304
+ // Handle any errors
5305
+ if (err != null) {
5306
+ if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: err })); } catch (ex) { } }
5307
+ return;
5308
+ }
5309
+
5310
+ // Convert user names to userid's
5311
+ if (command.userids == null) {
5312
+ command.userids = [];
5313
+ for (var i in command.usernames) {
5314
+ if (parent.users['user/' + domain.id + '/' + command.usernames[i].toLowerCase()] != null) { command.userids.push('user/' + domain.id + '/' + command.usernames[i].toLowerCase()); }
5315
+ else if (parent.users['user/' + domain.id + '/' + command.usernames[i]] != null) { command.userids.push('user/' + domain.id + '/' + command.usernames[i]); }
5316
+ }
5317
+ }
5318
+ var unknownUsers = [], successCount = 0, failCount = 0, msgs = [];
5319
+ for (var i in command.userids) {
5320
+ // Check if the user exists
5321
+ var newuserid = command.userids[i], newuser = null;
5322
+ if (newuserid.startsWith('user/')) { newuser = parent.users[newuserid]; }
5323
+ else if (newuserid.startsWith('ugrp/')) { newuser = parent.userGroups[newuserid]; }
5324
+
5325
+ // Search for a user name in that windows domain is the username starts with *\
5326
+ if ((newuser == null) && (newuserid.startsWith('user/' + domain.id + '/*\\')) == true) {
5327
+ var search = newuserid.split('/')[2].substring(1);
5328
+ for (var i in parent.users) { if (i.endsWith(search) && (parent.users[i].domain == domain.id)) { newuser = parent.users[i]; command.userids[i] = newuserid = parent.users[i]._id; break; } }
5329
+ }
5330
+
5331
+ // Make sure this user is in the same domain as the device group
5332
+ if (meshIdSplit[1] != newuserid.split('/')[1]) { msgs.push("Mismatch domains"); continue; }
5333
+
5334
+ if (newuser != null) {
5335
+ // Can't add or modify self
5336
+ if (newuserid == obj.user._id) { msgs.push("Can't change self"); continue; }
5337
+
5338
+ var targetMeshRights = 0;
5339
+ if ((newuser.links != null) && (newuser.links[command.meshid] != null) && (newuser.links[command.meshid].rights != null)) { targetMeshRights = newuser.links[command.meshid].rights; }
5340
+ if ((targetMeshRights === MESHRIGHT_ADMIN) && (selfMeshRights != MESHRIGHT_ADMIN)) { msgs.push("Can't change rights of device group administrator"); continue; } // A non-admin can't kick out an admin
5341
+
5342
+ if (command.remove === true) {
5343
+ // Remove mesh from user or user group
5344
+ delete newuser.links[command.meshid];
5345
+ } else {
5346
+ // Adjust rights since we can't add more rights that we have outself for MESHRIGHT_MANAGEUSERS
5347
+ if ((selfMeshRights != MESHRIGHT_ADMIN) && (command.meshadmin == MESHRIGHT_ADMIN)) { msgs.push("Can't set device group administrator, if not administrator"); continue; }
5348
+ if (((selfMeshRights & 2) == 0) && ((command.meshadmin & 2) != 0) && ((targetMeshRights & 2) == 0)) { command.meshadmin -= 2; }
5349
+
5350
+ // Add mesh to user or user group
5351
+ if (newuser.links == null) { newuser.links = {}; }
5352
+ if (newuser.links[command.meshid]) { newuser.links[command.meshid].rights = command.meshadmin; } else { newuser.links[command.meshid] = { rights: command.meshadmin }; }
5353
+ }
5354
+ if (newuserid.startsWith('user/')) { db.SetUser(newuser); }
5355
+ else if (newuserid.startsWith('ugrp/')) { db.Set(newuser); }
5356
+ parent.parent.DispatchEvent([newuser._id], obj, 'resubscribe');
5357
+
5358
+ if (newuserid.startsWith('user/')) {
5359
+ // Notify user change
5360
+ var targets = ['*', 'server-users', user._id, newuser._id];
5361
+ var event = { etype: 'user', userid: user._id, username: user.name, account: parent.CloneSafeUser(newuser), action: 'accountchange', msgid: 78, msgArgs: [newuser.name], msg: 'Device group membership changed: ' + newuser.name, domain: domain.id };
5362
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
5363
+ parent.parent.DispatchEvent(targets, obj, event);
5364
+ } else if (newuserid.startsWith('ugrp/')) {
5365
+ // Notify user group change
5366
+ var targets = ['*', 'server-ugroups', user._id, newuser._id];
5367
+ var event = { etype: 'ugrp', username: user.name, ugrpid: newuser._id, name: newuser.name, desc: newuser.desc, action: 'usergroupchange', links: newuser.links, msgid: 79, msgArgs: [newuser.name], msg: 'User group changed: ' + newuser.name, domain: domain.id };
5368
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user. Another event will come.
5369
+ parent.parent.DispatchEvent(targets, obj, event);
5370
+ }
5371
+
5372
+ var event;
5373
+ if (command.remove === true) {
5374
+ // Remove userid from the mesh
5375
+ delete mesh.links[newuserid];
5376
+ db.Set(mesh);
5377
+ event = { etype: 'mesh', username: newuser.name, userid: user._id, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Removed user ' + newuser.name + ' from device group ' + mesh.name, domain: domain.id, invite: mesh.invite };
5378
+ } else {
5379
+ // Add userid to the mesh
5380
+ mesh.links[newuserid] = { name: newuser.name, rights: command.meshadmin };
5381
+ db.Set(mesh);
5382
+ event = { etype: 'mesh', username: newuser.name, userid: user._id, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: 'Added user ' + newuser.name + ' to device group ' + mesh.name, domain: domain.id, invite: mesh.invite };
5383
+ }
5384
+
5385
+ // Notify mesh change
5386
+ if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the mesh. Another event will come.
5387
+ parent.parent.DispatchEvent(parent.CreateMeshDispatchTargets(mesh, [user._id, newuserid]), obj, event);
5388
+ if (command.remove === true) { msgs.push("Removed user " + newuserid.split('/')[2]); } else { msgs.push("Added user " + newuserid.split('/')[2]); }
5389
+ successCount++;
5390
+ } else {
5391
+ msgs.push("Unknown user " + newuserid.split('/')[2]);
5392
+ unknownUsers.push(newuserid.split('/')[2]);
5393
+ failCount++;
5394
+ }
5395
+ }
5396
+
5397
+ if ((successCount == 0) && (failCount == 0)) { msgs.push("Nothing done"); }
5398
+
5399
+ if (unknownUsers.length > 0) {
5400
+ // Send error back, user not found.
5401
+ displayNotificationMessage('User' + ((unknownUsers.length > 1) ? 's' : '') + ' ' + EscapeHtml(unknownUsers.join(', ')) + ' not found.', "Device Group", 'ServerNotify', 5, (unknownUsers.length > 1) ? 16 : 15, [EscapeHtml(unknownUsers.join(', '))]);
5402
+ }
5403
+
5404
+ if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addmeshuser', responseid: command.responseid, result: msgs.join(', '), success: successCount, failed: failCount })); } catch (ex) { } }
5405
+ }
5406
+
5407
function serverCommandAddUser(command) {
5408
// If the email is the username, set this here.
5409
if (domain.usernameisemail) { if (command.email) { command.username = command.email; } else { command.email = command.username; } }
@@ -5703,6 +5691,18 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5691
if (command.responseid != null) { try { ws.send(JSON.stringify({ action: 'addusertousergroup', responseid: command.responseid, result: 'ok', added: addedCount, failed: failCount })); } catch (ex) { } }
5692
}
5693
5694
+ function serverCommandAgentDisconnect(command) {
5695
+ if (common.validateInt(command.disconnectMode) == false) return; // Check disconnect mode
5696
+
5697
+ // Get the node and the rights for this node
5698
+ parent.GetNodeWithRights(domain, user, command.nodeid, function (node, rights, visible) {
5699
+ if ((node == null) || (((rights & MESHRIGHT_AGENTCONSOLE) == 0) && (user.siteadmin != SITERIGHT_ADMIN))) return;
5700
+
5701
+ // Force mesh agent disconnection
5702
+ parent.forceMeshAgentDisconnect(user, domain, node._id, command.disconnectMode);
5703
+ });
5704
+ }
5705
+
5706
function serverCommandAuthCookie(command) {
5707
try {
5708
ws.send(JSON.stringify({