mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 06:35:21 +00:00
feature: project templates with docs
This commit is contained in:
@@ -3,7 +3,7 @@ import { ForbiddenError } from "@casl/ability";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectPermissionCmekActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { ProjectServiceActor } from "@app/lib/types";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
import {
|
||||
TCmekDecryptDTO,
|
||||
TCmekEncryptDTO,
|
||||
@@ -23,7 +23,7 @@ type TCmekServiceFactoryDep = {
|
||||
export type TCmekServiceFactory = ReturnType<typeof cmekServiceFactory>;
|
||||
|
||||
export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TCmekServiceFactoryDep) => {
|
||||
const createCmek = async ({ projectId, ...dto }: TCreateCmekDTO, actor: ProjectServiceActor) => {
|
||||
const createCmek = async ({ projectId, ...dto }: TCreateCmekDTO, actor: OrgServiceActor) => {
|
||||
const { permission } = await permissionService.getProjectPermission(
|
||||
actor.type,
|
||||
actor.id,
|
||||
@@ -43,7 +43,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
|
||||
return cmek;
|
||||
};
|
||||
|
||||
const updateCmekById = async ({ keyId, ...data }: TUpdabteCmekByIdDTO, actor: ProjectServiceActor) => {
|
||||
const updateCmekById = async ({ keyId, ...data }: TUpdabteCmekByIdDTO, actor: OrgServiceActor) => {
|
||||
const key = await kmsDAL.findById(keyId);
|
||||
|
||||
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
|
||||
@@ -65,7 +65,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
|
||||
return cmek;
|
||||
};
|
||||
|
||||
const deleteCmekById = async (keyId: string, actor: ProjectServiceActor) => {
|
||||
const deleteCmekById = async (keyId: string, actor: OrgServiceActor) => {
|
||||
const key = await kmsDAL.findById(keyId);
|
||||
|
||||
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
|
||||
@@ -87,10 +87,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
|
||||
return cmek;
|
||||
};
|
||||
|
||||
const listCmeksByProjectId = async (
|
||||
{ projectId, ...filters }: TListCmeksByProjectIdDTO,
|
||||
actor: ProjectServiceActor
|
||||
) => {
|
||||
const listCmeksByProjectId = async ({ projectId, ...filters }: TListCmeksByProjectIdDTO, actor: OrgServiceActor) => {
|
||||
const { permission } = await permissionService.getProjectPermission(
|
||||
actor.type,
|
||||
actor.id,
|
||||
@@ -106,7 +103,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
|
||||
return { cmeks, totalCount };
|
||||
};
|
||||
|
||||
const cmekEncrypt = async ({ keyId, plaintext }: TCmekEncryptDTO, actor: ProjectServiceActor) => {
|
||||
const cmekEncrypt = async ({ keyId, plaintext }: TCmekEncryptDTO, actor: OrgServiceActor) => {
|
||||
const key = await kmsDAL.findById(keyId);
|
||||
|
||||
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
|
||||
@@ -132,7 +129,7 @@ export const cmekServiceFactory = ({ kmsService, kmsDAL, permissionService }: TC
|
||||
return cipherTextBlob.toString("base64");
|
||||
};
|
||||
|
||||
const cmekDecrypt = async ({ keyId, ciphertext }: TCmekDecryptDTO, actor: ProjectServiceActor) => {
|
||||
const cmekDecrypt = async ({ keyId, ciphertext }: TCmekDecryptDTO, actor: OrgServiceActor) => {
|
||||
const key = await kmsDAL.findById(keyId);
|
||||
|
||||
if (!key) throw new NotFoundError({ message: `Key with ID ${keyId} not found` });
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@ import { ForbiddenError } from "@casl/ability";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectServiceActor } from "@app/lib/types";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
import { constructGroupOrgMembershipRoleMappings } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-fns";
|
||||
import { TSyncExternalGroupOrgMembershipRoleMappingsDTO } from "@app/services/external-group-org-role-mapping/external-group-org-role-mapping-types";
|
||||
import { TOrgRoleDALFactory } from "@app/services/org/org-role-dal";
|
||||
@@ -25,7 +25,7 @@ export const externalGroupOrgRoleMappingServiceFactory = ({
|
||||
permissionService,
|
||||
orgRoleDAL
|
||||
}: TExternalGroupOrgRoleMappingServiceFactoryDep) => {
|
||||
const listExternalGroupOrgRoleMappings = async (actor: ProjectServiceActor) => {
|
||||
const listExternalGroupOrgRoleMappings = async (actor: OrgServiceActor) => {
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor.type,
|
||||
actor.id,
|
||||
@@ -46,7 +46,7 @@ export const externalGroupOrgRoleMappingServiceFactory = ({
|
||||
|
||||
const updateExternalGroupOrgRoleMappings = async (
|
||||
dto: TSyncExternalGroupOrgMembershipRoleMappingsDTO,
|
||||
actor: ProjectServiceActor
|
||||
actor: OrgServiceActor
|
||||
) => {
|
||||
const { permission } = await permissionService.getOrgPermission(
|
||||
actor.type,
|
||||
|
||||
@@ -6,6 +6,7 @@ import { TLicenseServiceFactory } from "@app/ee/services/license/license-service
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { TProjectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-service";
|
||||
import { TKeyStoreFactory } from "@app/keystore/keystore";
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { infisicalSymmetricEncypt } from "@app/lib/crypto/encryption";
|
||||
@@ -94,7 +95,7 @@ type TProjectServiceFactoryDep = {
|
||||
orgDAL: Pick<TOrgDALFactory, "findOne">;
|
||||
keyStore: Pick<TKeyStoreFactory, "deleteItem">;
|
||||
projectBotDAL: Pick<TProjectBotDALFactory, "create">;
|
||||
projectRoleDAL: Pick<TProjectRoleDALFactory, "find">;
|
||||
projectRoleDAL: Pick<TProjectRoleDALFactory, "find" | "insertMany">;
|
||||
kmsService: Pick<
|
||||
TKmsServiceFactory,
|
||||
| "updateProjectSecretManagerKmsKey"
|
||||
@@ -104,6 +105,7 @@ type TProjectServiceFactoryDep = {
|
||||
| "getProjectSecretManagerKmsKeyId"
|
||||
| "deleteInternalKms"
|
||||
>;
|
||||
projectTemplateService: TProjectTemplateServiceFactory;
|
||||
};
|
||||
|
||||
export type TProjectServiceFactory = ReturnType<typeof projectServiceFactory>;
|
||||
@@ -134,7 +136,8 @@ export const projectServiceFactory = ({
|
||||
kmsService,
|
||||
projectBotDAL,
|
||||
projectSlackConfigDAL,
|
||||
slackIntegrationDAL
|
||||
slackIntegrationDAL,
|
||||
projectTemplateService
|
||||
}: TProjectServiceFactoryDep) => {
|
||||
/*
|
||||
* Create workspace. Make user the admin
|
||||
@@ -148,7 +151,8 @@ export const projectServiceFactory = ({
|
||||
slug: projectSlug,
|
||||
kmsKeyId,
|
||||
tx: trx,
|
||||
createDefaultEnvs = true
|
||||
createDefaultEnvs = true,
|
||||
templateId
|
||||
}: TCreateProjectDTO) => {
|
||||
const organization = await orgDAL.findOne({ id: actorOrgId });
|
||||
|
||||
@@ -183,6 +187,25 @@ export const projectServiceFactory = ({
|
||||
}
|
||||
}
|
||||
|
||||
let projectTemplate: Awaited<ReturnType<typeof projectTemplateService.findProjectTemplatesById>> | null = null;
|
||||
|
||||
if (templateId) {
|
||||
if (!plan.projectTemplates)
|
||||
throw new BadRequestError({
|
||||
message:
|
||||
"Failed to apply project template due to plan restriction. Upgrade plan to access project templates."
|
||||
});
|
||||
|
||||
projectTemplate = await projectTemplateService.findProjectTemplatesById(templateId, {
|
||||
id: actorId,
|
||||
orgId: organization.id,
|
||||
type: actor,
|
||||
authMethod: actorAuthMethod
|
||||
});
|
||||
|
||||
if (!projectTemplate) throw new NotFoundError({ message: `Project template with ID ${templateId} not found.` });
|
||||
}
|
||||
|
||||
const project = await projectDAL.create(
|
||||
{
|
||||
name: workspaceName,
|
||||
@@ -210,7 +233,24 @@ export const projectServiceFactory = ({
|
||||
|
||||
// set default environments and root folder for provided environments
|
||||
let envs: TProjectEnvironments[] = [];
|
||||
if (createDefaultEnvs) {
|
||||
if (projectTemplate) {
|
||||
envs = await projectEnvDAL.insertMany(
|
||||
projectTemplate.environments.map((env) => ({ ...env, projectId: project.id })),
|
||||
tx
|
||||
);
|
||||
await folderDAL.insertMany(
|
||||
envs.map(({ id }) => ({ name: ROOT_FOLDER_NAME, envId: id, version: 1 })),
|
||||
tx
|
||||
);
|
||||
await projectRoleDAL.insertMany(
|
||||
projectTemplate.packedRoles.map((role) => ({
|
||||
...role,
|
||||
permissions: JSON.stringify(role.permissions),
|
||||
projectId: project.id
|
||||
})),
|
||||
tx
|
||||
);
|
||||
} else if (createDefaultEnvs) {
|
||||
envs = await projectEnvDAL.insertMany(
|
||||
DEFAULT_PROJECT_ENVS.map((el, i) => ({ ...el, projectId: project.id, position: i + 1 })),
|
||||
tx
|
||||
|
||||
@@ -32,6 +32,7 @@ export type TCreateProjectDTO = {
|
||||
slug?: string;
|
||||
kmsKeyId?: string;
|
||||
createDefaultEnvs?: boolean;
|
||||
templateId?: string;
|
||||
tx?: Knex;
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { TSecretSnapshotServiceFactory } from "@app/ee/services/secret-snapshot/secret-snapshot-service";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { OrderByDirection, ProjectServiceActor } from "@app/lib/types";
|
||||
import { OrderByDirection, OrgServiceActor } from "@app/lib/types";
|
||||
|
||||
import { TProjectDALFactory } from "../project/project-dal";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
@@ -514,7 +514,7 @@ export const secretFolderServiceFactory = ({
|
||||
|
||||
const getFoldersDeepByEnvs = async (
|
||||
{ projectId, environments, secretPath }: TGetFoldersDeepByEnvsDTO,
|
||||
actor: ProjectServiceActor
|
||||
actor: OrgServiceActor
|
||||
) => {
|
||||
// folder list is allowed to be read by anyone
|
||||
// permission to check does user have access
|
||||
|
||||
@@ -27,7 +27,7 @@ import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/
|
||||
import { groupBy, pick } from "@app/lib/fn";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||
import { ProjectServiceActor } from "@app/lib/types";
|
||||
import { OrgServiceActor } from "@app/lib/types";
|
||||
import { TGetSecretsRawByFolderMappingsDTO } from "@app/services/secret-v2-bridge/secret-v2-bridge-types";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
@@ -2849,7 +2849,7 @@ export const secretServiceFactory = ({
|
||||
|
||||
const getSecretsRawByFolderMappings = async (
|
||||
params: Omit<TGetSecretsRawByFolderMappingsDTO, "userId">,
|
||||
actor: ProjectServiceActor
|
||||
actor: OrgServiceActor
|
||||
) => {
|
||||
const { shouldUseSecretV2Bridge } = await projectBotService.getBotKey(params.projectId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user