Skip to content

Commit 989b283

Browse files
committed
try this new method of doing auth
1 parent 5a11bfd commit 989b283

19 files changed

+410
-341
lines changed

src/api/components/index.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { AppRoles } from "common/roles.js";
2+
import { FastifyZodOpenApiSchema } from "fastify-zod-openapi";
13
import { z } from "zod";
24

35
export const ts = z.coerce
@@ -10,9 +12,28 @@ export const groupId = z.string().min(1).openapi({
1012
example: "d8cbb7c9-2f6d-4b7e-8ba6-b54f8892003b",
1113
});
1214

13-
export function withTags<T>(tags: string[], schema: T) {
15+
export function withTags<T extends FastifyZodOpenApiSchema>(
16+
tags: string[],
17+
schema: T,
18+
) {
1419
return {
1520
tags,
1621
...schema,
1722
};
1823
}
24+
25+
type RoleSchema = {
26+
"x-required-roles": AppRoles[];
27+
description: string;
28+
};
29+
30+
export function withRoles<T extends FastifyZodOpenApiSchema>(
31+
roles: AppRoles[],
32+
schema: T,
33+
): T & RoleSchema {
34+
return {
35+
"x-required-roles": roles,
36+
description: `Requires one of the following roles: ${roles.join(", ")}.${schema.description ? "\n\n" + schema.description : ""}`,
37+
...schema,
38+
};
39+
}

src/api/index.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import { RunEnvironment, runEnvironments } from "../common/roles.js";
1111
import { InternalServerError } from "../common/errors/index.js";
1212
import eventsPlugin from "./routes/events.js";
1313
import cors from "@fastify/cors";
14-
import fastifyZodValidationPlugin from "./plugins/validate.js";
1514
import { environmentConfig, genericConfig } from "../common/config.js";
1615
import organizationsPlugin from "./routes/organizations.js";
16+
import authorizeFromSchemaPlugin from "./plugins/authorizeFromSchema.js";
1717
import icalPlugin from "./routes/ics.js";
1818
import vendingPlugin from "./routes/vending.js";
1919
import * as dotenv from "dotenv";
@@ -93,15 +93,18 @@ async function init(prettyPrint: boolean = false) {
9393
return event.requestContext.requestId;
9494
},
9595
});
96+
app.setValidatorCompiler(validatorCompiler);
97+
app.setSerializerCompiler(serializerCompiler);
98+
await app.register(authorizeFromSchemaPlugin);
9699
await app.register(fastifyAuthPlugin);
97-
await app.register(fastifyZodValidationPlugin);
98100
await app.register(FastifyAuthProvider);
99101
await app.register(errorHandlerPlugin);
100102
await app.register(fastifyZodOpenApiPlugin);
101103
await app.register(fastifySwagger, {
102104
openapi: {
103105
info: {
104106
title: "ACM @ UIUC Core API",
107+
description: "ACM @ UIUC Core Management Platform",
105108
version: "1.0.0",
106109
},
107110
servers: [
@@ -119,11 +122,11 @@ async function init(prettyPrint: boolean = false) {
119122
{
120123
name: "Events",
121124
description:
122-
"Retrieve ACM-wide and organization-specific calendars and event metadata.",
125+
"Retrieve ACM @ UIUC-wide and organization-specific calendars and event metadata.",
123126
},
124127
{
125128
name: "Generic",
126-
description: "Retrieve metadata about a user or ACM.",
129+
description: "Retrieve metadata about a user or ACM @ UIUC .",
127130
},
128131
{
129132
name: "iCalendar Integration",
@@ -139,6 +142,10 @@ async function init(prettyPrint: boolean = false) {
139142
name: "Logging",
140143
description: "View audit logs for various services.",
141144
},
145+
{
146+
name: "Membership",
147+
description: "Purchasing or checking ACM @ UIUC membership.",
148+
},
142149
],
143150
openapi: "3.0.3" satisfies ZodOpenApiVersion, // If this is not specified, it will default to 3.1.0
144151
},
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { FastifyPluginAsync } from "fastify";
2+
import { AppRoles } from "common/roles.js";
3+
import { InternalServerError } from "common/errors/index.js";
4+
import fp from "fastify-plugin";
5+
6+
declare module "fastify" {
7+
interface FastifyInstance {
8+
authorizeFromSchema: (
9+
request: FastifyRequest,
10+
reply: FastifyReply,
11+
) => Promise<void>;
12+
}
13+
}
14+
15+
const authorizeFromSchemaPlugin: FastifyPluginAsync = fp(async (fastify) => {
16+
fastify.decorate("authorizeFromSchema", async (request, reply) => {
17+
const schema = request.routeOptions?.schema;
18+
19+
if (!schema || !("x-required-roles" in schema)) {
20+
throw new InternalServerError({
21+
message:
22+
"Server has not specified authentication roles for this route.",
23+
});
24+
}
25+
26+
const roles = (schema as { "x-required-roles": AppRoles[] })[
27+
"x-required-roles"
28+
];
29+
await fastify.authorize(request, reply, roles);
30+
});
31+
});
32+
33+
export default authorizeFromSchemaPlugin;

src/api/plugins/validate.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/api/routes/events.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,14 @@ const eventsPlugin: FastifyPluginAsyncZodOpenApi = async (
8383
fastify,
8484
_options,
8585
) => {
86-
fastify.setValidatorCompiler(validatorCompiler);
87-
fastify.setSerializerCompiler(serializerCompiler);
8886
const limitedRoutes: FastifyPluginAsync = async (fastify) => {
8987
fastify.register(rateLimiter, {
9088
limit: 30,
9189
duration: 60,
9290
rateLimitIdentifier: "events",
9391
});
9492
fastify.withTypeProvider<FastifyZodOpenApiTypeProvider>().get(
95-
"/",
93+
"",
9694
{
9795
schema: withTags(["Events"], {
9896
querystring: z.object({
@@ -230,6 +228,13 @@ const eventsPlugin: FastifyPluginAsyncZodOpenApi = async (
230228
// }),
231229
// },
232230
body: postRequestSchema,
231+
params: z.object({
232+
id: z.string().min(1).optional().openapi({
233+
description:
234+
"Event ID to modify (leave empty to create a new event).",
235+
example: "6667e095-8b04-4877-b361-f636f459ba42",
236+
}),
237+
}),
233238
}) satisfies FastifyZodOpenApiSchema,
234239
onRequest: async (request, reply) => {
235240
await fastify.authorize(request, reply, [AppRoles.EVENTS_MANAGER]);
@@ -241,9 +246,7 @@ const eventsPlugin: FastifyPluginAsyncZodOpenApi = async (
241246
}
242247
try {
243248
let originalEvent;
244-
const userProvidedId = (
245-
request.params as Record<string, string | undefined>
246-
).id;
249+
const userProvidedId = request.params.id;
247250
const entryUUID = userProvidedId || randomUUID();
248251
if (userProvidedId) {
249252
const response = await fastify.dynamoClient.send(

src/api/routes/iam.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ const iamRoutes: FastifyPluginAsync = async (fastify, _options) => {
7676
};
7777
}
7878
};
79-
fastify.setValidatorCompiler(validatorCompiler);
80-
fastify.setSerializerCompiler(serializerCompiler);
8179
fastify.withTypeProvider<FastifyZodOpenApiTypeProvider>().patch(
8280
"/profile",
8381
{

src/api/routes/ics.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ function generateHostName(host: string) {
4444
}
4545

4646
const icalPlugin: FastifyPluginAsync = async (fastify, _options) => {
47-
fastify.setValidatorCompiler(validatorCompiler);
48-
fastify.setSerializerCompiler(serializerCompiler);
4947
fastify.register(rateLimiter, {
5048
limit: OrganizationList.length,
5149
duration: 30,

src/api/routes/linkry.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ type LinkryGetRequest = {
7474
};
7575

7676
const linkryRoutes: FastifyPluginAsync = async (fastify, _options) => {
77-
fastify.setValidatorCompiler(validatorCompiler);
78-
fastify.setSerializerCompiler(serializerCompiler);
7977
const limitedRoutes: FastifyPluginAsync = async (fastify) => {
8078
fastify.register(rateLimiter, {
8179
limit: 30,

src/api/routes/logs.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ const responseSchema = z.array(loggingEntryFromDatabase);
2525
type ResponseType = z.infer<typeof responseSchema>;
2626

2727
const logsPlugin: FastifyPluginAsync = async (fastify, _options) => {
28-
fastify.setValidatorCompiler(validatorCompiler);
29-
fastify.setSerializerCompiler(serializerCompiler);
3028
fastify.register(rateLimiter, {
3129
limit: 10,
3230
duration: 30,

0 commit comments

Comments
 (0)