diff --git a/lib/auth/index.ts b/lib/auth/index.ts index 610b48c..eb4080f 100644 --- a/lib/auth/index.ts +++ b/lib/auth/index.ts @@ -1,7 +1,7 @@ import { getServerSession } from "next-auth"; import { redirect } from "next/navigation"; -import { checkPermission, flattenPermissionsFor } from "./rbacEngine"; +import { checkAnyPermission, flattenPermissionsFor } from "./rbacEngine"; /** * Check whether the currently authorised user has a given scope and return them if such @@ -16,7 +16,7 @@ export async function getScopedUser(scope: string) { email: session.user.email, }); - if (!checkPermission(permissions, scope)) { + if (!checkAnyPermission(permissions, [scope])) { console.debug(`${session.user.email} rejected, lacking ${scope}`); return redirect("/panel/access-denied?missing=" + scope); } @@ -24,6 +24,27 @@ export async function getScopedUser(scope: string) { return session.user.email; } +/** + * Check whether the currently authorised user has a given scope and return them if such + * @param scope Required scope + * @returns User email + */ +export async function getMultiScopedUser(scopes: string[]) { + const session = await getServerSession(); + if (!session?.user?.email) return redirect("/panel/access-denied"); + + const permissions = await flattenPermissionsFor({ + email: session.user.email, + }); + + if (!checkAnyPermission(permissions, scopes)) { + console.debug(`${session.user.email} rejected, lacking any of ${scopes}`); + return redirect("/panel/access-denied?missing=" + scopes); + } + + return session.user.email; +} + /** * Check which of the given scopes are allowed to the given user * @param scopes Scopes to check diff --git a/lib/auth/rbacEngine.ts b/lib/auth/rbacEngine.ts index 96c7ed0..69fd243 100644 --- a/lib/auth/rbacEngine.ts +++ b/lib/auth/rbacEngine.ts @@ -18,16 +18,19 @@ export async function flattenPermissionsFor( return roles.flatMap((role) => role.permissions); } -export function checkPermission(permissions: string[], permission: string) { +export function checkAnyPermission(permissions: string[], requested_permissions: string[]) { if (permissions.includes("*")) return true; - const segments = permission.split("."); - while (segments.length) { - if (permissions.includes(segments.join("."))) { - return true; - } + for(let i=0; i