Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 55x 55x 55x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 7x | import {type IMeta, handler} from '@feasibleone/blong';
import * as model from './accessModel.ts';
type KnexQb = any;
/**
* `access.dropdown.list` — the auto-bound per-table dropdowns plus the
* `access.crudEntity` list backing the capability action pivot, and the two ACL
* lists used by the ACL pages.
*
* The base dropdowns (`access.user`, `access.role`, `access.capability`,
* `access.action`, …) come from `super.exec` (the knex adapter's generic
* dropdown handler). The `access.crudEntity` dropdown derives the distinct
* `access<Entity>` prefixes of every standard-CRUD action registered in
* `access_action`, so the capability pivot can list one row per entity with
* the CRUD verbs (`find`/`get`/`add`/`edit`/`remove`) as columns.
*
* `access.aclPrincipal` / `access.aclTarget` list the graph resources an ACL
* rule can name, labelled `<short type>: <name>` — principals are the users,
* roles, units and capabilities the rules hang off; targets are the records and
* scopes they point at.
*/
export default handler(() => ({
async accessDropdownList(
params: Record<string, unknown>,
$meta: IMeta,
): Promise<Record<string, unknown>> {
const qb: KnexQb = this.config?.context?.queryBuilder;
const base = (await super.exec({}, $meta)) as Record<string, unknown>;
if (!qb) return base;
const rows = (await qb('access_action as a')
.join('core_resource as r', 'r.resourceId', 'a.actionId')
.select('r.resourceName as actionName')) as Array<{actionName: string}>;
const entities = new Set<string>();
for (const row of rows) {
const parts = model.crudActionParts(row.actionName ?? '');
if (parts) entities.add(parts.entity);
}
return {
...base,
'access.crudEntity': [...entities].sort().map(name => ({value: name, label: name})),
'access.aclPrincipal': await model.resourceOptions(qb, [
'access.user',
'access.role',
'party.unit',
'access.capability',
]),
'access.aclTarget': await model.resourceOptions(qb, [
'party.unit',
'party.organization',
'party.person',
'access.role',
'access.user',
// The wildcard rule target: a rule anchored on it matches every
// record (`targetKind: 'all'`).
'access.any',
]),
};
},
}));
|