55 *--------------------------------------------------------*/
66
77import vscode = require( 'vscode' ) ;
8- import { getFromWorkspaceState , updateWorkspaceState } from './stateUtils' ;
9-
10- const WORKSPACE_IS_TRUSTED_KEY = 'WORKSPACE_IS_TRUSTED_KEY' ;
11- const SECURITY_SENSITIVE_CONFIG : string [ ] = [
12- 'alternateTools' ,
13- 'gopath' ,
14- 'goroot' ,
15- 'inferGopath' ,
16- 'toolsGopath' ,
17- 'toolsEnvVars'
18- ] ;
19-
20- // Set true only if the vscode is the recent version that has the workspace trust API AND
21- // if the security.workspace.trust is enabled. Change of this configuration requires restart
22- // of VSCode, so we don't need to set up the configuration change listener.
23- // TODO(hyangah): remove this and Configuration & WrappedConfiguration when we update
24- // our extension to require 2021 June VSCode engine.
25- const isVscodeWorkspaceTrustAPIAvailable =
26- 'boolean' === typeof ( vscode . workspace as any ) . isTrusted &&
27- vscode . workspace . getConfiguration ( 'security.workspace.trust' ) ?. get ( 'enabled' ) === true ;
28-
29- // Initialize the singleton defaultConfig and register related commands.
30- // Prompt if workspace configuration was found but had to be ignored until
31- // the user has to explicitly opt in to trust the workspace.
32- export async function initConfig ( ctx : vscode . ExtensionContext ) {
33- ctx . subscriptions . push ( vscode . commands . registerCommand ( 'go.workspace.isTrusted.toggle' , toggleWorkspaceIsTrusted ) ) ;
34-
35- if ( isVscodeWorkspaceTrustAPIAvailable ) {
36- return ; // let vscode handle configuration management.
37- }
38-
39- const isTrusted = getFromWorkspaceState ( WORKSPACE_IS_TRUSTED_KEY , false ) ;
40- if ( isTrusted !== defaultConfig . workspaceIsTrusted ( ) ) {
41- defaultConfig . toggleWorkspaceIsTrusted ( ) ;
42- }
43-
44- if ( isTrusted ) {
45- return ;
46- }
47- const ignored = ignoredWorkspaceConfig ( vscode . workspace . getConfiguration ( 'go' ) , SECURITY_SENSITIVE_CONFIG ) ;
48- if ( ignored . length === 0 ) {
49- return ;
50- }
51- const ignoredSettings = ignored . map ( ( x ) => `"go.${ x } "` ) . join ( ',' ) ;
52- const val = await vscode . window . showWarningMessage (
53- `Some workspace/folder-level settings (${ ignoredSettings } ) from the untrusted workspace are disabled ` +
54- 'by default. If this workspace is trusted, explicitly enable the workspace/folder-level settings ' +
55- 'by running the "Go: Toggle Workspace Trust Flag" command.' ,
56- 'OK' ,
57- 'Trust This Workspace' ,
58- 'More Info'
59- ) ;
60- switch ( val ) {
61- case 'Trust This Workspace' :
62- await toggleWorkspaceIsTrusted ( ) ;
63- break ;
64- case 'More Info' :
65- vscode . env . openExternal (
66- vscode . Uri . parse ( 'https://github.com/golang/vscode-go/blob/master/docs/settings.md#security' )
67- ) ;
68- break ;
69- default :
70- break ;
71- }
72- }
73-
74- function ignoredWorkspaceConfig ( cfg : vscode . WorkspaceConfiguration , keys : string [ ] ) {
75- return keys . filter ( ( key ) => {
76- const inspect = cfg . inspect ( key ) ;
77- return inspect . workspaceValue !== undefined || inspect . workspaceFolderValue !== undefined ;
78- } ) ;
79- }
80-
81- async function toggleWorkspaceIsTrusted ( ) {
82- if ( isVscodeWorkspaceTrustAPIAvailable ) {
83- vscode . commands . executeCommand ( 'workbench.action.manageTrust' ) ;
84- return ;
85- }
86- const v = defaultConfig . toggleWorkspaceIsTrusted ( ) ;
87- await updateWorkspaceState ( WORKSPACE_IS_TRUSTED_KEY , v ) ;
88- }
89-
90- // Go extension configuration for a workspace.
91- export class Configuration {
92- constructor ( private _workspaceIsTrusted = false , private getConfiguration = vscode . workspace . getConfiguration ) { }
93-
94- public toggleWorkspaceIsTrusted ( ) {
95- this . _workspaceIsTrusted = ! this . _workspaceIsTrusted ;
96- return this . _workspaceIsTrusted ;
97- }
98-
99- // returns a Proxied vscode.WorkspaceConfiguration, which prevents
100- // from using the workspace configuration if the workspace is untrusted.
101- public get ( section : string , uri ?: vscode . Uri ) : vscode . WorkspaceConfiguration {
102- const cfg = this . getConfiguration ( section , uri ) ;
103- if ( section !== 'go' || this . _workspaceIsTrusted ) {
104- return cfg ;
105- }
106- return new WrappedConfiguration ( cfg ) ;
107- }
108-
109- public workspaceIsTrusted ( ) : boolean {
110- return this . _workspaceIsTrusted ;
111- }
112- }
113-
114- class vscodeConfiguration {
115- public toggleWorkspaceIsTrusted ( ) {
116- /* no-op */
117- }
118- public get ( section : string , uri ?: vscode . Uri ) : vscode . WorkspaceConfiguration {
119- return vscode . workspace . getConfiguration ( section , uri ) ;
120- }
121- public workspaceIsTrusted ( ) : boolean {
122- return ! ! ( vscode . workspace as any ) . isTrusted ;
123- }
124- }
125-
126- const defaultConfig = isVscodeWorkspaceTrustAPIAvailable ? new vscodeConfiguration ( ) : new Configuration ( ) ;
127-
128- // Returns the workspace Configuration used by the extension.
129- export function DefaultConfig ( ) {
130- return defaultConfig ;
131- }
132-
133- // wrappedConfiguration wraps vscode.WorkspaceConfiguration.
134- class WrappedConfiguration implements vscode . WorkspaceConfiguration {
135- constructor ( private readonly _wrapped : vscode . WorkspaceConfiguration ) {
136- // set getters for direct setting access (e.g. cfg.gopath), but don't overwrite _wrapped.
137- const desc = Object . getOwnPropertyDescriptors ( _wrapped ) ;
138- for ( const prop in desc ) {
139- // TODO(hyangah): find a better way to exclude WrappedConfiguration's members.
140- // These methods are defined by WrappedConfiguration.
141- if ( typeof prop === 'string' && ! [ 'get' , 'has' , 'inspect' , 'update' , '_wrapped' ] . includes ( prop ) ) {
142- const d = desc [ prop ] ;
143- if ( SECURITY_SENSITIVE_CONFIG . includes ( prop ) ) {
144- const inspect = this . _wrapped . inspect ( prop ) ;
145- d . value = inspect . globalValue ?? inspect . defaultValue ;
146- }
147- Object . defineProperty ( this , prop , desc [ prop ] ) ;
148- }
149- }
150- }
151-
152- public get ( section : any , defaultValue ?: any ) {
153- if ( SECURITY_SENSITIVE_CONFIG . includes ( section ) ) {
154- const inspect = this . _wrapped . inspect ( section ) ;
155- return inspect . globalValue ?? defaultValue ?? inspect . defaultValue ;
156- }
157- return this . _wrapped . get ( section , defaultValue ) ;
158- }
159- public has ( section : string ) {
160- return this . _wrapped . has ( section ) ;
161- }
162- public inspect < T > ( section : string ) {
163- return this . _wrapped . inspect < T > ( section ) ;
164- }
165- public update (
166- section : string ,
167- value : any ,
168- configurationTarget ?: boolean | vscode . ConfigurationTarget ,
169- overrideInLanguage ?: boolean
170- ) : Thenable < void > {
171- return this . _wrapped . update ( section , value , configurationTarget , overrideInLanguage ) ;
172- }
173- }
1748
1759// getGoConfig is declared as an exported const rather than a function, so it can be stubbbed in testing.
17610export const getGoConfig = ( uri ?: vscode . Uri ) => {
@@ -190,7 +24,7 @@ function getConfig(section: string, uri?: vscode.Uri) {
19024 uri = null ;
19125 }
19226 }
193- return defaultConfig . get ( section , uri ) ;
27+ return vscode . workspace . getConfiguration ( section , uri ) ;
19428}
19529
19630// True if the extension is running in known cloud-based IDEs.
0 commit comments