mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-15 00:39:43 +02:00
@@ -33,7 +33,9 @@ import {
|
||||
resourcePolicyPassword,
|
||||
ResourcePolicyPassword,
|
||||
resourcePolicyHeaderAuth,
|
||||
ResourcePolicyHeaderAuth
|
||||
ResourcePolicyHeaderAuth,
|
||||
resourceWhitelist,
|
||||
resourcePolicyWhiteList
|
||||
} from "@server/db";
|
||||
import { alias } from "@server/db";
|
||||
import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
|
||||
@@ -448,6 +450,36 @@ export async function getResourceRules(
|
||||
return [...directRules, ...offsetPolicyRules] as ResourceRule[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the whitelisted email associated with a resource session's whitelist
|
||||
* match (either a direct resource whitelist entry or a resource policy
|
||||
* whitelist entry).
|
||||
*/
|
||||
export async function getWhitelistEmail(
|
||||
whitelistId?: number | null,
|
||||
policyWhitelistId?: number | null
|
||||
): Promise<string | null> {
|
||||
if (whitelistId) {
|
||||
const [row] = await db
|
||||
.select({ email: resourceWhitelist.email })
|
||||
.from(resourceWhitelist)
|
||||
.where(eq(resourceWhitelist.whitelistId, whitelistId))
|
||||
.limit(1);
|
||||
return row?.email ?? null;
|
||||
}
|
||||
|
||||
if (policyWhitelistId) {
|
||||
const [row] = await db
|
||||
.select({ email: resourcePolicyWhiteList.email })
|
||||
.from(resourcePolicyWhiteList)
|
||||
.where(eq(resourcePolicyWhiteList.whitelistId, policyWhitelistId))
|
||||
.limit(1);
|
||||
return row?.email ?? null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get organization login page
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,8 @@ import {
|
||||
getRoleResourceAccess,
|
||||
getUserResourceAccess,
|
||||
getOrgLoginPage,
|
||||
getUserSessionWithUser
|
||||
getUserSessionWithUser,
|
||||
getWhitelistEmail
|
||||
} from "@server/db/queries/verifySessionQueries";
|
||||
import { getUserOrgRoles } from "@server/lib/userOrgRoles";
|
||||
import {
|
||||
@@ -94,6 +95,13 @@ type BasicUserData = {
|
||||
role: string | null;
|
||||
};
|
||||
|
||||
// Some auth methods (e.g. email whitelist) only know the remote email and
|
||||
// have no associated user record to attach userId/username/name/role to.
|
||||
type EmailOnlyUserData = {
|
||||
dontStripSession?: boolean;
|
||||
email: string;
|
||||
};
|
||||
|
||||
export type { ClientErrorResponse };
|
||||
|
||||
export type VerifyUserResponse = {
|
||||
@@ -782,6 +790,18 @@ export async function verifyResourceSession(
|
||||
"Resource allowed because whitelist session is valid"
|
||||
);
|
||||
|
||||
const whitelistCacheKey = `whitelistEmail:${resourceSession.whitelistId}:${resourceSession.policyWhitelistId}`;
|
||||
let whitelistEmail: string | null | undefined =
|
||||
localCache.get(whitelistCacheKey);
|
||||
|
||||
if (whitelistEmail === undefined) {
|
||||
whitelistEmail = await getWhitelistEmail(
|
||||
resourceSession.whitelistId,
|
||||
resourceSession.policyWhitelistId
|
||||
);
|
||||
localCache.set(whitelistCacheKey, whitelistEmail, 12);
|
||||
}
|
||||
|
||||
logRequestAudit(
|
||||
{
|
||||
action: true,
|
||||
@@ -793,7 +813,11 @@ export async function verifyResourceSession(
|
||||
parsedBody.data
|
||||
);
|
||||
|
||||
return allowed(res, undefined, dontStripSession);
|
||||
return allowed(
|
||||
res,
|
||||
whitelistEmail ? { email: whitelistEmail } : undefined,
|
||||
dontStripSession
|
||||
);
|
||||
}
|
||||
|
||||
if (resourceSession.accessTokenId) {
|
||||
@@ -1022,7 +1046,7 @@ async function notAllowed(
|
||||
|
||||
function allowed(
|
||||
res: Response,
|
||||
userData?: BasicUserData,
|
||||
userData?: BasicUserData | EmailOnlyUserData,
|
||||
dontStripSession?: boolean,
|
||||
virtualApiKeyId?: string
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user