implement group member endpoints

This commit is contained in:
Arthur Lu 2023-12-21 01:48:46 +00:00
parent b63cce671c
commit 595d18b72f
2 changed files with 90 additions and 94 deletions

View File

@ -25,9 +25,9 @@ export default class LDAP {
async addUser (bind, uid, attrs) { async addUser (bind, uid, attrs) {
const logger = new LDAP_MULTIOP_LOGGER(`add ${uid}`); const logger = new LDAP_MULTIOP_LOGGER(`add ${uid}`);
await this.#client.bind(bind.dn, bind.password, logger); const bindResult = await this.#client.bind(bind.dn, bind.password, logger);
if (!logger.ok) { if (!bindResult.ok) {
return logger; return bindResult;
} }
const userDN = `uid=${uid},${this.#peopledn}`; const userDN = `uid=${uid},${this.#peopledn}`;
if (!attrs.cn || !attrs.sn || !attrs.userPassword) { if (!attrs.cn || !attrs.sn || !attrs.userPassword) {
@ -63,9 +63,9 @@ export default class LDAP {
async modUser (bind, uid, newAttrs) { async modUser (bind, uid, newAttrs) {
const logger = new LDAP_MULTIOP_LOGGER(`modify ${uid}`); const logger = new LDAP_MULTIOP_LOGGER(`modify ${uid}`);
await this.#client.bind(bind.dn, bind.password, logger); const bindResult = await this.#client.bind(bind.dn, bind.password, logger);
if (!logger.ok) { if (!bindResult.ok) {
return logger; return bindResult;
} }
for (const attr of ["cn", "sn", "userPassword"]) { for (const attr of ["cn", "sn", "userPassword"]) {
if (attr in newAttrs && newAttrs[attr]) { // attr should exist and not be undefined or null if (attr in newAttrs && newAttrs[attr]) { // attr should exist and not be undefined or null
@ -84,9 +84,9 @@ export default class LDAP {
async delUser (bind, uid) { async delUser (bind, uid) {
const logger = new LDAP_MULTIOP_LOGGER(`del ${uid}`); const logger = new LDAP_MULTIOP_LOGGER(`del ${uid}`);
await this.#client.bind(bind.dn, bind.password, logger); const bindResult = await this.#client.bind(bind.dn, bind.password, logger);
if (!logger.ok) { if (!bindResult.ok) {
return logger; return bindResult;
} }
const userDN = `uid=${uid},${this.#peopledn}`; const userDN = `uid=${uid},${this.#peopledn}`;
await this.#client.del(userDN, logger); await this.#client.del(userDN, logger);
@ -98,40 +98,28 @@ export default class LDAP {
return logger; return logger;
} }
for (const element of groups.entries) { for (const element of groups.entries) {
let change = null; const change = {
if (element.attributes.member.length === 1) {
change = new ldap.Change({
operation: "replace",
modification: {
type: "member",
values: [""]
}
});
}
else {
change = new ldap.Change({
operation: "delete", operation: "delete",
modification: { modification: {
type: "member", type: "member",
values: [`uid=${uid},${this.#peopledn}`] values: [`uid=${uid},${this.#peopledn}`]
} }
}); };
}
await this.#client.modify(element.dn, change, logger); await this.#client.modify(element.dn, change, logger);
} }
return logger; return logger;
} }
async addGroup (bind, gid, attrs) { async addGroup (bind, gid) {
const logger = new LDAP_MULTIOP_LOGGER(`add ${gid}`); const logger = new LDAP_MULTIOP_LOGGER(`add ${gid}`);
await this.#client.bind(bind.dn, bind.password, logger); const bindResult = await this.#client.bind(bind.dn, bind.password, logger);
if (!logger.ok) { if (!bindResult.ok) {
return logger; return bindResult;
} }
const groupDN = `cn=${gid},${this.#groupsdn}`; const groupDN = `cn=${gid},${this.#groupsdn}`;
const entry = { const entry = {
objectClass: "groupOfNames", objectClass: "groupOfNames",
member: attrs && attrs.member ? attrs.member : "", member: "",
cn: gid cn: gid
}; };
await this.#client.add(groupDN, entry, logger); await this.#client.add(groupDN, entry, logger);
@ -143,14 +131,16 @@ export default class LDAP {
if (!bindResult.ok) { if (!bindResult.ok) {
return bindResult; return bindResult;
} }
return await this.#client.search(`cn=${gid},${this.#groupsdn}`, {}); const result = await this.#client.search(`cn=${gid},${this.#groupsdn}`, {});
result.group = result.entries[0]; // assume there should only be 1 entry
return result;
} }
async delGroup (bind, gid) { async delGroup (bind, gid) {
const logger = new LDAP_MULTIOP_LOGGER(`del ${gid}`); const logger = new LDAP_MULTIOP_LOGGER(`del ${gid}`);
await this.#client.bind(bind.dn, bind.password, logger); const bindResult = await this.#client.bind(bind.dn, bind.password, logger);
if (!logger.ok) { if (!bindResult.ok) {
return logger; return bindResult;
} }
const groupDN = `cn=${gid},${this.#groupsdn}`; const groupDN = `cn=${gid},${this.#groupsdn}`;
await this.#client.del(groupDN, logger); await this.#client.del(groupDN, logger);
@ -159,12 +149,10 @@ export default class LDAP {
async addUserToGroup (bind, uid, gid) { async addUserToGroup (bind, uid, gid) {
const logger = new LDAP_MULTIOP_LOGGER(`add ${uid} to ${gid}`); const logger = new LDAP_MULTIOP_LOGGER(`add ${uid} to ${gid}`);
await this.#client.bind(bind.dn, bind.password, logger); const bindResult = await this.#client.bind(bind.dn, bind.password, logger);
if (!logger.ok) { if (!bindResult.ok) {
return logger; return bindResult;
} }
const checkGroupEntry = await this.#client.search(`cn=${gid},${this.#groupsdn}`, {}, logger);
if (logger.ok) {
// add the user // add the user
const change = new ldap.Change({ const change = new ldap.Change({
operation: "add", operation: "add",
@ -174,34 +162,14 @@ export default class LDAP {
} }
}); });
await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger); await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger);
if (!logger.ok) {
return logger; return logger;
} }
// check if there is a blank entry in the group
const groupEntry = checkGroupEntry.entries[0];
if (groupEntry.attributes.member.includes("")) {
// delete the blank user
const change = new ldap.Change({
operation: "delete",
modification: {
type: "member",
values: [""]
}
});
await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger);
}
return logger;
}
else {
return logger;
}
}
async delUserFromGroup (bind, uid, gid) { async delUserFromGroup (bind, uid, gid) {
const logger = new LDAP_MULTIOP_LOGGER(`del ${uid} from ${gid}`); const logger = new LDAP_MULTIOP_LOGGER(`del ${uid} from ${gid}`);
await this.#client.bind(bind.dn, bind.password, logger); const bindResult = await this.#client.bind(bind.dn, bind.password, logger);
if (!logger.ok) { if (!bindResult.ok) {
return logger; return bindResult;
} }
const change = new ldap.Change({ const change = new ldap.Change({
operation: "delete", operation: "delete",
@ -213,10 +181,6 @@ export default class LDAP {
await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger); await this.#client.modify(`cn=${gid},${this.#groupsdn}`, change, logger);
return logger; return logger;
} }
async search (branch, opts) {
return await this.#client.search(`${branch},${this.#basedn}`, opts);
}
} }
class LDAP_MULTIOP_LOGGER { class LDAP_MULTIOP_LOGGER {

View File

@ -151,12 +151,12 @@ app.post("/groups/:groupid", async (req, res) => {
const params = { const params = {
groupid: req.params.groupid, groupid: req.params.groupid,
bind: ldap.createUserBind(req.body.binduser, req.body.bindpass) bind: ldap.createUserBind(req.body.binduser, req.body.bindpass)
} };
const result = await ldap.addGroup(params.bind, groupid); const result = await ldap.addGroup(params.bind, params.groupid);
res.send({ res.send({
ok: result.ok, ok: result.ok,
error: result.error error: result.error
}) });
}); });
/** /**
@ -170,12 +170,21 @@ app.get("/groups/:groupid", async (req, res) => {
const params = { const params = {
groupid: req.params.groupid, groupid: req.params.groupid,
bind: ldap.createUserBind(req.body.binduser, req.body.bindpass) bind: ldap.createUserBind(req.body.binduser, req.body.bindpass)
};
const result = await ldap.getGroup(params.bind, params.groupid);
if (result.ok) {
res.send({
ok: result.ok,
error: result.error,
group: result.group
});
} }
const result = await ldap.getGroup(params.bind, groupid); else {
res.send({ res.send({
ok: result.ok, ok: result.ok,
error: result.error error: result.error
}) });
}
}); });
/** /**
@ -189,28 +198,51 @@ app.delete("/groups/:groupid", async (req, res) => {
const params = { const params = {
groupid: req.params.groupid, groupid: req.params.groupid,
bind: ldap.createUserBind(req.body.binduser, req.body.bindpass) bind: ldap.createUserBind(req.body.binduser, req.body.bindpass)
} };
const result = await ldap.delGroup(params.bind, groupid); const result = await ldap.delGroup(params.bind, params.groupid);
res.send({ res.send({
ok: result.ok, ok: result.ok,
error: result.error error: result.error
}) });
}); });
/** /**
* GET - get group members only * POST - add a member to the group
* request: * request:
* - groupid: group id * - groupid: group id
* - userid: user id
* - binduser: bind user id * - binduser: bind user id
* - bindpass: bind user password * - bindpass: bind user password
*/ */
app.get("/groups/:groupid/members", async (req, res) => {}); app.post("/groups/:groupid/members/:userid", async (req, res) => {
const params = {
groupid: req.params.groupid,
userid: req.params.userid,
bind: ldap.createUserBind(req.body.binduser, req.body.bindpass)
};
const result = await ldap.addUserToGroup(params.bind, params.userid, params.groupid);
res.send({
ok: result.ok,
error: result.error
});
});
/** /**
* POST - add member(s) to group * DELETE - remove a member from the group
* - groupid: group id * - groupid: group id
* - members: new list of members * - userid: user id
* - binduser: bind user id * - binduser: bind user id
* - bindpass: bind user password * - bindpass: bind user password
*/ */
app.post("/groups/:groupid/members", async (req, res) => {}); app.delete("/groups/:groupid/members/:userid", async (req, res) => {
const params = {
groupid: req.params.groupid,
userid: req.params.userid,
bind: ldap.createUserBind(req.body.binduser, req.body.bindpass)
};
const result = await ldap.delUserFromGroup(params.bind, params.userid, params.groupid);
res.send({
ok: result.ok,
error: result.error
});
});