Merge pull request #1809 from akhilmhdh/fix/patches-v2

Workspace slug support in secret v3 Get Key
This commit is contained in:
Maidul Islam
2024-05-09 12:17:14 -04:00
committed by GitHub
5 changed files with 20 additions and 8 deletions
+3 -1
View File
@@ -288,7 +288,8 @@ export const RAW_SECRETS = {
recursive: recursive:
"Whether or not to fetch all secrets from the specified base path, and all of its subdirectories. Note, the max depth is 20 deep.", "Whether or not to fetch all secrets from the specified base path, and all of its subdirectories. Note, the max depth is 20 deep.",
workspaceId: "The ID of the project to list secrets from.", workspaceId: "The ID of the project to list secrets from.",
workspaceSlug: "The slug of the project to list secrets from. This parameter is only usable by machine identities.", workspaceSlug:
"The slug of the project to list secrets from. This parameter is only applicable by machine identities.",
environment: "The slug of the environment to list secrets from.", environment: "The slug of the environment to list secrets from.",
secretPath: "The secret path to list secrets from.", secretPath: "The secret path to list secrets from.",
includeImports: "Weather to include imported secrets or not." includeImports: "Weather to include imported secrets or not."
@@ -307,6 +308,7 @@ export const RAW_SECRETS = {
GET: { GET: {
secretName: "The name of the secret to get.", secretName: "The name of the secret to get.",
workspaceId: "The ID of the project to get the secret from.", workspaceId: "The ID of the project to get the secret from.",
workspaceSlug: "The slug of the project to get the secret from.",
environment: "The slug of the environment to get the secret from.", environment: "The slug of the environment to get the secret from.",
secretPath: "The path of the secret to get.", secretPath: "The path of the secret to get.",
version: "The version of the secret to get.", version: "The version of the secret to get.",
@@ -293,6 +293,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}), }),
querystring: z.object({ querystring: z.object({
workspaceId: z.string().trim().optional().describe(RAW_SECRETS.GET.workspaceId), workspaceId: z.string().trim().optional().describe(RAW_SECRETS.GET.workspaceId),
workspaceSlug: z.string().trim().optional().describe(RAW_SECRETS.GET.workspaceSlug),
environment: z.string().trim().optional().describe(RAW_SECRETS.GET.environment), environment: z.string().trim().optional().describe(RAW_SECRETS.GET.environment),
secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.GET.secretPath), secretPath: z.string().trim().default("/").transform(removeTrailingSlash).describe(RAW_SECRETS.GET.secretPath),
version: z.coerce.number().optional().describe(RAW_SECRETS.GET.version), version: z.coerce.number().optional().describe(RAW_SECRETS.GET.version),
@@ -311,6 +312,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}, },
onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]), onRequest: verifyAuth([AuthMode.JWT, AuthMode.API_KEY, AuthMode.SERVICE_TOKEN, AuthMode.IDENTITY_ACCESS_TOKEN]),
handler: async (req) => { handler: async (req) => {
const { workspaceSlug } = req.query;
let { secretPath, environment, workspaceId } = req.query; let { secretPath, environment, workspaceId } = req.query;
if (req.auth.actor === ActorType.SERVICE) { if (req.auth.actor === ActorType.SERVICE) {
const scope = ServiceTokenScopes.parse(req.auth.serviceToken.scopes); const scope = ServiceTokenScopes.parse(req.auth.serviceToken.scopes);
@@ -322,7 +324,9 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
} }
} }
if (!workspaceId || !environment) throw new BadRequestError({ message: "Missing workspace id or environment" }); if (!environment) throw new BadRequestError({ message: "Missing environment" });
if (!workspaceId && !workspaceSlug)
throw new BadRequestError({ message: "You must provide workspaceSlug or workspaceId" });
const secret = await server.services.secret.getSecretByNameRaw({ const secret = await server.services.secret.getSecretByNameRaw({
actorId: req.permission.id, actorId: req.permission.id,
@@ -331,6 +335,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
environment, environment,
projectId: workspaceId, projectId: workspaceId,
projectSlug: workspaceSlug,
path: secretPath, path: secretPath,
secretName: req.params.secretName, secretName: req.params.secretName,
type: req.query.type, type: req.query.type,
@@ -339,7 +344,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
}); });
await server.services.auditLog.createAuditLog({ await server.services.auditLog.createAuditLog({
projectId: req.query.workspaceId, projectId: secret.workspace,
...req.auditLogInfo, ...req.auditLogInfo,
event: { event: {
type: EventType.GET_SECRET, type: EventType.GET_SECRET,
@@ -358,7 +363,7 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
distinctId: getTelemetryDistinctId(req), distinctId: getTelemetryDistinctId(req),
properties: { properties: {
numberOfSecrets: 1, numberOfSecrets: 1,
workspaceId, workspaceId: secret.workspace,
environment, environment,
secretPath: req.query.secretPath, secretPath: req.query.secretPath,
channel: getUserAgentType(req.headers["user-agent"]), channel: getUserAgentType(req.headers["user-agent"]),
@@ -52,7 +52,7 @@ export const identityUaServiceFactory = ({
}: TIdentityUaServiceFactoryDep) => { }: TIdentityUaServiceFactoryDep) => {
const login = async (clientId: string, clientSecret: string, ip: string) => { const login = async (clientId: string, clientSecret: string, ip: string) => {
const identityUa = await identityUaDAL.findOne({ clientId }); const identityUa = await identityUaDAL.findOne({ clientId });
if (!identityUa) throw new UnauthorizedError(); if (!identityUa) throw new UnauthorizedError({ message: "Invalid credentials" });
const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityUa.identityId }); const identityMembershipOrg = await identityOrgMembershipDAL.findOne({ identityId: identityUa.identityId });
@@ -68,7 +68,7 @@ export const identityUaServiceFactory = ({
const validClientSecretInfo = clientSecrtInfo.find(({ clientSecretHash }) => const validClientSecretInfo = clientSecrtInfo.find(({ clientSecretHash }) =>
bcrypt.compareSync(clientSecret, clientSecretHash) bcrypt.compareSync(clientSecret, clientSecretHash)
); );
if (!validClientSecretInfo) throw new UnauthorizedError(); if (!validClientSecretInfo) throw new UnauthorizedError({ message: "Invalid credentials" });
const { clientSecretTTL, clientSecretNumUses, clientSecretNumUsesLimit } = validClientSecretInfo; const { clientSecretTTL, clientSecretNumUses, clientSecretNumUsesLimit } = validClientSecretInfo;
if (Number(clientSecretTTL) > 0) { if (Number(clientSecretTTL) > 0) {
@@ -972,7 +972,8 @@ export const secretServiceFactory = ({
path, path,
actor, actor,
environment, environment,
projectId, projectId: workspaceId,
projectSlug,
actorId, actorId,
actorOrgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
@@ -980,6 +981,8 @@ export const secretServiceFactory = ({
includeImports, includeImports,
version version
}: TGetASecretRawDTO) => { }: TGetASecretRawDTO) => {
const projectId = workspaceId || (await projectDAL.findProjectBySlug(projectSlug as string, actorOrgId)).id;
const botKey = await projectBotService.getBotKey(projectId); const botKey = await projectBotService.getBotKey(projectId);
if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" }); if (!botKey) throw new BadRequestError({ message: "Project bot not found", name: "bot_not_found_error" });
+3 -1
View File
@@ -152,7 +152,9 @@ export type TGetASecretRawDTO = {
type: "shared" | "personal"; type: "shared" | "personal";
includeImports?: boolean; includeImports?: boolean;
version?: number; version?: number;
} & TProjectPermission; projectSlug?: string;
projectId?: string;
} & Omit<TProjectPermission, "projectId">;
export type TCreateSecretRawDTO = TProjectPermission & { export type TCreateSecretRawDTO = TProjectPermission & {
secretPath: string; secretPath: string;