Sync users into groups

This does not yet remove users from groups

Part of #685
This commit is contained in:
Johannes Zellner
2020-06-05 10:29:36 +02:00
parent 48af17e052
commit 0b2eb8fb9e

View File

@@ -82,6 +82,41 @@ function getClient(externalLdapConfig, callback) {
});
}
function ldapGetByDN(externalLdapConfig, dn, callback) {
assert.strictEqual(typeof externalLdapConfig, 'object');
assert.strictEqual(typeof dn, 'string');
assert.strictEqual(typeof callback, 'function');
getClient(externalLdapConfig, function (error, client) {
if (error) return callback(error);
let searchOptions = {
paged: true,
scope: 'sub' // We may have to make this configurable
};
debug(`Get object at ${dn}`);
client.search(dn, searchOptions, function (error, result) {
if (error instanceof ldap.NoSuchObjectError) return callback(new BoxError(BoxError.NOT_FOUND));
if (error) return callback(new BoxError(BoxError.EXTERNAL_ERROR, error));
let ldapObjects = [];
result.on('searchEntry', entry => ldapObjects.push(entry.object));
result.on('error', error => callback(new BoxError(BoxError.EXTERNAL_ERROR, error)));
result.on('end', function (result) {
client.unbind();
if (result.status !== 0) return callback(new BoxError(BoxError.EXTERNAL_ERROR, 'Server returned status ' + result.status));
if (ldapObjects.length === 0) return callback(new BoxError(BoxError.NOT_FOUND));
callback(null, ldapObjects[0]);
});
});
});
}
// TODO support search by email
function ldapUserSearch(externalLdapConfig, options, callback) {
@@ -140,10 +175,10 @@ function ldapGroupSearch(externalLdapConfig, options, callback) {
if (externalLdapConfig.groupFilter) searchOptions.filter = ldap.parseFilter(externalLdapConfig.groupFilter);
// if (options.filter) { // https://github.com/ldapjs/node-ldapjs/blob/master/docs/filters.md
// let extraFilter = ldap.parseFilter(options.filter);
// searchOptions.filter = new ldap.AndFilter({ filters: [ extraFilter, searchOptions.filter ] });
// }
if (options.filter) { // https://github.com/ldapjs/node-ldapjs/blob/master/docs/filters.md
let extraFilter = ldap.parseFilter(options.filter);
searchOptions.filter = new ldap.AndFilter({ filters: [ extraFilter, searchOptions.filter ] });
}
debug(`Listing groups at ${externalLdapConfig.groupBaseDn} with filter ${searchOptions.filter.toString()}`);
@@ -420,13 +455,56 @@ function syncGroupUsers(externalLdapConfig, progressCallback, callback) {
return callback(null, []);
}
groups.getAllWithMembers(function (error, groups) {
groups.getAll(function (error, result) {
if (error) return callback(error);
var ldapGroups = groups.filter(function (g) { return g.source === 'ldap'; });
var ldapGroups = result.filter(function (g) { return g.source === 'ldap'; });
debug(`Found ${ldapGroups.length} groups to sync users`);
callback();
async.eachSeries(ldapGroups, function (group, iteratorCallback) {
debug(`Synd users for group ${group.name}`);
ldapGroupSearch(externalLdapConfig, { filter: `${externalLdapConfig.groupnameField}=${group.name}` }, function (error, result) {
if (error) return callback(error);
if (!result || result.length === 0) {
console.error(`Unable to find group ${group.name} ignoring for now.`);
return callback();
}
var ldapGroupMembers = result[0].member;
debug(`Group ${group.name} has ${ldapGroupMembers.length} members.`);
async.eachSeries(ldapGroupMembers, function (memberDn, iteratorCallback) {
ldapGetByDN(externalLdapConfig, memberDn, function (error, result) {
if (error) {
console.error(`Failed to get ${memberDn}:`, error);
return iteratorCallback();
}
debug(`Found member object at ${memberDn} adding to group ${group.name}`);
const username = result[externalLdapConfig.usernameField];
if (!username) return iteratorCallback();
users.getByUsername(username, function (error, result) {
if (error) {
console.error(`Failed to get user by username ${username}`, error);
return iteratorCallback();
}
groups.addMember(group.id, result.id, function (error) {
if (error && error.reason !== BoxError.ALREADY_EXISTS) console.error('Failed to add member', error);
iteratorCallback();
});
});
});
}, function (error) {
if (error) console.error(error);
iteratorCallback();
});
});
}, callback);
});
}