workspace trust telem

This commit is contained in:
SteVen Batten 2021-03-04 17:49:31 -08:00
parent 0f97504942
commit aca4cb1298
3 changed files with 117 additions and 12 deletions

View file

@ -36,7 +36,7 @@ export interface IWorkspaceTrustModel {
readonly onDidChangeTrustState: Event<void>;
setFolderTrustState(folder: URI, trustState: WorkspaceTrustState): void;
getFolderTrustState(folder: URI): WorkspaceTrustState;
getFolderTrustStateInfo(folder: URI): IWorkspaceTrustFolderInfo;
setTrustedFolders(folders: URI[]): void;
setUntrustedFolders(folders: URI[]): void;
@ -78,8 +78,13 @@ export interface IWorkspaceTrustService {
requireWorkspaceTrust(request?: WorkspaceTrustRequest): Promise<WorkspaceTrustState>;
}
export interface IWorkspaceTrustFolderInfo {
uri: string,
trustState: WorkspaceTrustState
}
export interface IWorkspaceTrustStateInfo {
localFolders: { uri: string, trustState: WorkspaceTrustState }[]
localFolders: IWorkspaceTrustFolderInfo[]
// Removing complexity of remote items
//trustedRemoteItems: { uri: string }[]

View file

@ -30,6 +30,9 @@ import { WorkspaceTrustEditor } from 'vs/workbench/contrib/workspace/browser/wor
import { WorkspaceTrustEditorInput } from 'vs/workbench/services/workspaces/browser/workspaceTrustEditorInput';
import { WorkspaceTrustContext, WORKSPACE_TRUST_ENABLED } from 'vs/workbench/services/workspaces/common/workspaceTrust';
import { EditorInput, Extensions as EditorInputExtensions, IEditorInputFactory, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
const workspaceTrustIcon = registerIcon('workspace-trust-icon', Codicon.shield, localize('workspaceTrustIcon', "Icon for workspace trust badge."));
@ -46,7 +49,10 @@ export class WorkspaceTrustRequestHandler extends Disposable implements IWorkben
@IActivityService private readonly activityService: IActivityService,
@ICommandService private readonly commandService: ICommandService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IWorkspaceTrustService private readonly workspaceTrustService: IWorkspaceTrustService
@ITelemetryService private readonly telemetryService: ITelemetryService,
@IExtensionService private readonly extensionService: IExtensionService,
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
@IWorkspaceTrustService private readonly workspaceTrustService: IWorkspaceTrustService,
) {
super();
@ -69,6 +75,24 @@ export class WorkspaceTrustRequestHandler extends Disposable implements IWorkben
if (this.requestModel.trustRequest) {
this.toggleRequestBadge(true);
type WorkspaceTrustRequestedEventClassification = {
modal: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
workspaceId: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
extensions: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
type WorkspaceTrustRequestedEvent = {
modal: boolean,
workspaceId: string,
extensions: string[]
};
this.telemetryService.publicLog2<WorkspaceTrustRequestedEvent, WorkspaceTrustRequestedEventClassification>('workspaceTrustRequested', {
modal: this.requestModel.trustRequest.modal,
workspaceId: this.workspaceContextService.getWorkspace().id,
extensions: (await this.extensionService.getExtensions()).filter(ext => !!ext.requiresWorkspaceTrust).map(ext => ext.identifier.value)
});
if (this.requestModel.trustRequest.modal) {
const result = await this.dialogService.show(
Severity.Warning,
@ -114,6 +138,24 @@ export class WorkspaceTrustRequestHandler extends Disposable implements IWorkben
if (trustState.currentTrustState !== undefined && trustState.currentTrustState !== WorkspaceTrustState.Unknown) {
this.toggleRequestBadge(false);
}
type WorkspaceTrustStateChangedEventClassification = {
workspaceId: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
previousState: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
newState: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type WorkspaceTrustStateChangedEvent = {
workspaceId: string,
previousState: WorkspaceTrustState,
newState: WorkspaceTrustState
};
this.telemetryService.publicLog2<WorkspaceTrustStateChangedEvent, WorkspaceTrustStateChangedEventClassification>('workspaceTrustStateChanged', {
workspaceId: this.workspaceContextService.getWorkspace().id,
previousState: trustState.previousTrustState,
newState: trustState.currentTrustState
});
}));
this._register(this.configurationService.onDidChangeConfiguration(e => {

View file

@ -11,9 +11,11 @@ import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/cont
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { IWorkspace, IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceTrustModel, WorkspaceTrustRequest, IWorkspaceTrustRequestModel, IWorkspaceTrustService, IWorkspaceTrustStateInfo, WorkspaceTrustState, WorkspaceTrustStateChangeEvent } from 'vs/platform/workspace/common/workspaceTrust';
import { IWorkspaceTrustModel, WorkspaceTrustRequest, IWorkspaceTrustRequestModel, IWorkspaceTrustService, IWorkspaceTrustStateInfo, WorkspaceTrustState, WorkspaceTrustStateChangeEvent, IWorkspaceTrustFolderInfo } from 'vs/platform/workspace/common/workspaceTrust';
import { isEqual, isEqualOrParent } from 'vs/base/common/extpath';
import { EditorModel } from 'vs/workbench/common/editor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { dirname, resolve } from 'vs/base/common/path';
export const WORKSPACE_TRUST_ENABLED = 'workspace.trustEnabled';
export const WORKSPACE_TRUST_STORAGE_KEY = 'content.trust.model.key';
@ -153,23 +155,26 @@ export class WorkspaceTrustModel extends Disposable implements IWorkspaceTrustMo
}
}
getFolderTrustState(folder: URI): WorkspaceTrustState {
let result = WorkspaceTrustState.Unknown;
getFolderTrustStateInfo(folder: URI): IWorkspaceTrustFolderInfo {
let resultState = WorkspaceTrustState.Unknown;
let maxLength = -1;
const folderPath = folder.fsPath;
let resultFolder = folderPath;
for (const trustInfo of this.trustStateInfo.localFolders) {
const trustInfoPath = URI.file(trustInfo.uri).fsPath;
if (isEqualOrParent(folderPath, trustInfoPath)) {
if (trustInfoPath.length > maxLength) {
maxLength = trustInfoPath.length;
result = trustInfo.trustState;
resultState = trustInfo.trustState;
resultFolder = trustInfoPath;
}
}
}
return result;
return { trustState: resultState, uri: resultFolder };
}
getTrustStateInfo(): IWorkspaceTrustStateInfo {
@ -224,6 +229,7 @@ export class WorkspaceTrustService extends Disposable implements IWorkspaceTrust
@IContextKeyService readonly contextKeyService: IContextKeyService,
@IStorageService private readonly storageService: IStorageService,
@IWorkspaceContextService private readonly workspaceService: IWorkspaceContextService,
@ITelemetryService private readonly telemetryService: ITelemetryService,
) {
super();
@ -233,6 +239,8 @@ export class WorkspaceTrustService extends Disposable implements IWorkspaceTrust
this._workspace = this.workspaceService.getWorkspace();
this._currentTrustState = this.calculateWorkspaceTrustState();
this.logInitialWorkspaceTrustInfo();
this._register(this.dataModel.onDidChangeTrustState(() => this.currentTrustState = this.calculateWorkspaceTrustState()));
this._register(this.requestModel.onDidCompleteRequest((trustState) => this.onTrustRequestCompleted(trustState)));
@ -261,6 +269,55 @@ export class WorkspaceTrustService extends Disposable implements IWorkspaceTrust
return this.editorModel;
}
private logInitialWorkspaceTrustInfo(): void {
type WorkspaceTrustInfoEventClassification = {
trustedFoldersCount: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
untrustedFoldersCount: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type WorkspaceTrustInfoEvent = {
trustedFoldersCount: number,
untrustedFoldersCount: number
};
this.telemetryService.publicLog2<WorkspaceTrustInfoEvent, WorkspaceTrustInfoEventClassification>('workspaceTrustFolderCounts', {
trustedFoldersCount: this.dataModel.getTrustStateInfo().localFolders.filter(item => item.trustState === WorkspaceTrustState.Trusted).length,
untrustedFoldersCount: this.dataModel.getTrustStateInfo().localFolders.filter(item => item.trustState === WorkspaceTrustState.Untrusted).length
});
}
private logWorkspaceTrustFolderInfo(workspaceFolder: string, trustedFolder: string): void {
type WorkspaceTrustFolderInfoEventClassification = {
trustedFolderDepth: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
workspaceFolderDepth: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
delta: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type WorkspaceTrustFolderInfoEvent = {
trustedFolderDepth: number,
workspaceFolderDepth: number,
delta: number
};
const getDepth = (folder: string): number => {
let resolvedPath = resolve(folder);
let depth = 0;
while (dirname(resolvedPath) !== resolvedPath && depth < 100) {
resolvedPath = dirname(resolvedPath);
depth++;
}
return depth;
};
const workspaceFolderDepth = getDepth(workspaceFolder);
const trustedFolderDepth = getDepth(trustedFolder);
const delta = workspaceFolderDepth - trustedFolderDepth;
this.telemetryService.publicLog2<WorkspaceTrustFolderInfoEvent, WorkspaceTrustFolderInfoEventClassification>('workspaceFolderDepthBelowTrustedFolder', { workspaceFolderDepth, trustedFolderDepth, delta });
}
private calculateWorkspaceTrustState(): WorkspaceTrustState {
if (!this.isWorkspaceTrustEnabled()) {
return WorkspaceTrustState.Trusted;
@ -272,17 +329,18 @@ export class WorkspaceTrustService extends Disposable implements IWorkspaceTrust
let state = undefined;
for (const folder of this._workspace.folders) {
const folderTrust = this.dataModel.getFolderTrustState(folder.uri);
const { trustState, uri } = this.dataModel.getFolderTrustStateInfo(folder.uri);
switch (folderTrust) {
switch (trustState) {
case WorkspaceTrustState.Untrusted:
return WorkspaceTrustState.Untrusted;
case WorkspaceTrustState.Unknown:
state = folderTrust;
state = trustState;
break;
case WorkspaceTrustState.Trusted:
this.logWorkspaceTrustFolderInfo(folder.uri.fsPath, uri);
if (state === undefined) {
state = folderTrust;
state = trustState;
}
break;
}