Skip to content

Commit

Permalink
feat: performed requested changes
Browse files Browse the repository at this point in the history
  • Loading branch information
aryanjassal committed Sep 10, 2024
1 parent 9782f35 commit 0c9a476
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 53 deletions.
8 changes: 3 additions & 5 deletions src/client/handlers/VaultsSecretsRemove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ class VaultsSecretsRemove extends UnaryHandler<
await vaultManager.withVaults(
[vaultId],
async (vault) => {
for (const secretName of input.secretNames) {
await vaultOps.deleteSecret(vault, secretName, {
recursive: input.options?.recursive,
});
}
await vaultOps.deleteSecret(vault, input.secretNames, {
recursive: input.options?.recursive,
});
},
tran,
);
Expand Down
15 changes: 5 additions & 10 deletions src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,18 +304,14 @@ type SecretPathMessage = {
secretName: string;
};

type SecretPathsMessage = {
secretNames: Array<string>;
};

type SecretIdentifierMessage = VaultIdentifierMessage & SecretPathMessage;

type SecretRemoveMessage = VaultIdentifierMessage &
SecretPathsMessage & {
options?: {
recursive?: boolean;
};
type SecretRemoveMessage = VaultIdentifierMessage & {
secretNames: Array<string>;
options?: {
recursive?: boolean;
};
};

// Contains binary content as a binary string 'toString('binary')'
type ContentMessage = {
Expand Down Expand Up @@ -426,7 +422,6 @@ export type {
VaultsVersionMessage,
VaultsLatestVersionMessage,
SecretPathMessage,
SecretPathsMessage,
SecretIdentifierMessage,
SecretRemoveMessage,
ContentMessage,
Expand Down
54 changes: 28 additions & 26 deletions src/vaults/VaultOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,37 +129,39 @@ async function statSecret(vault: Vault, secretName: string): Promise<Stat> {
*/
async function deleteSecret(
vault: Vault,
secretName: string,
secretNames: Array<string>,
fileOptions?: FileOptions,
logger?: Logger,
): Promise<void> {
try {
await vault.writeF(async (efs) => {
const stat = await efs.stat(secretName);
if (stat.isDirectory()) {
await efs.rmdir(secretName, fileOptions);
logger?.info(`Deleted directory at '${secretName}'`);
} else {
// Remove the specified file
await efs.unlink(secretName);
logger?.info(`Deleted secret at '${secretName}'`);
await vault.writeF(async (efs) => {
for (const secretName of secretNames) {
try {
const stat = await efs.stat(secretName);
if (stat.isDirectory()) {
await efs.rmdir(secretName, fileOptions);
logger?.info(`Deleted directory at '${secretName}'`);
} else {
// Remove the specified file
await efs.unlink(secretName);
logger?.info(`Deleted secret at '${secretName}'`);
}
} catch (e) {
if (e.code === 'ENOENT') {
throw new vaultsErrors.ErrorSecretsSecretUndefined(
`Secret with name: ${secretName} does not exist`,
{ cause: e },
);
}
if (e.code === 'ENOTEMPTY') {
throw new vaultsErrors.ErrorVaultsRecursive(
`Could not delete directory '${secretName}' without recursive option`,
{ cause: e },
);
}
throw e;
}
});
} catch (e) {
if (e.code === 'ENOENT') {
throw new vaultsErrors.ErrorSecretsSecretUndefined(
`Secret with name: ${secretName} does not exist`,
{ cause: e },
);
}
if (e.code === 'ENOTEMPTY') {
throw new vaultsErrors.ErrorVaultsRecursive(
`Could not delete directory '${secretName}' without recursive option`,
{ cause: e },
);
}
throw e;
}
});
}

/**
Expand Down
33 changes: 29 additions & 4 deletions tests/client/handlers/vaults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,7 @@ describe('vaultsSecretsNew and vaultsSecretsDelete, vaultsSecretsGet', () => {
vaultsSecretsRemove: typeof vaultsSecretsRemove;
vaultsSecretsGet: typeof vaultsSecretsGet;
vaultsSecretsNewDir: typeof vaultsSecretsNewDir;
vaultsSecretsStat: typeof vaultsSecretsStat;
}>;
let vaultManager: VaultManager;
beforeEach(async () => {
Expand Down Expand Up @@ -1410,6 +1411,10 @@ describe('vaultsSecretsNew and vaultsSecretsDelete, vaultsSecretsGet', () => {
fs,
vaultManager,
}),
vaultsSecretsStat: new VaultsSecretsStat({
db,
vaultManager,
}),
},
host: localhost,
});
Expand All @@ -1427,6 +1432,7 @@ describe('vaultsSecretsNew and vaultsSecretsDelete, vaultsSecretsGet', () => {
vaultsSecretsRemove,
vaultsSecretsGet,
vaultsSecretsNewDir,
vaultsSecretsStat,
},
streamFactory: () => webSocketClient.connection.newStream(),
toError: networkUtils.toError,
Expand Down Expand Up @@ -1527,10 +1533,12 @@ describe('vaultsSecretsNew and vaultsSecretsDelete, vaultsSecretsGet', () => {
);
});
test('deletes directory recursively', async () => {
// Create secret
// Create secrets
const vaultName = 'test-vault';
const secretDirName = 'secretDir';
const secretList = ['test-secret1', 'test-secret2', 'test-secret3'];
const secretDir = path.join(dataDir, 'secretDir');
const secretDir = path.join(dataDir, secretDirName);
const secretNames = secretList.map((v) => path.join(secretDirName, v));
await fs.promises.mkdir(secretDir);
for (const secret of secretList) {
const secretFile = path.join(secretDir, secret);
Expand All @@ -1548,18 +1556,35 @@ describe('vaultsSecretsNew and vaultsSecretsDelete, vaultsSecretsGet', () => {
await testsUtils.expectRemoteError(
rpcClient.methods.vaultsSecretsRemove({
nameOrId: vaultsIdEncoded,
secretNames: ['secretDir'],
secretNames: [secretDirName],
}),
vaultsErrors.ErrorVaultsRecursive,
);
const deleteResponse = await rpcClient.methods.vaultsSecretsRemove({
nameOrId: vaultsIdEncoded,
secretNames: ['secretDir'],
secretNames: [secretDirName],
options: {
recursive: true,
},
});
expect(deleteResponse.success).toBeTruthy();
// Check secret was deleted
for (const secretName of secretNames) {
await testsUtils.expectRemoteError(
rpcClient.methods.vaultsSecretsGet({
nameOrId: vaultsIdEncoded,
secretName: secretName,
}),
vaultsErrors.ErrorSecretsSecretUndefined,
);
}
await testsUtils.expectRemoteError(
rpcClient.methods.vaultsSecretsStat({
nameOrId: vaultsIdEncoded,
secretName: secretDirName,
}),
vaultsErrors.ErrorSecretsSecretUndefined,
);
});
});
describe('vaultsSecretsNewDir and vaultsSecretsList', () => {
Expand Down
18 changes: 10 additions & 8 deletions tests/vaults/VaultOps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,36 +265,36 @@ describe('VaultOps', () => {
describe('deleteSecret', () => {
test('deleting a secret', async () => {
await writeSecret(secretName, secretContent);
await vaultOps.deleteSecret(vault, secretName);
await vaultOps.deleteSecret(vault, [secretName]);
await expectSecretNot(secretName);
});
test('deleting a secret in a directory', async () => {
const secretPath = path.join(dirName, secretName);
await writeSecret(secretPath, secretContent);
await vaultOps.deleteSecret(vault, secretPath);
await vaultOps.deleteSecret(vault, [secretPath]);
await expectSecretNot(secretPath);
await expectDirExists(dirName);
});
test('deleting a directory', async () => {
await mkdir(dirName);
await vaultOps.deleteSecret(vault, dirName);
await vaultOps.deleteSecret(vault, [dirName]);
await expectDirExistsNot(dirName);
});
test('deleting a directory with a file should fail', async () => {
const secretPath = path.join(dirName, secretName);
await writeSecret(secretPath, secretContent);
await expect(vaultOps.deleteSecret(vault, dirName)).rejects.toThrow(
await expect(vaultOps.deleteSecret(vault, [dirName])).rejects.toThrow(
vaultsErrors.ErrorVaultsRecursive,
);
});
test('deleting a directory with force', async () => {
const secretPath = path.join(dirName, secretName);
await writeSecret(secretPath, secretContent);
await vaultOps.deleteSecret(vault, dirName, { recursive: true });
await vaultOps.deleteSecret(vault, [dirName], { recursive: true });
await expectDirExistsNot(dirName);
});
test('deleting a secret that does not exist should fail', async () => {
await expect(vaultOps.deleteSecret(vault, secretName)).rejects.toThrow(
await expect(vaultOps.deleteSecret(vault, [secretName])).rejects.toThrow(
vaultsErrors.ErrorSecretsSecretUndefined,
);
});
Expand Down Expand Up @@ -521,8 +521,10 @@ describe('VaultOps', () => {
await vaultOps.getSecret(vault, '.hidingDir/.hiddenInSecret')
).toString(),
).toStrictEqual('change_inside');
await vaultOps.deleteSecret(vault, '.hidingSecret', { recursive: true });
await vaultOps.deleteSecret(vault, '.hidingDir', { recursive: true });
await vaultOps.deleteSecret(vault, ['.hidingSecret'], {
recursive: true,
});
await vaultOps.deleteSecret(vault, ['.hidingDir'], { recursive: true });
list = await vaultOps.listSecrets(vault);
expect(list.sort()).toStrictEqual([].sort());
},
Expand Down

0 comments on commit 0c9a476

Please sign in to comment.