mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge pull request #3816 from Infisical/fix/addProjectSlugToSecretsV3
Add projectSlug parameter on secrets v3 endpoints
This commit is contained in:
@@ -4,7 +4,7 @@ import { z } from "zod";
|
||||
import { SecretApprovalRequestsSchema, SecretsSchema, SecretType, ServiceTokenScopes } from "@app/db/schemas";
|
||||
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { ApiDocsTags, RAW_SECRETS, SECRETS } from "@app/lib/api-docs";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { removeTrailingSlash } from "@app/lib/fn";
|
||||
import { secretsLimit, writeLimit } from "@app/server/config/rateLimiter";
|
||||
import { BaseSecretNameSchema, SecretNameSchema } from "@app/server/lib/schemas";
|
||||
@@ -12,7 +12,6 @@ import { getTelemetryDistinctId } from "@app/server/lib/telemetry";
|
||||
import { getUserAgentType } from "@app/server/plugins/audit-log";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { ActorType, AuthMode } from "@app/services/auth/auth-type";
|
||||
import { ProjectFilterType } from "@app/services/project/project-types";
|
||||
import { ResourceMetadataSchema } from "@app/services/resource-metadata/resource-metadata-schema";
|
||||
import { SecretOperations, SecretProtectionType } from "@app/services/secret/secret-types";
|
||||
import { SecretUpdateMode } from "@app/services/secret-v2-bridge/secret-v2-bridge-types";
|
||||
@@ -286,22 +285,17 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
environment = scope[0].environment;
|
||||
workspaceId = req.auth.serviceToken.projectId;
|
||||
}
|
||||
} else if (req.permission.type === ActorType.IDENTITY && req.query.workspaceSlug && !workspaceId) {
|
||||
const workspace = await server.services.project.getAProject({
|
||||
filter: {
|
||||
type: ProjectFilterType.SLUG,
|
||||
orgId: req.permission.orgId,
|
||||
slug: req.query.workspaceSlug
|
||||
},
|
||||
} else {
|
||||
const projectId = await server.services.project.extractProjectIdFromSlug({
|
||||
projectSlug: req.query.workspaceSlug,
|
||||
projectId: workspaceId,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId
|
||||
});
|
||||
|
||||
if (!workspace) throw new NotFoundError({ message: `No project found with slug ${req.query.workspaceSlug}` });
|
||||
|
||||
workspaceId = workspace.id;
|
||||
workspaceId = projectId;
|
||||
}
|
||||
|
||||
if (!workspaceId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" });
|
||||
@@ -442,11 +436,23 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
environment = scope[0].environment;
|
||||
workspaceId = req.auth.serviceToken.projectId;
|
||||
}
|
||||
} else {
|
||||
const projectId = await server.services.project.extractProjectIdFromSlug({
|
||||
projectSlug: workspaceSlug,
|
||||
projectId: workspaceId,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId
|
||||
});
|
||||
|
||||
workspaceId = projectId;
|
||||
}
|
||||
|
||||
if (!environment) throw new BadRequestError({ message: "Missing environment" });
|
||||
if (!workspaceId && !workspaceSlug)
|
||||
if (!workspaceId) {
|
||||
throw new BadRequestError({ message: "You must provide workspaceSlug or workspaceId" });
|
||||
}
|
||||
|
||||
const secret = await server.services.secret.getSecretByNameRaw({
|
||||
actorId: req.permission.id,
|
||||
@@ -457,7 +463,6 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
environment,
|
||||
projectId: workspaceId,
|
||||
viewSecretValue: req.query.viewSecretValue,
|
||||
projectSlug: workspaceSlug,
|
||||
path: secretPath,
|
||||
secretName: req.params.secretName,
|
||||
type: req.query.type,
|
||||
@@ -518,7 +523,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretName: SecretNameSchema.describe(RAW_SECRETS.CREATE.secretName)
|
||||
}),
|
||||
body: z.object({
|
||||
workspaceId: z.string().trim().describe(RAW_SECRETS.CREATE.workspaceId),
|
||||
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.CREATE.workspaceId),
|
||||
projectSlug: z.string().trim().optional().describe(RAW_SECRETS.CREATE.projectSlug),
|
||||
environment: z.string().trim().describe(RAW_SECRETS.CREATE.environment),
|
||||
secretPath: z
|
||||
.string()
|
||||
@@ -558,13 +564,22 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const projectId = await server.services.project.extractProjectIdFromSlug({
|
||||
projectSlug: req.body.projectSlug,
|
||||
projectId: req.body.workspaceId,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId
|
||||
});
|
||||
|
||||
const secretOperation = await server.services.secret.createSecretRaw({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
environment: req.body.environment,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
projectId: req.body.workspaceId,
|
||||
projectId,
|
||||
secretPath: req.body.secretPath,
|
||||
secretName: req.params.secretName,
|
||||
type: req.body.type,
|
||||
@@ -582,7 +597,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
|
||||
const { secret } = secretOperation;
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
projectId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.CREATE_SECRET,
|
||||
@@ -602,7 +617,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
distinctId: getTelemetryDistinctId(req),
|
||||
properties: {
|
||||
numberOfSecrets: 1,
|
||||
workspaceId: req.body.workspaceId,
|
||||
workspaceId: projectId,
|
||||
environment: req.body.environment,
|
||||
secretPath: req.body.secretPath,
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
@@ -633,7 +648,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretName: BaseSecretNameSchema.describe(RAW_SECRETS.UPDATE.secretName)
|
||||
}),
|
||||
body: z.object({
|
||||
workspaceId: z.string().trim().describe(RAW_SECRETS.UPDATE.workspaceId),
|
||||
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.UPDATE.workspaceId),
|
||||
projectSlug: z.string().trim().optional().describe(RAW_SECRETS.UPDATE.projectSlug),
|
||||
environment: z.string().trim().describe(RAW_SECRETS.UPDATE.environment),
|
||||
secretValue: z
|
||||
.string()
|
||||
@@ -679,13 +695,22 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const projectId = await server.services.project.extractProjectIdFromSlug({
|
||||
projectSlug: req.body.projectSlug,
|
||||
projectId: req.body.workspaceId,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId
|
||||
});
|
||||
|
||||
const secretOperation = await server.services.secret.updateSecretRaw({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
environment: req.body.environment,
|
||||
projectId: req.body.workspaceId,
|
||||
projectId,
|
||||
secretPath: req.body.secretPath,
|
||||
secretName: req.params.secretName,
|
||||
type: req.body.type,
|
||||
@@ -707,7 +732,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
const { secret } = secretOperation;
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
projectId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.UPDATE_SECRET,
|
||||
@@ -727,7 +752,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
distinctId: getTelemetryDistinctId(req),
|
||||
properties: {
|
||||
numberOfSecrets: 1,
|
||||
workspaceId: req.body.workspaceId,
|
||||
workspaceId: projectId,
|
||||
environment: req.body.environment,
|
||||
secretPath: req.body.secretPath,
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
@@ -757,7 +782,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretName: z.string().min(1).describe(RAW_SECRETS.DELETE.secretName)
|
||||
}),
|
||||
body: z.object({
|
||||
workspaceId: z.string().trim().describe(RAW_SECRETS.DELETE.workspaceId),
|
||||
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.DELETE.workspaceId),
|
||||
projectSlug: z.string().trim().optional().describe(RAW_SECRETS.DELETE.projectSlug),
|
||||
environment: z.string().trim().describe(RAW_SECRETS.DELETE.environment),
|
||||
secretPath: z
|
||||
.string()
|
||||
@@ -780,13 +806,22 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req) => {
|
||||
const projectId = await server.services.project.extractProjectIdFromSlug({
|
||||
projectSlug: req.body.projectSlug,
|
||||
projectId: req.body.workspaceId,
|
||||
actorId: req.permission.id,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actor: req.permission.type,
|
||||
actorOrgId: req.permission.orgId
|
||||
});
|
||||
|
||||
const secretOperation = await server.services.secret.deleteSecretRaw({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type,
|
||||
actorAuthMethod: req.permission.authMethod,
|
||||
actorOrgId: req.permission.orgId,
|
||||
environment: req.body.environment,
|
||||
projectId: req.body.workspaceId,
|
||||
projectId,
|
||||
secretPath: req.body.secretPath,
|
||||
secretName: req.params.secretName,
|
||||
type: req.body.type
|
||||
@@ -798,7 +833,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
const { secret } = secretOperation;
|
||||
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
projectId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.DELETE_SECRET,
|
||||
@@ -817,7 +852,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
distinctId: getTelemetryDistinctId(req),
|
||||
properties: {
|
||||
numberOfSecrets: 1,
|
||||
workspaceId: req.body.workspaceId,
|
||||
workspaceId: projectId,
|
||||
environment: req.body.environment,
|
||||
secretPath: req.body.secretPath,
|
||||
channel: getUserAgentType(req.headers["user-agent"]),
|
||||
|
||||
@@ -42,7 +42,7 @@ import { TProjectPermission } from "@app/lib/types";
|
||||
import { TQueueServiceFactory } from "@app/queue";
|
||||
import { TPkiSubscriberDALFactory } from "@app/services/pki-subscriber/pki-subscriber-dal";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
import { ActorAuthMethod, ActorType } from "../auth/auth-type";
|
||||
import { TCertificateDALFactory } from "../certificate/certificate-dal";
|
||||
import { TCertificateAuthorityDALFactory } from "../certificate-authority/certificate-authority-dal";
|
||||
import { expandInternalCa } from "../certificate-authority/certificate-authority-fns";
|
||||
@@ -82,6 +82,7 @@ import { assignWorkspaceKeysToMembers, bootstrapSshProject, createProjectKey } f
|
||||
import { TProjectQueueFactory } from "./project-queue";
|
||||
import { TProjectSshConfigDALFactory } from "./project-ssh-config-dal";
|
||||
import {
|
||||
ProjectFilterType,
|
||||
TCreateProjectDTO,
|
||||
TDeleteProjectDTO,
|
||||
TDeleteProjectWorkflowIntegration,
|
||||
@@ -866,6 +867,39 @@ export const projectServiceFactory = ({
|
||||
});
|
||||
};
|
||||
|
||||
const extractProjectIdFromSlug = async ({
|
||||
projectSlug,
|
||||
projectId,
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actor,
|
||||
actorOrgId
|
||||
}: {
|
||||
projectSlug?: string;
|
||||
projectId?: string;
|
||||
actorId: string;
|
||||
actorAuthMethod: ActorAuthMethod;
|
||||
actor: ActorType;
|
||||
actorOrgId: string;
|
||||
}) => {
|
||||
if (projectId) return projectId;
|
||||
if (!projectSlug) throw new BadRequestError({ message: "You must provide projectSlug or workspaceId" });
|
||||
const project = await getAProject({
|
||||
filter: {
|
||||
type: ProjectFilterType.SLUG,
|
||||
orgId: actorOrgId,
|
||||
slug: projectSlug
|
||||
},
|
||||
actorId,
|
||||
actorAuthMethod,
|
||||
actor,
|
||||
actorOrgId
|
||||
});
|
||||
|
||||
if (!project) throw new NotFoundError({ message: `No project found with slug ${projectSlug}` });
|
||||
return project.id;
|
||||
};
|
||||
|
||||
const getProjectUpgradeStatus = async ({
|
||||
projectId,
|
||||
actor,
|
||||
@@ -2006,6 +2040,7 @@ export const projectServiceFactory = ({
|
||||
getProjectSshConfig,
|
||||
updateProjectSshConfig,
|
||||
requestProjectAccess,
|
||||
searchProjects
|
||||
searchProjects,
|
||||
extractProjectIdFromSlug
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1543,9 +1543,8 @@ export const secretServiceFactory = ({
|
||||
actor,
|
||||
environment,
|
||||
viewSecretValue,
|
||||
projectId: workspaceId,
|
||||
projectId,
|
||||
expandSecretReferences,
|
||||
projectSlug,
|
||||
actorId,
|
||||
actorOrgId,
|
||||
actorAuthMethod,
|
||||
@@ -1553,7 +1552,6 @@ export const secretServiceFactory = ({
|
||||
includeImports,
|
||||
version
|
||||
}: TGetASecretRawDTO) => {
|
||||
const projectId = workspaceId || (await projectDAL.findProjectBySlug(projectSlug as string, actorOrgId)).id;
|
||||
const { botKey, shouldUseSecretV2Bridge } = await projectBotService.getBotKey(projectId);
|
||||
if (shouldUseSecretV2Bridge) {
|
||||
const secret = await secretV2BridgeService.getSecretByName({
|
||||
|
||||
@@ -229,8 +229,7 @@ export type TGetASecretRawDTO = {
|
||||
type: "shared" | "personal";
|
||||
includeImports?: boolean;
|
||||
version?: number;
|
||||
projectSlug?: string;
|
||||
projectId?: string;
|
||||
projectId: string;
|
||||
} & Omit<TProjectPermission, "projectId">;
|
||||
|
||||
export type TGetASecretByIdRawDTO = {
|
||||
|
||||
Reference in New Issue
Block a user