diff --git a/src/common/policies/events.ts b/src/common/policies/events.ts index 93733eba..e31ca752 100644 --- a/src/common/policies/events.ts +++ b/src/common/policies/events.ts @@ -7,6 +7,13 @@ export const hostRestrictionPolicy = createPolicy( "EventsHostRestrictionPolicy", z.object({ host: z.array(z.enum(OrganizationList)) }), (request: FastifyRequest & { username?: string }, params) => { + if (request.method === "GET") { + return { + allowed: true, + message: "Skipped as route not in scope.", + cacheKey: null, + }; + } if (!request.url.startsWith("/api/v1/events")) { return { allowed: true, diff --git a/tests/unit/policies/EventsHostRestrictionPolicy.test.ts b/tests/unit/policies/EventsHostRestrictionPolicy.test.ts new file mode 100644 index 00000000..df0ba460 --- /dev/null +++ b/tests/unit/policies/EventsHostRestrictionPolicy.test.ts @@ -0,0 +1,119 @@ +import { describe, expect, test, vi } from "vitest"; +import { type FastifyRequest } from "fastify"; +import { evaluateAllRequestPolicies } from "../../../src/api/plugins/evaluatePolicies.js"; +import init from "../../../src/api/index.js"; + +describe("Policy Evalulator Tests", async () => { + test("Policy evalulation is true for non-event routes.", async () => { + const mockRequest = { + url: "/api/v1/healthz", + body: { + host: "ACM", + featured: true, + }, + log: { + info: vi.fn(), + }, + username: "test@acm.illinois.edu", + policyRestrictions: [], + } as unknown as FastifyRequest; + const response = await evaluateAllRequestPolicies(mockRequest); + expect(response).toBe(true); + }) + test("Policy evalulation skips GET routes.", async () => { + const mockRequest = { + url: "/api/v1/events/123", + method: "GET", + body: { + host: "ACM", + featured: true, + }, + log: { + info: vi.fn(), + }, + username: "test@acm.illinois.edu", + policyRestrictions: [{ + "name": "EventsHostRestrictionPolicy", + "params": { + "host": [ + "NONE" + ] + } + }], + } as unknown as FastifyRequest; + const response = await evaluateAllRequestPolicies(mockRequest); + expect(response).toBe(true); + }) + test("Policy evalulation does not permit featured events even for the correct host.", async () => { + const mockRequest = { + url: "/api/v1/events", + method: "POST", + body: { + host: "ACM", + featured: true, + }, + log: { + info: vi.fn(), + }, + username: "test@acm.illinois.edu", + policyRestrictions: [{ + "name": "EventsHostRestrictionPolicy", + "params": { + "host": [ + "ACM" + ] + } + }], + } as unknown as FastifyRequest; + const response = await evaluateAllRequestPolicies(mockRequest); + expect(response).toBe(`Denied by policy "EventsHostRestrictionPolicy". Event must not be featured.`) + }) + test("Policy evalulation denies incorrect host.", async () => { + const mockRequest = { + url: "/api/v1/events", + method: "DELETE", + body: { + host: "ACM", + featured: false, + }, + log: { + info: vi.fn(), + }, + username: "test@acm.illinois.edu", + policyRestrictions: [{ + "name": "EventsHostRestrictionPolicy", + "params": { + "host": [ + "Infrastructure Committee" + ] + } + }], + } as unknown as FastifyRequest; + const response = await evaluateAllRequestPolicies(mockRequest); + expect(response).toBe(`Denied by policy "EventsHostRestrictionPolicy". Host must be one of: Infrastructure Committee.`); + }) + test("Policy evalulation permits correct host non-featured requests.", async () => { + const mockRequest = { + url: "/api/v1/events", + method: "POST", + body: { + host: "ACM", + featured: false, + }, + log: { + info: vi.fn(), + }, + username: "test@acm.illinois.edu", + policyRestrictions: [{ + "name": "EventsHostRestrictionPolicy", + "params": { + "host": [ + "ACM" + ] + } + }], + } as unknown as FastifyRequest; + const response = await evaluateAllRequestPolicies(mockRequest); + expect(response).toBe(true); + }) +}) diff --git a/tests/unit/vitest.config.ts b/tests/unit/vitest.config.ts index 0158429b..8c802e30 100644 --- a/tests/unit/vitest.config.ts +++ b/tests/unit/vitest.config.ts @@ -11,6 +11,7 @@ export default defineConfig({ coverage: { provider: "istanbul", include: ["src/api/**/*.ts", "src/common/**/*.ts"], + exclude: ["src/api/lambda.ts"], }, }, resolve: {