mirror of
https://github.com/fosrl/pangolin.git
synced 2026-07-09 07:30:40 +02:00
Merge branch 'dev' into feat/geoip-country-is-not-rule
This commit is contained in:
@@ -197,15 +197,6 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
||||
policyCheck
|
||||
});
|
||||
|
||||
if (policyCheck?.error) {
|
||||
logger.error(
|
||||
`[handleOlmRegisterMessage] Error checking access policies for olm user ${olm.userId} in org ${orgId}: ${policyCheck?.error}`,
|
||||
{ orgId: client.orgId, clientId: client.clientId }
|
||||
);
|
||||
sendOlmError(OlmErrorCodes.ORG_ACCESS_POLICY_DENIED, olm.olmId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (policyCheck.policies?.passwordAge?.compliant === false) {
|
||||
logger.warn(
|
||||
`[handleOlmRegisterMessage] Olm user ${olm.userId} has non-compliant password age for org ${orgId}`,
|
||||
@@ -238,7 +229,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => {
|
||||
olm.olmId
|
||||
);
|
||||
return;
|
||||
} else if (!policyCheck.allowed) {
|
||||
} else if (!policyCheck.allowed || policyCheck.error) {
|
||||
logger.warn(
|
||||
`[handleOlmRegisterMessage] Olm user ${olm.userId} does not pass access policies for org ${orgId}: ${policyCheck.error}`,
|
||||
{ orgId: client.orgId, clientId: client.clientId }
|
||||
|
||||
@@ -76,6 +76,15 @@ export async function setResourcePolicyHeaderAuth(
|
||||
const { resourcePolicyId } = parsedParams.data;
|
||||
const { headerAuth } = parsedBody.data;
|
||||
|
||||
const headerAuthHash =
|
||||
headerAuth !== null
|
||||
? await hashPassword(
|
||||
Buffer.from(
|
||||
`${headerAuth.user}:${headerAuth.password}`
|
||||
).toString("base64")
|
||||
)
|
||||
: null;
|
||||
|
||||
await db.transaction(async (trx) => {
|
||||
await trx
|
||||
.delete(resourcePolicyHeaderAuth)
|
||||
@@ -86,13 +95,7 @@ export async function setResourcePolicyHeaderAuth(
|
||||
)
|
||||
);
|
||||
|
||||
if (headerAuth !== null) {
|
||||
const headerAuthHash = await hashPassword(
|
||||
Buffer.from(
|
||||
`${headerAuth.user}:${headerAuth.password}`
|
||||
).toString("base64")
|
||||
);
|
||||
|
||||
if (headerAuth !== null && headerAuthHash !== null) {
|
||||
await trx.insert(resourcePolicyHeaderAuth).values({
|
||||
resourcePolicyId,
|
||||
headerAuthHash,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Request, Response, NextFunction } from "express";
|
||||
import { z } from "zod";
|
||||
import { db, resourcePolicyRules, resourcePolicies } from "@server/db";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { and, eq, notInArray } from "drizzle-orm";
|
||||
import response from "@server/lib/response";
|
||||
import HttpCode from "@server/types/HttpCode";
|
||||
import createHttpError from "http-errors";
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
|
||||
const ruleSchema = z.strictObject({
|
||||
ruleId: z.int().positive().optional(),
|
||||
action: z.enum(["ACCEPT", "DROP", "PASS"]).openapi({
|
||||
type: "string",
|
||||
enum: ["ACCEPT", "DROP", "PASS"],
|
||||
@@ -121,17 +122,74 @@ export async function setResourcePolicyRules(
|
||||
.set({ applyRules })
|
||||
.where(eq(resourcePolicies.resourcePolicyId, resourcePolicyId));
|
||||
|
||||
await trx
|
||||
.delete(resourcePolicyRules)
|
||||
.where(
|
||||
eq(resourcePolicyRules.resourcePolicyId, resourcePolicyId)
|
||||
);
|
||||
const incomingRuleIds = rules
|
||||
.map((r) => r.ruleId)
|
||||
.filter((id): id is number => id !== undefined);
|
||||
|
||||
if (rules.length > 0) {
|
||||
// Delete rules that are no longer in the incoming list
|
||||
if (incomingRuleIds.length > 0) {
|
||||
await trx
|
||||
.delete(resourcePolicyRules)
|
||||
.where(
|
||||
and(
|
||||
eq(
|
||||
resourcePolicyRules.resourcePolicyId,
|
||||
resourcePolicyId
|
||||
),
|
||||
notInArray(
|
||||
resourcePolicyRules.ruleId,
|
||||
incomingRuleIds
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
await trx
|
||||
.delete(resourcePolicyRules)
|
||||
.where(
|
||||
eq(
|
||||
resourcePolicyRules.resourcePolicyId,
|
||||
resourcePolicyId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Update existing rules (those with a ruleId)
|
||||
const existingRules = rules.filter(
|
||||
(r): r is typeof r & { ruleId: number } =>
|
||||
r.ruleId !== undefined
|
||||
);
|
||||
for (const rule of existingRules) {
|
||||
await trx
|
||||
.update(resourcePolicyRules)
|
||||
.set({
|
||||
action: rule.action,
|
||||
match: rule.match,
|
||||
value: rule.value,
|
||||
priority: rule.priority,
|
||||
enabled: rule.enabled
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(resourcePolicyRules.ruleId, rule.ruleId),
|
||||
eq(
|
||||
resourcePolicyRules.resourcePolicyId,
|
||||
resourcePolicyId
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Insert new rules (those without a ruleId)
|
||||
const newRules = rules.filter((r) => r.ruleId === undefined);
|
||||
if (newRules.length > 0) {
|
||||
await trx.insert(resourcePolicyRules).values(
|
||||
rules.map((rule) => ({
|
||||
newRules.map((rule) => ({
|
||||
resourcePolicyId,
|
||||
...rule
|
||||
action: rule.action,
|
||||
match: rule.match,
|
||||
value: rule.value,
|
||||
priority: rule.priority,
|
||||
enabled: rule.enabled
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -107,6 +107,13 @@ export async function setResourceHeaderAuth(
|
||||
resource.resourcePolicyId === null &&
|
||||
resource.defaultResourcePolicyId !== null;
|
||||
|
||||
const headerAuthHash =
|
||||
user && password && extendedCompatibility !== null
|
||||
? await hashPassword(
|
||||
Buffer.from(`${user}:${password}`).toString("base64")
|
||||
)
|
||||
: null;
|
||||
|
||||
await db.transaction(async (trx) => {
|
||||
if (isInlinePolicy) {
|
||||
const policyId = resource.defaultResourcePolicyId!;
|
||||
@@ -116,11 +123,7 @@ export async function setResourceHeaderAuth(
|
||||
eq(resourcePolicyHeaderAuth.resourcePolicyId, policyId)
|
||||
);
|
||||
|
||||
if (user && password && extendedCompatibility !== null) {
|
||||
const headerAuthHash = await hashPassword(
|
||||
Buffer.from(`${user}:${password}`).toString("base64")
|
||||
);
|
||||
|
||||
if (headerAuthHash !== null && extendedCompatibility !== null) {
|
||||
await trx.insert(resourcePolicyHeaderAuth).values({
|
||||
resourcePolicyId: policyId,
|
||||
headerAuthHash,
|
||||
@@ -140,11 +143,7 @@ export async function setResourceHeaderAuth(
|
||||
)
|
||||
);
|
||||
|
||||
if (user && password && extendedCompatibility !== null) {
|
||||
const headerAuthHash = await hashPassword(
|
||||
Buffer.from(`${user}:${password}`).toString("base64")
|
||||
);
|
||||
|
||||
if (headerAuthHash !== null && extendedCompatibility !== null) {
|
||||
await Promise.all([
|
||||
trx
|
||||
.insert(resourceHeaderAuth)
|
||||
|
||||
@@ -10,6 +10,7 @@ import logger from "@server/logger";
|
||||
import stoi from "@server/lib/stoi";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
import { getCountryCodeForIp } from "@server/lib/geoip";
|
||||
|
||||
const getSiteSchema = z.strictObject({
|
||||
siteId: z
|
||||
@@ -47,6 +48,7 @@ type SiteQueryRow = NonNullable<Awaited<ReturnType<typeof query>>>;
|
||||
export type GetSiteResponse = SiteQueryRow["sites"] & {
|
||||
newtId: string | null;
|
||||
newtVersion: string | null;
|
||||
countryCode: string | null;
|
||||
};
|
||||
|
||||
registry.registerPath({
|
||||
@@ -134,7 +136,10 @@ export async function getSite(
|
||||
const data: GetSiteResponse = {
|
||||
...site.sites,
|
||||
newtId: site.newt ? site.newt.newtId : null,
|
||||
newtVersion: site.newt?.version ?? null
|
||||
newtVersion: site.newt?.version ?? null,
|
||||
countryCode: site.sites.endpoint
|
||||
? ((await getCountryCodeForIp(site.sites.endpoint)) ?? null)
|
||||
: null
|
||||
};
|
||||
|
||||
return response<GetSiteResponse>(res, {
|
||||
|
||||
Reference in New Issue
Block a user