Skip to content

Commit edaf784

Browse files
feat: stop displaying error when scanning ignored file
1 parent 47ce4df commit edaf784

File tree

4 files changed

+129
-86
lines changed

4 files changed

+129
-86
lines changed

src/extension.ts

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ import {
1010
scanFile,
1111
showAPIQuota,
1212
} from "./lib/ggshield-api";
13-
import {
14-
getConfiguration,
15-
setApiKey,
16-
} from "./lib/ggshield-configuration";
13+
import { getConfiguration, setApiKey } from "./lib/ggshield-configuration";
1714
import {
1815
ExtensionContext,
1916
Uri,
@@ -26,15 +23,18 @@ import {
2623
import { GGShieldResolver } from "./lib/ggshield-resolver";
2724
import { getCurrentFile, isGitInstalled } from "./utils";
2825
import { GitGuardianWebviewProvider } from "./ggshield-webview/gitguardian-webview-view";
29-
import { createStatusBarItem, StatusBarStatus, updateStatusBarItem } from "./gitguardian-interface/gitguardian-status-bar";
26+
import {
27+
createStatusBarItem,
28+
StatusBarStatus,
29+
updateStatusBarItem,
30+
} from "./gitguardian-interface/gitguardian-status-bar";
3031
import {
3132
generateSecretName,
3233
GitGuardianSecretHoverProvider,
3334
} from "./gitguardian-interface/gitguardian-hover-provider";
3435
import { GitGuardianQuotaWebviewProvider } from "./ggshield-webview/gitguardian-quota-webview";
3536
import { GitGuardianRemediationMessageWebviewProvider } from "./ggshield-webview/gitguardian-remediation-message-view";
3637

37-
3838
function registerOpenViewsCommands(
3939
context: ExtensionContext,
4040
outputChannel: any
@@ -76,7 +76,7 @@ function registerQuotaViewCommands(view: GitGuardianQuotaWebviewProvider) {
7676

7777
export function activate(context: ExtensionContext) {
7878
// Check if ggshield if available
79-
commands.executeCommand('setContext', 'isAuthenticated', false);
79+
commands.executeCommand("setContext", "isAuthenticated", false);
8080

8181
const outputChannel = window.createOutputChannel("GitGuardian");
8282
let configuration = getConfiguration(context);
@@ -92,11 +92,12 @@ export function activate(context: ExtensionContext) {
9292
context
9393
);
9494

95-
const ggshieldRemediationMessageViewProvider = new GitGuardianRemediationMessageWebviewProvider(
96-
configuration,
97-
context.extensionUri,
98-
context
99-
);
95+
const ggshieldRemediationMessageViewProvider =
96+
new GitGuardianRemediationMessageWebviewProvider(
97+
configuration,
98+
context.extensionUri,
99+
context
100+
);
100101
const ggshieldQuotaViewProvider = new GitGuardianQuotaWebviewProvider(
101102
configuration,
102103
context.extensionUri,
@@ -111,7 +112,11 @@ export function activate(context: ExtensionContext) {
111112
"gitguardianQuotaView",
112113
ggshieldQuotaViewProvider
113114
);
114-
context.subscriptions.push(ggshieldViewProvider, ggshieldRemediationMessageViewProvider, ggshieldQuotaViewProvider);
115+
context.subscriptions.push(
116+
ggshieldViewProvider,
117+
ggshieldRemediationMessageViewProvider,
118+
ggshieldQuotaViewProvider
119+
);
115120

116121
createStatusBarItem(context);
117122

@@ -134,7 +139,6 @@ export function activate(context: ExtensionContext) {
134139
ggshieldViewProvider.refresh();
135140
ggshieldRemediationMessageViewProvider.refresh();
136141
ggshieldQuotaViewProvider.refresh();
137-
138142
} else {
139143
updateStatusBarItem(StatusBarStatus.unauthenticated);
140144
}
@@ -156,10 +160,13 @@ export function activate(context: ExtensionContext) {
156160
context.subscriptions.push(
157161
workspace.onDidSaveTextDocument((textDocument) => {
158162
// Check if the document is inside the workspace
159-
const workspaceFolder = workspace.getWorkspaceFolder(textDocument.uri);
160-
console.log(context.globalState.get("isAuthenticated", false), workspaceFolder);
161-
console.log('»»»»»»»»»»»»»»', context.globalState.get("isAuthenticated", false) && workspaceFolder);
162-
if (context.globalState.get("isAuthenticated", false) && workspaceFolder) {
163+
const workspaceFolder = workspace.getWorkspaceFolder(
164+
textDocument.uri
165+
);
166+
if (
167+
context.globalState.get("isAuthenticated", false) &&
168+
workspaceFolder
169+
) {
163170
scanFile(
164171
textDocument.fileName,
165172
textDocument.uri,
@@ -182,9 +189,7 @@ export function activate(context: ExtensionContext) {
182189
commands.registerCommand(
183190
"gitguardian.ignoreSecret",
184191
(diagnosticData) => {
185-
window.showInformationMessage(
186-
'Secret ignored.'
187-
);
192+
window.showInformationMessage("Secret ignored.");
188193
let currentFile = getCurrentFile();
189194
let secretName = generateSecretName(currentFile, diagnosticData);
190195

@@ -196,7 +201,7 @@ export function activate(context: ExtensionContext) {
196201
scanFile(
197202
currentFile,
198203
Uri.file(currentFile),
199-
ggshieldResolver.configuration,
204+
ggshieldResolver.configuration
200205
);
201206
}
202207
),
@@ -207,19 +212,21 @@ export function activate(context: ExtensionContext) {
207212
outputChannel,
208213
ggshieldViewProvider.getView() as WebviewView,
209214
context
210-
).then(() => {
211-
if (context.globalState.get("isAuthenticated", false)) {
212-
updateStatusBarItem(StatusBarStatus.ready);
213-
setApiKey(configuration, ggshieldApiKey(configuration));
214-
} else {
215-
updateStatusBarItem(StatusBarStatus.unauthenticated);
216-
}
217-
ggshieldViewProvider.refresh();
218-
ggshieldRemediationMessageViewProvider.refresh();
219-
ggshieldQuotaViewProvider.refresh();
220-
}).catch((err) => {
221-
outputChannel.appendLine(`Authentication failed: ${err.message}`);
222-
});
215+
)
216+
.then(() => {
217+
if (context.globalState.get("isAuthenticated", false)) {
218+
updateStatusBarItem(StatusBarStatus.ready);
219+
setApiKey(configuration, ggshieldApiKey(configuration));
220+
} else {
221+
updateStatusBarItem(StatusBarStatus.unauthenticated);
222+
}
223+
ggshieldViewProvider.refresh();
224+
ggshieldRemediationMessageViewProvider.refresh();
225+
ggshieldQuotaViewProvider.refresh();
226+
})
227+
.catch((err) => {
228+
outputChannel.appendLine(`Authentication failed: ${err.message}`);
229+
});
223230
}),
224231
commands.registerCommand("gitguardian.logout", async () => {
225232
logoutGGShield(ggshieldResolver.configuration, context);

src/lib/ggshield-api.ts

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
/* eslint-disable @typescript-eslint/naming-convention */
2+
import { SpawnOptionsWithoutStdio, spawn } from "child_process";
23
import {
3-
SpawnOptionsWithoutStdio,
4-
spawn,
5-
} from "child_process";
6-
import { window, WebviewView, DiagnosticCollection, commands, ExtensionContext, languages, Uri, Diagnostic } from "vscode";
7-
import axios from 'axios';
4+
window,
5+
WebviewView,
6+
DiagnosticCollection,
7+
commands,
8+
ExtensionContext,
9+
languages,
10+
Uri,
11+
Diagnostic,
12+
} from "vscode";
13+
import axios from "axios";
814
import { GGShieldConfiguration } from "./ggshield-configuration";
915
import { GGShieldScanResults } from "./api-types";
1016
import * as os from "os";
1117
import { apiToDashboard, dasboardToApi, isFileGitignored } from "../utils";
1218
import { runGGShieldCommand } from "./run-ggshield";
13-
import { StatusBarStatus, updateStatusBarItem } from "../gitguardian-interface/gitguardian-status-bar";
19+
import {
20+
StatusBarStatus,
21+
updateStatusBarItem,
22+
} from "../gitguardian-interface/gitguardian-status-bar";
1423
import { parseGGShieldResults } from "./ggshield-results-parser";
1524

1625
/**
@@ -50,22 +59,21 @@ export async function getAPIquota(
5059
}
5160
}
5261

53-
5462
export async function getRemediationMessage(
5563
configuration: GGShieldConfiguration
5664
): Promise<string> {
5765
const apiUrl = dasboardToApi(configuration.apiUrl);
58-
const path = require('node:path');
59-
try {
60-
const response = await axios.get(path.join(apiUrl,'v1/metadata'), {
61-
headers: {
62-
'authorization': `Token ${configuration.apiKey}`
63-
}
64-
});
65-
return response.data.remediation_messages.pre_commit;
66-
} catch (error) {
67-
return "An error occured.";
68-
}
66+
const path = require("node:path");
67+
try {
68+
const response = await axios.get(path.join(apiUrl, "v1/metadata"), {
69+
headers: {
70+
authorization: `Token ${configuration.apiKey}`,
71+
},
72+
});
73+
return response.data.remediation_messages.pre_commit;
74+
} catch (error) {
75+
return "An error occurred.";
76+
}
6977
}
7078

7179
/**
@@ -135,7 +143,6 @@ export function cleanUpFileDiagnostics(fileUri: Uri): void {
135143
diagnosticCollection.delete(fileUri);
136144
}
137145

138-
139146
/**
140147
* Scan a file using ggshield
141148
*
@@ -167,6 +174,15 @@ export async function scanFile(
167174

168175
// Ignore errors concerning usage
169176
// This occurs when the path of the file is invalid (i.e.VSCode sending an event for files not on the file system)
177+
// or when the file is ignored in the .gitguardian.yaml
178+
if (
179+
proc.stderr.includes(
180+
"Error: An ignored file or directory cannot be scanned"
181+
)
182+
) {
183+
updateStatusBarItem(StatusBarStatus.ignoredFile);
184+
return;
185+
}
170186
if (proc.stderr.includes("Usage: ggshield secret scan path")) {
171187
return undefined;
172188
}
@@ -195,11 +211,10 @@ export async function scanFile(
195211
} else {
196212
updateStatusBarItem(StatusBarStatus.noSecretFound);
197213
}
198-
214+
199215
diagnosticCollection.set(fileUri, incidentsDiagnostics);
200216
}
201217

202-
203218
export async function loginGGShield(
204219
configuration: GGShieldConfiguration,
205220
outputChannel: any,
@@ -232,7 +247,7 @@ export async function loginGGShield(
232247
if (urlLine) {
233248
const authUrl = urlLine[0];
234249
webviewView.webview.postMessage({
235-
type: 'authLink',
250+
type: "authLink",
236251
link: authUrl,
237252
});
238253
}
@@ -249,7 +264,7 @@ export async function loginGGShield(
249264
} else {
250265
outputChannel.appendLine("ggshield login completed successfully");
251266
commands.executeCommand("setContext", "isAuthenticated", true);
252-
await context.globalState.update('isAuthenticated', true);
267+
await context.globalState.update("isAuthenticated", true);
253268
resolve();
254269
}
255270
});
@@ -261,44 +276,41 @@ export async function loginGGShield(
261276
});
262277
}
263278

264-
265279
export async function logoutGGShield(
266280
configuration: GGShieldConfiguration,
267281
context: ExtensionContext
268282
): Promise<void> {
269283
runGGShieldCommand(configuration, ["auth", "logout"]);
270-
commands.executeCommand('setContext', 'isAuthenticated', false);
271-
await context.globalState.update('isAuthenticated', false);
272-
284+
commands.executeCommand("setContext", "isAuthenticated", false);
285+
await context.globalState.update("isAuthenticated", false);
273286
}
274287

275288
export async function ggshieldAuthStatus(
276289
configuration: GGShieldConfiguration,
277290
context: ExtensionContext
278-
): Promise<void> {
279-
let isAuthenticated: boolean;
280-
const proc = runGGShieldCommand(configuration, ["api-status", "--json"]);
281-
if (proc.status === 0 && JSON.parse(proc.stdout).status_code === 200) {
282-
isAuthenticated = true;
291+
): Promise<void> {
292+
let isAuthenticated: boolean;
293+
const proc = runGGShieldCommand(configuration, ["api-status", "--json"]);
294+
if (proc.status === 0 && JSON.parse(proc.stdout).status_code === 200) {
295+
isAuthenticated = true;
296+
} else {
297+
if (proc.stderr && proc.stderr.includes("Config key")) {
298+
window.showErrorMessage(`Gitguardian: ${proc.stderr}`);
283299
}
284-
else{
285-
if (proc.stderr && proc.stderr.includes("Config key")){
286-
window.showErrorMessage(`Gitguardian: ${proc.stderr}`);
287-
}
288-
console.log(proc.stderr);
289-
isAuthenticated = false;
290-
}
291-
commands.executeCommand('setContext', 'isAuthenticated', isAuthenticated);
292-
await context.globalState.update('isAuthenticated', isAuthenticated);
300+
console.log(proc.stderr);
301+
isAuthenticated = false;
302+
}
303+
commands.executeCommand("setContext", "isAuthenticated", isAuthenticated);
304+
await context.globalState.update("isAuthenticated", isAuthenticated);
293305
}
294306

295307
/**
296308
* Get ggshield API key from ggshield config list
297-
*
309+
*
298310
* Search for the correct instance section and return the token
299311
* */
300312
export function ggshieldApiKey(
301-
configuration: GGShieldConfiguration,
313+
configuration: GGShieldConfiguration
302314
): string | undefined {
303315
const proc = runGGShieldCommand(configuration, ["config", "list"]);
304316
if (proc.stderr || proc.error) {
@@ -308,7 +320,9 @@ export function ggshieldApiKey(
308320
console.log(proc.stdout);
309321
const apiUrl = configuration.apiUrl;
310322

311-
const regexInstanceSection = `\\[${apiToDashboard(apiUrl)}\\]([\\s\\S]*?)(?=\\[|$)`;
323+
const regexInstanceSection = `\\[${apiToDashboard(
324+
apiUrl
325+
)}\\]([\\s\\S]*?)(?=\\[|$)`;
312326
const instanceSectionMatch = proc.stdout.match(regexInstanceSection);
313327

314328
if (instanceSectionMatch) {
@@ -317,11 +331,11 @@ export function ggshieldApiKey(
317331
const matchToken = instanceSection.match(regexToken);
318332

319333
// if the token is not found, or is not a valid token, return undefined
320-
if (!matchToken || matchToken[1].trim().length !== 71 ) {
334+
if (!matchToken || matchToken[1].trim().length !== 71) {
321335
return undefined;
322336
}
323-
337+
324338
return matchToken[1].trim();
325339
}
326340
}
327-
}
341+
}

0 commit comments

Comments
 (0)