Skip to content

Commit b591d42

Browse files
author
ipierre1
committed
feat ✨: vault_id_list integration
1 parent 9d0ae2f commit b591d42

File tree

5 files changed

+264
-141
lines changed

5 files changed

+264
-141
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to the `ansible-vault-vscode` extension will be documented in this file.
44

5+
## [1.0.4] - 2024-03-22
6+
7+
### Feat
8+
9+
- Vault ID List with password search.
10+
511
## [1.0.3] - 2024-03-18
612

713
### Fixed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ansible-vault-vscode",
3-
"version": "1.0.3",
3+
"version": "1.0.4",
44
"publisher": "ipierre1",
55
"engines": {
66
"vscode": "^1.83.0"

src/extension.ts

Lines changed: 80 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import * as vscode from "vscode";
22
import untildify from "untildify";
3-
import * as tmp from "tmp";
4-
import * as fs from "fs";
53
import * as util from "./util";
64
import { Vault } from "ansible-vault";
75

@@ -30,17 +28,44 @@ export function activate(context: vscode.ExtensionContext) {
3028

3129
// Read `ansible.cfg`
3230
const rootPath = util.getRootPath(logs, editor.document.uri);
33-
const otherPath = util.findAnsibleCfgFile(logs, rootPath);
34-
let keyInCfg: string, vaultIds: false | Array<string>;
31+
let otherPath = util.findAnsibleCfgFile(logs, rootPath, "ansible.cfg");
32+
33+
if (otherPath !== undefined) {
34+
otherPath = util.verifyAnsibleDirectory(logs, editor.document.uri, otherPath);
35+
}
36+
37+
38+
let keyInCfg: string,
39+
vaultIds: false | Array<string>,
40+
vaultPass: false | { [key: string]: string };
3541
// eslint-disable-next-line prefer-const
36-
[keyInCfg, vaultIds] = util.scanAnsibleCfg(logs, otherPath, rootPath);
42+
[keyInCfg, vaultIds, vaultPass] = util.scanAnsibleCfg(
43+
logs,
44+
otherPath,
45+
rootPath
46+
);
47+
48+
const vaultId = await encryptVaultId(vaultIds);
3749

3850
// Extract `ansible-vault` password
3951
if (keyInCfg) {
4052
logs.appendLine(`Getting vault keyfile from ${keyInCfg}`);
4153
vscode.window.showInformationMessage(
4254
`Getting vault keyfile from ${keyInCfg}`
4355
);
56+
if (vaultPass) {
57+
if (vaultPass["default"] !== undefined) {
58+
pass = util.findPassword(logs, rootPath, vaultPass["default"]);
59+
} else if (vaultPass[vaultId] !== undefined) {
60+
pass = util.findPassword(logs, rootPath, vaultPass[vaultId]);
61+
} else {
62+
// Handle case when neither default nor vaultId specific password is found
63+
vscode.window.showErrorMessage(
64+
"No password found for the specified vault ID."
65+
);
66+
return;
67+
}
68+
}
4469
} else {
4570
logs.appendLine(`Found nothing from config files`);
4671

@@ -64,10 +89,6 @@ export function activate(context: vscode.ExtensionContext) {
6489
pass = val;
6590
});
6691
}
67-
68-
keypath = tmp.tmpNameSync();
69-
fs.writeFileSync(keypath, pass, "utf8");
70-
logs.appendLine(`Wrote password to temporary file: '${keypath}'`);
7192
}
7293
}
7394

@@ -79,14 +100,8 @@ export function activate(context: vscode.ExtensionContext) {
79100

80101
if (type === "plaintext") {
81102
logs.appendLine(`Encrypt selected text`);
82-
const vaultId = await encryptVaultId(vaultIds);
83103

84-
let encryptedText = await encryptInline(
85-
text,
86-
rootPath,
87-
pass,
88-
vaultId,
89-
);
104+
let encryptedText = await encryptInline(text, rootPath, pass, vaultId);
90105
encryptedText = "!vault |\n" + encryptedText;
91106
editor.edit((editBuilder) => {
92107
editBuilder.replace(
@@ -99,17 +114,26 @@ export function activate(context: vscode.ExtensionContext) {
99114
});
100115
} else if (type === "encrypted") {
101116
logs.appendLine(`Decrypt selected text`);
102-
const test = text.replace('!vault |', '').trim().replace(/[^\S\r\n]+/gm, '');
103-
logs.appendLine(test);
117+
const test = text
118+
.replace("!vault |", "")
119+
.trim()
120+
.replace(/[^\S\r\n]+/gm, "");
104121
const decryptedText = await decryptInline(
105-
text.replace('!vault |', '').trim().replace(/[^\S\r\n]+/gm, ''),
122+
text
123+
.replace("!vault |", "")
124+
.trim()
125+
.replace(/[^\S\r\n]+/gm, ""),
106126
rootPath,
107127
pass,
108-
await encryptVaultId(vaultIds)
128+
vaultId
109129
);
110-
editor.edit((editBuilder) => {
111-
editBuilder.replace(selection, decryptedText);
112-
});
130+
if (decryptedText === undefined) {
131+
vscode.window.showErrorMessage(`Decryption failed: Invalid Vault`);
132+
} else {
133+
editor.edit((editBuilder) => {
134+
editBuilder.replace(selection, decryptedText);
135+
});
136+
}
113137
}
114138
} else {
115139
const content = editor.document.getText();
@@ -122,7 +146,7 @@ export function activate(context: vscode.ExtensionContext) {
122146
content,
123147
rootPath,
124148
pass,
125-
await encryptVaultId(vaultIds)
149+
vaultId
126150
);
127151
editor.edit((builder) => {
128152
builder.replace(
@@ -143,27 +167,26 @@ export function activate(context: vscode.ExtensionContext) {
143167
content,
144168
rootPath,
145169
pass,
146-
await encryptVaultId(vaultIds)
170+
vaultId
147171
);
148-
editor.edit((builder) => {
149-
builder.replace(
150-
new vscode.Range(
151-
doc.lineAt(0).range.start,
152-
doc.lineAt(doc.lineCount - 1).range.end
153-
),
154-
decryptedText
172+
if (decryptedText === undefined) {
173+
vscode.window.showErrorMessage(`Decryption failed: Invalid Vault`);
174+
} else {
175+
editor.edit((builder) => {
176+
builder.replace(
177+
new vscode.Range(
178+
doc.lineAt(0).range.start,
179+
doc.lineAt(doc.lineCount - 1).range.end
180+
),
181+
decryptedText
182+
);
183+
});
184+
vscode.window.showInformationMessage(
185+
`File decrypted: '${doc.fileName}'`
155186
);
156-
});
157-
vscode.window.showInformationMessage(
158-
`File decrypted: '${doc.fileName}'`
159-
);
187+
}
160188
}
161189
}
162-
163-
if (!!pass && !!keypath) {
164-
fs.unlinkSync(keypath);
165-
logs.appendLine(`Removed temporary file: '${keypath}'`);
166-
}
167190
};
168191

169192
const selectVaultId = async () => {
@@ -174,17 +197,23 @@ export function activate(context: vscode.ExtensionContext) {
174197
let otherPath = undefined;
175198
if (editor) {
176199
rootPath = util.getRootPath(logs, editor.document.uri);
177-
otherPath = util.findAnsibleCfgFile(logs, rootPath);
200+
otherPath = util.findAnsibleCfgFile(logs, rootPath, "ansible.cfg");
178201
} else {
179202
vscode.window.showWarningMessage(
180203
"No editor opened! Failed to determine current workspace root folder"
181204
);
182205
}
183206
const config = vscode.workspace.getConfiguration("ansibleVault");
184207

185-
let keyInCfg: string, vaultIds: false | Array<string>;
208+
let keyInCfg: string,
209+
vaultIds: false | Array<string>,
210+
vaultPass: false | { [key: string]: string };
186211
// eslint-disable-next-line prefer-const
187-
[keyInCfg, vaultIds] = util.scanAnsibleCfg(logs, otherPath, rootPath);
212+
[keyInCfg, vaultIds, vaultPass] = util.scanAnsibleCfg(
213+
logs,
214+
otherPath,
215+
rootPath
216+
);
188217
// Try to get vault list from workspace config
189218
if (!keyInCfg && !!config.keyfile && isVaultIdList(config.keyfile)) {
190219
vaultIds = util.getVaultIdList(config.keyfile);
@@ -276,21 +305,23 @@ const decryptInline = async (
276305
encryptVaultId: any
277306
) => {
278307
const vault = new Vault({ password: pass });
308+
let decryptedContent = undefined;
279309

280310
try {
281311
if (encryptVaultId) {
282-
const decryptedContent = await vault.decrypt(text, encryptVaultId);
283-
return <string>decryptedContent;
312+
decryptedContent = await vault.decrypt(text, encryptVaultId);
284313
} else {
285-
const decryptedContent = await vault.decrypt(text, "");
286-
return <string>decryptedContent;
314+
decryptedContent = await vault.decrypt(text, "");
287315
}
288316
} catch (error: any) {
289317
console.error("Decryption failed:", error);
290318
vscode.window.showErrorMessage(`Decryption failed: ${error.message}`);
291-
throw error;
319+
// Instead of throwing an error, return the original text
320+
return text;
292321
}
322+
return <string>decryptedContent;
293323
};
324+
294325
const encryptVaultId = async (vaultIds: false | Array<string>) => {
295326
if (!vaultIds) {
296327
return "";

0 commit comments

Comments
 (0)