fix: list routes answer for permitted orgs only; org lists go through the hooks

This commit is contained in:
2026-11-02 00:22:35 +01:00
parent bc05d312a6
commit 12964793cf
17 changed files with 179 additions and 57 deletions
+32
View File
@@ -304,6 +304,38 @@ export async function hasPermissionAny(
return true;
}
/**
* The orgs of a list request the caller may read in, or null once a 401 or 403
* is sent. An unpinned request (no org header) is decided on the no-org
* perimeter and answers []. A pinned one keeps only the orgs that pass, hooks
* included, and is refused only when none does: one refused org neither fails
* the list nor widens it to orgs the caller cannot read.
*/
export async function permittedScope(
db: Pool,
req: FastifyRequest,
reply: FastifyReply,
orgIds: string[],
activity: string,
target: string,
): Promise<string[] | null> {
if (orgIds.length === 0) return await hasPermission(db, req, reply, null, activity, target) ? [] : null;
const user = getUser(req);
if (!user) {
reply.code(401).send({ error: 'Authentication required' });
return null;
}
const apiKeyScope = ((req as unknown) as Record<string, unknown>).apiKeyScope as ApiKeyScope | undefined;
const allowed = scopeAllows(apiKeyScope, activity, target)
? await permittedOrgs(db, user.id, orgIds, activity, target, req)
: [];
if (allowed.length === 0) {
reply.code(403).send({ error: 'Insufficient permissions' });
return null;
}
return allowed;
}
/**
* The one permission decision every helper makes: morbac's answer, narrowed by
* the application's permission hooks (`addPermissionHook`). Use it instead of