未验证 提交 2532ffff 编写于 作者: B Benjamin Pasero 提交者: GitHub

Sandboxed issue reporter, fixes #101833

上级 459a9aed
......@@ -77,7 +77,7 @@ const vscodeResources = [
'out-build/vs/platform/files/**/*.md',
'out-build/vs/code/electron-browser/workbench/**',
'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js',
'out-build/vs/code/electron-browser/issue/issueReporter.js',
'out-build/vs/code/electron-sandbox/issue/issueReporter.js',
'out-build/vs/code/electron-sandbox/processExplorer/processExplorer.js',
'out-build/vs/platform/auth/common/auth.css',
'!**/test/**'
......
......@@ -22,9 +22,8 @@ exports.collectModules = function () {
createModuleDescription('vs/code/electron-main/main', []),
createModuleDescription('vs/code/node/cli', []),
createModuleDescription('vs/code/node/cliProcessMain', ['vs/code/node/cli']),
createModuleDescription('vs/code/electron-browser/issue/issueReporterMain', []),
createModuleDescription('vs/code/electron-sandbox/issue/issueReporterMain', []),
createModuleDescription('vs/code/electron-browser/sharedProcess/sharedProcessMain', []),
createModuleDescription('vs/code/electron-browser/issue/issueReporterMain', []),
createModuleDescription('vs/platform/driver/node/driver', []),
createModuleDescription('vs/code/electron-sandbox/processExplorer/processExplorerMain', [])
];
......
......@@ -14,6 +14,6 @@ const bootstrapWindow = (() => {
return window.MonacoBootstrapWindow;
})();
bootstrapWindow.load(['vs/code/electron-browser/issue/issueReporterMain'], function (issueReporter, configuration) {
bootstrapWindow.load(['vs/code/electron-sandbox/issue/issueReporterMain'], function (issueReporter, configuration) {
issueReporter.startup(configuration);
}, { forceEnableDeveloperKeybindings: true, disallowReloadKeybinding: true });
......@@ -5,9 +5,8 @@
import 'vs/css!./media/issueReporter';
import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is loaded
import * as os from 'os';
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { ipcRenderer, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window';
import { $, windowOpenNoOpener, addClass } from 'vs/base/browser/dom';
import { Button } from 'vs/base/browser/ui/button/button';
......@@ -17,29 +16,15 @@ import { debounce } from 'vs/base/common/decorators';
import { Disposable } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import { escape } from 'vs/base/common/strings';
import { getDelayedChannel, createChannelSender } from 'vs/base/parts/ipc/common/ipc';
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
import { normalizeGitHubUrl } from 'vs/platform/issue/common/issueReporterUtil';
import { IssueReporterData as IssueReporterModelData, IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel';
import BaseHtml from 'vs/code/electron-browser/issue/issueReporterPage';
import { IssueReporterData as IssueReporterModelData, IssueReporterModel } from 'vs/code/electron-sandbox/issue/issueReporterModel';
import BaseHtml from 'vs/code/electron-sandbox/issue/issueReporterPage';
import { localize } from 'vs/nls';
import { isRemoteDiagnosticError, SystemInfo } from 'vs/platform/diagnostics/common/diagnostics';
import { EnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { ISettingsSearchIssueReporterData, IssueReporterData, IssueReporterExtensionData, IssueReporterFeatures, IssueReporterStyles, IssueType } from 'vs/platform/issue/common/issue';
import { getLogLevel, ILogService } from 'vs/platform/log/common/log';
import { FollowerLogService, LoggerChannelClient } from 'vs/platform/log/common/logIpc';
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
import product from 'vs/platform/product/common/product';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ITelemetryServiceConfig, TelemetryService } from 'vs/platform/telemetry/common/telemetryService';
import { combinedAppender, LogAppender, NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
import { INativeWindowConfiguration } from 'vs/platform/windows/node/window';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
const MAX_URL_LENGTH = 2045;
......@@ -49,9 +34,23 @@ interface SearchResult {
state?: string;
}
export interface IssueReporterConfiguration extends INativeWindowConfiguration {
export interface IssueReporterConfiguration extends IWindowConfiguration {
windowId: number;
disableExtensions: boolean;
data: IssueReporterData;
features: IssueReporterFeatures;
os: {
type: string;
arch: string;
release: string;
},
product: {
nameShort: string;
version: string;
commit: string | undefined;
date: string | undefined;
reportIssueUrl: string | undefined;
}
}
export function startup(configuration: IssueReporterConfiguration) {
......@@ -66,10 +65,7 @@ export function startup(configuration: IssueReporterConfiguration) {
}
export class IssueReporter extends Disposable {
private environmentService!: INativeEnvironmentService;
private electronService!: IElectronService;
private telemetryService!: ITelemetryService;
private logService!: ILogService;
private readonly issueReporterModel: IssueReporterModel;
private numberOfSearchResultsDisplayed = 0;
private receivedSystemInfo = false;
......@@ -79,7 +75,7 @@ export class IssueReporter extends Disposable {
private readonly previewButton!: Button;
constructor(configuration: IssueReporterConfiguration) {
constructor(private readonly configuration: IssueReporterConfiguration) {
super();
this.initServices(configuration);
......@@ -90,10 +86,10 @@ export class IssueReporter extends Disposable {
this.issueReporterModel = new IssueReporterModel({
issueType: configuration.data.issueType || IssueType.Bug,
versionInfo: {
vscodeVersion: `${product.nameShort} ${product.version} (${product.commit || 'Commit unknown'}, ${product.date || 'Date unknown'})`,
os: `${os.type()} ${os.arch()} ${os.release()}${isSnap ? ' snap' : ''}`
vscodeVersion: `${configuration.product.nameShort} ${configuration.product.version} (${configuration.product.commit || 'Commit unknown'}, ${configuration.product.date || 'Date unknown'})`,
os: `${this.configuration.os.type} ${this.configuration.os.arch} ${this.configuration.os.release}${isSnap ? ' snap' : ''}`
},
extensionsDisabled: !!this.environmentService.disableExtensions,
extensionsDisabled: !!configuration.disableExtensions,
fileOnExtension: configuration.data.extensionId ? !targetExtension?.isBuiltin : undefined,
selectedExtension: targetExtension,
});
......@@ -121,7 +117,6 @@ export class IssueReporter extends Disposable {
}
ipcRenderer.on('vscode:issuePerformanceInfoResponse', (_: unknown, info: Partial<IssueReporterData>) => {
this.logService.trace('issueReporter: Received performance data');
this.issueReporterModel.update(info);
this.receivedPerformanceInfo = true;
......@@ -132,7 +127,6 @@ export class IssueReporter extends Disposable {
});
ipcRenderer.on('vscode:issueSystemInfoResponse', (_: unknown, info: SystemInfo) => {
this.logService.trace('issueReporter: Received system data');
this.issueReporterModel.update({ systemInfo: info });
this.receivedSystemInfo = true;
......@@ -144,7 +138,6 @@ export class IssueReporter extends Disposable {
if (configuration.data.issueType === IssueType.PerformanceIssue) {
ipcRenderer.send('vscode:issuePerformanceInfoRequest');
}
this.logService.trace('issueReporter: Sent data requests');
if (window.document.documentElement.lang !== 'en') {
show(this.getElementById('english'));
......@@ -266,7 +259,7 @@ export class IssueReporter extends Disposable {
this.issueReporterModel.update({ numberOfThemeExtesions, enabledNonThemeExtesions: nonThemes, allExtensions: installedExtensions });
this.updateExtensionTable(nonThemes, numberOfThemeExtesions);
if (this.environmentService.disableExtensions || installedExtensions.length === 0) {
if (this.configuration.disableExtensions || installedExtensions.length === 0) {
(<HTMLButtonElement>this.getElementById('disableExtensions')).disabled = true;
}
......@@ -314,40 +307,13 @@ export class IssueReporter extends Disposable {
}
}
private initServices(configuration: INativeWindowConfiguration): void {
private initServices(configuration: IssueReporterConfiguration): void {
const serviceCollection = new ServiceCollection();
const mainProcessService = new MainProcessService(configuration.windowId);
serviceCollection.set(IMainProcessService, mainProcessService);
this.electronService = new ElectronService(configuration.windowId, mainProcessService) as IElectronService;
serviceCollection.set(IElectronService, this.electronService);
this.environmentService = new EnvironmentService(configuration, configuration.execPath);
const logService = new SpdLogService(`issuereporter${configuration.windowId}`, this.environmentService.logsPath, getLogLevel(this.environmentService));
const loggerClient = new LoggerChannelClient(mainProcessService.getChannel('logger'));
this.logService = new FollowerLogService(loggerClient, logService);
const sharedProcessService = createChannelSender<ISharedProcessService>(mainProcessService.getChannel('sharedProcess'));
const sharedProcess = sharedProcessService.whenSharedProcessReady()
.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${configuration.windowId}`));
const instantiationService = new InstantiationService(serviceCollection, true);
if (!this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
const channel = getDelayedChannel(sharedProcess.then(c => c.getChannel('telemetryAppender')));
const appender = combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(logService));
const commonProperties = resolveCommonProperties(product.commit || 'Commit unknown', product.version, configuration.machineId, product.msftInternalDomains, this.environmentService.installSourcePath);
const piiPaths = this.environmentService.extensionsPath ? [this.environmentService.appRoot, this.environmentService.extensionsPath] : [this.environmentService.appRoot];
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths, sendErrorTelemetry: true };
const telemetryService = instantiationService.createInstance(TelemetryService, config);
this._register(telemetryService);
this.telemetryService = telemetryService;
} else {
this.telemetryService = NullTelemetryService;
}
}
private setEventHandlers(): void {
......@@ -617,11 +583,11 @@ export class IssueReporter extends Disposable {
}, timeToWait * 1000);
}
}
}).catch(e => {
this.logSearchError(e);
}).catch(_ => {
// Ignore
});
}).catch(e => {
this.logSearchError(e);
}).catch(_ => {
// Ignore
});
}
......@@ -648,11 +614,11 @@ export class IssueReporter extends Disposable {
} else {
throw new Error('Unexpected response, no candidates property');
}
}).catch((error) => {
this.logSearchError(error);
}).catch(_ => {
// Ignore
});
}).catch((error) => {
this.logSearchError(error);
}).catch(_ => {
// Ignore
});
}
......@@ -705,18 +671,6 @@ export class IssueReporter extends Disposable {
}
}
private logSearchError(error: Error) {
this.logService.warn('issueReporter#search ', error.message);
type IssueReporterSearchErrorClassification = {
message: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' }
};
type IssueReporterSearchError = {
message: string;
};
this.telemetryService.publicLogError2<IssueReporterSearchError, IssueReporterSearchErrorClassification>('issueReporterSearchError', { message: error.message });
}
private setUpTypes(): void {
const makeOption = (issueType: IssueType, description: string) => `<option value="${issueType.valueOf()}">${escape(description)}</option>`;
......@@ -910,15 +864,6 @@ export class IssueReporter extends Disposable {
return false;
}
type IssueReporterSubmitClassification = {
issueType: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
numSimilarIssuesDisplayed: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type IssueReporterSubmitEvent = {
issueType: any;
numSimilarIssuesDisplayed: number;
};
this.telemetryService.publicLog2<IssueReporterSubmitEvent, IssueReporterSubmitClassification>('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed });
this.hasBeenSubmitted = true;
const baseUrl = this.getIssueUrlWithTitle((<HTMLInputElement>this.getElementById('issue-title')).value);
......@@ -967,7 +912,7 @@ export class IssueReporter extends Disposable {
}
private getIssueUrlWithTitle(issueTitle: string): string {
let repositoryUrl = product.reportIssueUrl;
let repositoryUrl = this.configuration.product.reportIssueUrl;
if (this.issueReporterModel.fileOnExtension()) {
const extensionGitHubUrl = this.getExtensionGitHubUrl();
if (extensionGitHubUrl) {
......@@ -975,7 +920,7 @@ export class IssueReporter extends Disposable {
}
}
const queryStringPrefix = product.reportIssueUrl && product.reportIssueUrl.indexOf('?') === -1 ? '?' : '&';
const queryStringPrefix = this.configuration.product.reportIssueUrl && this.configuration.product.reportIssueUrl.indexOf('?') === -1 ? '?' : '&';
return `${repositoryUrl}${queryStringPrefix}title=${encodeURIComponent(issueTitle)}`;
}
......@@ -1136,7 +1081,7 @@ export class IssueReporter extends Disposable {
private updateExtensionTable(extensions: IssueReporterExtensionData[], numThemeExtensions: number): void {
const target = document.querySelector('.block-extensions .block-info');
if (target) {
if (this.environmentService.disableExtensions) {
if (this.configuration.disableExtensions) {
target.innerHTML = localize('disabledExtensions', "Extensions are disabled");
return;
}
......@@ -1193,7 +1138,6 @@ export class IssueReporter extends Disposable {
// Exclude right click
if (event.which < 3) {
windowOpenNoOpener((<HTMLAnchorElement>event.target).href);
this.telemetryService.publicLog2('issueReporterViewSimilarIssue');
}
}
......
......@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { assign } from 'vs/base/common/objects';
import { IssueType, ISettingSearchResult, IssueReporterExtensionData } from 'vs/platform/issue/common/issue';
import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
......@@ -49,7 +48,7 @@ export class IssueReporterModel {
allExtensions: []
};
this._data = initialData ? assign(defaultData, initialData) : defaultData;
this._data = initialData ? Object.assign(defaultData, initialData) : defaultData;
}
getData(): IssueReporterData {
......@@ -57,7 +56,7 @@ export class IssueReporterModel {
}
update(newData: Partial<IssueReporterData>): void {
assign(this._data, newData);
Object.assign(this._data, newData);
}
serialize(): string {
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel';
import { IssueReporterModel } from 'vs/code/electron-sandbox/issue/issueReporterModel';
import { normalizeGitHubUrl } from 'vs/platform/issue/common/issueReporterUtil';
import { IssueType } from 'vs/platform/issue/common/issue';
......
......@@ -4,6 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { localize } from 'vs/nls';
import * as os from 'os';
import product from 'vs/platform/product/common/product';
import * as objects from 'vs/base/common/objects';
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
import { ICommonIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/common/issue';
......@@ -196,12 +198,23 @@ export class IssueMainService implements ICommonIssueService {
backgroundColor: data.styles.backgroundColor || DEFAULT_BACKGROUND_COLOR,
webPreferences: {
preload: URI.parse(require.toUrl('vs/base/parts/sandbox/electron-browser/preload.js')).fsPath,
nodeIntegration: true,
enableWebSQL: false,
enableRemoteModule: false,
spellcheck: false,
nativeWindowOpen: true,
zoomFactor: zoomLevelToZoomFactor(data.zoomLevel)
zoomFactor: zoomLevelToZoomFactor(data.zoomLevel),
...this.environmentService.sandbox ?
// Sandbox
{
sandbox: true,
contextIsolation: true
} :
// No Sandbox
{
nodeIntegration: true
}
}
});
......@@ -408,10 +421,23 @@ export class IssueMainService implements ICommonIssueService {
machineId: this.machineId,
userEnv: this.userEnv,
data,
features
features,
disableExtensions: this.environmentService.disableExtensions,
os: {
type: os.type(),
arch: os.arch(),
release: os.release(),
},
product: {
nameShort: product.nameShort,
version: product.version,
commit: product.commit,
date: product.date,
reportIssueUrl: product.reportIssueUrl
}
};
return toLauchUrl('vs/code/electron-browser/issue/issueReporter.html', windowConfiguration);
return toLauchUrl('vs/code/electron-sandbox/issue/issueReporter.html', windowConfiguration);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册