improvement: skip edit/delete permissions for personal secrets

This commit is contained in:
Scott Wilson
2025-09-18 12:37:45 -07:00
parent 91d3ed632a
commit 55b240f32d
2 changed files with 33 additions and 30 deletions
@@ -478,15 +478,16 @@ export const secretV2BridgeServiceFactory = ({
secret = sharedSecretToModify; secret = sharedSecretToModify;
} }
ForbiddenError.from(permission).throwUnlessCan( if (secret.type !== SecretType.Personal)
ProjectPermissionSecretActions.Edit, ForbiddenError.from(permission).throwUnlessCan(
subject(ProjectPermissionSub.Secrets, { ProjectPermissionSecretActions.Edit,
environment, subject(ProjectPermissionSub.Secrets, {
secretPath, environment,
secretName: inputSecret.secretName, secretPath,
secretTags: secret.tags.map((el) => el.slug) secretName: inputSecret.secretName,
}) secretTags: secret.tags.map((el) => el.slug)
); })
);
// validate tags // validate tags
// fetch all tags and if not same count throw error meaning one was invalid tags // fetch all tags and if not same count throw error meaning one was invalid tags
@@ -497,17 +498,18 @@ export const secretV2BridgeServiceFactory = ({
const tagsToCheck = inputSecret.tagIds ? newTags : secret.tags; const tagsToCheck = inputSecret.tagIds ? newTags : secret.tags;
// now check with new ids // now check with new ids
ForbiddenError.from(permission).throwUnlessCan( if (secret.type !== SecretType.Personal)
ProjectPermissionSecretActions.Edit, ForbiddenError.from(permission).throwUnlessCan(
subject(ProjectPermissionSub.Secrets, { ProjectPermissionSecretActions.Edit,
environment, subject(ProjectPermissionSub.Secrets, {
secretPath, environment,
secretName: inputSecret.secretName, secretPath,
...(tagsToCheck.length && { secretName: inputSecret.secretName,
secretTags: tagsToCheck.map((el) => el.slug) ...(tagsToCheck.length && {
secretTags: tagsToCheck.map((el) => el.slug)
})
}) })
}) );
);
if (inputSecret.newSecretName) { if (inputSecret.newSecretName) {
const doesNewNameSecretExist = await secretDAL.findOne({ const doesNewNameSecretExist = await secretDAL.findOne({
@@ -706,15 +708,17 @@ export const secretV2BridgeServiceFactory = ({
}) })
}); });
if (!secretToDelete) throw new NotFoundError({ message: "Secret not found" }); if (!secretToDelete) throw new NotFoundError({ message: "Secret not found" });
ForbiddenError.from(permission).throwUnlessCan(
ProjectPermissionSecretActions.Delete, if (secretToDelete.type !== SecretType.Personal)
subject(ProjectPermissionSub.Secrets, { ForbiddenError.from(permission).throwUnlessCan(
environment, ProjectPermissionSecretActions.Delete,
secretPath, subject(ProjectPermissionSub.Secrets, {
secretName: secretToDelete.key, environment,
secretTags: secretToDelete.tags?.map((el) => el.slug) secretPath,
}) secretName: secretToDelete.key,
); secretTags: secretToDelete.tags?.map((el) => el.slug)
})
);
try { try {
const deletedSecret = await secretDAL.transaction(async (tx) => { const deletedSecret = await secretDAL.transaction(async (tx) => {
@@ -515,7 +515,6 @@ export const SecretItem = memo(
isErrorLoadingValue={isErrorFetchingSecretValue} isErrorLoadingValue={isErrorFetchingSecretValue}
key="value-overriden" key="value-overriden"
isVisible={isVisible} isVisible={isVisible}
isReadOnly={isReadOnly}
{...field} {...field}
onFocus={() => { onFocus={() => {
if (secret.idOverride) setIsFieldFocused.on(); if (secret.idOverride) setIsFieldFocused.on();
@@ -718,7 +717,7 @@ export const SecretItem = memo(
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
<ProjectPermissionCan <ProjectPermissionCan
I={ProjectPermissionActions.Edit} I={ProjectPermissionActions.Create}
a={subject(ProjectPermissionSub.Secrets, { a={subject(ProjectPermissionSub.Secrets, {
environment, environment,
secretPath, secretPath,