Skip to content

Commit a11c1a5

Browse files
authored
Merge pull request #53 from GitGuardian/salomevoltz/scrt-4987-allow-self-signed-certificates
Add optional 'allow self signed' option in settings
2 parents 44117fb + 68d4932 commit a11c1a5

File tree

8 files changed

+147
-45
lines changed

8 files changed

+147
-45
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
"type": "string",
3535
"default": "",
3636
"markdownDescription": "Your API Key"
37+
},
38+
"gitguardian.allowSelfSigned": {
39+
"type": "boolean",
40+
"default": false,
41+
"markdownDescription": "Allow Self Signed Certificates"
3742
}
3843
}
3944
},

src/extension.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ import {
1010
scanFile,
1111
showAPIQuota,
1212
} from "./lib/ggshield-api";
13-
import { getConfiguration, setApiKey } from "./lib/ggshield-configuration";
13+
import {
14+
getConfiguration,
15+
setApiKey,
16+
} from "./lib/ggshield-configuration-utils";
1417
import {
1518
ExtensionContext,
1619
Uri,

src/gitguardian-interface/gitguardian-status-bar.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ function getStatusBarConfig(status: StatusBarStatus): StatusBarConfig {
4646
command: "gitguardian.openSidebar",
4747
};
4848
case StatusBarStatus.ready:
49-
return { text: "GitGuardian is ready", color: "statusBar.foreground" };
49+
return {
50+
text: "GitGuardian is ready",
51+
color: "statusBar.foreground",
52+
command: "gitguardian.openSidebar",
53+
};
5054
case StatusBarStatus.scanning:
5155
return {
5256
text: "GitGuardian - Scanning...",
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { getBinaryAbsolutePath } from "./ggshield-resolver-utils";
2+
import { ExtensionContext, workspace } from "vscode";
3+
import * as os from "os";
4+
import { GGShieldConfiguration } from "./ggshield-configuration";
5+
6+
const apiUrlDefault = "https://dashboard.gitguardian.com/";
7+
8+
/**
9+
* Retrieve configuration from settings
10+
*
11+
* TODO: Check with Mathieu if this behaviour is expected
12+
* @returns {GGShieldConfiguration} from the extension settings
13+
*/
14+
export function getConfiguration(
15+
context: ExtensionContext
16+
): GGShieldConfiguration {
17+
const config = workspace.getConfiguration("gitguardian");
18+
19+
const ggshieldPath: string | undefined = config.get("GGShieldPath");
20+
const apiUrl: string | undefined = config.get("apiUrl");
21+
const apiKey: string | undefined = config.get("apiKey");
22+
const allowSelfSigned: boolean = config.get("allowSelfSigned", false);
23+
return new GGShieldConfiguration(
24+
ggshieldPath
25+
? ggshieldPath
26+
: getBinaryAbsolutePath(os.platform(), os.arch(), context),
27+
apiUrl || apiUrlDefault,
28+
apiKey || "",
29+
allowSelfSigned || false
30+
);
31+
}
32+
33+
export function setApiKey(
34+
configuration: GGShieldConfiguration,
35+
apiKey: string | undefined
36+
): void {
37+
configuration.apiKey = apiKey ? apiKey : "";
38+
}

src/lib/ggshield-configuration.ts

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,18 @@
1-
import { getBinaryAbsolutePath } from "./ggshield-resolver-utils";
2-
import { ExtensionContext, workspace } from "vscode";
3-
import * as os from "os";
4-
5-
const apiUrlDefault = "https://dashboard.gitguardian.com/";
6-
71
export class GGShieldConfiguration {
82
ggshieldPath: string;
93
apiUrl: string;
104
apiKey: string;
5+
allowSelfSigned: boolean;
116

127
constructor(
138
ggshieldPath: string = "",
149
apiUrl: string = "",
15-
apiKey: string = ""
10+
apiKey: string = "",
11+
allowSelfSigned: boolean = false
1612
) {
1713
this.ggshieldPath = ggshieldPath;
1814
this.apiUrl = apiUrl;
1915
this.apiKey = apiKey;
16+
this.allowSelfSigned = allowSelfSigned;
2017
}
2118
}
22-
23-
/**
24-
* Retrieve configuration from settings
25-
*
26-
* TODO: Check with Mathieu if this behaviour is expected
27-
* @returns {GGShieldConfiguration} from the extension settings
28-
*/
29-
export function getConfiguration(
30-
context: ExtensionContext
31-
): GGShieldConfiguration {
32-
const config = workspace.getConfiguration("gitguardian");
33-
34-
const ggshieldPath: string | undefined = config.get("GGShieldPath");
35-
const apiUrl: string | undefined = config.get("apiUrl");
36-
const apiKey: string | undefined = config.get("apiKey");
37-
38-
return new GGShieldConfiguration(
39-
ggshieldPath
40-
? ggshieldPath
41-
: getBinaryAbsolutePath(os.platform(), os.arch(), context),
42-
apiUrl ? apiUrl : apiUrlDefault,
43-
apiKey ? apiKey : ""
44-
);
45-
}
46-
47-
export function setApiKey(
48-
configuration: GGShieldConfiguration,
49-
apiKey: string | undefined
50-
): void {
51-
configuration.apiKey = apiKey ? apiKey : "";
52-
}

src/lib/run-ggshield.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export function runGGShieldCommand(
4141
if (workspace.workspaceFolders?.length || 0 > 0) {
4242
options["cwd"] = workspace.workspaceFolders![0].uri.fsPath;
4343
}
44+
// if allowSelfSigned is enabled, add the --allow-self-signed flag
45+
if (configuration.allowSelfSigned) {
46+
args = ["--allow-self-signed"].concat(args);
47+
}
4448
let proc = spawnSync(ggshieldPath, args, options);
4549

4650
return proc;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import * as simple from "simple-mock";
2+
import assert = require("assert");
3+
import { ExtensionContext, workspace } from "vscode";
4+
import { getConfiguration } from "../../../lib/ggshield-configuration-utils";
5+
6+
suite("getConfiguration", () => {
7+
let getConfigurationMock: simple.Stub<Function>;
8+
9+
setup(() => {
10+
// Mock workspace.getConfiguration
11+
getConfigurationMock = simple.mock(workspace, "getConfiguration");
12+
});
13+
14+
teardown(() => {
15+
simple.restore();
16+
});
17+
18+
test("Vscode settings are correctly read", async () => {
19+
getConfigurationMock.returnWith({
20+
get: (key: string) => {
21+
if (key === "GGShieldPath") {
22+
return "path/to/ggshield";
23+
}
24+
if (key === "apiUrl") {
25+
return "https://custom-url.com";
26+
}
27+
if (key === "apiKey") {
28+
return "test-api-key";
29+
}
30+
if (key === "allowSelfSigned") {
31+
return true;
32+
}
33+
},
34+
});
35+
const configuration = getConfiguration({} as ExtensionContext);
36+
37+
// Assert both workspace.getConfiguration and GGShieldConfiguration constructor were called
38+
assert(
39+
getConfigurationMock.called,
40+
"getConfiguration should be called once"
41+
);
42+
43+
// Assert that the configuration has the expected values
44+
assert.strictEqual(configuration.ggshieldPath, "path/to/ggshield");
45+
assert.strictEqual(configuration.apiUrl, "https://custom-url.com");
46+
assert.strictEqual(configuration.apiKey, "test-api-key");
47+
assert.strictEqual(configuration.allowSelfSigned, true);
48+
});
49+
});

src/test/suite/lib/run-ggshield.test.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ suite("runGGShieldCommand", () => {
1717

1818
test("Global env variables are set correctly", async () => {
1919
process.env.TEST_GLOBAL_VAR = "GlobalValue";
20-
21-
const spawnSyncSpy = simple.mock(childProcess, "spawnSync");
2220
runGGShield.runGGShieldCommand(
2321
{
2422
ggshieldPath: "path/to/ggshield",
@@ -29,14 +27,49 @@ suite("runGGShieldCommand", () => {
2927
);
3028

3129
// Assert that spawnSync was called
32-
assert(spawnSyncSpy.called, "spawnSync should be called once");
30+
assert(spawnSyncMock.called, "spawnSync should be called once");
3331

3432
// Check the arguments passed to spawnSync
35-
const spawnSyncArgs = spawnSyncSpy.lastCall.args;
33+
const spawnSyncArgs = spawnSyncMock.lastCall.args;
3634
const options = spawnSyncArgs[2];
3735
assert.strictEqual(options.env.TEST_GLOBAL_VAR, "GlobalValue");
3836

39-
simple.restore();
4037
delete process.env.TEST_GLOBAL_VAR;
4138
});
39+
40+
const testCasesAllowSelfSigned = [
41+
{
42+
allowSelfSigned: true,
43+
description:
44+
"GGshield is called with flag --allow-self-signed when allowSelfSigned is true",
45+
},
46+
{
47+
allowSelfSigned: false,
48+
description:
49+
"GGshield is not called with flag --allow-self-signed when allowSelfSigned is false",
50+
},
51+
];
52+
53+
testCasesAllowSelfSigned.forEach(({ allowSelfSigned, description }) => {
54+
test(description, async () => {
55+
process.env.TEST_GLOBAL_VAR = "GlobalValue";
56+
57+
runGGShield.runGGShieldCommand(
58+
{
59+
ggshieldPath: "path/to/ggshield",
60+
apiUrl: "",
61+
apiKey: "",
62+
allowSelfSigned: allowSelfSigned,
63+
} as GGShieldConfiguration,
64+
["test"]
65+
);
66+
67+
assert(spawnSyncMock.called, "spawnSync should be called once");
68+
69+
const spawnSyncArgs = spawnSyncMock.lastCall.args;
70+
const args = spawnSyncArgs[1];
71+
72+
assert.strictEqual(args[0] === "--allow-self-signed", allowSelfSigned);
73+
});
74+
});
4275
});

0 commit comments

Comments
 (0)