improve ldap wrapper return values
This commit is contained in:
parent
164f937b0a
commit
444ed847cd
206
src/ldap.js
206
src/ldap.js
@ -17,9 +17,10 @@ export default class LDAP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async addUser (bind, uid, attrs) {
|
async addUser (bind, uid, attrs) {
|
||||||
const bindResult = await this.#client.bind(bind.dn, bind.password);
|
const logger = new LDAP_MULTIOP_LOGGER(`add ${uid}`);
|
||||||
if (!bindResult.ok) {
|
await this.#client.bind(bind.dn, bind.password, logger);
|
||||||
return bindResult;
|
if (!logger.ok) {
|
||||||
|
return logger;
|
||||||
}
|
}
|
||||||
const userDN = `uid=${uid},${this.#peopledn}`;
|
const userDN = `uid=${uid},${this.#peopledn}`;
|
||||||
const entry = {
|
const entry = {
|
||||||
@ -29,8 +30,8 @@ export default class LDAP {
|
|||||||
uid,
|
uid,
|
||||||
userPassword: attrs.userPassword
|
userPassword: attrs.userPassword
|
||||||
};
|
};
|
||||||
const addResult = await this.#client.add(userDN, entry);
|
await this.#client.add(userDN, entry, logger);
|
||||||
return { op: `add ${uid}`, ok: addResult.ok, error: addResult.error };
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUser (bind, uid) {
|
async getUser (bind, uid) {
|
||||||
@ -42,11 +43,11 @@ export default class LDAP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async modUser (bind, uid, newAttrs) {
|
async modUser (bind, uid, newAttrs) {
|
||||||
const bindResult = await this.#client.bind(bind.dn, bind.password);
|
const logger = new LDAP_MULTIOP_LOGGER(`modify ${uid}`);
|
||||||
if (!bindResult.ok) {
|
await this.#client.bind(bind.dn, bind.password, logger);
|
||||||
return bindResult;
|
if (!logger.ok) {
|
||||||
|
return logger;
|
||||||
}
|
}
|
||||||
const subops = [bindResult];
|
|
||||||
for (const attr of ["cn", "sn", "userPassword"]) {
|
for (const attr of ["cn", "sn", "userPassword"]) {
|
||||||
if (attr in newAttrs) {
|
if (attr in newAttrs) {
|
||||||
const change = new ldap.Change({
|
const change = new ldap.Change({
|
||||||
@ -56,27 +57,27 @@ export default class LDAP {
|
|||||||
values: [newAttrs[attr]]
|
values: [newAttrs[attr]]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
subops.push(await this.#client.modify(`uid=${uid},${this.#peopledn}`, change));
|
await this.#client.modify(`uid=${uid},${this.#peopledn}`, change, logger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { op: `modify ${uid}`, ok: !subops.some((e) => !e.ok), error: subops.find((e) => !e.ok) || null, subops };
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
async delUser (bind, uid) {
|
async delUser (bind, uid) {
|
||||||
const bindResult = await this.#client.bind(bind.dn, bind.password);
|
const logger = new LDAP_MULTIOP_LOGGER(`del ${uid}`);
|
||||||
if (!bindResult.ok) {
|
await this.#client.bind(bind.dn, bind.password, logger);
|
||||||
return bindResult;
|
if (!logger.ok) {
|
||||||
|
return logger;
|
||||||
}
|
}
|
||||||
const userDN = `uid=${uid},${this.#peopledn}`;
|
const userDN = `uid=${uid},${this.#peopledn}`;
|
||||||
const delResult = await this.#client.del(userDN);
|
await this.#client.del(userDN, logger);
|
||||||
const groups = await this.#client.search(this.#groupsdn, {
|
const groups = await this.#client.search(this.#groupsdn, {
|
||||||
scope: "one",
|
scope: "one",
|
||||||
filter: `(member=uid=${uid},${this.#peopledn})`
|
filter: `(member=uid=${uid},${this.#peopledn})`
|
||||||
});
|
}, logger);
|
||||||
if (!groups.ok) {
|
if (!logger.ok) {
|
||||||
return { op: `del ${uid}`, ok: groups.ok, error: groups.error, subops: [bindResult, delResult, groups]}
|
return logger;
|
||||||
}
|
}
|
||||||
const groupsubops = [];
|
|
||||||
for (const element of groups.entries) {
|
for (const element of groups.entries) {
|
||||||
let change = null;
|
let change = null;
|
||||||
if (element.attributes.member.length === 1) {
|
if (element.attributes.member.length === 1) {
|
||||||
@ -97,16 +98,16 @@ export default class LDAP {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const delResult = await this.#client.modify(element.dn, change);
|
await this.#client.modify(element.dn, change, logger);
|
||||||
groupsubops.push(delResult);
|
|
||||||
}
|
}
|
||||||
return { op: `del ${uid}`, ok: delResult.ok, error: delResult.error, subops: [bindResult, delResult, groups].concat(groupsubops) };
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
async addGroup (bind, gid, attrs) {
|
async addGroup (bind, gid, attrs) {
|
||||||
const bindResult = await this.#client.bind(bind.dn, bind.password);
|
const logger = new LDAP_MULTIOP_LOGGER(`add ${gid}`);
|
||||||
if (!bindResult.ok) {
|
await this.#client.bind(bind.dn, bind.password, logger);
|
||||||
return bindResult;
|
if (!logger.ok) {
|
||||||
|
return logger;
|
||||||
}
|
}
|
||||||
const groupDN = `cn=${gid},${this.#groupsdn}`;
|
const groupDN = `cn=${gid},${this.#groupsdn}`;
|
||||||
const entry = {
|
const entry = {
|
||||||
@ -114,8 +115,8 @@ export default class LDAP {
|
|||||||
member: attrs && attrs.member ? attrs.member : "",
|
member: attrs && attrs.member ? attrs.member : "",
|
||||||
cn: gid
|
cn: gid
|
||||||
};
|
};
|
||||||
const addResult = await this.#client.add(groupDN, entry);
|
await this.#client.add(groupDN, entry, logger);
|
||||||
return { op: `add ${gid}`, ok: addResult.ok, error: addResult.error, subops: [bindResult, addResult] };
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGroup (bind, gid) {
|
async getGroup (bind, gid) {
|
||||||
@ -127,22 +128,24 @@ export default class LDAP {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async delGroup (bind, gid) {
|
async delGroup (bind, gid) {
|
||||||
const bindResult = await this.#client.bind(bind.dn, bind.password);
|
const logger = new LDAP_MULTIOP_LOGGER(`del ${gid}`);
|
||||||
if (!bindResult.ok) {
|
await this.#client.bind(bind.dn, bind.password, logger);
|
||||||
return bindResult;
|
if (!logger.ok) {
|
||||||
|
return logger;
|
||||||
}
|
}
|
||||||
const groupDN = `cn=${gid},${this.#groupsdn}`;
|
const groupDN = `cn=${gid},${this.#groupsdn}`;
|
||||||
const delResult = await this.#client.del(groupDN);
|
await this.#client.del(groupDN, logger);
|
||||||
return { op: `del ${gid}`, ok: delResult.ok, error: delResult.error, subops: [bindResult, delResult] };
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
async addUserToGroup (bind, uid, gid) {
|
async addUserToGroup (bind, uid, gid) {
|
||||||
const bindResult = await this.#client.bind(bind.dn, bind.password);
|
const logger = new LDAP_MULTIOP_LOGGER(`add ${uid} to ${gid}`);
|
||||||
if (!bindResult.ok) {
|
await this.#client.bind(bind.dn, bind.password, logger);
|
||||||
return bindResult;
|
if (!logger.ok) {
|
||||||
|
return logger;
|
||||||
}
|
}
|
||||||
const checkGroupEntry = await this.#client.search(`cn=${gid},${this.#groupsdn}`, {});
|
const checkGroupEntry = await this.#client.search(`cn=${gid},${this.#groupsdn}`, {}, logger);
|
||||||
if (checkGroupEntry.ok) {
|
if (logger.ok) {
|
||||||
// add the user
|
// add the user
|
||||||
const change = new ldap.Change({
|
const change = new ldap.Change({
|
||||||
operation: "add",
|
operation: "add",
|
||||||
@ -151,9 +154,9 @@ export default class LDAP {
|
|||||||
values: [`uid=${uid},${this.#peopledn}`]
|
values: [`uid=${uid},${this.#peopledn}`]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const addResult = await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change);
|
await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger);
|
||||||
if (!addResult.ok) {
|
if (!logger.ok) {
|
||||||
return addResult;
|
return logger;
|
||||||
}
|
}
|
||||||
// check if there is a blank entry in the group
|
// check if there is a blank entry in the group
|
||||||
const groupEntry = checkGroupEntry.entries[0];
|
const groupEntry = checkGroupEntry.entries[0];
|
||||||
@ -166,20 +169,20 @@ export default class LDAP {
|
|||||||
values: [""]
|
values: [""]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const fixResult = await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change);
|
await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger);
|
||||||
return { op: `add ${uid} to ${gid}`, ok: addResult.ok && fixResult.ok, error: addResult.error ? addResult.error : fixResult.error, subops: [bindResult, addResult, fixResult] };
|
|
||||||
}
|
}
|
||||||
return { op: `add ${uid} to ${gid}`, ok: true, error: null, subops: [bindResult, addResult] };
|
return logger;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return { op: `add ${uid} to ${gid}`, ok: false, error: `${gid} does not exist`, subops: [bindResult] };
|
return logger;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async delUserFromGroup (bind, uid, gid) {
|
async delUserFromGroup (bind, uid, gid) {
|
||||||
const bindResult = await this.#client.bind(bind.dn, bind.password);
|
const logger = new LDAP_MULTIOP_LOGGER(`del ${uid} from ${gid}`);
|
||||||
if (!bindResult.ok) {
|
await this.#client.bind(bind.dn, bind.password, logger);
|
||||||
return bindResult;
|
if (!logger.ok) {
|
||||||
|
return logger;
|
||||||
}
|
}
|
||||||
const change = new ldap.Change({
|
const change = new ldap.Change({
|
||||||
operation: "delete",
|
operation: "delete",
|
||||||
@ -188,12 +191,30 @@ export default class LDAP {
|
|||||||
values: [`uid=${uid},${this.#peopledn}`]
|
values: [`uid=${uid},${this.#peopledn}`]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const delResult = await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change);
|
await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger);
|
||||||
return { op: `del ${uid} from ${gid}`, ok: delResult.ok, error: delResult.error, subops: [bindResult, delResult] };
|
return logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
async search (base, opts) {
|
async search (branch, opts) {
|
||||||
return await this.#client.search(base, opts);
|
return await this.#client.search(`${branch},${this.#basedn}`, opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LDAP_MULTIOP_LOGGER {
|
||||||
|
op = null;
|
||||||
|
ok = true;
|
||||||
|
error = [];
|
||||||
|
subops = [];
|
||||||
|
constructor (op) {
|
||||||
|
this.op = op;
|
||||||
|
}
|
||||||
|
|
||||||
|
push (op) {
|
||||||
|
if (!op.ok) {
|
||||||
|
this.ok = false;
|
||||||
|
this.error.push(op.error);
|
||||||
|
}
|
||||||
|
this.subops.push(op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,86 +230,95 @@ class LDAPJS_CLIENT_ASYNC_WRAPPER {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bind (dn, password) {
|
#parseError (err) {
|
||||||
|
if (err) {
|
||||||
|
return {code: err.code, name: err.name, message: err.message};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bind (dn, password, logger = null) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.#client.bind(dn, password, (err) => {
|
this.#client.bind(dn, password, (err) => {
|
||||||
if (err) {
|
const result = { op: `bind ${dn}`, ok: err === null, error: this.#parseError(err) };
|
||||||
resolve({ op: `bind ${dn}`, ok: false, error: err });
|
if (logger) {
|
||||||
}
|
logger.push(result);
|
||||||
else {
|
|
||||||
resolve({ op: `bind ${dn}`, ok: true, error: null });
|
|
||||||
}
|
}
|
||||||
|
resolve(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add (dn, entry) {
|
add (dn, entry, logger = null) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.#client.add(dn, entry, (err) => {
|
this.#client.add(dn, entry, (err) => {
|
||||||
if (err) {
|
const result = { op: `add ${dn}`, ok: err === null, error: this.#parseError(err) };
|
||||||
resolve({ op: `add ${dn}`, ok: false, error: err });
|
if (logger) {
|
||||||
}
|
logger.push(result);
|
||||||
else {
|
|
||||||
resolve({ op: `add ${dn}`, ok: true, error: null });
|
|
||||||
}
|
}
|
||||||
|
resolve(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
search (base, options) {
|
search (base, options, logger = null) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.#client.search(base, options, (err, res) => {
|
this.#client.search(base, options, (err, res) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return resolve({ op: `search ${base}`, ok: false, error: err });
|
return resolve({ op: `search ${base}`, ok: false, error: err });
|
||||||
}
|
}
|
||||||
const results = { op: `search ${base}`, ok: false, error: null, status: 1, message: "", entries: [] };
|
const result = { op: `search ${base}`, ok: false, error: null, entries: [] };
|
||||||
res.on("searchRequest", (searchRequest) => { });
|
res.on("searchRequest", (searchRequest) => { });
|
||||||
res.on("searchEntry", (entry) => {
|
res.on("searchEntry", (entry) => {
|
||||||
const attributes = {};
|
const attributes = {};
|
||||||
for (const element of entry.pojo.attributes) {
|
for (const element of entry.pojo.attributes) {
|
||||||
attributes[element.type] = element.values;
|
attributes[element.type] = element.values;
|
||||||
}
|
}
|
||||||
results.entries.push({ dn: entry.pojo.objectName, attributes });
|
result.entries.push({ dn: entry.pojo.objectName, attributes });
|
||||||
});
|
});
|
||||||
res.on("searchReference", (referral) => { });
|
res.on("searchReference", (referral) => { });
|
||||||
res.on("error", (error) => {
|
res.on("error", (err) => {
|
||||||
results.ok = error.status === 0;
|
result.ok = false;
|
||||||
results.status = error.status;
|
result.error = this.#parseError(err);
|
||||||
results.message = error.message;
|
if (logger) {
|
||||||
resolve(results);
|
logger.push(result);
|
||||||
|
}
|
||||||
|
resolve(result);
|
||||||
});
|
});
|
||||||
res.on("end", (result) => {
|
res.on("end", (res) => {
|
||||||
results.ok = result.status === 0;
|
result.ok = true;
|
||||||
results.status = result.status;
|
result.error = null;
|
||||||
results.message = result.message;
|
if (logger) {
|
||||||
resolve(results);
|
logger.push(result);
|
||||||
|
}
|
||||||
|
resolve(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
modify (name, changes) {
|
modify (name, changes, logger = null) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.#client.modify(name, changes, (err) => {
|
this.#client.modify(name, changes, (err) => {
|
||||||
if (err) {
|
const result = { op: `modify ${name} ${changes.operation} ${changes.modification.type}`, ok: err === null, error: this.#parseError(err) };
|
||||||
resolve({ op: `modify ${name} ${changes.operation} ${changes.modification.type}`, ok: false, error: err });
|
if (logger) {
|
||||||
}
|
logger.push(result);
|
||||||
else {
|
|
||||||
resolve({ op: `modify ${name} ${changes.operation} ${changes.modification.type}`, ok: true, error: null });
|
|
||||||
}
|
}
|
||||||
|
resolve(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
del (dn) {
|
del (dn, logger = null) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.#client.del(dn, (err) => {
|
this.#client.del(dn, (err) => {
|
||||||
if (err) {
|
const result = { op: `del ${dn}`, ok: err === null, error: this.#parseError(err) };
|
||||||
resolve({ op: `del ${dn}`, ok: false, error: err });
|
if (logger) {
|
||||||
}
|
logger.push(result);
|
||||||
else {
|
|
||||||
resolve({ op: `del ${dn}`, ok: true, error: null });
|
|
||||||
}
|
}
|
||||||
|
resolve(result);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user