mecano
Version:
Common functions for system deployment.
271 lines (264 loc) • 9.22 kB
JavaScript
// Generated by CoffeeScript 1.7.1
var child, conditions, each, ldap, misc;
each = require('each');
ldap = require('ldapjs');
misc = require('./misc');
conditions = require('./misc/conditions');
child = require('./misc/child');
module.exports = function(goptions, options, callback) {
var finish, result, _ref;
_ref = misc.args(arguments), goptions = _ref[0], options = _ref[1], callback = _ref[2];
result = child();
finish = function(err, modified) {
if (callback) {
callback(err, modified);
}
return result.end(err, modified);
};
misc.options(options, function(err, options) {
var modified;
if (err) {
return finish(err);
}
modified = 0;
return each(options).parallel(goptions.parallel).on('item', function(options, next) {
if (options.acls == null) {
options.acls = [{}];
}
return conditions.all(options, next, function() {
var updated;
updated = false;
return each(options.acls).parallel(false).on('item', function(acl, next) {
var b, client, connect, do_diff, end, i, parse, save, search, stringify, unbind, _i, _len, _ref1;
if (acl.before == null) {
acl.before = options.before;
}
if (acl.to == null) {
acl.to = options.to;
}
if (acl.by == null) {
acl.by = options.by;
}
client = null;
acl.to = acl.to.trim();
_ref1 = acl.by;
for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) {
b = _ref1[i];
acl.by[i] = b.trim();
}
connect = function() {
var _ref2, _ref3, _ref4;
if (((_ref2 = options.ldap) != null ? (_ref3 = _ref2.url) != null ? (_ref4 = _ref3.protocol) != null ? _ref4.indexOf('ldap') : void 0 : void 0 : void 0) === 0) {
client = options.ldap;
return search();
}
if (typeof options.log === "function") {
options.log('Open and bind connection');
}
client = ldap.createClient({
url: options.url
});
return client.bind(options.binddn, options.passwd, function(err) {
if (err) {
return end(err);
}
return search();
});
};
search = function() {
if (typeof options.log === "function") {
options.log('Search attribute olcAccess');
}
return client.search(options.name, {
scope: 'base',
attributes: ['olcAccess']
}, function(err, search) {
var olcAccess;
if (err) {
return unbind(err);
}
olcAccess = null;
search.on('searchEntry', function(entry) {
if (typeof options.log === "function") {
options.log("Found " + (JSON.stringify(entry.object)));
}
olcAccess = entry.object.olcAccess || [];
if (!Array.isArray(olcAccess)) {
return olcAccess = [olcAccess];
}
});
return search.on('end', function() {
if (typeof options.log === "function") {
options.log("Attribute olcAccess was " + (JSON.stringify(olcAccess)));
}
return parse(olcAccess);
});
});
};
parse = function(_olcAccess) {
var access, buf, buftype, bys, c, matches, olcAccess, to, _j, _k, _len1, _len2;
olcAccess = [];
for (i = _j = 0, _len1 = _olcAccess.length; _j < _len1; i = ++_j) {
access = _olcAccess[i];
to = '';
bys = [];
buftype = 0;
buf = '';
for (i = _k = 0, _len2 = access.length; _k < _len2; i = ++_k) {
c = access[i];
buf += c;
if (buftype === 0) {
if (/to$/.test(buf)) {
buf = '';
buftype = 1;
}
}
if (buftype === 1) {
if (matches = /^(.*)by$/.exec(buf)) {
to = matches[1].trim();
buf = '';
buftype = 2;
}
}
if (buftype === 2) {
if (matches = /^(.*)by$/.exec(buf)) {
bys.push(matches[1].trim());
buf = '';
} else if (i + 1 === access.length) {
bys.push(buf.trim());
}
}
}
olcAccess.push({
to: to,
by: bys
});
}
return do_diff(olcAccess);
};
do_diff = function(olcAccess) {
var aby, access, fby, found, oby, toAlreadyExist, _j, _k, _l, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref2, _ref3;
toAlreadyExist = false;
for (i = _j = 0, _len1 = olcAccess.length; _j < _len1; i = ++_j) {
access = olcAccess[i];
if (acl.to !== access.to) {
continue;
}
toAlreadyExist = true;
fby = !options.overwrite ? access.by : [];
_ref2 = acl.by;
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
oby = _ref2[_k];
found = false;
_ref3 = access.by;
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
aby = _ref3[_l];
if (oby === aby) {
found = true;
break;
}
}
if (!found) {
updated = true;
fby.push(oby);
}
}
olcAccess[i].by = fby;
}
if (!toAlreadyExist) {
updated = true;
if (acl.before) {
found = null;
for (i = _m = 0, _len4 = olcAccess.length; _m < _len4; i = ++_m) {
access = olcAccess[i];
if (access.to === acl.before) {
found = i;
}
}
olcAccess.splice(found - 1, 0, {
to: acl.to,
by: acl.by
});
} else if (acl.after) {
found = false;
for (i = _n = 0, _len5 = olcAccess.length; _n < _len5; i = ++_n) {
access = olcAccess[i];
if (access.to === options.after) {
found = i;
}
}
olcAccess.splice(found, 0, {
to: acl.to,
by: acl.by
});
} else {
olcAccess.push({
to: acl.to,
by: acl.by
});
}
}
if (updated) {
return stringify(olcAccess);
} else {
return unbind();
}
};
stringify = function(olcAccess) {
var access, bie, value, _j, _k, _len1, _len2, _ref2;
for (i = _j = 0, _len1 = olcAccess.length; _j < _len1; i = ++_j) {
access = olcAccess[i];
value = "{" + i + "}to " + access.to;
_ref2 = access.by;
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
bie = _ref2[_k];
value += " by " + bie;
}
olcAccess[i] = value;
}
return save(olcAccess);
};
save = function(olcAccess) {
var change;
change = new ldap.Change({
operation: 'replace',
modification: {
olcAccess: olcAccess
}
});
return client.modify(options.name, change, function(err) {
return unbind(err);
});
};
unbind = function(err) {
var _ref2, _ref3, _ref4;
if (typeof options.log === "function") {
options.log('Unbind connection');
}
if (((_ref2 = options.ldap) != null ? (_ref3 = _ref2.url) != null ? (_ref4 = _ref3.protocol) != null ? _ref4.indexOf('ldap') : void 0 : void 0 : void 0) === 0 && !options.unbind) {
return end(err);
}
return client.unbind(function(e) {
if (e) {
return next(e);
}
return end(err);
});
};
end = function(err) {
return next(err);
};
return connect();
}).on('both', function(err) {
if (updated && !err) {
modified += 1;
}
return next(err);
});
});
}).on('both', function(err) {
return finish(err, modified);
});
});
return result;
};