diff --git a/backend/src/ee/services/license/license-fns.ts b/backend/src/ee/services/license/license-fns.ts index 2a60fb03e..fa67b72d1 100644 --- a/backend/src/ee/services/license/license-fns.ts +++ b/backend/src/ee/services/license/license-fns.ts @@ -21,14 +21,14 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({ secretVersioning: true, pitRecovery: false, ipAllowlisting: false, - rbac: true, + rbac: false, customRateLimits: false, customAlerts: false, auditLogs: false, auditLogsRetentionDays: 0, auditLogStreams: false, auditLogStreamLimit: 3, - samlSSO: true, + samlSSO: false, oidcSSO: false, scim: false, ldap: false, diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index 71cd78821..7c9e75ded 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -137,9 +137,7 @@ const SecretConditionSchema = z export const ProjectPermissionSchema = z.discriminatedUnion("subject", [ z.object({ - subject: z - .literal(ProjectPermissionSub.Secrets) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Secrets).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ), @@ -148,185 +146,139 @@ export const ProjectPermissionSchema = z.discriminatedUnion("subject", [ ).optional() }), z.object({ - subject: z - .literal(ProjectPermissionSub.SecretApproval) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.SecretApproval).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.SecretRotation) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.SecretRotation).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.SecretRollback) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.SecretRollback).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_ENUM([ProjectPermissionActions.Read, ProjectPermissionActions.Create]).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Member) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Member).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Groups) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Groups).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Role) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Role).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Integrations) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Integrations).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Webhooks) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Webhooks).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Identity) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Identity).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.ServiceTokens) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.ServiceTokens).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Settings) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Settings).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Environments) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Environments).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Tags) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Tags).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.AuditLogs) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.AuditLogs).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.IpAllowList) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.IpAllowList).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.CertificateAuthorities) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.CertificateAuthorities).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Certificates) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Certificates).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.CertificateTemplates) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.CertificateTemplates).describe("The entity this permission pertains to. "), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.PkiAlerts) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.PkiAlerts).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.PkiCollections) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.PkiCollections).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Project) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Project).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_ENUM([ProjectPermissionActions.Edit, ProjectPermissionActions.Delete]).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.Kms) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.Kms).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_ENUM([ProjectPermissionActions.Edit]).describe( "Describe what action an entity can take." ) }), z.object({ - subject: z - .literal(ProjectPermissionSub.SecretFolders) - .describe("The entity this permission pertains to. Possible options: secrets, environments"), + subject: z.literal(ProjectPermissionSub.SecretFolders).describe("The entity this permission pertains to."), action: CASL_ACTION_SCHEMA_ENUM([ProjectPermissionActions.Read]).describe( "Describe what action an entity can take." ) diff --git a/backend/src/lib/knex/dynamic.ts b/backend/src/lib/knex/dynamic.ts index 90a9d2abe..c336d7a9e 100644 --- a/backend/src/lib/knex/dynamic.ts +++ b/backend/src/lib/knex/dynamic.ts @@ -21,6 +21,7 @@ type TKnexGroupOperator = { value: (TKnexNonGroupOperator | TKnexGroupOperator)[]; }; +// akhilmhdh: This is still in pending state and not yet ready. If you want to use it ping me. // used when you need to write a complex query with the orm // use it when you need complex or and and condition - most of the time not needed // majorly used with casl permission to filter data based on permission @@ -33,19 +34,19 @@ export const buildDynamicKnexQuery = (dynamicQuery: TKnexDynamicOperator, rootQu const { filterAst, queryBuilder } = stack.pop()!; switch (filterAst.operator) { case "eq": { - void queryBuilder.where(filterAst.field, filterAst.value); + void queryBuilder.where(filterAst.field, "=", filterAst.value); break; } case "ne": { - void queryBuilder.where(filterAst.field, filterAst.value); + void queryBuilder.whereNot(filterAst.field, filterAst.value); break; } case "startsWith": { - void queryBuilder.where(filterAst.field, filterAst.value); + void queryBuilder.whereILike(filterAst.field, `${filterAst.value}%`); break; } case "endsWith": { - void queryBuilder.where(filterAst.field, filterAst.value); + void queryBuilder.whereILike(filterAst.field, `%${filterAst.value}`); break; } case "and": { diff --git a/frontend/src/views/Org/IdentityPage/components/IdentityDetailsSection.tsx b/frontend/src/views/Org/IdentityPage/components/IdentityDetailsSection.tsx index c9cba17c6..fe56d3260 100644 --- a/frontend/src/views/Org/IdentityPage/components/IdentityDetailsSection.tsx +++ b/frontend/src/views/Org/IdentityPage/components/IdentityDetailsSection.tsx @@ -85,7 +85,7 @@ export const IdentityDetailsSection = ({ identityId, handlePopUpOpen }: Props) =

Metadata

{data?.metadata?.length ? ( -
+
{data.metadata?.map((el) => (
-
{el.value}
+
+ {el.value} +
))} diff --git a/frontend/src/views/Org/UserPage/components/UserDetailsSection.tsx b/frontend/src/views/Org/UserPage/components/UserDetailsSection.tsx index c00e55688..d439c7ecd 100644 --- a/frontend/src/views/Org/UserPage/components/UserDetailsSection.tsx +++ b/frontend/src/views/Org/UserPage/components/UserDetailsSection.tsx @@ -171,7 +171,7 @@ export const UserDetailsSection = ({ membershipId, handlePopUpOpen }: Props) =>

Metadata

{membership?.metadata?.length ? ( -
+
{membership.metadata?.map((el) => (
size="xs" className="flex items-center rounded-l-none border border-mineshaft-500 bg-mineshaft-900 pl-1" > -
{el.value}
+
+ {el.value} +
))} diff --git a/frontend/src/views/Project/RolePage/RolePage.tsx b/frontend/src/views/Project/RolePage/RolePage.tsx index 373de2538..929265dcf 100644 --- a/frontend/src/views/Project/RolePage/RolePage.tsx +++ b/frontend/src/views/Project/RolePage/RolePage.tsx @@ -17,7 +17,7 @@ import { } from "@app/components/v2"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { withProjectPermission } from "@app/hoc"; -import { useDeleteProjectRole,useGetProjectRoleBySlug } from "@app/hooks/api"; +import { useDeleteProjectRole, useGetProjectRoleBySlug } from "@app/hooks/api"; import { usePopUp } from "@app/hooks/usePopUp"; import { TabSections } from "../Types"; @@ -76,7 +76,9 @@ export const RolePage = withProjectPermission( variant="link" type="submit" leftIcon={} - onClick={() => router.push(`/project/${projectId}/members?selectedTab=${TabSections.Roles}`)} + onClick={() => + router.push(`/project/${projectId}/members?selectedTab=${TabSections.Roles}`) + } className="mb-4" > Roles @@ -139,7 +141,7 @@ export const RolePage = withProjectPermission(
- +
)} diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts index 84ffc85d1..94a118058 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.ts @@ -178,7 +178,7 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true; } else if (subject === ProjectPermissionSub.SecretFolders) { const canRead = action.includes(ProjectPermissionActions.Read); - if (!formVal[subject]) formVal[subject] = []; + if (!formVal[subject]) formVal[subject] = [{}]; // from above statement we are sure it won't be undefined if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx index 8f2cce4a1..3828d9c21 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/RolePermissionsSection.tsx @@ -2,7 +2,6 @@ import { FormProvider, useForm } from "react-hook-form"; import { faPlus } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; -import { AnimatePresence } from "framer-motion"; import { createNotification } from "@app/components/notifications"; import { Button, Modal, ModalContent, ModalTrigger } from "@app/components/v2"; @@ -95,22 +94,21 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => { )}
- -
- {(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[]).map((subject) => ( - - {subject === ProjectPermissionSub.Secrets ? ( - - ) : undefined} - - ))} -
-
+
+ {(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[]).map((subject) => ( + + {subject === ProjectPermissionSub.Secrets ? ( + + ) : undefined} + + ))} +
handlePopUpToggle("createPolicy", isOpen)} diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx index e55180948..be3404dfe 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/GeneralPermissionOptions.tsx @@ -2,7 +2,7 @@ import { cloneElement } from "react"; import { Controller, useFieldArray, useFormContext } from "react-hook-form"; import { faChevronDown, faChevronRight, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { motion } from "framer-motion"; +import { AnimatePresence, motion } from "framer-motion"; import { Button, Checkbox, Tag } from "@app/components/v2"; import { ProjectPermissionSub } from "@app/context"; @@ -15,13 +15,15 @@ type Props = { subject: T; actions: TProjectPermissionObject[T]["actions"]; children?: JSX.Element; + isDisabled?: boolean; }; export const GeneralPermissionOptions = >({ subject, actions, children, - title + title, + isDisabled }: Props) => { const { control } = useFormContext(); const items = useFieldArray({ @@ -57,74 +59,93 @@ export const GeneralPermissionOptions = )}
- {isOpen && ( - - {items.fields.map((el, rootIndex) => ( -
-
-
Actions
-
- {actions.map(({ label, value }) => { - if (typeof value !== "string") return undefined; - return ( - ( -
- - {label} - -
- )} - /> - ); - })} -
-
- {children && - cloneElement(children, { - position: rootIndex - })} -
- {subject === ProjectPermissionSub.Secrets && ( - - )} - -
-
- ))} -
- )} +
+
Actions
+
+ {actions.map(({ label, value }) => { + if (typeof value !== "string") return undefined; + return ( + ( +
+ + {label} + +
+ )} + /> + ); + })} +
+
+ {children && + cloneElement(children, { + position: rootIndex + })} +
+ {!isDisabled && subject === ProjectPermissionSub.Secrets && ( + + )} + {!isDisabled && ( + + )}{" "} +
+ + ))} + + + )} +
); }; diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/NewPermissionRule.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/NewPermissionRule.tsx index 390e4d272..5950bee36 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/NewPermissionRule.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/NewPermissionRule.tsx @@ -90,16 +90,20 @@ export const NewPermissionRule = ({ onClose }: Props) => { onClick={form.handleSubmit((el) => { const rootPolicyValue = rootForm.getValues("permissions")?.[el.type]; if (rootPolicyValue && selectedSubject === ProjectPermissionSub.Secrets) { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore-error akhilmhdh: this is because of ts collision with both - rootForm.setValue(`permissions.${el.type}`, [ - ...rootPolicyValue, - ...(el?.permissions[el.type] || []) - ]); + rootForm.setValue( + `permissions.${el.type}`, + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore-error akhilmhdh: this is because of ts collision with both + [...rootPolicyValue, ...(el?.permissions[el.type] || [])], + { shouldDirty: true, shouldTouch: true } + ); } else { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore-error akhilmhdh: this is because of ts collision with both - rootForm.setValue(`permissions.${el.type}`, el?.permissions?.[el.type]); + rootForm.setValue(`permissions.${el.type}`, el?.permissions?.[el.type], { + shouldDirty: true, + shouldTouch: true + }); } onClose(); })} diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx index a4713cfbf..f724f8121 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/components/SecretPermissionConditions.tsx @@ -9,9 +9,10 @@ import { TFormSchema } from "../ProjectRoleModifySection.utils"; type Props = { position?: number; + isDisabled?: boolean; }; -export const SecretPermissionConditions = ({ position = 0 }: Props) => { +export const SecretPermissionConditions = ({ position = 0, isDisabled }: Props) => { const { control } = useFormContext(); const items = useFieldArray({ control, @@ -108,6 +109,7 @@ export const SecretPermissionConditions = ({ position = 0 }: Props) => { variant="star" size="xs" className="mt-3" + isDisabled={isDisabled} onClick={() => items.append({ lhs: "environment",