blob: b12ba5109074344316b0d153c26199a4303b737c [file] [log] [blame]
/*---------------------------------------------------------
* Copyright 2021 The Go Authors. All rights reserved.
* Licensed under the MIT License. See LICENSE in the project root for license information.
*--------------------------------------------------------*/
import vscode = require('vscode');
const SECURITY_SENSITIVE_CONFIG: string[] = [
'goroot', 'gopath', 'toolsGopath', 'alternateTools'
];
// Go extension configuration for a workspace.
export class Configuration {
constructor(
private isTrustedWorkspace: boolean,
private getConfiguration: typeof vscode.workspace.getConfiguration) { }
// returns a Proxied vscode.WorkspaceConfiguration, which prevents
// from using the workspace configuration if the workspace is untrusted.
public get<T>(uri?: vscode.Uri): vscode.WorkspaceConfiguration {
const cfg = this.getConfiguration('go', uri);
if (this.isTrustedWorkspace) {
return cfg;
}
return new WrappedConfiguration(cfg);
}
}
// wrappedConfiguration wraps vscode.WorkspaceConfiguration.
class WrappedConfiguration implements vscode.WorkspaceConfiguration {
constructor(private readonly _wrapped: vscode.WorkspaceConfiguration) {
// set getters for direct setting access (e.g. cfg.gopath), but don't overwrite _wrapped.
const desc = Object.getOwnPropertyDescriptors(_wrapped);
for (const prop in desc) {
if (typeof prop === 'string' && prop !== '_wrapped') {
const d = desc[prop];
if (SECURITY_SENSITIVE_CONFIG.includes(prop)) {
const inspect = this._wrapped.inspect(prop);
d.value = inspect.globalValue ?? inspect.defaultValue;
}
Object.defineProperty(this, prop, desc[prop]);
}
}
}
public get(section: any, defaultValue?: any) {
if (SECURITY_SENSITIVE_CONFIG.includes(section)) {
const inspect = this._wrapped.inspect(section);
return inspect.globalValue ?? defaultValue ?? inspect.defaultValue;
}
return this._wrapped.get(section, defaultValue);
}
public has(section: string) {
return this._wrapped.has(section);
}
public inspect<T>(section: string) {
return this._wrapped.inspect<T>(section);
}
public update(
section: string, value: any, configurationTarget?: boolean | vscode.ConfigurationTarget,
overrideInLanguage?: boolean): Thenable<void> {
return this._wrapped.update(section, value, configurationTarget, overrideInLanguage);
}
}