Only list users in ldap groups who have access to the app

Fixes #215
This commit is contained in:
Johannes Zellner
2017-03-13 11:06:27 +01:00
parent 2f598529fc
commit 1763144278
2 changed files with 72 additions and 29 deletions
+36 -28
View File
@@ -105,40 +105,48 @@ function userSearch(req, res, next) {
function groupSearch(req, res, next) {
debug('group search: dn %s, scope %s, filter %s (from %s)', req.dn.toString(), req.scope, req.filter.toString(), req.connection.ldap.id);
user.list(function (error, result){
if (error) return next(new ldap.OperationsError(error.toString()));
getAppByRequest(req, function (error, app) {
if (error) return next(error);
var groups = [{
name: 'users',
admin: false
}, {
name: 'admins',
admin: true
}];
user.list(function (error, result){
if (error) return next(new ldap.OperationsError(error.toString()));
groups.forEach(function (group) {
var dn = ldap.parseDN('cn=' + group.name + ',ou=groups,dc=cloudron');
var members = group.admin ? result.filter(function (entry) { return entry.admin; }) : result;
async.filter(result, apps.hasAccessTo.bind(null, app), function (error, result) {
if (error) return next(new ldap.OperationsError(error.toString()));
var obj = {
dn: dn.toString(),
attributes: {
objectclass: ['group'],
cn: group.name,
memberuid: members.map(function(entry) { return entry.id; })
}
};
var groups = [{
name: 'users',
admin: false
}, {
name: 'admins',
admin: true
}];
// ensure all filter values are also lowercase
var lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null);
if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString()));
groups.forEach(function (group) {
var dn = ldap.parseDN('cn=' + group.name + ',ou=groups,dc=cloudron');
var members = group.admin ? result.filter(function (entry) { return entry.admin; }) : result;
if ((req.dn.equals(dn) || req.dn.parentOf(dn)) && lowerCaseFilter.matches(obj.attributes)) {
res.send(obj);
}
var obj = {
dn: dn.toString(),
attributes: {
objectclass: ['group'],
cn: group.name,
memberuid: members.map(function(entry) { return entry.id; })
}
};
// ensure all filter values are also lowercase
var lowerCaseFilter = safe(function () { return ldap.parseFilter(req.filter.toString().toLowerCase()); }, null);
if (!lowerCaseFilter) return next(new ldap.OperationsError(safe.error.toString()));
if ((req.dn.equals(dn) || req.dn.parentOf(dn)) && lowerCaseFilter.matches(obj.attributes)) {
res.send(obj);
}
});
res.end();
});
});
res.end();
});
}
+36 -1
View File
@@ -453,7 +453,7 @@ describe('Ldap', function () {
});
});
it ('does not list users who have access', function (done) {
it ('does only list users who have access', function (done) {
appdb.update(APP_0.id, { accessRestriction: { users: [], groups: [ GROUP_ID ] } }, function (error) {
expect(error).to.be(null);
@@ -577,6 +577,41 @@ describe('Ldap', function () {
});
});
});
it ('does only list users who have access', function (done) {
appdb.update(APP_0.id, { accessRestriction: { users: [], groups: [ GROUP_ID ] } }, function (error) {
expect(error).to.be(null);
var client = ldap.createClient({ url: 'ldap://127.0.0.1:' + config.get('ldapPort') });
var opts = {
filter: '&(objectclass=group)(cn=*)'
};
client.search('ou=groups,dc=cloudron', opts, function (error, result) {
expect(error).to.be(null);
expect(result).to.be.an(EventEmitter);
var entries = [];
result.on('searchEntry', function (entry) { entries.push(entry.object); });
result.on('error', done);
result.on('end', function (result) {
expect(result.status).to.equal(0);
expect(entries.length).to.equal(2);
expect(entries[0].cn).to.equal('users');
expect(entries[0].memberuid.length).to.equal(2);
expect(entries[0].memberuid[0]).to.equal(USER_0.id);
expect(entries[0].memberuid[1]).to.equal(USER_1.id);
expect(entries[1].cn).to.equal('admins');
// if only one entry, the array becomes a string :-/
expect(entries[1].memberuid).to.equal(USER_0.id);
appdb.update(APP_0.id, { accessRestriction: null }, done);
});
});
});
});
});
function ldapSearch(dn, filter, callback) {