fix: permission error instead of not found error on single secret import

This commit is contained in:
Daniel Hougaard
2025-03-05 22:47:40 +04:00
parent ea9da6d2a8
commit bdbb6346cb
2 changed files with 38 additions and 15 deletions
@@ -3,10 +3,10 @@ import { groupBy, unique } from "@app/lib/fn";
import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema"; import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema";
import { TSecretDALFactory } from "../secret/secret-dal"; import { TSecretDALFactory } from "../secret/secret-dal";
import { INFISICAL_SECRET_VALUE_HIDDEN_MASK } from "../secret/secret-fns";
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal"; import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal"; import { TSecretV2BridgeDALFactory } from "../secret-v2-bridge/secret-v2-bridge-dal";
import { TSecretImportDALFactory } from "./secret-import-dal"; import { TSecretImportDALFactory } from "./secret-import-dal";
import { INFISICAL_SECRET_VALUE_HIDDEN_MASK } from "../secret/secret-fns";
type TSecretImportSecrets = { type TSecretImportSecrets = {
secretPath: string; secretPath: string;
@@ -33,6 +33,12 @@ type TSecretImportSecretsV2 = {
folderId: string | undefined; folderId: string | undefined;
importFolderId: string; importFolderId: string;
secrets: (TSecretsV2 & { secrets: (TSecretsV2 & {
secretTags: {
slug: string;
name: string;
color?: string | null;
id: string;
}[];
workspace: string; workspace: string;
environment: string; environment: string;
_id: string; _id: string;
@@ -175,7 +181,10 @@ export const fnSecretsV2FromImports = async ({
const stack: { const stack: {
secretImports: typeof rootSecretImports; secretImports: typeof rootSecretImports;
depth: number; depth: number;
parentImportedSecrets: (TSecretsV2 & { secretValueHidden: boolean })[]; parentImportedSecrets: (TSecretsV2 & {
secretValueHidden: boolean;
secretTags: { slug: string; name: string; id: string; color: string }[];
})[];
}[] = [{ secretImports: rootSecretImports, depth: 0, parentImportedSecrets: [] }]; }[] = [{ secretImports: rootSecretImports, depth: 0, parentImportedSecrets: [] }];
const processedImports: TSecretImportSecretsV2[] = []; const processedImports: TSecretImportSecretsV2[] = [];
@@ -237,6 +246,7 @@ export const fnSecretsV2FromImports = async ({
secretKey: item.key, secretKey: item.key,
secretValue: viewSecretValue ? decryptor(item.encryptedValue) : INFISICAL_SECRET_VALUE_HIDDEN_MASK, secretValue: viewSecretValue ? decryptor(item.encryptedValue) : INFISICAL_SECRET_VALUE_HIDDEN_MASK,
secretValueHidden: !viewSecretValue, secretValueHidden: !viewSecretValue,
secretTags: item.tags,
secretComment: decryptor(item.encryptedComment), secretComment: decryptor(item.encryptedComment),
environment: importEnv.slug, environment: importEnv.slug,
workspace: "", // This field should not be used, it's only here to keep the older Python SDK versions backwards compatible with the new Postgres backend. workspace: "", // This field should not be used, it's only here to keep the older Python SDK versions backwards compatible with the new Postgres backend.
@@ -1234,7 +1234,7 @@ export const secretV2BridgeServiceFactory = ({
decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""), decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""),
expandSecretReferences: shouldExpandSecretReferences ? expandSecretReferences : undefined, expandSecretReferences: shouldExpandSecretReferences ? expandSecretReferences : undefined,
hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => { hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => {
const canDescribe = permission.can( return permission.can(
ProjectPermissionSecretActions.DescribeSecret, ProjectPermissionSecretActions.DescribeSecret,
subject(ProjectPermissionSub.Secrets, { subject(ProjectPermissionSub.Secrets, {
environment: expandEnvironment, environment: expandEnvironment,
@@ -1243,17 +1243,6 @@ export const secretV2BridgeServiceFactory = ({
secretTags: expandSecretTags secretTags: expandSecretTags
}) })
); );
const canReadValue = permission.can(
ProjectPermissionSecretActions.ReadValue,
subject(ProjectPermissionSub.Secrets, {
environment: expandEnvironment,
secretPath: expandSecretPath,
secretName: expandSecretKey,
secretTags: expandSecretTags
})
);
return viewSecretValue ? canDescribe && canReadValue : canDescribe;
} }
}); });
@@ -1261,6 +1250,30 @@ export const secretV2BridgeServiceFactory = ({
for (let j = 0; j < importedSecrets[i].secrets.length; j += 1) { for (let j = 0; j < importedSecrets[i].secrets.length; j += 1) {
const importedSecret = importedSecrets[i].secrets[j]; const importedSecret = importedSecrets[i].secrets[j];
if (secretName === importedSecret.key) { if (secretName === importedSecret.key) {
let secretValueHidden = true;
if (viewSecretValue) {
if (
!permission.can(
ProjectPermissionSecretActions.ReadValue,
subject(ProjectPermissionSub.Secrets, {
environment: importedSecret.environment,
secretPath: importedSecrets[i].secretPath,
secretName: importedSecret.key,
secretTags: (importedSecret.secretTags || []).map((el) => el.slug)
})
) &&
secretType !== SecretType.Personal
) {
throw new ForbiddenRequestError({
message: `You do not have permission to view secret import value on secret with name '${secretName}'`,
name: "ForbiddenReadSecretError"
});
}
secretValueHidden = false;
}
return reshapeBridgeSecret( return reshapeBridgeSecret(
projectId, projectId,
importedSecrets[i].environment, importedSecrets[i].environment,
@@ -1270,7 +1283,7 @@ export const secretV2BridgeServiceFactory = ({
value: importedSecret.secretValue || "", value: importedSecret.secretValue || "",
comment: importedSecret.secretComment || "" comment: importedSecret.secretComment || ""
}, },
importedSecret.secretValueHidden secretValueHidden
); );
} }
} }