Skip to content

Commit 2734738

Browse files
committed
Require authentication for staleness bound
1 parent e8c7323 commit 2734738

File tree

4 files changed

+53
-4
lines changed

4 files changed

+53
-4
lines changed

src/api/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ async function init(prettyPrint: boolean = false, initClients: boolean = true) {
150150
},
151151
{
152152
name: "Generic",
153-
description: "Retrieve metadata about a user or ACM @ UIUC .",
153+
description: "Retrieve metadata about a user or ACM @ UIUC.",
154154
},
155155
{
156156
name: "iCalendar Integration",

src/api/routes/events.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,17 @@ const eventsPlugin: FastifyPluginAsyncZodOpenApi = async (
185185
const includeMetadata = request.query.includeMetadata || false;
186186
const host = request.query?.host;
187187
const ts = request.query?.ts; // we only use this to disable cache control
188+
if (ts) {
189+
// cache bypass requires auth
190+
try {
191+
await fastify.authorize(request, reply, [], false);
192+
} catch (e) {
193+
throw new UnauthenticatedError({
194+
message:
195+
"You must be authenticated to specify a staleness bound.",
196+
});
197+
}
198+
}
188199
const projection = createProjectionParams(includeMetadata);
189200
try {
190201
const ifNoneMatch = request.headers["if-none-match"];
@@ -683,6 +694,16 @@ const eventsPlugin: FastifyPluginAsyncZodOpenApi = async (
683694
async (request, reply) => {
684695
const id = request.params.id;
685696
const ts = request.query?.ts;
697+
if (ts) {
698+
// cache bypass requires auth
699+
try {
700+
await fastify.authorize(request, reply, [], false);
701+
} catch (e) {
702+
throw new UnauthenticatedError({
703+
message: "You must be authenticated to specify a staleness bound.",
704+
});
705+
}
706+
}
686707
const includeMetadata = request.query?.includeMetadata || false;
687708

688709
try {

src/ui/pages/events/ManageEvent.page.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,14 +307,19 @@ export const ManageEventPage: React.FC = () => {
307307
resourceDef={{ service: "core", validRoles: [AppRoles.EVENTS_MANAGER] }}
308308
>
309309
<Box maw={400} mx="auto" mt="xl">
310-
<Title mb="sm" order={2}>
311-
{isEditing ? `Edit` : `Create`} Event
312-
</Title>
310+
<Title order={2}>{isEditing ? `Edit` : `Create`} Event</Title>
311+
{eventId && (
312+
<Text size="xs" c="dimmed">
313+
Event ID: <code>{eventId}</code>
314+
</Text>
315+
)}
313316
{Intl.DateTimeFormat().resolvedOptions().timeZone !==
314317
"America/Chicago" && (
315318
<Alert
316319
variant="light"
317320
color="red"
321+
mt="xs"
322+
mb="xs"
318323
title="Timezone Alert"
319324
icon={<IconInfoCircle />}
320325
>

tests/live/events.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,15 @@ test("getting events for a given host", async () => {
2626
});
2727

2828
test("metadata is included when includeMetadata query parameter is set", async () => {
29+
const token = await createJwt();
2930
const response = await fetch(
3031
`${baseEndpoint}/api/v1/events?host=Infrastructure Committee&includeMetadata=true&ts=${Date.now()}`,
32+
{
33+
headers: {
34+
Authorization: `Bearer ${token}`,
35+
"Content-Type": "application/json",
36+
},
37+
},
3138
);
3239
expect(response.status).toBe(200);
3340

@@ -38,8 +45,15 @@ test("metadata is included when includeMetadata query parameter is set", async (
3845
});
3946

4047
test("metadata is not included when includeMetadata query parameter is unset", async () => {
48+
const token = await createJwt();
4149
const response = await fetch(
4250
`${baseEndpoint}/api/v1/events?host=Infrastructure Committee&ts=${Date.now()}`,
51+
{
52+
headers: {
53+
Authorization: `Bearer ${token}`,
54+
"Content-Type": "application/json",
55+
},
56+
},
4357
);
4458
expect(response.status).toBe(200);
4559

@@ -80,6 +94,7 @@ describe("Event lifecycle tests", async () => {
8094
expect(response.headers.get("location")).not.toBeNull();
8195
});
8296
test("Getting an event", { timeout: 30000 }, async () => {
97+
const token = await createJwt();
8398
if (!createdEventUuid) {
8499
throw new Error("Event UUID not found");
85100
}
@@ -88,6 +103,7 @@ describe("Event lifecycle tests", async () => {
88103
{
89104
method: "GET",
90105
headers: {
106+
Authorization: `Bearer ${token}`,
91107
"Content-Type": "application/json",
92108
},
93109
},
@@ -123,11 +139,13 @@ describe("Event lifecycle tests", async () => {
123139
if (!createdEventUuid) {
124140
throw new Error("Event UUID not found");
125141
}
142+
const token = await createJwt();
126143
const response = await fetch(
127144
`${baseEndpoint}/api/v1/events/${createdEventUuid}?ts=${Date.now()}`,
128145
{
129146
method: "GET",
130147
headers: {
148+
Authorization: `Bearer ${token}`,
131149
"Content-Type": "application/json",
132150
},
133151
},
@@ -162,10 +180,15 @@ describe("Event lifecycle tests", async () => {
162180
if (!createdEventUuid) {
163181
throw new Error("Event UUID not found");
164182
}
183+
const token = await createJwt();
165184
const response = await fetch(
166185
`${baseEndpoint}/api/v1/events/${createdEventUuid}?ts=${Date.now()}`,
167186
{
168187
method: "GET",
188+
headers: {
189+
Authorization: `Bearer ${token}`,
190+
"Content-Type": "application/json",
191+
},
169192
},
170193
);
171194
expect(response.status).toBe(404);

0 commit comments

Comments
 (0)