mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
fix(view-secret-value): requested changes
This commit is contained in:
@@ -14,7 +14,7 @@ import {
|
||||
SecretSubjectFields
|
||||
} from "./project-permission";
|
||||
|
||||
export function CheckForbiddenErrorSecretsSubject(
|
||||
export function throwIfMissingSecretReadValueOrDescribePermission(
|
||||
permission: MongoAbility<ProjectPermissionSet> | PureAbility,
|
||||
action: Extract<
|
||||
ProjectPermissionSecretActions,
|
||||
@@ -43,7 +43,7 @@ export function CheckForbiddenErrorSecretsSubject(
|
||||
}
|
||||
}
|
||||
|
||||
export function CheckCanSecretsSubject(
|
||||
export function hasSecretReadValueOrDescribePermission(
|
||||
permission: MongoAbility<ProjectPermissionSet>,
|
||||
action: Extract<
|
||||
ProjectPermissionSecretActions,
|
||||
@@ -83,12 +83,10 @@ export function checkForInvalidPermissionCombination(permissions: z.infer<typeof
|
||||
|
||||
if (!hasReadValue && !hasDescribeSecret) return;
|
||||
|
||||
const hasBothDescribeAndReadValue =
|
||||
permission.action.includes(ProjectPermissionSecretActions.DescribeSecret) &&
|
||||
permission.action.includes(ProjectPermissionSecretActions.ReadValue);
|
||||
const hasBothDescribeAndReadValue = hasReadValue && hasDescribeSecret;
|
||||
|
||||
throw new BadRequestError({
|
||||
message: `You have selected Full Read Access, and ${
|
||||
message: `You have selected Read, and ${
|
||||
hasBothDescribeAndReadValue
|
||||
? "both Read Value and Describe Secret"
|
||||
: hasReadValue
|
||||
@@ -96,7 +94,7 @@ export function checkForInvalidPermissionCombination(permissions: z.infer<typeof
|
||||
: hasDescribeSecret
|
||||
? "Describe Secret"
|
||||
: ""
|
||||
}. You cannot select Read Value or Describe Secret if you have selected Full Read Access.`
|
||||
}. You cannot select Read Value or Describe Secret if you have selected Read. The Read permission is a legacy action which has been replaced by Describe Secret and Read Value.`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -565,7 +565,7 @@ const buildAdminPermissionRules = () => {
|
||||
|
||||
can(
|
||||
[
|
||||
// not adding DescribeAndReadValue, because it's already covered by DescribeSecret and ReadValue
|
||||
ProjectPermissionSecretActions.DescribeAndReadValue,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
ProjectPermissionSecretActions.Create,
|
||||
@@ -634,7 +634,7 @@ const buildMemberPermissionRules = () => {
|
||||
|
||||
can(
|
||||
[
|
||||
// not adding DescribeAndReadValue, because it's already covered by DescribeSecret and ReadValue
|
||||
ProjectPermissionSecretActions.DescribeAndReadValue,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
ProjectPermissionSecretActions.Edit,
|
||||
@@ -811,7 +811,7 @@ export const projectMemberPermissions = buildMemberPermissionRules();
|
||||
const buildViewerPermissionRules = () => {
|
||||
const { can, rules } = new AbilityBuilder<MongoAbility<ProjectPermissionSet>>(createMongoAbility);
|
||||
|
||||
// not adding DescribeAndReadValue, because it's already covered by DescribeSecret and ReadValue
|
||||
can(ProjectPermissionSecretActions.DescribeAndReadValue, ProjectPermissionSub.Secrets);
|
||||
can(ProjectPermissionSecretActions.DescribeSecret, ProjectPermissionSub.Secrets);
|
||||
can(ProjectPermissionSecretActions.ReadValue, ProjectPermissionSub.Secrets);
|
||||
can(ProjectPermissionActions.Read, ProjectPermissionSub.SecretFolders);
|
||||
|
||||
@@ -77,7 +77,7 @@ import {
|
||||
TSecretApprovalDetailsDTO,
|
||||
TStatusChangeDTO
|
||||
} from "./secret-approval-request-types";
|
||||
import { CheckForbiddenErrorSecretsSubject } from "../permission/permission-fns";
|
||||
import { throwIfMissingSecretReadValueOrDescribePermission } from "../permission/permission-fns";
|
||||
|
||||
type TSecretApprovalRequestServiceFactoryDep = {
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
@@ -919,7 +919,7 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
|
||||
@@ -23,7 +23,10 @@ import { TSecretVersionV2DALFactory } from "@app/services/secret-v2-bridge/secre
|
||||
import { TSecretVersionV2TagDALFactory } from "@app/services/secret-v2-bridge/secret-version-tag-dal";
|
||||
|
||||
import { TLicenseServiceFactory } from "../license/license-service";
|
||||
import { CheckCanSecretsSubject, CheckForbiddenErrorSecretsSubject } from "../permission/permission-fns";
|
||||
import {
|
||||
hasSecretReadValueOrDescribePermission,
|
||||
throwIfMissingSecretReadValueOrDescribePermission
|
||||
} from "../permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "../permission/permission-service";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
@@ -103,7 +106,7 @@ export const secretSnapshotServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
||||
|
||||
// We need to check if the user has access to the secrets in the folder. If we don't do this, a user could theoretically access snapshot secret values even if they don't have read access to the secrets in the folder.
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
@@ -140,7 +143,7 @@ export const secretSnapshotServiceFactory = ({
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.SecretRollback);
|
||||
|
||||
// We need to check if the user has access to the secrets in the folder. If we don't do this, a user could theoretically access snapshot secret values even if they don't have read access to the secrets in the folder.
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
@@ -187,12 +190,16 @@ export const secretSnapshotServiceFactory = ({
|
||||
snapshotDetails = {
|
||||
...encryptedSnapshotDetails,
|
||||
secretVersions: encryptedSnapshotDetails.secretVersions.map((el) => {
|
||||
const canReadValue = CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: encryptedSnapshotDetails.environment.slug,
|
||||
secretPath: fullFolderPath,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.length ? el.tags.map((tag) => tag.slug) : undefined
|
||||
});
|
||||
const canReadValue = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment: encryptedSnapshotDetails.environment.slug,
|
||||
secretPath: fullFolderPath,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.length ? el.tags.map((tag) => tag.slug) : undefined
|
||||
}
|
||||
);
|
||||
|
||||
let secretValue = "";
|
||||
if (canReadValue) {
|
||||
@@ -236,12 +243,16 @@ export const secretSnapshotServiceFactory = ({
|
||||
key: botKey
|
||||
});
|
||||
|
||||
const canReadValue = CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: encryptedSnapshotDetails.environment.slug,
|
||||
secretPath: fullFolderPath,
|
||||
secretName: secretKey,
|
||||
secretTags: el.tags.length ? el.tags.map((tag) => tag.slug) : undefined
|
||||
});
|
||||
const canReadValue = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment: encryptedSnapshotDetails.environment.slug,
|
||||
secretPath: fullFolderPath,
|
||||
secretName: secretKey,
|
||||
secretTags: el.tags.length ? el.tags.map((tag) => tag.slug) : undefined
|
||||
}
|
||||
);
|
||||
|
||||
let secretValue = "";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
import { ActionProjectType } from "@app/db/schemas";
|
||||
import { CheckForbiddenErrorSecretsSubject } from "@app/ee/services/permission/permission-fns";
|
||||
import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
@@ -96,7 +96,7 @@ export const integrationServiceFactory = ({
|
||||
});
|
||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.Integrations);
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: sourceEnvironment,
|
||||
secretPath
|
||||
});
|
||||
@@ -176,7 +176,7 @@ export const integrationServiceFactory = ({
|
||||
const newSecretPath = secretPath || integration.secretPath;
|
||||
|
||||
if (environment || secretPath) {
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: newEnvironment,
|
||||
secretPath: newSecretPath
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission";
|
||||
import { CheckForbiddenErrorSecretsSubject } from "@app/ee/services/permission/permission-fns";
|
||||
import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
@@ -765,7 +765,7 @@ export const projectServiceFactory = ({
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.Any
|
||||
});
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
|
||||
const project = await projectDAL.findProjectById(projectId);
|
||||
|
||||
|
||||
@@ -4,7 +4,10 @@ import { ForbiddenError, subject } from "@casl/ability";
|
||||
|
||||
import { ActionProjectType, TableName } from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { CheckCanSecretsSubject, CheckForbiddenErrorSecretsSubject } from "@app/ee/services/permission/permission-fns";
|
||||
import {
|
||||
hasSecretReadValueOrDescribePermission,
|
||||
throwIfMissingSecretReadValueOrDescribePermission
|
||||
} from "@app/ee/services/permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
@@ -94,7 +97,7 @@ export const secretImportServiceFactory = ({
|
||||
);
|
||||
|
||||
// check if user has permission to import from target path
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment: data.environment,
|
||||
secretPath: data.path
|
||||
});
|
||||
@@ -404,7 +407,7 @@ export const secretImportServiceFactory = ({
|
||||
if (!secretImportDoc.isReplication) throw new BadRequestError({ message: "Import is not in replication mode" });
|
||||
|
||||
// check if user has permission to import from target path
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment: secretImportDoc.importEnv.slug,
|
||||
secretPath: secretImportDoc.importPath
|
||||
});
|
||||
@@ -595,7 +598,7 @@ export const secretImportServiceFactory = ({
|
||||
// so anything based on this order will also be in right position
|
||||
const secretImports = await secretImportDAL.find({ folderId: folder.id, isReplication: false });
|
||||
const allowedImports = secretImports.filter((el) =>
|
||||
CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: el.importEnv.slug,
|
||||
secretPath: el.importPath
|
||||
})
|
||||
@@ -645,7 +648,7 @@ export const secretImportServiceFactory = ({
|
||||
secretImportDAL,
|
||||
decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""),
|
||||
hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) =>
|
||||
CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
@@ -663,7 +666,7 @@ export const secretImportServiceFactory = ({
|
||||
});
|
||||
|
||||
const allowedImports = secretImports.filter((el) =>
|
||||
CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: el.importEnv.slug,
|
||||
secretPath: el.importPath
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
|
||||
import { ActionProjectType } from "@app/db/schemas";
|
||||
import { CheckForbiddenErrorSecretsSubject } from "@app/ee/services/permission/permission-fns";
|
||||
import { throwIfMissingSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import {
|
||||
ProjectPermissionSecretActions,
|
||||
@@ -179,7 +179,7 @@ export const secretSyncServiceFactory = ({
|
||||
ProjectPermissionSub.SecretSyncs
|
||||
);
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(projectPermission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(projectPermission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -267,7 +267,7 @@ export const secretSyncServiceFactory = ({
|
||||
if (!updatedEnvironment || !updatedSecretPath)
|
||||
throw new BadRequestError({ message: "Must specify both source environment and secret path" });
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: updatedEnvironment,
|
||||
secretPath: updatedSecretPath
|
||||
});
|
||||
|
||||
@@ -10,7 +10,10 @@ import {
|
||||
TableName,
|
||||
TSecretsV2
|
||||
} from "@app/db/schemas";
|
||||
import { CheckCanSecretsSubject, CheckForbiddenErrorSecretsSubject } from "@app/ee/services/permission/permission-fns";
|
||||
import {
|
||||
hasSecretReadValueOrDescribePermission,
|
||||
throwIfMissingSecretReadValueOrDescribePermission
|
||||
} from "@app/ee/services/permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
@@ -197,7 +200,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const referredSecretsGroupBySecretKey = groupBy(referredSecrets, (i) => i.key);
|
||||
references.forEach((el) => {
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: el.environment,
|
||||
secretPath: el.secretPath,
|
||||
secretName: el.secretKey,
|
||||
@@ -542,14 +545,18 @@ export const secretV2BridgeServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: inputSecret.secretName,
|
||||
...(tagsToCheck.length && {
|
||||
secretTags: tagsToCheck.map((el) => el.slug)
|
||||
})
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: inputSecret.secretName,
|
||||
...(tagsToCheck.length && {
|
||||
secretTags: tagsToCheck.map((el) => el.slug)
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
return reshapeBridgeSecret(
|
||||
projectId,
|
||||
@@ -650,12 +657,16 @@ export const secretV2BridgeServiceFactory = ({
|
||||
projectId
|
||||
});
|
||||
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secretToDelete.key,
|
||||
secretTags: secretToDelete.tags?.map((el) => el.slug)
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secretToDelete.key,
|
||||
secretTags: secretToDelete.tags?.map((el) => el.slug)
|
||||
}
|
||||
);
|
||||
|
||||
return reshapeBridgeSecret(
|
||||
projectId,
|
||||
@@ -698,7 +709,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
}
|
||||
|
||||
const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environments, path);
|
||||
@@ -744,7 +755,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
|
||||
const folder = await folderDAL.findBySecretPath(projectId, environment, path);
|
||||
if (!folder) return 0;
|
||||
@@ -779,37 +790,27 @@ export const secretV2BridgeServiceFactory = ({
|
||||
});
|
||||
|
||||
const decryptedSecrets = secrets
|
||||
.filter((el) => {
|
||||
if (
|
||||
filterByAction === ProjectPermissionSecretActions.ReadValue ||
|
||||
filterByAction === ProjectPermissionSecretActions.DescribeSecret
|
||||
) {
|
||||
return CheckCanSecretsSubject(projectPermission, filterByAction, {
|
||||
environment: groupedFolderMappings[el.folderId][0].environment,
|
||||
secretPath: groupedFolderMappings[el.folderId][0].path,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.map((i) => i.slug)
|
||||
});
|
||||
}
|
||||
.filter((el) =>
|
||||
hasSecretReadValueOrDescribePermission(projectPermission, filterByAction, {
|
||||
environment: groupedFolderMappings[el.folderId][0].environment,
|
||||
secretPath: groupedFolderMappings[el.folderId][0].path,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.map((i) => i.slug)
|
||||
})
|
||||
)
|
||||
|
||||
return projectPermission.can(
|
||||
filterByAction,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment: groupedFolderMappings[el.folderId][0].environment,
|
||||
secretPath: groupedFolderMappings[el.folderId][0].path,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.map((i) => i.slug)
|
||||
})
|
||||
);
|
||||
})
|
||||
.map((secret) => {
|
||||
// Note(Daniel): This is only relevant if the filterAction isn't set to ReadValue. This is needed for the frontend.
|
||||
const secretValueHidden = !CheckCanSecretsSubject(projectPermission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: groupedFolderMappings[secret.folderId][0].environment,
|
||||
secretPath: groupedFolderMappings[secret.folderId][0].path,
|
||||
secretName: secret.key,
|
||||
secretTags: secret.tags.map((i) => i.slug)
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
projectPermission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment: groupedFolderMappings[secret.folderId][0].environment,
|
||||
secretPath: groupedFolderMappings[secret.folderId][0].path,
|
||||
secretName: secret.key,
|
||||
secretTags: secret.tags.map((i) => i.slug)
|
||||
}
|
||||
);
|
||||
|
||||
return reshapeBridgeSecret(
|
||||
projectId,
|
||||
@@ -855,7 +856,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
if (!isInternal) {
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret);
|
||||
}
|
||||
|
||||
const folders = await folderDAL.findBySecretPathMultiEnv(projectId, environments, path);
|
||||
@@ -907,7 +908,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath: path,
|
||||
secretTags: params.tagSlugs
|
||||
@@ -950,12 +951,16 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const decryptedSecrets = secrets
|
||||
.filter((el) => {
|
||||
const canDescribeSecret = CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath: groupedPaths[el.folderId][0].path,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.map((i) => i.slug)
|
||||
});
|
||||
const canDescribeSecret = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
{
|
||||
environment,
|
||||
secretPath: groupedPaths[el.folderId][0].path,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.map((i) => i.slug)
|
||||
}
|
||||
);
|
||||
|
||||
if (!canDescribeSecret) {
|
||||
return false;
|
||||
@@ -964,7 +969,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
if (viewSecretValue) {
|
||||
// Recursive secret, should be filtered out
|
||||
if (groupedPaths[el.folderId][0].path !== path) {
|
||||
const canReadRecursiveSecretValue = CheckCanSecretsSubject(
|
||||
const canReadRecursiveSecretValue = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
@@ -981,7 +986,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
}
|
||||
|
||||
if (throwOnMissingReadValuePermission) {
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: groupedPaths[el.folderId][0].path,
|
||||
secretName: el.key,
|
||||
@@ -999,7 +1004,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const secretValueHidden =
|
||||
!viewSecretValue ||
|
||||
!CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
!hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: groupedPaths[secret.folderId][0].path,
|
||||
secretName: secret.key,
|
||||
@@ -1029,7 +1034,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
secretDAL,
|
||||
decryptSecretValue: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : undefined),
|
||||
canExpandValue: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) =>
|
||||
CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
@@ -1074,19 +1079,27 @@ export const secretV2BridgeServiceFactory = ({
|
||||
expandSecretReferences,
|
||||
decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""),
|
||||
hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => {
|
||||
const canDescribe = CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
secretTags: expandSecretTags
|
||||
});
|
||||
const canDescribe = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
{
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
secretTags: expandSecretTags
|
||||
}
|
||||
);
|
||||
|
||||
const canReadValue = CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
secretTags: expandSecretTags
|
||||
});
|
||||
const canReadValue = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
secretTags: expandSecretTags
|
||||
}
|
||||
);
|
||||
|
||||
return viewSecretValue ? canDescribe && canReadValue : canDescribe;
|
||||
}
|
||||
@@ -1128,7 +1141,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: folderWithPath.environmentSlug,
|
||||
secretPath: folderWithPath.path,
|
||||
secretName: secret.key,
|
||||
@@ -1240,7 +1253,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
})
|
||||
));
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath: path,
|
||||
secretName,
|
||||
@@ -1255,7 +1268,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
secretDAL,
|
||||
decryptSecretValue: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : undefined),
|
||||
canExpandValue: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => {
|
||||
return CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
return hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
@@ -1280,7 +1293,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
decryptor: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : ""),
|
||||
expandSecretReferences: shouldExpandSecretReferences ? expandSecretReferences : undefined,
|
||||
hasSecretAccess: (expandEnvironment, expandSecretPath, expandSecretKey, expandSecretTags) => {
|
||||
return CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
return hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretKey,
|
||||
@@ -1297,7 +1310,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
if (viewSecretValue) {
|
||||
if (
|
||||
!CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
!hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: importedSecret.environment,
|
||||
secretPath: importedSecrets[i].secretPath,
|
||||
secretName: importedSecret.key,
|
||||
@@ -1350,7 +1363,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
if (viewSecretValue) {
|
||||
if (
|
||||
!CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
!hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: path,
|
||||
secretName,
|
||||
@@ -1523,12 +1536,16 @@ export const secretV2BridgeServiceFactory = ({
|
||||
});
|
||||
|
||||
return newSecrets.map((el) => {
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags?.map((i) => i.slug)
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags?.map((i) => i.slug)
|
||||
}
|
||||
);
|
||||
|
||||
return reshapeBridgeSecret(
|
||||
projectId,
|
||||
@@ -1857,12 +1874,16 @@ export const secretV2BridgeServiceFactory = ({
|
||||
);
|
||||
|
||||
return updatedSecrets.map((el) => {
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: el.secretPath,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.map((i) => i.slug)
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath: el.secretPath,
|
||||
secretName: el.key,
|
||||
secretTags: el.tags.map((i) => i.slug)
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
...reshapeBridgeSecret(
|
||||
@@ -1987,7 +2008,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
|
||||
const secretValueHidden =
|
||||
!secretToDeleteMatch ||
|
||||
!CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
!hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: el.key,
|
||||
@@ -2049,14 +2070,18 @@ export const secretV2BridgeServiceFactory = ({
|
||||
sort: [["createdAt", "desc"]]
|
||||
});
|
||||
return secretVersions.map((el) => {
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: folder.environment.envSlug,
|
||||
secretPath: folderWithPath.path,
|
||||
secretName: el.key,
|
||||
...(el.tags?.length && {
|
||||
secretTags: el.tags.map((tag) => tag.slug)
|
||||
})
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment: folder.environment.envSlug,
|
||||
secretPath: folderWithPath.path,
|
||||
secretName: el.key,
|
||||
...(el.tags?.length && {
|
||||
secretTags: el.tags.map((tag) => tag.slug)
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
return reshapeBridgeSecret(
|
||||
folder.projectId,
|
||||
@@ -2178,7 +2203,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
sourceAction === ProjectPermissionSecretActions.DescribeSecret ||
|
||||
sourceAction === ProjectPermissionSecretActions.ReadValue
|
||||
) {
|
||||
CheckForbiddenErrorSecretsSubject(permission, sourceAction, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, sourceAction, {
|
||||
environment: sourceEnvironment,
|
||||
secretPath: sourceSecretPath,
|
||||
secretName: secret.key,
|
||||
@@ -2517,7 +2542,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath
|
||||
});
|
||||
@@ -2541,7 +2566,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
type: SecretType.Shared
|
||||
});
|
||||
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
@@ -2558,7 +2583,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
secretDAL,
|
||||
decryptSecretValue: (value) => (value ? secretManagerDecryptor({ cipherTextBlob: value }).toString() : undefined),
|
||||
canExpandValue: (expandEnvironment, expandSecretPath, expandSecretName, expandSecretTags) =>
|
||||
CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: expandEnvironment,
|
||||
secretPath: expandSecretPath,
|
||||
secretName: expandSecretName,
|
||||
@@ -2567,7 +2592,7 @@ export const secretV2BridgeServiceFactory = ({
|
||||
});
|
||||
|
||||
if (
|
||||
!CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
!hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
|
||||
@@ -349,5 +349,5 @@ export type TGetSecretsRawByFolderMappingsDTO = {
|
||||
folderMappings: { folderId: string; path: string; environment: string }[];
|
||||
userId: string;
|
||||
filters: TFindSecretsByFolderIdsFilter;
|
||||
filterByAction?: ProjectPermissionSecretActions;
|
||||
filterByAction?: ProjectPermissionSecretActions.DescribeSecret | ProjectPermissionSecretActions.ReadValue;
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
TSecretFolders,
|
||||
TSecrets
|
||||
} from "@app/db/schemas";
|
||||
import { CheckCanSecretsSubject } from "@app/ee/services/permission/permission-fns";
|
||||
import { hasSecretReadValueOrDescribePermission } from "@app/ee/services/permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import { ProjectPermissionSecretActions } from "@app/ee/services/permission/project-permission";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
@@ -191,7 +191,7 @@ export const recursivelyGetSecretPaths = ({
|
||||
// Filter out paths that the user does not have permission to access, and paths that are not in the current path
|
||||
const allowedPaths = paths.filter(
|
||||
(folder) =>
|
||||
CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: folder.path
|
||||
}) && folder.path.startsWith(currentPath === "/" ? "" : currentPath)
|
||||
|
||||
@@ -13,7 +13,10 @@ import {
|
||||
SecretType
|
||||
} from "@app/db/schemas";
|
||||
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
|
||||
import { CheckCanSecretsSubject, CheckForbiddenErrorSecretsSubject } from "@app/ee/services/permission/permission-fns";
|
||||
import {
|
||||
hasSecretReadValueOrDescribePermission,
|
||||
throwIfMissingSecretReadValueOrDescribePermission
|
||||
} from "@app/ee/services/permission/permission-fns";
|
||||
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
@@ -453,10 +456,14 @@ export const secretServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath: path
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
...updatedSecret[0],
|
||||
@@ -560,10 +567,14 @@ export const secretServiceFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath: path
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
...deletedSecret[0],
|
||||
@@ -620,7 +631,7 @@ export const secretServiceFactory = ({
|
||||
|
||||
paths = deepPaths.map(({ folderId, path: p }) => ({ folderId, path: p }));
|
||||
} else {
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
@@ -645,7 +656,7 @@ export const secretServiceFactory = ({
|
||||
// if its service token allow full access over imported one
|
||||
actor === ActorType.SERVICE
|
||||
? true
|
||||
: CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
: hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: importEnv.slug,
|
||||
secretPath: importPath
|
||||
})
|
||||
@@ -699,7 +710,7 @@ export const secretServiceFactory = ({
|
||||
actorOrgId,
|
||||
actionProjectType: ActionProjectType.SecretManager
|
||||
});
|
||||
CheckForbiddenErrorSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
@@ -750,7 +761,7 @@ export const secretServiceFactory = ({
|
||||
// if its service token allow full access over imported one
|
||||
actor === ActorType.SERVICE
|
||||
? true
|
||||
: CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
: hasSecretReadValueOrDescribePermission(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: importEnv.slug,
|
||||
secretPath: importPath
|
||||
})
|
||||
@@ -969,10 +980,14 @@ export const secretServiceFactory = ({
|
||||
secretVersionTagDAL
|
||||
});
|
||||
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath: path
|
||||
}
|
||||
);
|
||||
|
||||
return updatedSecrets.map((secret) => ({
|
||||
...secret,
|
||||
@@ -1063,10 +1078,14 @@ export const secretServiceFactory = ({
|
||||
});
|
||||
}
|
||||
}
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment,
|
||||
secretPath: path
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment,
|
||||
secretPath: path
|
||||
}
|
||||
);
|
||||
|
||||
return secrets.map((secret) => ({
|
||||
...secret,
|
||||
@@ -1257,7 +1276,7 @@ export const secretServiceFactory = ({
|
||||
action === ProjectPermissionSecretActions.DescribeSecret ||
|
||||
action === ProjectPermissionSecretActions.ReadValue
|
||||
) {
|
||||
return CheckCanSecretsSubject(entityPermission.permission, action, {
|
||||
return hasSecretReadValueOrDescribePermission(entityPermission.permission, action, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
@@ -2429,14 +2448,18 @@ export const secretServiceFactory = ({
|
||||
key: botKey
|
||||
});
|
||||
|
||||
const secretValueHidden = !CheckCanSecretsSubject(permission, ProjectPermissionSecretActions.ReadValue, {
|
||||
environment: folder.environment.envSlug,
|
||||
secretPath: folderWithPath.path,
|
||||
secretName: secretKey,
|
||||
...(el.tags?.length && {
|
||||
secretTags: el.tags.map((tag) => tag.slug)
|
||||
})
|
||||
});
|
||||
const secretValueHidden = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
environment: folder.environment.envSlug,
|
||||
secretPath: folderWithPath.path,
|
||||
secretName: secretKey,
|
||||
...(el.tags?.length && {
|
||||
secretTags: el.tags.map((tag) => tag.slug)
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
return decryptSecretRaw(
|
||||
{
|
||||
@@ -2839,7 +2862,7 @@ export const secretServiceFactory = ({
|
||||
sourceAction === ProjectPermissionSecretActions.ReadValue ||
|
||||
sourceAction === ProjectPermissionSecretActions.DescribeSecret
|
||||
) {
|
||||
CheckForbiddenErrorSecretsSubject(permission, sourceAction, {
|
||||
throwIfMissingSecretReadValueOrDescribePermission(permission, sourceAction, {
|
||||
environment: sourceEnvironment,
|
||||
secretPath: sourceSecretPath
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
SecretSubjectFields
|
||||
} from "@app/context/ProjectPermissionContext/types";
|
||||
|
||||
export function secretsPermissionCan(
|
||||
export function hasSecretReadValueOrDescribePermission(
|
||||
permission: MongoAbility<ProjectPermissionSet>,
|
||||
action: Extract<
|
||||
ProjectPermissionSecretActions,
|
||||
|
||||
@@ -29,11 +29,11 @@ const GeneralPolicyActionSchema = z.object({
|
||||
|
||||
const SecretPolicyActionSchema = z.object({
|
||||
[ProjectPermissionSecretActions.DescribeAndReadValue]: z.boolean().optional(), // existing read, gives both describe and read value
|
||||
[ProjectPermissionSecretActions.DescribeSecret]: z.boolean().optional(), // describe secret, cannot read value
|
||||
[ProjectPermissionSecretActions.ReadValue]: z.boolean().optional(), // read value
|
||||
[ProjectPermissionSecretActions.Edit]: z.boolean().optional(), // edit secret
|
||||
[ProjectPermissionSecretActions.Delete]: z.boolean().optional(), // delete secret
|
||||
[ProjectPermissionSecretActions.Create]: z.boolean().optional() // create secret
|
||||
[ProjectPermissionSecretActions.DescribeSecret]: z.boolean().optional(),
|
||||
[ProjectPermissionSecretActions.ReadValue]: z.boolean().optional(),
|
||||
[ProjectPermissionSecretActions.Edit]: z.boolean().optional(),
|
||||
[ProjectPermissionSecretActions.Delete]: z.boolean().optional(),
|
||||
[ProjectPermissionSecretActions.Create]: z.boolean().optional()
|
||||
});
|
||||
|
||||
const CmekPolicyActionSchema = z.object({
|
||||
|
||||
@@ -15,7 +15,7 @@ import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionCo
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { useUpdateSecretV3 } from "@app/hooks/api";
|
||||
import { SecretType, SecretV3RawSanitized } from "@app/hooks/api/types";
|
||||
import { secretsPermissionCan } from "@app/lib/fn/permission";
|
||||
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
||||
|
||||
enum SecretActionType {
|
||||
Created = "created",
|
||||
@@ -52,7 +52,7 @@ function SecretRenameRow({ environments, getSecretByKey, secretKey, secretPath }
|
||||
secretTags: (secretDetails?.tags || []).map((i) => i.slug)
|
||||
});
|
||||
const isSecretInEnvReadOnly =
|
||||
secretsPermissionCan(
|
||||
hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
secretPermissionSubject
|
||||
|
||||
@@ -38,7 +38,7 @@ import { useGetProjectSecretsDetails } from "@app/hooks/api/dashboard";
|
||||
import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
import { secretsPermissionCan } from "@app/lib/fn/permission";
|
||||
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
||||
|
||||
import { SecretTableResourceCount } from "../OverviewPage/components/SecretTableResourceCount";
|
||||
import { SecretV2MigrationSection } from "../OverviewPage/components/SecretV2MigrationSection";
|
||||
@@ -105,7 +105,7 @@ const Page = () => {
|
||||
const projectSlug = currentWorkspace?.slug || "";
|
||||
const secretPath = (routerQueryParams.secretPath as string) || "/";
|
||||
|
||||
const canReadSecret = secretsPermissionCan(
|
||||
const canReadSecret = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
{
|
||||
@@ -116,7 +116,7 @@ const Page = () => {
|
||||
}
|
||||
);
|
||||
|
||||
const canReadSecretValue = secretsPermissionCan(
|
||||
const canReadSecretValue = hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@ import { ActorType } from "@app/hooks/api/auditLogs/enums";
|
||||
import { useGetSecretAccessList } from "@app/hooks/api/secrets/queries";
|
||||
import { SecretV3RawSanitized, WsTag } from "@app/hooks/api/types";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
import { secretsPermissionCan } from "@app/lib/fn/permission";
|
||||
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
||||
|
||||
import { CreateReminderForm } from "./CreateReminderForm";
|
||||
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
|
||||
@@ -141,7 +141,7 @@ export const SecretDetailSidebar = ({
|
||||
})
|
||||
);
|
||||
|
||||
const cannotReadSecretValue = !secretsPermissionCan(
|
||||
const cannotReadSecretValue = !hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.ReadValue,
|
||||
{
|
||||
@@ -153,12 +153,16 @@ export const SecretDetailSidebar = ({
|
||||
);
|
||||
|
||||
const isReadOnly =
|
||||
secretsPermissionCan(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secretKey,
|
||||
secretTags: selectTagSlugs
|
||||
}) &&
|
||||
hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
{
|
||||
environment,
|
||||
secretPath,
|
||||
secretName: secretKey,
|
||||
secretTags: selectTagSlugs
|
||||
}
|
||||
) &&
|
||||
cannotEditSecret &&
|
||||
cannotReadSecretValue;
|
||||
|
||||
@@ -361,11 +365,11 @@ export const SecretDetailSidebar = ({
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<InfisicalSecretInput
|
||||
isReadOnly={isReadOnly}
|
||||
isReadOnly={isReadOnly || !isAllowed}
|
||||
environment={environment}
|
||||
secretPath={secretPath}
|
||||
key="secret-value"
|
||||
isDisabled={isOverridden || !isAllowed}
|
||||
isDisabled={isOverridden}
|
||||
containerClassName="text-bunker-300 w-full hover:border-primary-400/50 border border-mineshaft-600 bg-bunker-800 px-2 py-1.5"
|
||||
{...field}
|
||||
autoFocus={false}
|
||||
|
||||
@@ -47,7 +47,7 @@ import {
|
||||
|
||||
import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
|
||||
import { Blur } from "@app/components/v2/Blur";
|
||||
import { secretsPermissionCan } from "@app/lib/fn/permission";
|
||||
import { hasSecretReadValueOrDescribePermission } from "@app/lib/fn/permission";
|
||||
import {
|
||||
FontAwesomeSpriteName,
|
||||
formSchema,
|
||||
@@ -132,12 +132,16 @@ export const SecretItem = memo(
|
||||
});
|
||||
|
||||
const isReadOnly =
|
||||
secretsPermissionCan(permission, ProjectPermissionSecretActions.DescribeSecret, {
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
}) &&
|
||||
hasSecretReadValueOrDescribePermission(
|
||||
permission,
|
||||
ProjectPermissionSecretActions.DescribeSecret,
|
||||
{
|
||||
environment,
|
||||
secretPath,
|
||||
secretName,
|
||||
secretTags: selectedTagSlugs
|
||||
}
|
||||
) &&
|
||||
permission.cannot(
|
||||
ProjectPermissionSecretActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
|
||||
Reference in New Issue
Block a user