feat: review comments over dynamic-secrets, folder read, neq removed in backend, contain in tag

This commit is contained in:
=
2024-10-18 00:33:37 +05:30
parent c8410ac6f3
commit 0c3024819c
8 changed files with 33 additions and 22 deletions
@@ -228,7 +228,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionDynamicSecretActions.Edit, ProjectPermissionDynamicSecretActions.Delete,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
); );
@@ -284,6 +284,10 @@ export const dynamicSecretServiceFactory = ({
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionDynamicSecretActions.Read,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
);
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionDynamicSecretActions.Edit, ProjectPermissionDynamicSecretActions.Edit,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
@@ -331,7 +335,7 @@ export const dynamicSecretServiceFactory = ({
// verify user has access to each env in request // verify user has access to each env in request
environmentSlugs.forEach((environmentSlug) => environmentSlugs.forEach((environmentSlug) =>
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionDynamicSecretActions.Lease, ProjectPermissionDynamicSecretActions.Read,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
) )
); );
@@ -367,7 +371,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionDynamicSecretActions.Lease, ProjectPermissionDynamicSecretActions.Read,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
); );
@@ -413,7 +417,7 @@ export const dynamicSecretServiceFactory = ({
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionDynamicSecretActions.Lease, ProjectPermissionDynamicSecretActions.Read,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
); );
@@ -455,7 +459,7 @@ export const dynamicSecretServiceFactory = ({
// verify user has access to each env in request // verify user has access to each env in request
environmentSlugs.forEach((environmentSlug) => environmentSlugs.forEach((environmentSlug) =>
ForbiddenError.from(permission).throwUnlessCan( ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionDynamicSecretActions.Lease, ProjectPermissionDynamicSecretActions.Read,
subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path }) subject(ProjectPermissionSub.DynamicSecrets, { environment: environmentSlug, secretPath: path })
) )
); );
@@ -21,7 +21,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
secretVersioning: true, secretVersioning: true,
pitRecovery: false, pitRecovery: false,
ipAllowlisting: false, ipAllowlisting: false,
rbac: false, rbac: true,
customRateLimits: false, customRateLimits: false,
customAlerts: false, customAlerts: false,
auditLogs: false, auditLogs: false,
@@ -10,7 +10,7 @@ export const GlobPermissionInfo = () => {
return ( return (
<div> <div>
<div className="mt-2">A glob pattern uses wildcards to match file names or paths.</div> <div className="mt-2">A glob pattern uses wildcards to match resources or paths.</div>
<div> <div>
<FormControl label="Glob pattern" helperText="Examples: /{a,b}, DB_**"> <FormControl label="Glob pattern" helperText="Examples: /{a,b}, DB_**">
<Input value={pattern} onChange={(e) => setPattern(e.target.value)} /> <Input value={pattern} onChange={(e) => setPattern(e.target.value)} />
@@ -19,7 +19,7 @@ export const GlobPermissionInfo = () => {
<div> <div>
<FormControl <FormControl
label="Test string" label="Test string"
helperText="Type value to test" helperText="Type a value to test glob match"
isError={ isError={
pattern && text ? !picomatch.isMatch(text, pattern, { strictSlashes: false }) : false pattern && text ? !picomatch.isMatch(text, pattern, { strictSlashes: false }) : false
} }
@@ -29,7 +29,7 @@ export enum PermissionConditionOperators {
$ALL = "$all", $ALL = "$all",
$REGEX = "$regex", $REGEX = "$regex",
$EQ = "$eq", $EQ = "$eq",
$NEQ = "$neq", $NEQ = "$ne",
$GLOB = "$glob" $GLOB = "$glob"
} }
@@ -45,7 +45,7 @@ export type TPermissionConditionOperators = {
export type TPermissionCondition = Record< export type TPermissionCondition = Record<
string, string,
| string | string
| { $in: string[]; $all: string[]; $regex: string; $eq: string; $neq: string; $glob: string } | { $in: string[]; $all: string[]; $regex: string; $eq: string; $ne: string; $glob: string }
>; >;
export enum ProjectPermissionSub { export enum ProjectPermissionSub {
@@ -370,7 +370,6 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = {
[ProjectPermissionSub.SecretFolders]: { [ProjectPermissionSub.SecretFolders]: {
title: "Secret Folders", title: "Secret Folders",
actions: [ actions: [
{ label: "Read", value: "read" },
{ label: "Create", value: "create" }, { label: "Create", value: "create" },
{ label: "Modify", value: "edit" }, { label: "Modify", value: "edit" },
{ label: "Remove", value: "delete" } { label: "Remove", value: "delete" }
@@ -392,7 +391,7 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = {
{ label: "Create", value: "create" }, { label: "Create", value: "create" },
{ label: "Modify", value: "edit" }, { label: "Modify", value: "edit" },
{ label: "Remove", value: "delete" }, { label: "Remove", value: "delete" },
{ label: "Lease", value: "lease" } { label: "Manage Leases", value: "lease" }
] ]
}, },
[ProjectPermissionSub.Cmek]: { [ProjectPermissionSub.Cmek]: {
@@ -50,11 +50,12 @@ export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }:
</p> </p>
<div className="mt-2 flex flex-col space-y-2"> <div className="mt-2 flex flex-col space-y-2">
{items.fields.map((el, index) => { {items.fields.map((el, index) => {
const condition = watch(`permissions.secrets.${position}.conditions.${index}`) as { const condition =
lhs: string; (watch(`permissions.${type}.${position}.conditions.${index}`) as {
rhs: string; lhs: string;
operator: string; rhs: string;
}; operator: string;
}) || {};
return ( return (
<div <div
key={el.id} key={el.id}
@@ -86,7 +87,7 @@ export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }:
<div className="flex w-36 items-center space-x-2"> <div className="flex w-36 items-center space-x-2">
<Controller <Controller
control={control} control={control}
name={`permissions.secrets.${position}.conditions.${index}.operator`} name={`permissions.${type}.${position}.conditions.${index}.operator`}
render={({ field, fieldState: { error } }) => ( render={({ field, fieldState: { error } }) => (
<FormControl <FormControl
isError={Boolean(error?.message)} isError={Boolean(error?.message)}
@@ -108,7 +109,7 @@ export const GeneralPermissionConditions = ({ position = 0, isDisabled, type }:
<Tooltip <Tooltip
asChild asChild
content={getConditionOperatorHelperInfo( content={getConditionOperatorHelperInfo(
condition.operator as PermissionConditionOperators condition?.operator as PermissionConditionOperators
)} )}
className="max-w-xs" className="max-w-xs"
> >
@@ -28,6 +28,7 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props)
const { const {
control, control,
watch, watch,
setValue,
formState: { errors } formState: { errors }
} = useFormContext<TFormSchema>(); } = useFormContext<TFormSchema>();
const items = useFieldArray({ const items = useFieldArray({
@@ -66,7 +67,13 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props)
<Select <Select
defaultValue={field.value} defaultValue={field.value}
{...field} {...field}
onValueChange={(e) => field.onChange(e)} onValueChange={(e) => {
setValue(
`permissions.secrets.${position}.conditions.${index}.operator`,
PermissionConditionOperators.$IN as never
);
field.onChange(e);
}}
className="w-full" className="w-full"
> >
<SelectItem value="environment">Environment Slug</SelectItem> <SelectItem value="environment">Environment Slug</SelectItem>
@@ -103,7 +110,7 @@ export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props)
<Tooltip <Tooltip
asChild asChild
content={getConditionOperatorHelperInfo( content={getConditionOperatorHelperInfo(
condition.operator as PermissionConditionOperators condition?.operator as PermissionConditionOperators
)} )}
className="max-w-xs" className="max-w-xs"
> >
@@ -94,7 +94,7 @@ export const SecretMainPage = () => {
); );
const canReadDynamicSecret = permission.can( const canReadDynamicSecret = permission.can(
ProjectPermissionDynamicSecretActions.Lease, ProjectPermissionDynamicSecretActions.Read,
subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath }) subject(ProjectPermissionSub.DynamicSecrets, { environment, secretPath })
); );