forked from denoland/vscode_deno
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig_paths.ts
More file actions
102 lines (87 loc) · 2.81 KB
/
config_paths.ts
File metadata and controls
102 lines (87 loc) · 2.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
import * as vscode from "vscode";
import { EXTENSION_NS } from "./constants";
const APPROVED_PATHS_KEY = "deno.approvedPaths";
export interface DenoPathInfo {
path: string;
isFromWorkspace: boolean;
}
export function getDenoPathInfo(): DenoPathInfo | undefined {
const config = vscode.workspace.getConfiguration(EXTENSION_NS);
const inspection = config.inspect<string>("path");
const rawPath = config.get<string>("path");
if (typeof rawPath === "string" && rawPath.trim().length > 0) {
// check if path is set in workspace or folder settings (not global/user)
const workspaceValue = inspection?.workspaceValue;
const folderValue = inspection?.workspaceFolderValue;
const isFromWorkspace = (typeof workspaceValue === "string" &&
workspaceValue.trim().length > 0) ||
(typeof folderValue === "string" && folderValue.trim().length > 0);
return {
path: rawPath.trim(),
isFromWorkspace,
};
} else {
return undefined;
}
}
export class ApprovedConfigPaths {
readonly #context: vscode.ExtensionContext;
readonly #sessionDeniedPaths = new Set<string>();
constructor(context: vscode.ExtensionContext) {
this.#context = context;
}
#getApprovedPaths(): string[] {
const value = this.#context.workspaceState.get(APPROVED_PATHS_KEY);
if (!Array.isArray(value)) {
return [];
}
return value.filter((item): item is string => typeof item === "string");
}
isPathApproved(path: string): boolean {
const approvedPaths = this.#getApprovedPaths();
return approvedPaths.includes(path);
}
async #approvePath(path: string): Promise<void> {
const approvedPaths = this.#getApprovedPaths();
if (!approvedPaths.includes(path)) {
approvedPaths.push(path);
await this.#context.workspaceState.update(
APPROVED_PATHS_KEY,
approvedPaths,
);
}
}
/** Prompts the user for approval if the path hasn't been approved yet. */
async promptForApproval(
pathInfo: DenoPathInfo | undefined,
): Promise<boolean> {
// null and global paths don't need approval
if (pathInfo == null || !pathInfo.isFromWorkspace) {
return true;
}
const path = pathInfo.path;
if (this.isPathApproved(path)) {
return true;
}
// already denied for this session
if (this.#sessionDeniedPaths.has(path)) {
return false;
}
const allow = "Allow";
const deny = "Deny";
const result = await vscode.window.showWarningMessage(
`A workspace setting wants to run a custom Deno executable: ${path}`,
allow,
deny,
);
if (result === allow) {
await this.#approvePath(path);
return true;
}
if (result === deny) {
this.#sessionDeniedPaths.add(path);
}
return false;
}
}