mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 17:30:06 +00:00
feat(rbac): implemented project based permission loading and role management
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
export { useCreateRole, useDeleteRole, useUpdateRole } from "./mutation";
|
||||
export { useGetRoles, useGetUserOrgPermissions } from "./queries";
|
||||
export { useGetRoles, useGetUserOrgPermissions,useGetUserProjectPermissions } from "./queries";
|
||||
|
||||
@@ -5,22 +5,22 @@ import { apiRequest } from "@app/config/request";
|
||||
import { roleQueryKeys } from "./queries";
|
||||
import { TCreateRoleDTO, TDeleteRoleDTO, TUpdateRoleDTO } from "./types";
|
||||
|
||||
export const useCreateRole = () => {
|
||||
export const useCreateRole = <T extends string | undefined>() => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (dto: TCreateRoleDTO) => apiRequest.post("/api/v1/roles", dto),
|
||||
mutationFn: (dto: TCreateRoleDTO<T>) => apiRequest.post("/api/v1/roles", dto),
|
||||
onSuccess: (_, { orgId, workspaceId }) => {
|
||||
queryClient.invalidateQueries(roleQueryKeys.getRoles({ orgId, workspaceId }));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const useUpdateRole = () => {
|
||||
export const useUpdateRole = <T extends string | undefined>() => {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ id, ...dto }: TUpdateRoleDTO) => apiRequest.patch(`/api/v1/roles/${id}`, dto),
|
||||
mutationFn: ({ id, ...dto }: TUpdateRoleDTO<T>) => apiRequest.patch(`/api/v1/roles/${id}`, dto),
|
||||
onSuccess: (_, { orgId, workspaceId }) => {
|
||||
queryClient.invalidateQueries(roleQueryKeys.getRoles({ orgId, workspaceId }));
|
||||
}
|
||||
|
||||
@@ -4,22 +4,33 @@ import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
import { OrgPermissionSet } from "@app/context/OrgPermissionContext/types";
|
||||
import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext/types";
|
||||
|
||||
import { TGetRolesDTO, TGetUserOrgPermissionsDTO, TRole } from "./types";
|
||||
import {
|
||||
TGetRolesDTO,
|
||||
TGetUserOrgPermissionsDTO,
|
||||
TGetUserProjectPermissionDTO,
|
||||
TRole
|
||||
} from "./types";
|
||||
|
||||
export const roleQueryKeys = {
|
||||
getRoles: ({ orgId, workspaceId }: TGetRolesDTO) => ["roles", { orgId, workspaceId }] as const,
|
||||
getUserOrgPermissions: ({ orgId }: TGetUserOrgPermissionsDTO) =>
|
||||
["user-permissions", { orgId }] as const
|
||||
["user-permissions", { orgId }] as const,
|
||||
getUserProjectPermissions: ({ workspaceId }: TGetUserProjectPermissionDTO) =>
|
||||
["user-project-permissions", { workspaceId }] as const
|
||||
};
|
||||
|
||||
const getRoles = async ({ orgId, workspaceId }: TGetRolesDTO) => {
|
||||
const { data } = await apiRequest.get<{ data: { roles: TRole[] } }>("/api/v1/roles", {
|
||||
params: {
|
||||
workspaceId,
|
||||
orgId
|
||||
const { data } = await apiRequest.get<{ data: { roles: TRole<typeof workspaceId>[] } }>(
|
||||
"/api/v1/roles",
|
||||
{
|
||||
params: {
|
||||
workspaceId,
|
||||
orgId
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
return data.data.roles;
|
||||
};
|
||||
@@ -34,7 +45,7 @@ export const useGetRoles = ({ orgId, workspaceId }: TGetRolesDTO) =>
|
||||
const getUserOrgPermissions = async ({ orgId }: TGetUserOrgPermissionsDTO) => {
|
||||
const { data } = await apiRequest.get<{
|
||||
data: { permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[] };
|
||||
}>(`/api/v1/roles/${orgId}/permissions`, {});
|
||||
}>(`/api/v1/roles/organization/${orgId}/permissions`, {});
|
||||
|
||||
return data.data.permissions;
|
||||
};
|
||||
@@ -50,3 +61,23 @@ export const useGetUserOrgPermissions = ({ orgId }: TGetUserOrgPermissionsDTO) =
|
||||
return ability;
|
||||
}
|
||||
});
|
||||
|
||||
const getUserProjectPermissions = async ({ workspaceId }: TGetUserProjectPermissionDTO) => {
|
||||
const { data } = await apiRequest.get<{
|
||||
data: { permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[] };
|
||||
}>(`/api/v1/roles/workspace/${workspaceId}/permissions`, {});
|
||||
|
||||
return data.data.permissions;
|
||||
};
|
||||
|
||||
export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPermissionDTO) =>
|
||||
useQuery({
|
||||
queryKey: roleQueryKeys.getUserProjectPermissions({ workspaceId }),
|
||||
queryFn: () => getUserProjectPermissions({ workspaceId }),
|
||||
enabled: Boolean(workspaceId),
|
||||
select: (data) => {
|
||||
const rule = unpackRules<RawRuleOf<MongoAbility<ProjectPermissionSet>>>(data);
|
||||
const ability = createMongoAbility<ProjectPermissionSet>(rule);
|
||||
return ability;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,14 +3,14 @@ export type TGetRolesDTO = {
|
||||
workspaceId?: string;
|
||||
};
|
||||
|
||||
export type TRole = {
|
||||
export type TRole<T extends string | undefined> = {
|
||||
_id: string;
|
||||
organization: string;
|
||||
workspace: string;
|
||||
workspace: T;
|
||||
name: string;
|
||||
description: string;
|
||||
slug: string;
|
||||
permissions: TPermission[];
|
||||
permissions: T extends string ? TProjectPermission[] : TPermission[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
};
|
||||
@@ -29,20 +29,42 @@ type TWorkspacePermission = {
|
||||
subject: "workspace";
|
||||
};
|
||||
|
||||
export type TCreateRoleDTO = {
|
||||
export type TProjectPermission = TProjectGeneralPermission | TProjectWorkspacePermission;
|
||||
|
||||
type TProjectGeneralPermission = {
|
||||
condition?: Record<string, any>;
|
||||
action: "read" | "edit" | "create" | "delete";
|
||||
subject:
|
||||
| "member"
|
||||
| "role"
|
||||
| "settings"
|
||||
| "secrets"
|
||||
| "environments"
|
||||
| "folders"
|
||||
| "secret-imports"
|
||||
| "service-tokens";
|
||||
};
|
||||
|
||||
type TProjectWorkspacePermission = {
|
||||
condition?: Record<string, any>;
|
||||
action: "delete" | "edit";
|
||||
subject: "workspace";
|
||||
};
|
||||
|
||||
export type TCreateRoleDTO<T extends string | undefined> = {
|
||||
orgId: string;
|
||||
workspaceId?: string;
|
||||
workspaceId?: T;
|
||||
name: string;
|
||||
description?: string;
|
||||
slug: string;
|
||||
permissions: TPermission[];
|
||||
permissions: T extends string ? TProjectPermission[] : TPermission[];
|
||||
};
|
||||
|
||||
export type TUpdateRoleDTO = {
|
||||
export type TUpdateRoleDTO<T extends string | undefined> = {
|
||||
orgId: string;
|
||||
id: string;
|
||||
workspaceId?: string;
|
||||
} & Partial<Omit<TCreateRoleDTO, "orgId" | "workspaceId">>;
|
||||
workspaceId?: T;
|
||||
} & Partial<Omit<TCreateRoleDTO<T>, "orgId" | "workspaceId">>;
|
||||
|
||||
export type TDeleteRoleDTO = {
|
||||
orgId: string;
|
||||
@@ -53,3 +75,7 @@ export type TDeleteRoleDTO = {
|
||||
export type TGetUserOrgPermissionsDTO = {
|
||||
orgId: string;
|
||||
};
|
||||
|
||||
export type TGetUserProjectPermissionDTO = {
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user