@opengis/fastify-table
Version:
core-plugins
99 lines (98 loc) • 4.05 kB
JavaScript
import pgClients from "../../pg/pgClients.js";
import getMeta from "../../pg/funcs/getMeta.js";
import getTemplate from "../../table/funcs/getTemplate.js";
import applyHook from "../../hook/applyHook.js";
const allActions = ["view", "edit", "add", "del"];
const q = `select a.route_id as id, d.actions as user_roles, d.actions as role_actions, coalesce(b.actions, array['view']) as interface_actions, b.scope, c.role_id
from admin.routes a
left join admin.role_access b on
a.route_id=b.route_id
left join admin.roles c on
b.role_id=c.role_id
and c.enabled
left join admin.user_roles d on
c.role_id=d.role_id
and ( case when
d.expiration is not null
then d.expiration > CURRENT_DATE
else 1=1
end )
where $1 in (a.route_id, a.alias, a.table_name) and $2 in (b.user_uid, d.user_uid)`;
/**
* @param {Array} user_roles.actions Actions - user actions <> group actions
* @param {Array} role_access.actions Actions - user actions = group actions
* @param {String} body.actions Actions from table template
* @param {String} table Table name / Interface alias
* @param {Object} user User object
* @param {String} user.uid User ID
* @param {String} user.user_type User type
* @returns { scope: String, roles: String[], actions: String[], query: String }
*/
export default async function getAccess({ table, form, user = {} }, pg = pgClients.client) {
if (!table)
return null;
const hookData = await applyHook("getAccess", { table, user, pg });
if (hookData)
return hookData;
const { uid, user_type: userType = "regular" } = user;
if (userType === "superadmin") {
return { actions: allActions, query: "1=1" };
}
if (userType === "viewer") {
return { actions: ["view"], query: "1=1" };
}
const body = await getTemplate("table", table);
const tableActions = !body && form
? allActions // if db table and form => full access (token)
: ["view"].concat(body?.actions || body?.action_default || []);
if (userType === "admin") {
if (!(body?.actions || body?.action_default) && (body?.form || form)) {
return { actions: allActions, query: "1=1" };
}
return { actions: tableActions, query: "1=1" };
}
if (body?.public || body?.access === "public") {
return { actions: tableActions, query: "1=1" };
}
if (body?.access === "user" && uid) {
// subquery handled by template
if (body?.query?.includes?.("{{uid}}")) {
return { actions: tableActions, query: "1=1" };
}
const authorColumn = await getMeta({
pg,
table: body?.table || table,
}).then((el) => el?.columns?.find((col) => ["uid", "created_by"].includes(col.name))?.name);
if (!authorColumn) {
return { actions: [], query: "false" };
}
return { actions: tableActions, query: `${authorColumn}='${uid}'` };
}
if (!uid) {
return { actions: [], query: "false" };
}
const userAccess = pg?.pk?.["admin.routes"] &&
pg.pk?.["admin.role_access"] &&
pg.pk?.["admin.roles"] &&
pg.pk?.["admin.user_roles"]
? await pg.query(q, [table, uid]).then((el) => ({
...(el.rows[0] || {}),
roles: el.rows?.map?.((row) => row.role_id) || [],
actions: el.rows?.map?.((row) => row.actions).flat() || [],
interface_actions: el.rows?.map?.((row) => row.interface_actions).flat() || [],
}))
: {};
const query = userAccess?.scope === "my" ? `uid='${uid}'` : "1=1";
const actions = userAccess?.interface_actions
?.filter((el) => userAccess?.role_actions?.length
? userAccess?.role_actions.includes(el)
: true)
?.filter((el) => tableActions.includes(el))
?.filter?.((el, idx, arr) => arr.indexOf(el) === idx);
return {
scope: userAccess?.scope,
roles: userAccess?.roles,
actions,
query,
};
}