mirror of
https://github.com/fosrl/pangolin.git
synced 2026-08-15 08:49:59 +02:00
@@ -33,7 +33,9 @@ import {
|
|||||||
resourcePolicyPassword,
|
resourcePolicyPassword,
|
||||||
ResourcePolicyPassword,
|
ResourcePolicyPassword,
|
||||||
resourcePolicyHeaderAuth,
|
resourcePolicyHeaderAuth,
|
||||||
ResourcePolicyHeaderAuth
|
ResourcePolicyHeaderAuth,
|
||||||
|
resourceWhitelist,
|
||||||
|
resourcePolicyWhiteList
|
||||||
} from "@server/db";
|
} from "@server/db";
|
||||||
import { alias } from "@server/db";
|
import { alias } from "@server/db";
|
||||||
import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
|
import { and, eq, inArray, isNull, or, sql } from "drizzle-orm";
|
||||||
@@ -448,6 +450,36 @@ export async function getResourceRules(
|
|||||||
return [...directRules, ...offsetPolicyRules] as ResourceRule[];
|
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
|
* Get organization login page
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import {
|
|||||||
getRoleResourceAccess,
|
getRoleResourceAccess,
|
||||||
getUserResourceAccess,
|
getUserResourceAccess,
|
||||||
getOrgLoginPage,
|
getOrgLoginPage,
|
||||||
getUserSessionWithUser
|
getUserSessionWithUser,
|
||||||
|
getWhitelistEmail
|
||||||
} from "@server/db/queries/verifySessionQueries";
|
} from "@server/db/queries/verifySessionQueries";
|
||||||
import { getUserOrgRoles } from "@server/lib/userOrgRoles";
|
import { getUserOrgRoles } from "@server/lib/userOrgRoles";
|
||||||
import {
|
import {
|
||||||
@@ -94,6 +95,13 @@ type BasicUserData = {
|
|||||||
role: string | null;
|
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 { ClientErrorResponse };
|
||||||
|
|
||||||
export type VerifyUserResponse = {
|
export type VerifyUserResponse = {
|
||||||
@@ -782,6 +790,18 @@ export async function verifyResourceSession(
|
|||||||
"Resource allowed because whitelist session is valid"
|
"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(
|
logRequestAudit(
|
||||||
{
|
{
|
||||||
action: true,
|
action: true,
|
||||||
@@ -793,7 +813,11 @@ export async function verifyResourceSession(
|
|||||||
parsedBody.data
|
parsedBody.data
|
||||||
);
|
);
|
||||||
|
|
||||||
return allowed(res, undefined, dontStripSession);
|
return allowed(
|
||||||
|
res,
|
||||||
|
whitelistEmail ? { email: whitelistEmail } : undefined,
|
||||||
|
dontStripSession
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resourceSession.accessTokenId) {
|
if (resourceSession.accessTokenId) {
|
||||||
@@ -1022,7 +1046,7 @@ async function notAllowed(
|
|||||||
|
|
||||||
function allowed(
|
function allowed(
|
||||||
res: Response,
|
res: Response,
|
||||||
userData?: BasicUserData,
|
userData?: BasicUserData | EmailOnlyUserData,
|
||||||
dontStripSession?: boolean,
|
dontStripSession?: boolean,
|
||||||
virtualApiKeyId?: string
|
virtualApiKeyId?: string
|
||||||
) {
|
) {
|
||||||
|
|||||||
Reference in New Issue
Block a user