79 lines
2.2 KiB
JavaScript
79 lines
2.2 KiB
JavaScript
// Group membership model: the single source of truth for the OIDC `groups` claim
|
|
// (and, in a later phase, LDAP groups). A user's effective groups = their
|
|
// Saltcorn role exposed as a group (role:<name>) UNION their custom group
|
|
// memberships (group:<name>), so a role and a custom group with the same name
|
|
// never collide.
|
|
|
|
const db = require("@saltcorn/data/db");
|
|
|
|
const { TABLE_GROUPS, TABLE_GROUP_MEMBERS } = require("./constants");
|
|
|
|
const ROLE_PREFIX = "role:";
|
|
const GROUP_PREFIX = "group:";
|
|
|
|
|
|
const listGroups = async () => {
|
|
return await db.select(TABLE_GROUPS, {}, { orderBy: "name" });
|
|
};
|
|
|
|
|
|
const createGroup = async (name, description) => {
|
|
return await db.insert(TABLE_GROUPS, {
|
|
name: name,
|
|
description: description || null,
|
|
created_at: new Date().toISOString()
|
|
});
|
|
};
|
|
|
|
|
|
const deleteGroup = async (id) => {
|
|
await db.deleteWhere(TABLE_GROUP_MEMBERS, { group_id: id });
|
|
await db.deleteWhere(TABLE_GROUPS, { id: id });
|
|
};
|
|
|
|
|
|
const membersOf = async (groupId) => {
|
|
return await db.select(TABLE_GROUP_MEMBERS, { group_id: groupId });
|
|
};
|
|
|
|
|
|
const addMember = async (groupId, userId) => {
|
|
const existing = await db.selectMaybeOne(TABLE_GROUP_MEMBERS, { group_id: groupId, user_id: userId });
|
|
if (existing) {
|
|
return;
|
|
}
|
|
await db.insert(TABLE_GROUP_MEMBERS, { group_id: groupId, user_id: userId }, { noid: true });
|
|
};
|
|
|
|
|
|
const removeMember = async (groupId, userId) => {
|
|
await db.deleteWhere(TABLE_GROUP_MEMBERS, { group_id: groupId, user_id: userId });
|
|
};
|
|
|
|
|
|
const effectiveGroups = async (user) => {
|
|
const out = [];
|
|
const role = await db.selectMaybeOne("_sc_roles", { id: user.role_id });
|
|
if (role && role.role) {
|
|
out.push(ROLE_PREFIX + role.role);
|
|
}
|
|
const members = await db.select(TABLE_GROUP_MEMBERS, { user_id: user.id });
|
|
for (const member of members) {
|
|
const group = await db.selectMaybeOne(TABLE_GROUPS, { id: member.group_id });
|
|
if (group && group.name) {
|
|
out.push(GROUP_PREFIX + group.name);
|
|
}
|
|
}
|
|
return out;
|
|
};
|
|
|
|
|
|
module.exports = {
|
|
listGroups,
|
|
createGroup,
|
|
deleteGroup,
|
|
membersOf,
|
|
addMember,
|
|
removeMember,
|
|
effectiveGroups
|
|
};
|