From a6145120e68467e02a3048d189c10f9be7751cca Mon Sep 17 00:00:00 2001 From: = Date: Wed, 29 Jan 2025 17:01:45 +0530 Subject: [PATCH 1/3] feat: added validation for secret path in permission --- .../services/permission/project-permission.ts | 48 ++++++++++--------- .../ProjectRoleModifySection.utils.tsx | 4 ++ .../components/SecretPermissionConditions.tsx | 8 +++- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index 3dc7daddc..6e337e4d8 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -163,6 +163,30 @@ export type ProjectPermissionSet = | [ProjectPermissionActions.Create, ProjectPermissionSub.SecretRollback] | [ProjectPermissionActions.Edit, ProjectPermissionSub.Kms]; +const SECRET_PATH_MISSING_SLASH_ERR_MSG = "Invalid Secret Path; it must start with a '/'"; +const SECRET_PATH_PERMISSION_OPERATOR_SCHEMA = z.union([ + z.string().refine((val) => val.startsWith("/"), SECRET_PATH_MISSING_SLASH_ERR_MSG), + z + .object({ + [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ].refine( + (val) => val.startsWith("/"), + SECRET_PATH_MISSING_SLASH_ERR_MSG + ), + [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ].refine( + (val) => val.startsWith("/"), + SECRET_PATH_MISSING_SLASH_ERR_MSG + ), + [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN].refine( + (val) => val.every((el) => el.startsWith("/")), + SECRET_PATH_MISSING_SLASH_ERR_MSG + ), + [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB].refine( + (val) => val.startsWith("/"), + SECRET_PATH_MISSING_SLASH_ERR_MSG + ) + }) + .partial() +]); // akhilmhdh: don't modify this for v2 // if you want to update create a new schema const SecretConditionV1Schema = z @@ -177,17 +201,7 @@ const SecretConditionV1Schema = z }) .partial() ]), - secretPath: z.union([ - z.string(), - z - .object({ - [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ], - [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ], - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN], - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] - }) - .partial() - ]) + secretPath: SECRET_PATH_PERMISSION_OPERATOR_SCHEMA }) .partial(); @@ -204,17 +218,7 @@ const SecretConditionV2Schema = z }) .partial() ]), - secretPath: z.union([ - z.string(), - z - .object({ - [PermissionConditionOperators.$EQ]: PermissionConditionSchema[PermissionConditionOperators.$EQ], - [PermissionConditionOperators.$NEQ]: PermissionConditionSchema[PermissionConditionOperators.$NEQ], - [PermissionConditionOperators.$IN]: PermissionConditionSchema[PermissionConditionOperators.$IN], - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] - }) - .partial() - ]), + secretPath: SECRET_PATH_PERMISSION_OPERATOR_SCHEMA, secretName: z.union([ z.string(), z diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx index 3a9e311fd..9b1b1aa00 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx @@ -80,6 +80,10 @@ const ConditionSchema = z return true; }, { message: "Duplicate operator found for a condition" } + ) + .refine( + (val) => val.filter((el) => el.lhs === "secretPath").every((el) => el.rhs.startsWith("/")), + { message: "Invalid Secret Path. Must start with '/'" } ); export const projectRoleFormSchema = z.object({ diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx index 0956ab958..ab893cb09 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/SecretPermissionConditions.tsx @@ -36,6 +36,10 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) name: `permissions.secrets.${position}.conditions` }); + const conditionErrorMessage = + errors?.permissions?.secrets?.[position]?.conditions?.message || + errors?.permissions?.secrets?.[position]?.conditions?.root?.message; + return (

Conditions

@@ -147,10 +151,10 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) ); })}
- {errors?.permissions?.secrets?.[position]?.conditions?.message && ( + {conditionErrorMessage && (
- {errors?.permissions?.secrets?.[position]?.conditions?.message} + {conditionErrorMessage}
)}
From 61388753cf153ddb05035a0492b8b7bfa0cd073e Mon Sep 17 00:00:00 2001 From: = Date: Wed, 29 Jan 2025 17:32:13 +0530 Subject: [PATCH 2/3] feat: updated to support in error in ui --- .../components/ProjectRoleModifySection.utils.tsx | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx index 9b1b1aa00..182f6cb52 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx @@ -82,7 +82,14 @@ const ConditionSchema = z { message: "Duplicate operator found for a condition" } ) .refine( - (val) => val.filter((el) => el.lhs === "secretPath").every((el) => el.rhs.startsWith("/")), + (val) => + val + .filter((el) => el.lhs === "secretPath") + .every((el) => + el.operator === PermissionConditionOperators.$IN + ? el.rhs.split(",").every((i) => i.trim().startsWith("/")) + : el.rhs.trim().startsWith("/") + ), { message: "Invalid Secret Path. Must start with '/'" } ); From cffcb28bc9bfdc204288d6a649e6bdf306e1b28c Mon Sep 17 00:00:00 2001 From: = Date: Wed, 29 Jan 2025 17:50:02 +0530 Subject: [PATCH 3/3] feat: removed secret path check in glob --- backend/src/ee/services/permission/project-permission.ts | 5 +---- .../components/ProjectRoleModifySection.utils.tsx | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index 6e337e4d8..e9ba49127 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -180,10 +180,7 @@ const SECRET_PATH_PERMISSION_OPERATOR_SCHEMA = z.union([ (val) => val.every((el) => el.startsWith("/")), SECRET_PATH_MISSING_SLASH_ERR_MSG ), - [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB].refine( - (val) => val.startsWith("/"), - SECRET_PATH_MISSING_SLASH_ERR_MSG - ) + [PermissionConditionOperators.$GLOB]: PermissionConditionSchema[PermissionConditionOperators.$GLOB] }) .partial() ]); diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx index 182f6cb52..dc850581f 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx @@ -84,7 +84,9 @@ const ConditionSchema = z .refine( (val) => val - .filter((el) => el.lhs === "secretPath") + .filter( + (el) => el.lhs === "secretPath" && el.operator !== PermissionConditionOperators.$GLOB + ) .every((el) => el.operator === PermissionConditionOperators.$IN ? el.rhs.split(",").every((i) => i.trim().startsWith("/"))