From 7d7cdd1c9ace30706c0d13065167ab93e674b88a Mon Sep 17 00:00:00 2001 From: Anys Date: Tue, 6 Jan 2026 18:56:10 +0100 Subject: [PATCH] Add 403 error page and Polytech access control. --- defaults/interfaces.ts | 2 ++ fresh.gen.ts | 2 ++ routes/_403.tsx | 12 ++++++++++++ routes/_middleware.ts | 38 +++++++++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 routes/_403.tsx diff --git a/defaults/interfaces.ts b/defaults/interfaces.ts index a5a6268..5f2ef80 100644 --- a/defaults/interfaces.ts +++ b/defaults/interfaces.ts @@ -3,11 +3,13 @@ import { AsyncRoute } from "$fresh/src/server/types.ts"; interface AuthenticatedState { isAuthenticated: true; + isFromPolytech: boolean; session: CasContent; } interface UnauthenticatedState { isAuthenticated: false; + isFromPolytech: false; session: undefined; } diff --git a/fresh.gen.ts b/fresh.gen.ts index 1f123c6..2e4b1bb 100644 --- a/fresh.gen.ts +++ b/fresh.gen.ts @@ -20,6 +20,7 @@ import * as $_apps_students_partials_admin_consult from "./routes/(apps)/student import * as $_apps_students_partials_admin_upload from "./routes/(apps)/students/partials/(admin)/upload.tsx"; import * as $_apps_students_partials_index from "./routes/(apps)/students/partials/index.tsx"; import * as $_apps_students_partials_overview from "./routes/(apps)/students/partials/overview.tsx"; +import * as $_403 from "./routes/_403.tsx"; import * as $_404 from "./routes/_404.tsx"; import * as $_app from "./routes/_app.tsx"; import * as $_middleware from "./routes/_middleware.ts"; @@ -67,6 +68,7 @@ const manifest = { $_apps_students_partials_index, "./routes/(apps)/students/partials/overview.tsx": $_apps_students_partials_overview, + "./routes/_403.tsx": $_403, "./routes/_404.tsx": $_404, "./routes/_app.tsx": $_app, "./routes/_middleware.ts": $_middleware, diff --git a/routes/_403.tsx b/routes/_403.tsx new file mode 100644 index 0000000..ffae6dd --- /dev/null +++ b/routes/_403.tsx @@ -0,0 +1,12 @@ +import { Head } from "$fresh/runtime.ts"; + +export default function Error403() { + return ( + <> + + 403 - Forbidden + +

403

+ + ); +} diff --git a/routes/_middleware.ts b/routes/_middleware.ts index c8f8184..fac3c99 100644 --- a/routes/_middleware.ts +++ b/routes/_middleware.ts @@ -45,6 +45,7 @@ export function getKey(user: string): string { export const handler: MiddlewareHandler[] = [ /** * Check if user is authenticated and add session to context accordingly. + * Only authenticated users who are members of Polytech are allowed. * @param request The HTTP incomming request. * @param context The Fresh context object with custom `State`. * @returns The response from the next middleware. @@ -56,6 +57,7 @@ export const handler: MiddlewareHandler[] = [ const cookies = getCookies(request.headers); if (!cookies["sessionToken"]) { context.state.isAuthenticated = false; + context.state.isFromPolytech = false; return await context.next(); } @@ -71,8 +73,15 @@ export const handler: MiddlewareHandler[] = [ const session: CasContent = ( getJwtPayload(cookies["sessionToken"]) as LoginJWT ).user; - if (session.memberOf.includes("cn=amu:ufr:polytech:ldap")) { - console.log("Polytech trouvé !"); + + const isFromPolytech = Object.values(session.memberOf).some( + (value) => + typeof value === "string" && value.includes("cn=amu:ufr:polytech"), + ); + + context.state.isFromPolytech = isFromPolytech; + + if (isFromPolytech) { context.state.session = session; } } @@ -92,13 +101,24 @@ export const handler: MiddlewareHandler[] = [ ): Promise { const url = new URL(request.url); - if (!isRoutePublic(url.pathname) && !context.state.isAuthenticated) { - return new Response(null, { - status: 302, - headers: { - Location: "/login", - }, - }); + if (!isRoutePublic(url.pathname)) { + if (!context.state.isAuthenticated) { + return new Response(null, { + status: 302, + headers: { + Location: "/login", + }, + }); + } + + if (context.state.isAuthenticated && !context.state.isFromPolytech) { + return new Response(null, { + status: 403, + headers: { + Location: "/403", + }, + }); + } } return await context.next();