mirror of
https://github.com/fosrl/pangolin.git
synced 2026-06-12 10:27:06 +00:00
policies and policy on resource structure in a good place
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import z from "zod";
|
||||
import ipaddr from "ipaddr.js";
|
||||
import { COUNTRIES } from "@server/db/countries";
|
||||
import { isValidRegionId } from "@server/db/regions";
|
||||
|
||||
export function isValidCIDR(cidr: string): boolean {
|
||||
return (
|
||||
@@ -67,6 +69,45 @@ export function isValidUrlGlobPattern(pattern: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
export const RESOURCE_RULE_MATCH_TYPES = [
|
||||
"CIDR",
|
||||
"IP",
|
||||
"PATH",
|
||||
"COUNTRY",
|
||||
"ASN",
|
||||
"REGION"
|
||||
] as const;
|
||||
|
||||
export type ResourceRuleMatchType = (typeof RESOURCE_RULE_MATCH_TYPES)[number];
|
||||
|
||||
export function getResourceRuleValueValidationError(
|
||||
match: ResourceRuleMatchType,
|
||||
value: string
|
||||
): string | null {
|
||||
switch (match) {
|
||||
case "CIDR":
|
||||
return isValidCIDR(value) ? null : "Invalid CIDR provided";
|
||||
case "IP":
|
||||
return isValidIP(value) ? null : "Invalid IP provided";
|
||||
case "PATH":
|
||||
return isValidUrlGlobPattern(value)
|
||||
? null
|
||||
: "Invalid URL glob pattern provided";
|
||||
case "REGION":
|
||||
return isValidRegionId(value) ? null : "Invalid region ID provided";
|
||||
case "COUNTRY":
|
||||
return COUNTRIES.some((country) => country.code === value)
|
||||
? null
|
||||
: "Invalid country code provided";
|
||||
case "ASN":
|
||||
return /^AS\d+$/i.test(value.trim())
|
||||
? null
|
||||
: "Invalid ASN provided";
|
||||
default:
|
||||
return "Invalid rule match type provided";
|
||||
}
|
||||
}
|
||||
|
||||
export function isUrlValid(url: string | undefined) {
|
||||
if (!url) return true; // the link is optional in the schema so if it's empty it's valid
|
||||
var pattern = new RegExp(
|
||||
|
||||
@@ -33,9 +33,8 @@ import {
|
||||
import { getUniqueResourcePolicyName } from "@server/db/names";
|
||||
import response from "@server/lib/response";
|
||||
import {
|
||||
isValidCIDR,
|
||||
isValidIP,
|
||||
isValidUrlGlobPattern
|
||||
getResourceRuleValueValidationError,
|
||||
RESOURCE_RULE_MATCH_TYPES
|
||||
} from "@server/lib/validators";
|
||||
import logger from "@server/logger";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
@@ -56,9 +55,9 @@ const ruleSchema = z.strictObject({
|
||||
enum: ["ACCEPT", "DROP", "PASS"],
|
||||
description: "rule action"
|
||||
}),
|
||||
match: z.enum(["CIDR", "IP", "PATH"]).openapi({
|
||||
match: z.enum(RESOURCE_RULE_MATCH_TYPES).openapi({
|
||||
type: "string",
|
||||
enum: ["CIDR", "IP", "PATH"],
|
||||
enum: [...RESOURCE_RULE_MATCH_TYPES],
|
||||
description: "rule match"
|
||||
}),
|
||||
value: z.string().min(1),
|
||||
@@ -261,26 +260,13 @@ export async function createResourcePolicy(
|
||||
const niceId = await getUniqueResourcePolicyName(orgId);
|
||||
|
||||
for (const rule of rules) {
|
||||
if (rule.match === "CIDR" && !isValidCIDR(rule.value)) {
|
||||
const validationError = getResourceRuleValueValidationError(
|
||||
rule.match,
|
||||
rule.value
|
||||
);
|
||||
if (validationError) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"Invalid CIDR provided"
|
||||
)
|
||||
);
|
||||
} else if (rule.match === "IP" && !isValidIP(rule.value)) {
|
||||
return next(
|
||||
createHttpError(HttpCode.BAD_REQUEST, "Invalid IP provided")
|
||||
);
|
||||
} else if (
|
||||
rule.match === "PATH" &&
|
||||
!isValidUrlGlobPattern(rule.value)
|
||||
) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"Invalid URL glob pattern provided"
|
||||
)
|
||||
createHttpError(HttpCode.BAD_REQUEST, validationError)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -666,6 +666,13 @@ authenticated.get(
|
||||
resource.getResourcePolicies
|
||||
);
|
||||
|
||||
authenticated.get(
|
||||
"/resource-policy/:resourcePolicyId",
|
||||
verifyResourcePolicyAccess,
|
||||
verifyUserHasAction(ActionsEnum.getResourcePolicy),
|
||||
policy.getResourcePolicy
|
||||
);
|
||||
|
||||
authenticated.put(
|
||||
"/resource-policy/:resourcePolicyId",
|
||||
verifyResourcePolicyAccess,
|
||||
|
||||
@@ -8,9 +8,8 @@ import createHttpError from "http-errors";
|
||||
import logger from "@server/logger";
|
||||
import { fromError } from "zod-validation-error";
|
||||
import {
|
||||
isValidCIDR,
|
||||
isValidIP,
|
||||
isValidUrlGlobPattern
|
||||
getResourceRuleValueValidationError,
|
||||
RESOURCE_RULE_MATCH_TYPES
|
||||
} from "@server/lib/validators";
|
||||
import { OpenAPITags, registry } from "@server/openApi";
|
||||
|
||||
@@ -20,9 +19,9 @@ const ruleSchema = z.strictObject({
|
||||
enum: ["ACCEPT", "DROP", "PASS"],
|
||||
description: "rule action"
|
||||
}),
|
||||
match: z.enum(["CIDR", "IP", "PATH"]).openapi({
|
||||
match: z.enum(RESOURCE_RULE_MATCH_TYPES).openapi({
|
||||
type: "string",
|
||||
enum: ["CIDR", "IP", "PATH"],
|
||||
enum: [...RESOURCE_RULE_MATCH_TYPES],
|
||||
description: "rule match"
|
||||
}),
|
||||
value: z.string().min(1),
|
||||
@@ -105,26 +104,13 @@ export async function setResourcePolicyRules(
|
||||
}
|
||||
|
||||
for (const rule of rules) {
|
||||
if (rule.match === "CIDR" && !isValidCIDR(rule.value)) {
|
||||
const validationError = getResourceRuleValueValidationError(
|
||||
rule.match,
|
||||
rule.value
|
||||
);
|
||||
if (validationError) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"Invalid CIDR provided"
|
||||
)
|
||||
);
|
||||
} else if (rule.match === "IP" && !isValidIP(rule.value)) {
|
||||
return next(
|
||||
createHttpError(HttpCode.BAD_REQUEST, "Invalid IP provided")
|
||||
);
|
||||
} else if (
|
||||
rule.match === "PATH" &&
|
||||
!isValidUrlGlobPattern(rule.value)
|
||||
) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"Invalid URL glob pattern provided"
|
||||
)
|
||||
createHttpError(HttpCode.BAD_REQUEST, validationError)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user