mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-17 18:19:50 +00:00
feat: switched up all dal except policy ones
This commit is contained in:
@@ -29,6 +29,10 @@ export const newNamespaceRoleFactory = (_dto: TNamespaceRoleScopeFactoryDep): TR
|
||||
throw new BadRequestError({ message: "Invalid scope provided for the factory" });
|
||||
};
|
||||
|
||||
const isCustomRole: TRoleScopeFactory["isCustomRole"] = () => false;
|
||||
|
||||
const getPredefinedRoles: TRoleScopeFactory["getPredefinedRoles"] = async () => [];
|
||||
|
||||
return {
|
||||
onCreateRoleGuard,
|
||||
onUpdateRoleGuard,
|
||||
@@ -36,6 +40,8 @@ export const newNamespaceRoleFactory = (_dto: TNamespaceRoleScopeFactoryDep): TR
|
||||
onListRoleGuard,
|
||||
onGetRoleByIdGuard,
|
||||
onGetRoleBySlugGuard,
|
||||
getScopeField
|
||||
getScopeField,
|
||||
isCustomRole,
|
||||
getPredefinedRoles
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
import { AccessScope } from "@app/db/schemas";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import {
|
||||
orgAdminPermissions,
|
||||
orgMemberPermissions,
|
||||
orgNoAccessPermissions,
|
||||
OrgPermissionActions,
|
||||
OrgPermissionSubjects
|
||||
} from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
|
||||
import { TRoleScopeFactory } from "../role-types";
|
||||
import { isCustomOrgRole } from "@app/services/org/org-role-fns";
|
||||
|
||||
type TOrgRoleScopeFactoryDep = {
|
||||
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
|
||||
@@ -19,6 +26,8 @@ export const newOrgRoleFactory = ({ permissionService }: TOrgRoleScopeFactoryDep
|
||||
throw new BadRequestError({ message: "Invalid scope provided for the factory" });
|
||||
};
|
||||
|
||||
const isCustomRole: TRoleScopeFactory["isCustomRole"] = (role: string) => isCustomOrgRole(role);
|
||||
|
||||
const onCreateRoleGuard: TRoleScopeFactory["onCreateRoleGuard"] = async (dto) => {
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
dto.permission.type,
|
||||
@@ -85,6 +94,42 @@ export const newOrgRoleFactory = ({ permissionService }: TOrgRoleScopeFactoryDep
|
||||
ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Role);
|
||||
};
|
||||
|
||||
const getPredefinedRoles: TRoleScopeFactory["getPredefinedRoles"] = async (scopeData) => {
|
||||
const scopeField = getScopeField(scopeData);
|
||||
return [
|
||||
{
|
||||
id: "b11b49a9-09a9-4443-916a-4246f9ff2c69", // dummy userid
|
||||
name: "Admin",
|
||||
slug: "admin",
|
||||
orgId: scopeField.value,
|
||||
description: "Complete administration access over the organization",
|
||||
permissions: orgAdminPermissions,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
},
|
||||
{
|
||||
id: "b11b49a9-09a9-4443-916a-4246f9ff2c70", // dummy user for zod validation in response
|
||||
name: "Member",
|
||||
slug: "member",
|
||||
orgId: scopeField.value,
|
||||
description: "Non-administrative role in an organization",
|
||||
permissions: orgMemberPermissions,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
},
|
||||
{
|
||||
id: "b10d49a9-09a9-4443-916a-4246f9ff2c72", // dummy user for zod validation in response
|
||||
name: "No Access",
|
||||
slug: "no-access",
|
||||
orgId: scopeField.value,
|
||||
description: "No access to any resources in the organization",
|
||||
permissions: orgNoAccessPermissions,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
return {
|
||||
onCreateRoleGuard,
|
||||
onUpdateRoleGuard,
|
||||
@@ -92,6 +137,8 @@ export const newOrgRoleFactory = ({ permissionService }: TOrgRoleScopeFactoryDep
|
||||
onListRoleGuard,
|
||||
onGetRoleByIdGuard,
|
||||
onGetRoleBySlugGuard,
|
||||
getScopeField
|
||||
getScopeField,
|
||||
getPredefinedRoles,
|
||||
isCustomRole
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,17 +1,35 @@
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
import { AccessScope, ActionProjectType } from "@app/db/schemas";
|
||||
import { AccessScope, ActionProjectType, ProjectMembershipRole, ProjectType } from "@app/db/schemas";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service-types";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import {
|
||||
isCustomProjectRole,
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub
|
||||
} from "@app/ee/services/permission/project-permission";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
|
||||
import { TRoleScopeFactory } from "../role-types";
|
||||
import {
|
||||
cryptographicOperatorPermissions,
|
||||
projectAdminPermissions,
|
||||
projectMemberPermissions,
|
||||
projectNoAccessPermissions,
|
||||
projectViewerPermission,
|
||||
sshHostBootstrapPermissions
|
||||
} from "@app/ee/services/permission/default-roles";
|
||||
import { TProjectDALFactory } from "@app/services/project/project-dal";
|
||||
|
||||
type TProjectRoleScopeFactoryDep = {
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||
};
|
||||
|
||||
export const newProjectRoleFactory = ({ permissionService }: TProjectRoleScopeFactoryDep): TRoleScopeFactory => {
|
||||
export const newProjectRoleFactory = ({
|
||||
permissionService,
|
||||
projectDAL
|
||||
}: TProjectRoleScopeFactoryDep): TRoleScopeFactory => {
|
||||
const getScopeField: TRoleScopeFactory["getScopeField"] = (dto) => {
|
||||
if (dto.scope === AccessScope.Project) {
|
||||
return { key: "projectId" as const, value: dto.projectId };
|
||||
@@ -19,6 +37,8 @@ export const newProjectRoleFactory = ({ permissionService }: TProjectRoleScopeFa
|
||||
throw new BadRequestError({ message: "Invalid scope provided for the factory" });
|
||||
};
|
||||
|
||||
const isCustomRole: TRoleScopeFactory["isCustomRole"] = (role: string) => isCustomProjectRole(role);
|
||||
|
||||
const onCreateRoleGuard: TRoleScopeFactory["onCreateRoleGuard"] = async (dto) => {
|
||||
const scope = getScopeField(dto.scopeData);
|
||||
const { permission } = await permissionService.getProjectPermission({
|
||||
@@ -97,6 +117,78 @@ export const newProjectRoleFactory = ({ permissionService }: TProjectRoleScopeFa
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role);
|
||||
};
|
||||
|
||||
const getPredefinedRoles: TRoleScopeFactory["getPredefinedRoles"] = async (scopeData) => {
|
||||
const scope = getScopeField(scopeData);
|
||||
const project = await projectDAL.findById(scope.value);
|
||||
if (!project) throw new BadRequestError({ message: "Project not found" });
|
||||
const projectId = project.id;
|
||||
|
||||
return [
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Admin",
|
||||
slug: ProjectMembershipRole.Admin,
|
||||
permissions: projectAdminPermissions,
|
||||
description: "Full administrative access over a project",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
projectId
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Developer",
|
||||
slug: ProjectMembershipRole.Member,
|
||||
permissions: projectMemberPermissions,
|
||||
description: "Limited read/write role in a project",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
projectId
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "SSH Host Bootstrapper",
|
||||
slug: ProjectMembershipRole.SshHostBootstrapper,
|
||||
permissions: sshHostBootstrapPermissions,
|
||||
description: "Create and issue SSH Hosts in a project",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
projectId,
|
||||
type: ProjectType.SSH
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Cryptographic Operator",
|
||||
slug: ProjectMembershipRole.KmsCryptographicOperator,
|
||||
permissions: cryptographicOperatorPermissions,
|
||||
description: "Perform cryptographic operations, such as encryption and signing, in a project",
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
projectId,
|
||||
type: ProjectType.KMS
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "Viewer",
|
||||
slug: ProjectMembershipRole.Viewer,
|
||||
permissions: projectViewerPermission,
|
||||
description: "Only read role in a project",
|
||||
createdAt: new Date(),
|
||||
projectId,
|
||||
updatedAt: new Date()
|
||||
},
|
||||
{
|
||||
id: uuidv4(),
|
||||
name: "No Access",
|
||||
slug: ProjectMembershipRole.NoAccess,
|
||||
permissions: projectNoAccessPermissions,
|
||||
description: "No access to any resources in the project",
|
||||
createdAt: new Date(),
|
||||
projectId,
|
||||
updatedAt: new Date()
|
||||
}
|
||||
].filter(({ type }) => (type ? type === project.type : true));
|
||||
};
|
||||
|
||||
return {
|
||||
onCreateRoleGuard,
|
||||
onUpdateRoleGuard,
|
||||
@@ -104,6 +196,8 @@ export const newProjectRoleFactory = ({ permissionService }: TProjectRoleScopeFa
|
||||
onListRoleGuard,
|
||||
onGetRoleByIdGuard,
|
||||
onGetRoleBySlugGuard,
|
||||
getScopeField
|
||||
getScopeField,
|
||||
getPredefinedRoles,
|
||||
isCustomRole
|
||||
};
|
||||
};
|
||||
|
||||
@@ -16,20 +16,23 @@ import {
|
||||
TListRoleDTO,
|
||||
TUpdateRoleDTO
|
||||
} from "./role-types";
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
|
||||
type TRoleServiceFactoryDep = {
|
||||
roleDAL: TRoleDALFactory;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getOrgPermission">;
|
||||
projectDAL: Pick<TProjectDALFactory, "findById">;
|
||||
};
|
||||
|
||||
export type TRoleServiceFactory = ReturnType<typeof roleServiceFactory>;
|
||||
|
||||
export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceFactoryDep) => {
|
||||
export const roleServiceFactory = ({ roleDAL, permissionService, projectDAL }: TRoleServiceFactoryDep) => {
|
||||
const orgRoleFactory = newOrgRoleFactory({
|
||||
permissionService
|
||||
});
|
||||
const projectRoleFactory = newProjectRoleFactory({
|
||||
permissionService
|
||||
permissionService,
|
||||
projectDAL
|
||||
});
|
||||
const namespaceRoleFactory = newNamespaceRoleFactory({
|
||||
permissionService
|
||||
@@ -130,6 +133,7 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
await factory.onListRoleGuard(dto);
|
||||
|
||||
const scope = factory.getScopeField(scopeData);
|
||||
const predefinedRoles = await factory.getPredefinedRoles(scopeData);
|
||||
const roles = await roleDAL.find(
|
||||
{
|
||||
[scope.key]: scope.value
|
||||
@@ -137,7 +141,9 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
{ limit: dto.data.limit, offset: dto.data.offset, sort: [[`${TableName.Role}.slug` as "slug", "asc"]] }
|
||||
);
|
||||
|
||||
return { roles: roles.map((el) => ({ ...el, permissions: unpackPermissions(el.permissions) })) };
|
||||
return {
|
||||
roles: [...predefinedRoles, ...roles.map((el) => ({ ...el, permissions: unpackPermissions(el.permissions) }))]
|
||||
};
|
||||
};
|
||||
|
||||
const getRoleById = async (dto: TGetRoleByIdDTO) => {
|
||||
@@ -163,6 +169,14 @@ export const roleServiceFactory = ({ roleDAL, permissionService }: TRoleServiceF
|
||||
await factory.onGetRoleBySlugGuard(dto);
|
||||
|
||||
const scope = factory.getScopeField(scopeData);
|
||||
const isCustomRole = factory.isCustomRole(dto.selector.slug);
|
||||
if (!isCustomRole) {
|
||||
const predefinedRole = await factory.getPredefinedRoles(scopeData);
|
||||
const selectedRole = predefinedRole.find((el) => el.slug === dto.selector.slug);
|
||||
if (!selectedRole) throw new BadRequestError({ message: `Role with slug ${dto.selector.slug} not found` });
|
||||
return selectedRole;
|
||||
}
|
||||
|
||||
const role = await roleDAL.findOne({
|
||||
slug: selector.slug,
|
||||
[scope.key]: scope.value
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { AccessScopeData } from "@app/db/schemas";
|
||||
import { AccessScopeData, TRoles } from "@app/db/schemas";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
import { MongoAbility, RawRuleOf } from "@casl/ability";
|
||||
|
||||
export interface TRoleScopeFactory {
|
||||
onCreateRoleGuard: (arg: TCreateRoleDTO) => Promise<void>;
|
||||
onUpdateRoleGuard: (arg: TUpdateRoleDTO) => Promise<void>;
|
||||
onDeleteRoleGuard: (arg: TDeleteRoleDTO) => Promise<void>;
|
||||
onListRoleGuard: (arg: TListRoleDTO) => Promise<void>;
|
||||
getPredefinedRoles: (arg: AccessScopeData) => Promise<(TRoles & { permissions: RawRuleOf<MongoAbility>[] })[]>;
|
||||
onGetRoleByIdGuard: (arg: TGetRoleByIdDTO) => Promise<void>;
|
||||
onGetRoleBySlugGuard: (arg: TGetRoleBySlugDTO) => Promise<void>;
|
||||
getScopeField: (scope: AccessScopeData) => { key: "orgId" | "namespaceId" | "projectId"; value: string };
|
||||
isCustomRole: (role: string) => boolean;
|
||||
}
|
||||
|
||||
export type TCreateRoleDTO = {
|
||||
|
||||
Reference in New Issue
Block a user