MeshCentral will now auto-create LDAP user groups and sync users to their membership groups when the login using LDAP. (#4415)
This commit is contained in:
parent
2a42639f39
commit
8dd07495f5
27
meshuser.js
27
meshuser.js
|
@ -1514,11 +1514,11 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
db.Set(ugrp);
|
db.Set(ugrp);
|
||||||
if (db.changeStream == false) { parent.userGroups[ugrpid] = ugrp; }
|
if (db.changeStream == false) { parent.userGroups[ugrpid] = ugrp; }
|
||||||
|
|
||||||
// Event the device group creation
|
// Event the user group creation
|
||||||
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugrpid, name: ugrp.name, desc: ugrp.desc, action: 'createusergroup', links: ugrp.links, msgid: 69, msgArgv: [ugrp.name], msg: 'User group created: ' + ugrp.name, ugrpdomain: domain.id };
|
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugrpid, name: ugrp.name, desc: ugrp.desc, action: 'createusergroup', links: ugrp.links, msgid: 69, msgArgv: [ugrp.name], msg: 'User group created: ' + ugrp.name, ugrpdomain: domain.id };
|
||||||
parent.parent.DispatchEvent(['*', ugrpid, user._id], obj, event); // Even if DB change stream is active, this event must be acted upon.
|
parent.parent.DispatchEvent(['*', ugrpid, user._id], obj, event); // Even if DB change stream is active, this event must be acted upon.
|
||||||
|
|
||||||
// Event any pending events, these must be sent out after the group creation event is displatched.
|
// Event any pending events, these must be sent out after the group creation event is dispatched.
|
||||||
for (var i in pendingDispatchEvents) { var ev = pendingDispatchEvents[i]; parent.parent.DispatchEvent(ev[0], ev[1], ev[2]); }
|
for (var i in pendingDispatchEvents) { var ev = pendingDispatchEvents[i]; parent.parent.DispatchEvent(ev[0], ev[1], ev[2]); }
|
||||||
|
|
||||||
// Log in the auth log
|
// Log in the auth log
|
||||||
|
@ -1561,6 +1561,13 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
}
|
}
|
||||||
var group = groups[0];
|
var group = groups[0];
|
||||||
|
|
||||||
|
// If this user group is an externally managed user group, it can't be deleted unless there are no users in it.
|
||||||
|
if (group.membershipType != null) {
|
||||||
|
var userCount = 0;
|
||||||
|
if (group.links != null) { for (var i in group.links) { if (i.startsWith('user/')) { userCount++; } } }
|
||||||
|
if (userCount > 0) return;
|
||||||
|
}
|
||||||
|
|
||||||
// Unlink any user and meshes that have a link to this group
|
// Unlink any user and meshes that have a link to this group
|
||||||
if (group.links) {
|
if (group.links) {
|
||||||
for (var i in group.links) {
|
for (var i in group.links) {
|
||||||
|
@ -1621,7 +1628,8 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
change = '';
|
change = '';
|
||||||
var group = parent.userGroups[command.ugrpid];
|
var group = parent.userGroups[command.ugrpid];
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
if ((common.validateString(command.name, 1, 64) == true) && (command.name != group.name)) { change = 'User group name changed from "' + group.name + '" to "' + command.name + '"'; group.name = command.name; }
|
// If this user group is an externally managed user group, the name of the user group can't be edited
|
||||||
|
if ((group.membershipType == null) && (common.validateString(command.name, 1, 64) == true) && (command.name != group.name)) { change = 'User group name changed from "' + group.name + '" to "' + command.name + '"'; group.name = command.name; }
|
||||||
if ((common.validateString(command.desc, 0, 1024) == true) && (command.desc != group.desc)) { if (change != '') change += ' and description changed'; else change += 'User group "' + group.name + '" description changed'; group.desc = command.desc; }
|
if ((common.validateString(command.desc, 0, 1024) == true) && (command.desc != group.desc)) { if (change != '') change += ' and description changed'; else change += 'User group "' + group.name + '" description changed'; group.desc = command.desc; }
|
||||||
if ((typeof command.consent == 'number') && (command.consent != group.consent)) { if (change != '') change += ' and consent changed'; else change += 'User group "' + group.name + '" consent changed'; group.consent = command.consent; }
|
if ((typeof command.consent == 'number') && (command.consent != group.consent)) { if (change != '') change += ' and consent changed'; else change += 'User group "' + group.name + '" consent changed'; group.consent = command.consent; }
|
||||||
|
|
||||||
|
@ -5770,6 +5778,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
// Get the user group
|
// Get the user group
|
||||||
var group = parent.userGroups[command.ugrpid];
|
var group = parent.userGroups[command.ugrpid];
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
|
// If this user group is an externally managed user group, we can't add users to it.
|
||||||
|
if ((group != null) && (group.membershipType != null)) return;
|
||||||
|
|
||||||
if (group.links == null) { group.links = {}; }
|
if (group.links == null) { group.links = {}; }
|
||||||
|
|
||||||
var unknownUsers = [], addedCount = 0, failCount = 0, knownUsers = [];
|
var unknownUsers = [], addedCount = 0, failCount = 0, knownUsers = [];
|
||||||
|
@ -5779,7 +5790,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
var chguser = parent.users[chguserid];
|
var chguser = parent.users[chguserid];
|
||||||
if (chguser == null) { chguserid = 'user/' + addUserDomain.id + '/' + command.usernames[i]; chguser = parent.users[chguserid]; }
|
if (chguser == null) { chguserid = 'user/' + addUserDomain.id + '/' + command.usernames[i]; chguser = parent.users[chguserid]; }
|
||||||
if (chguser != null) {
|
if (chguser != null) {
|
||||||
// Add mesh to user
|
// Add usr group to user
|
||||||
if (chguser.links == null) { chguser.links = {}; }
|
if (chguser.links == null) { chguser.links = {}; }
|
||||||
chguser.links[group._id] = { rights: 1 };
|
chguser.links[group._id] = { rights: 1 };
|
||||||
db.SetUser(chguser);
|
db.SetUser(chguser);
|
||||||
|
@ -6235,6 +6246,12 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
|
|
||||||
var chguser = parent.users[command.userid];
|
var chguser = parent.users[command.userid];
|
||||||
if (chguser != null) {
|
if (chguser != null) {
|
||||||
|
// Get the user group
|
||||||
|
var group = parent.userGroups[command.ugrpid];
|
||||||
|
|
||||||
|
// If this user group is an externally managed user group, we can't remove a user from it.
|
||||||
|
if ((group != null) && (group.membershipType != null)) return;
|
||||||
|
|
||||||
if ((chguser.links != null) && (chguser.links[command.ugrpid] != null)) {
|
if ((chguser.links != null) && (chguser.links[command.ugrpid] != null)) {
|
||||||
delete chguser.links[command.ugrpid];
|
delete chguser.links[command.ugrpid];
|
||||||
|
|
||||||
|
@ -6248,8 +6265,6 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
|
||||||
parent.parent.DispatchEvent([chguser._id], obj, 'resubscribe');
|
parent.parent.DispatchEvent([chguser._id], obj, 'resubscribe');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the user group
|
|
||||||
var group = parent.userGroups[command.ugrpid];
|
|
||||||
if (group != null) {
|
if (group != null) {
|
||||||
// Remove the user from the group
|
// Remove the user from the group
|
||||||
if ((group.links != null) && (group.links[command.userid] != null)) {
|
if ((group.links != null) && (group.links[command.userid] != null)) {
|
||||||
|
|
|
@ -7539,7 +7539,7 @@
|
||||||
if (usergroups != null) {
|
if (usergroups != null) {
|
||||||
var userGroupCount = 0, newUserGroup = false;
|
var userGroupCount = 0, newUserGroup = false;
|
||||||
for (var i in usergroups) {
|
for (var i in usergroups) {
|
||||||
if (usergroups[i]._id.split('/')[1] != nodeid.split('/')[1]) continue;
|
if ((usergroups[i].membershipType != null) || (usergroups[i]._id.split('/')[1] != nodeid.split('/')[1])) continue;
|
||||||
userGroupCount++; if ((currentNode.links == null) || (currentNode.links[i] == null)) { newUserGroup = true; }
|
userGroupCount++; if ((currentNode.links == null) || (currentNode.links[i] == null)) { newUserGroup = true; }
|
||||||
}
|
}
|
||||||
if ((userGroupCount > 0) && (newUserGroup)) { x += '<a href=# onclick="return p20showAddMeshUserDialog(6)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add User Group" + '</a>'; }
|
if ((userGroupCount > 0) && (newUserGroup)) { x += '<a href=# onclick="return p20showAddMeshUserDialog(6)" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add User Group" + '</a>'; }
|
||||||
|
@ -12562,7 +12562,7 @@
|
||||||
if (usergroups != null) {
|
if (usergroups != null) {
|
||||||
var userGroupCount = 0, newUserGroup = false;
|
var userGroupCount = 0, newUserGroup = false;
|
||||||
for (var i in usergroups) {
|
for (var i in usergroups) {
|
||||||
if (usergroups[i]._id.split('/')[1] != currentMesh._id.split('/')[1]) continue;
|
if ((usergroups[i].membershipType != null) || (usergroups[i]._id.split('/')[1] != currentMesh._id.split('/')[1])) continue;
|
||||||
userGroupCount++;
|
userGroupCount++;
|
||||||
if ((currentMesh.links == null) || (currentMesh.links[i] == null)) { newUserGroup = true; }
|
if ((currentMesh.links == null) || (currentMesh.links[i] == null)) { newUserGroup = true; }
|
||||||
}
|
}
|
||||||
|
@ -13035,7 +13035,7 @@
|
||||||
if (selected == null) {
|
if (selected == null) {
|
||||||
var ousergroups = getOrderedList(usergroups, 'name');
|
var ousergroups = getOrderedList(usergroups, 'name');
|
||||||
for (var i in ousergroups) {
|
for (var i in ousergroups) {
|
||||||
if (currentNode._id.split('/')[1] != ousergroups[i]._id.split('/')[1]) continue;
|
if ((ousergroups[i].membershipType != null) || (currentNode._id.split('/')[1] != ousergroups[i]._id.split('/')[1])) continue;
|
||||||
if ((currentNode.links == null) || (currentNode.links[ousergroups[i]._id] == null)) { y += '<option value=' + encodeURIComponentEx(ousergroups[i]._id) + '>' + EscapeHtml(ousergroups[i].name) + '</option>'; }
|
if ((currentNode.links == null) || (currentNode.links[ousergroups[i]._id] == null)) { y += '<option value=' + encodeURIComponentEx(ousergroups[i]._id) + '>' + EscapeHtml(ousergroups[i].name) + '</option>'; }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -15151,7 +15151,7 @@
|
||||||
// Add user group name
|
// Add user group name
|
||||||
var gname = EscapeHtml(group.name);
|
var gname = EscapeHtml(group.name);
|
||||||
if (gname.length == 0) { gname = '<i>' + "None" + '</i>'; }
|
if (gname.length == 0) { gname = '<i>' + "None" + '</i>'; }
|
||||||
if ((userinfo.siteadmin & 256) != 0) { gname = '<span tabindex=0 title="' + "Click here to edit the user group name" + '" onclick=p51editgroup(1) onkeyup="if (event.key == \'Enter\') p51editgroup(1)" style=cursor:pointer>' + gname + ' <img class=hoverButton src="images/link5.png" /></span>'; }
|
if ((currentUserGroup.membershipType == null) && ((userinfo.siteadmin & 256) != 0)) { gname = '<span tabindex=0 title="' + "Click here to edit the user group name" + '" onclick=p51editgroup(1) onkeyup="if (event.key == \'Enter\') p51editgroup(1)" style=cursor:pointer>' + gname + ' <img class=hoverButton src="images/link5.png" /></span>'; }
|
||||||
QH('p51groupName', gname);
|
QH('p51groupName', gname);
|
||||||
|
|
||||||
var usercount = 0, meshcount = 0, devicecount = 0;
|
var usercount = 0, meshcount = 0, devicecount = 0;
|
||||||
|
@ -15172,8 +15172,11 @@
|
||||||
x += addDeviceAttribute("Domain", (d != '')?EscapeHtml(d):('<i>' + "Default" + '</i>'));
|
x += addDeviceAttribute("Domain", (d != '')?EscapeHtml(d):('<i>' + "Default" + '</i>'));
|
||||||
x += addDeviceAttribute("Group Identifier", EscapeHtml(group._id));
|
x += addDeviceAttribute("Group Identifier", EscapeHtml(group._id));
|
||||||
}
|
}
|
||||||
|
if (currentUserGroup.membershipType != null) {
|
||||||
|
x += addDeviceAttribute("Group Type", EscapeHtml(currentUserGroup.membershipType));
|
||||||
|
}
|
||||||
if ((userinfo.siteadmin & 256) != 0) {
|
if ((userinfo.siteadmin & 256) != 0) {
|
||||||
x += addDeviceAttribute("Description", '<span onclick=p51editgroup(2) style=cursor:pointer>' + desc + ' <img class=hoverButton src="images/link5.png" /></span>');
|
x += addDeviceAttribute("Description", '<span onclick=p51editgroup(2,' + (currentUserGroup.membershipType != null) + ') style=cursor:pointer>' + desc + ' <img class=hoverButton src="images/link5.png" /></span>');
|
||||||
} else {
|
} else {
|
||||||
x += addDeviceAttribute("Description", desc);
|
x += addDeviceAttribute("Description", desc);
|
||||||
}
|
}
|
||||||
|
@ -15217,7 +15220,7 @@
|
||||||
QH('p51group', x);
|
QH('p51group', x);
|
||||||
|
|
||||||
x = '<br />';
|
x = '<br />';
|
||||||
if ((userinfo.siteadmin & 256) != 0) {
|
if ((currentUserGroup.membershipType == null) && ((userinfo.siteadmin & 256) != 0)) {
|
||||||
x += '<a href=# onclick="return p51showAddUserDialog()" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Users" + '</a>';
|
x += '<a href=# onclick="return p51showAddUserDialog()" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Users" + '</a>';
|
||||||
}
|
}
|
||||||
x += '<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>' + "Group Members" + '</th><th scope=col style=text-align:left></th></tr>';
|
x += '<table style="color:black;background-color:#EEE;border-color:#AAA;border-width:1px;border-style:solid;border-collapse:collapse" border=0 cellpadding=2 cellspacing=0 width=100%><tbody><tr style=background-color:#AAAAAA;font-weight:bold><th scope=col style=text-align:left;width:430px>' + "Group Members" + '</th><th scope=col style=text-align:left></th></tr>';
|
||||||
|
@ -15235,7 +15238,8 @@
|
||||||
|
|
||||||
// Display all users for this user group
|
// Display all users for this user group
|
||||||
for (var i in sortedusers) {
|
for (var i in sortedusers) {
|
||||||
var trash = '<a href=# onclick=\'return p51deleteUser(event,"' + encodeURIComponentEx(sortedusers[i].id) + '")\' title="' + "Remove user rights to this device group" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>';
|
var trash = '';
|
||||||
|
if (currentUserGroup.membershipType == null) { trash = '<a href=# onclick=\'return p51deleteUser(event,"' + encodeURIComponentEx(sortedusers[i].id) + '")\' title="' + "Remove user rights to this device group" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
|
||||||
var username = EscapeHtml(decodeURIComponent(sortedusers[i].name));
|
var username = EscapeHtml(decodeURIComponent(sortedusers[i].name));
|
||||||
if (users != null) { username = '<a href=# onclick=\'gotoUser("' + encodeURIComponentEx(sortedusers[i].id) + '");haltEvent(event);\'>' + username + '</a>'; }
|
if (users != null) { username = '<a href=# onclick=\'gotoUser("' + encodeURIComponentEx(sortedusers[i].id) + '");haltEvent(event);\'>' + username + '</a>'; }
|
||||||
x += '<tr ' + (((count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td><div title="' + "User" + '" class=m2></div><div> ' + username + '<div></div></div></td><td><div style=float:right>' + trash + '</div></td></tr>';
|
x += '<tr ' + (((count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td><div title="' + "User" + '" class=m2></div><div> ' + username + '<div></div></div></td><td><div style=float:right>' + trash + '</div></td></tr>';
|
||||||
|
@ -15294,7 +15298,7 @@
|
||||||
if (count == 1) { x += '<tr><td><div style=padding:6px> <i>' + "No devices in common" + '</i><div></div></div></td><td></td></tr>'; }
|
if (count == 1) { x += '<tr><td><div style=padding:6px> <i>' + "No devices in common" + '</i><div></div></div></td><td></td></tr>'; }
|
||||||
x += '</tbody></table>';
|
x += '</tbody></table>';
|
||||||
|
|
||||||
if ((userinfo.siteadmin & 256) != 0) {
|
if (((currentUserGroup.membershipType == null) || (usercount == 0)) && ((userinfo.siteadmin & 256) != 0)) {
|
||||||
x += '<div style=font-size:small;text-align:right><span><a href=# onclick=p51showDeleteUserGroupDialog() style=cursor:pointer>' + "Delete User Group" + '</a></span></div>';
|
x += '<div style=font-size:small;text-align:right><span><a href=# onclick=p51showDeleteUserGroupDialog() style=cursor:pointer>' + "Delete User Group" + '</a></span></div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15349,9 +15353,9 @@
|
||||||
meshserver.send({ action: 'removemeshuser', meshid: meshid, userid: currentUserGroup._id });
|
meshserver.send({ action: 'removemeshuser', meshid: meshid, userid: currentUserGroup._id });
|
||||||
}
|
}
|
||||||
|
|
||||||
function p51editgroup(focus) {
|
function p51editgroup(focus, nameReadOnly) {
|
||||||
if (xxdialogMode) return;
|
if (xxdialogMode) return;
|
||||||
var x = addHtmlValue("Name", '<input id=dp51name style=width:230px maxlength=32 onchange=p51editgroupValidate() onkeyup=p51editgroupValidate(event) />');
|
var x = addHtmlValue("Name", '<input id=dp51name style=width:230px maxlength=32 onchange=p51editgroupValidate() onkeyup=p51editgroupValidate(event) ' + (nameReadOnly ? 'readonly disabled' : '') + '/>');
|
||||||
x += addHtmlValue("Description", '<div style=width:230px;margin:0;padding:0><textarea id=dp51desc maxlength=1024 style=width:100%;resize:none></textarea></div>');
|
x += addHtmlValue("Description", '<div style=width:230px;margin:0;padding:0><textarea id=dp51desc maxlength=1024 style=width:100%;resize:none></textarea></div>');
|
||||||
setDialogMode(2, "Edit User Group", 3, p51editgroupEx, x);
|
setDialogMode(2, "Edit User Group", 3, p51editgroupEx, x);
|
||||||
Q('dp51name').value = currentUserGroup.name;
|
Q('dp51name').value = currentUserGroup.name;
|
||||||
|
@ -15893,7 +15897,7 @@
|
||||||
if ((userinfo.siteadmin & 256) != 0) {
|
if ((userinfo.siteadmin & 256) != 0) {
|
||||||
var userGroupCount = 0, newUserGroup = false;
|
var userGroupCount = 0, newUserGroup = false;
|
||||||
for (var i in usergroups) {
|
for (var i in usergroups) {
|
||||||
if (usergroups[i]._id.split('/')[1] != currentUser._id.split('/')[1]) continue;
|
if ((usergroups[i].membershipType != null) || (usergroups[i]._id.split('/')[1] != currentUser._id.split('/')[1])) continue;
|
||||||
userGroupCount++;
|
userGroupCount++;
|
||||||
if ((currentUser.links == null) || (currentUser.links[i] == null)) { newUserGroup = true; }
|
if ((currentUser.links == null) || (currentUser.links[i] == null)) { newUserGroup = true; }
|
||||||
}
|
}
|
||||||
|
@ -15911,7 +15915,7 @@
|
||||||
groupname = EscapeHtml(group.name);
|
groupname = EscapeHtml(group.name);
|
||||||
if (usergroups != null) { groupname = '<a href=# onclick=\'gotoUserGroup("' + encodeURIComponentEx(ougroups[i]._id) + '");haltEvent(event);\'>' + groupname + '</a>'; }
|
if (usergroups != null) { groupname = '<a href=# onclick=\'gotoUserGroup("' + encodeURIComponentEx(ougroups[i]._id) + '");haltEvent(event);\'>' + groupname + '</a>'; }
|
||||||
}
|
}
|
||||||
if ((userinfo.siteadmin & 256) != 0) { trash = '<a href=# onclick=\'return p30RemoveUserGroup(event,"' + encodeURIComponentEx(ougroups[i]._id) + '")\' title="' + "Remove user group membership" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
|
if ((group.membershipType == null) && ((userinfo.siteadmin & 256) != 0)) { trash = '<a href=# onclick=\'return p30RemoveUserGroup(event,"' + encodeURIComponentEx(ougroups[i]._id) + '")\' title="' + "Remove user group membership" + '" style=cursor:pointer><img src=images/trash.png border=0 height=10 width=10></a>'; }
|
||||||
x += '<tr ' + (((++count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td><div title="' + "User Group" + '" class=m4></div><div> ' + groupname + '<div></div></div></td><td><div style=float:right>' + trash + '</div></td></tr>';
|
x += '<tr ' + (((++count % 2) == 0) ? 'style=background-color:#DDD' : '') + '><td><div title="' + "User Group" + '" class=m4></div><div> ' + groupname + '<div></div></div></td><td><div style=float:right>' + trash + '</div></td></tr>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15986,7 +15990,7 @@
|
||||||
if (xxdialogMode || (usergroups == null)) return;
|
if (xxdialogMode || (usergroups == null)) return;
|
||||||
var y = '';
|
var y = '';
|
||||||
for (var i in usergroups) {
|
for (var i in usergroups) {
|
||||||
if (usergroups[i]._id.split('/')[1] != currentUser._id.split('/')[1]) continue;
|
if ((usergroups[i].membershipType != null) || (usergroups[i]._id.split('/')[1] != currentUser._id.split('/')[1])) continue;
|
||||||
if ((currentUser.links == null) || (currentUser.links[i] == null)) { y += '<option value=' + encodeURIComponentEx(i) + '>' + EscapeHtml(usergroups[i].name) + '</option>'; }
|
if ((currentUser.links == null) || (currentUser.links[i] == null)) { y += '<option value=' + encodeURIComponentEx(i) + '>' + EscapeHtml(usergroups[i].name) + '</option>'; }
|
||||||
}
|
}
|
||||||
var x = addHtmlValue("User Group", '<div style=width:230px;margin:0;padding:0><select id=dp2groupid style=width:100%>' + y + '</select></div>');
|
var x = addHtmlValue("User Group", '<div style=width:230px;margin:0;padding:0><select id=dp2groupid style=width:100%>' + y + '</select></div>');
|
||||||
|
|
115
webserver.js
115
webserver.js
|
@ -472,21 +472,18 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||||
if (username == null) { username = shortname; }
|
if (username == null) { username = shortname; }
|
||||||
var userid = 'user/' + domain.id + '/' + shortname;
|
var userid = 'user/' + domain.id + '/' + shortname;
|
||||||
|
|
||||||
|
// Get the list of groups this user is a member of.
|
||||||
|
var userMemberships = xxuser[(typeof domain.ldapusergroups == 'string') ? domain.ldapusergroups : 'memberOf'];
|
||||||
|
if (typeof userMemberships == 'string') { userMemberships = [userMemberships]; }
|
||||||
|
if (Array.isArray(userMemberships) == false) { userMemberships = []; }
|
||||||
|
|
||||||
// See if the user is required to be part of an LDAP user group in order to log into this server.
|
// See if the user is required to be part of an LDAP user group in order to log into this server.
|
||||||
if (typeof domain.ldapuserrequiredgroupmembership == 'string') { domain.ldapuserrequiredgroupmembership = [domain.ldapuserrequiredgroupmembership]; }
|
if (typeof domain.ldapuserrequiredgroupmembership == 'string') { domain.ldapuserrequiredgroupmembership = [domain.ldapuserrequiredgroupmembership]; }
|
||||||
if (Array.isArray(domain.ldapuserrequiredgroupmembership) && (domain.ldapuserrequiredgroupmembership.length > 0)) {
|
if (Array.isArray(domain.ldapuserrequiredgroupmembership) && (domain.ldapuserrequiredgroupmembership.length > 0)) {
|
||||||
// We must be part of a LDAP user group, lets get the list of groups this user is a member of.
|
|
||||||
const memberOfKey = (typeof domain.ldapusergroups == 'string') ? domain.ldapusergroups : 'memberOf';
|
|
||||||
var userMemberships = xxuser[memberOfKey];
|
|
||||||
if (typeof userMemberships == 'string') { userMemberships = [userMemberships]; }
|
|
||||||
if (Array.isArray(userMemberships) == false) { userMemberships = []; }
|
|
||||||
|
|
||||||
// Look for a matching LDAP user group
|
// Look for a matching LDAP user group
|
||||||
var userMembershipMatch = false;
|
var userMembershipMatch = false;
|
||||||
for (var i in domain.ldapuserrequiredgroupmembership) { if (userMemberships.indexOf(domain.ldapuserrequiredgroupmembership[i]) >= 0) { userMembershipMatch = true; } }
|
for (var i in domain.ldapuserrequiredgroupmembership) { if (userMemberships.indexOf(domain.ldapuserrequiredgroupmembership[i]) >= 0) { userMembershipMatch = true; } }
|
||||||
|
if (userMembershipMatch === false) { fn('denied'); return; } // If there is no match, deny the login
|
||||||
// If there is no match, deny the login
|
|
||||||
if (userMembershipMatch === false) { fn('denied'); return; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the email address for this LDAP user
|
// Get the email address for this LDAP user
|
||||||
|
@ -578,6 +575,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||||
// Indicate that this user has a image
|
// Indicate that this user has a image
|
||||||
if (userimage != null) { user.flags = 1; }
|
if (userimage != null) { user.flags = 1; }
|
||||||
|
|
||||||
|
// Synd the user with LDAP matching user groups
|
||||||
|
if (syncExternalUserGroups(domain, user, userMemberships, 'ldap') == true) { userChanged = true; }
|
||||||
|
|
||||||
obj.users[user._id] = user;
|
obj.users[user._id] = user;
|
||||||
obj.db.SetUser(user);
|
obj.db.SetUser(user);
|
||||||
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msgid: 128, msgArgs: [user.name], msg: 'Account created, name is ' + user.name, domain: domain.id };
|
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountcreate', msgid: 128, msgArgs: [user.name], msg: 'Account created, name is ' + user.name, domain: domain.id };
|
||||||
|
@ -612,6 +612,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||||
if ((userimage != null) && ((user.flags == null) || ((user.flags & 1) == 0))) { if (user.flags == null) { user.flags = 1; } else { user.flags += 1; } userChanged = true; }
|
if ((userimage != null) && ((user.flags == null) || ((user.flags & 1) == 0))) { if (user.flags == null) { user.flags = 1; } else { user.flags += 1; } userChanged = true; }
|
||||||
if ((userimage == null) && (user.flags != null) && ((user.flags & 1) != 0)) { if (user.flags == 1) { delete user.flags; } else { user.flags -= 1; } userChanged = true; }
|
if ((userimage == null) && (user.flags != null) && ((user.flags & 1) != 0)) { if (user.flags == 1) { delete user.flags; } else { user.flags -= 1; } userChanged = true; }
|
||||||
|
|
||||||
|
// Synd the user with LDAP matching user groups
|
||||||
|
if (syncExternalUserGroups(domain, user, userMemberships, 'ldap') == true) { userChanged = true; }
|
||||||
|
|
||||||
// If the user changed, save the changes to the database here
|
// If the user changed, save the changes to the database here
|
||||||
if (userChanged) {
|
if (userChanged) {
|
||||||
obj.db.SetUser(user);
|
obj.db.SetUser(user);
|
||||||
|
@ -8694,5 +8697,99 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync an account with an external user group.
|
||||||
|
// Return true if the user was changed
|
||||||
|
function syncExternalUserGroups(domain, user, userMemberships, userMembershipType) {
|
||||||
|
var userChanged = false;
|
||||||
|
if (user.links == null) { user.links = {}; }
|
||||||
|
|
||||||
|
// Create a user of memberships for this user that type
|
||||||
|
var existingUserMemberships = {};
|
||||||
|
for (var i in user.links) {
|
||||||
|
if (i.startsWith('ugrp/') && (obj.userGroups[i] != null) && (obj.userGroups[i].membershipType == userMembershipType)) { existingUserMemberships[i] = obj.userGroups[i]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go thru the list user memberships and create and add to any user groups as needed
|
||||||
|
for (var i in userMemberships) {
|
||||||
|
const membership = userMemberships[i];
|
||||||
|
var ugrpid = 'ugrp/' + domain.id + '/' + obj.crypto.createHash('sha384').update(membership).digest('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||||
|
var ugrp = obj.userGroups[ugrpid];
|
||||||
|
if (ugrp == null) {
|
||||||
|
// This user group does not exist, create it
|
||||||
|
ugrp = { type: 'ugrp', _id: ugrpid, name: membership, domain: domain.id, membershipType: userMembershipType, links: {} };
|
||||||
|
|
||||||
|
// Save the new group
|
||||||
|
db.Set(ugrp);
|
||||||
|
if (db.changeStream == false) { obj.userGroups[ugrpid] = ugrp; }
|
||||||
|
|
||||||
|
// Event the user group creation
|
||||||
|
var event = { etype: 'ugrp', ugrpid: ugrpid, name: ugrp.name, action: 'createusergroup', links: ugrp.links, msgid: 69, msgArgv: [ugrp.name], msg: 'User group created: ' + ugrp.name, ugrpdomain: domain.id };
|
||||||
|
parent.DispatchEvent(['*', ugrpid, user._id], obj, event); // Even if DB change stream is active, this event must be acted upon.
|
||||||
|
|
||||||
|
// Log in the auth log
|
||||||
|
if (parent.authlog) { parent.authLog('https', 'Created ' + userMembershipType + ' user group ' + ugrp.name); }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingUserMemberships[ugrpid] == null) {
|
||||||
|
// This user is not part of the user group, add it.
|
||||||
|
if (user.links == null) { user.links = {}; }
|
||||||
|
user.links[ugrp._id] = { rights: 1 };
|
||||||
|
userChanged = true;
|
||||||
|
db.SetUser(user);
|
||||||
|
parent.DispatchEvent([user._id], obj, 'resubscribe');
|
||||||
|
|
||||||
|
// Notify user change
|
||||||
|
var targets = ['*', 'server-users', user._id];
|
||||||
|
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msgid: 67, msgArgs: [user.name], msg: 'User group membership changed: ' + user.name, domain: domain.id };
|
||||||
|
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.
|
||||||
|
parent.DispatchEvent(targets, obj, event);
|
||||||
|
|
||||||
|
// Add a user to the user group
|
||||||
|
ugrp.links[user._id] = { userid: user._id, name: user.name, rights: 1 };
|
||||||
|
db.Set(ugrp);
|
||||||
|
|
||||||
|
// Notify user group change
|
||||||
|
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugrp._id, name: ugrp.name, desc: ugrp.desc, action: 'usergroupchange', links: ugrp.links, msgid: 71, msgArgs: [user.name, ugrp.name], msg: 'Added user(s) ' + user.name + ' to user group ' + ugrp.name, addUserDomain: domain.id };
|
||||||
|
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
|
||||||
|
parent.DispatchEvent(['*', ugrp._id, user._id], obj, event);
|
||||||
|
} else {
|
||||||
|
// User is already part of this user group
|
||||||
|
delete existingUserMemberships[ugrpid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the user from any memberships they don't belong to anymore
|
||||||
|
for (var ugrpid in existingUserMemberships) {
|
||||||
|
var ugrp = obj.userGroups[ugrpid];
|
||||||
|
if ((user.links != null) && (user.links[ugrpid] != null)) {
|
||||||
|
delete user.links[ugrpid];
|
||||||
|
|
||||||
|
// Notify user change
|
||||||
|
var targets = ['*', 'server-users', user._id, user._id];
|
||||||
|
var event = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'accountchange', msgid: 67, msgArgs: [user.name], msg: 'User group membership changed: ' + user.name, domain: domain.id };
|
||||||
|
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.
|
||||||
|
parent.DispatchEvent(targets, obj, event);
|
||||||
|
|
||||||
|
db.SetUser(user);
|
||||||
|
parent.DispatchEvent([user._id], obj, 'resubscribe');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ugrp != null) {
|
||||||
|
// Remove the user from the group
|
||||||
|
if ((ugrp.links != null) && (ugrp.links[user._id] != null)) {
|
||||||
|
delete ugrp.links[user._id];
|
||||||
|
db.Set(ugrp);
|
||||||
|
|
||||||
|
// Notify user group change
|
||||||
|
var event = { etype: 'ugrp', userid: user._id, username: user.name, ugrpid: ugrp._id, name: ugrp.name, desc: ugrp.desc, action: 'usergroupchange', links: ugrp.links, msgid: 72, msgArgs: [user.name, ugrp.name], msg: 'Removed user ' + user.name + ' from user group ' + ugrp.name, domain: domain.id };
|
||||||
|
if (db.changeStream) { event.noact = 1; } // If DB change stream is active, don't use this event to change the user group. Another event will come.
|
||||||
|
parent.DispatchEvent(['*', ugrp._id, user._id], obj, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return userChanged;
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue