import { RouteHarness } from "@/pkg/testutil/route-harness"; import { newId } from "@aigxion/id"; import { PermissionQuery, buildQuery } from "@aigxion/rbac"; import { expect, test } from "vitest"; import { V1KeysVerifyKeyRequest, V1KeysVerifyKeyResponse } from "./v1_keys_verifyKey"; type TestCase = { name: string; roles: { name: string; permissions: string[]; }[]; query: PermissionQuery | undefined; expected: { status: number; valid: boolean; }; }; test.each([ { name: "No Roles and no query", roles: [], query: undefined, expected: { status: 200, valid: true }, }, { name: "No query", roles: [ { name: newId("test"), permissions: [], }, ], query: undefined, expected: { status: 200, valid: true }, }, { name: "Single role, single permission", roles: [ { name: newId("test"), permissions: ["p1"], }, ], query: buildQuery(({ or }) => or("p1")), expected: { status: 200, valid: true }, }, { name: "No roles, but required", roles: [], query: buildQuery(({ or }) => or("p1")), expected: { status: 200, valid: false }, }, { name: "nested of 'and' and 'or'", roles: [ { name: "r1", permissions: ["p1", "p2", "p3"], }, { name: "r2", permissions: ["p1", "p4", "p5"], }, ], query: buildQuery(({ or, and }) => and("p1", or("p2", "p6", and("p4", "p2")))), expected: { status: 200, valid: true }, }, { name: "Simple role check (Pass)", query: buildQuery(() => "p1"), roles: [ { name: "r1", permissions: ["p1", "p2", "p3"], }, { name: "r2", permissions: ["p4", "p5", "p6"] }, ], expected: { status: 200, valid: true }, }, { name: "Simple role check (Fail)", query: buildQuery(() => "p7"), roles: [ { name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"], }, ], expected: { status: 200, valid: false }, }, { name: "'and' of two permissions (Pass)", query: buildQuery(({ and }) => and("p1", "p2")), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "'and' of two permissions (Fail)", query: buildQuery(({ and }) => and("p1", "p7")), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: false }, }, { name: "'or' of two permissions (Pass)", query: buildQuery(({ or }) => or("p1", "p7")), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "or' of two permissions (Fail)", query: buildQuery(({ or }) => or("p7", "p3")), roles: [ { name: "r1", permissions: ["p1"], }, { name: "r2", permissions: ["p2"], }, { name: "r4", permissions: ["p4"], }, { name: "r5", permissions: ["p5"], }, { name: "r6", permissions: ["p6"], }, ], expected: { status: 200, valid: false }, }, { name: "and' and 'or' combination (Pass)", query: buildQuery(({ and, or }) => and("p1", or("p2", "p3"))), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "'and' and 'or' combination (Fail)", query: buildQuery(({ and, or }) => and("p1", or("p7", "p5"))), roles: [ { name: "r1", permissions: ["p2", "p3"], }, { name: "r2", permissions: ["p4"], }, { name: "r3", permissions: ["p5", "p6"], }, ], expected: { status: 200, valid: false }, }, { name: "Deep nesting of 'and'(Pass)", query: buildQuery(({ and }) => and("p1", and("p2", and("p3", "p4")))), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "Deep nesting of 'and' (Fail)", query: buildQuery(({ and }) => and("p1", and("p7", "p3"))), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: false }, }, { name: "Deep nesting of 'or'(Pass)", query: buildQuery(({ or }) => or("p1", or("p2", or("p3", "p4")))), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "Deep nesting of 'or' (Fail)", query: buildQuery(({ or }) => or("p7", or("p5", "p6"))), roles: [ { name: "r1", permissions: ["p1", "p2", "p3"], }, { name: "r2", permissions: ["p4"], }, ], expected: { status: 200, valid: false }, }, { name: "Complex combination of 'and' and 'or'(Pass)", query: buildQuery(({ and, or }) => or(and("p1", "p2"), and("p3", "p4"))), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "Complex combination of 'and' and 'or' (Fail)", query: buildQuery(({ and, or }) => or(and("p1", "p7"), and("p5", "p6"))), roles: [ { name: "r1", permissions: ["p1", "p2", "p3", "p4", "p6"], }, ], expected: { status: 200, valid: false }, }, { name: "Multiple levels of nesting(Pass)", query: buildQuery(({ and, or }) => or(and("p1", or("p2", and("p3", "p4"))), "p5")), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "Multiple levels of nesting (Fail)", query: buildQuery(({ and, or }) => or(and("p1", or("p7", and("p3", "p4"))), "p6")), roles: [{ name: "r1", permissions: ["p2", "p3", "p4", "p5"] }], expected: { status: 200, valid: false }, }, { name: "Complex combination of 'and' and 'or' at different levels (Pass)", query: buildQuery(({ and, or }) => or(and("p1", or("p2", and("p3", "p4"))), and("p5", "p6"))), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "Complex combination of 'and' and 'or' at different levels (Fail)", query: buildQuery(({ and, or }) => or(and("p1", or("p7", and("p3", "p4"))), and("p5", "p7"))), roles: [{ name: "r1", permissions: ["p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: false }, }, { name: "Deep nesting of 'and' and 'or'(Pass)", query: buildQuery(({ and, or }) => and("p1", or("p2", and("p3", or("p4", "p5"))))), roles: [{ name: "r1", permissions: ["p1", "p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: true }, }, { name: "Deep nesting of 'and' and 'or' (Fail)", query: buildQuery(({ and, or }) => and("p1", or("p7", and("p3", or("p4", "p5"))))), roles: [{ name: "r1", permissions: ["p2", "p3", "p4", "p5", "p6"] }], expected: { status: 200, valid: false }, }, ])( "$name", async ({ roles, query, expected }) => { const h = await RouteHarness.init(); const { key } = await h.createKey({ roles }); const res = await h.post({ url: "/v1/keys.verifyKey", headers: { "Content-Type": "application/json", }, body: { key, apiId: h.resources.userApi.id, authorization: query ? { permissions: query, } : undefined, }, }); expect(res.status).toEqual(expected.status); expect( res.body.valid, `key is ${res.body.valid ? "valid" : "not valid"}, received body: ${JSON.stringify( res.body, )}`, ).toBe(expected.valid); }, { timeout: 60_000 }, );