refactor extensions report to extensions control manifest

This commit is contained in:
Sandeep Somavarapu 2021-11-25 15:31:48 +01:00
parent 10d3e93db5
commit dd19b1d50b
No known key found for this signature in database
GPG key ID: 1FED25EC4646638B
12 changed files with 49 additions and 49 deletions

View file

@ -14,7 +14,7 @@ import { URI } from 'vs/base/common/uri';
import * as nls from 'vs/nls';
import {
DidUninstallExtensionEvent, ExtensionManagementError, IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementParticipant, IExtensionManagementService, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallExtensionEvent, InstallExtensionResult, InstallOperation, InstallOptions,
InstallVSIXOptions, IReportedExtension, StatisticType, UninstallOptions, TargetPlatform, isTargetPlatformCompatible, TargetPlatformToString, ExtensionManagementErrorCode
InstallVSIXOptions, IExtensionsControlManifest, StatisticType, UninstallOptions, TargetPlatform, isTargetPlatformCompatible, TargetPlatformToString, ExtensionManagementErrorCode
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { areSameExtensions, ExtensionIdentifierWithVersion, getGalleryExtensionTelemetryData, getLocalExtensionTelemetryData, getMaliciousExtensionsSet } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
@ -46,7 +46,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl
declare readonly _serviceBrand: undefined;
private reportedExtensions: Promise<IReportedExtension[]> | undefined;
private extensionsControlManifest: Promise<IExtensionsControlManifest> | undefined;
private lastReportTimestamp = 0;
private readonly installingExtensions = new Map<string, IInstallExtensionTask>();
private readonly uninstallingExtensions = new Map<string, IUninstallExtensionTask>();
@ -120,15 +120,15 @@ export abstract class AbstractExtensionManagementService extends Disposable impl
await this.installFromGallery(galleryExtension);
}
getExtensionsReport(): Promise<IReportedExtension[]> {
getExtensionsControlManifest(): Promise<IExtensionsControlManifest> {
const now = new Date().getTime();
if (!this.reportedExtensions || now - this.lastReportTimestamp > 1000 * 60 * 5) { // 5 minute cache freshness
this.reportedExtensions = this.updateReportCache();
if (!this.extensionsControlManifest || now - this.lastReportTimestamp > 1000 * 60 * 5) { // 5 minute cache freshness
this.extensionsControlManifest = this.updateControlCache();
this.lastReportTimestamp = now;
}
return this.reportedExtensions;
return this.extensionsControlManifest;
}
registerParticipant(participant: IExtensionManagementParticipant): void {
@ -403,7 +403,7 @@ export abstract class AbstractExtensionManagementService extends Disposable impl
}
private async isMalicious(extension: IGalleryExtension): Promise<boolean> {
const report = await this.getExtensionsReport();
const report = await this.getExtensionsControlManifest();
return getMaliciousExtensionsSet(report).has(extension.identifier.id);
}
@ -579,15 +579,15 @@ export abstract class AbstractExtensionManagementService extends Disposable impl
return galleryResult.firstPage[0];
}
private async updateReportCache(): Promise<IReportedExtension[]> {
private async updateControlCache(): Promise<IExtensionsControlManifest> {
try {
this.logService.trace('ExtensionManagementService.refreshReportedCache');
const result = await this.galleryService.getExtensionsReport();
this.logService.trace(`ExtensionManagementService.refreshReportedCache - got ${result.length} reported extensions from service`);
return result;
const manifest = await this.galleryService.getExtensionsControlManifest();
this.logService.trace(`ExtensionManagementService.refreshControlCache`, manifest);
return manifest;
} catch (err) {
this.logService.trace('ExtensionManagementService.refreshReportedCache - failed to get extension report');
return [];
this.logService.trace('ExtensionManagementService.refreshControlCache - failed to get extension control manifest');
return { malicious: [] };
}
}

View file

@ -15,7 +15,7 @@ import { URI } from 'vs/base/common/uri';
import { IHeaders, IRequestContext, IRequestOptions } from 'vs/base/parts/request/common/request';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { DefaultIconPath, getFallbackTargetPlarforms, getTargetPlatform, IExtensionGalleryService, IExtensionIdentifier, IExtensionIdentifierWithVersion, IGalleryExtension, IGalleryExtensionAsset, IGalleryExtensionAssets, IGalleryExtensionVersion, InstallOperation, IQueryOptions, IReportedExtension, isIExtensionIdentifier, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, ITranslation, SortBy, SortOrder, StatisticType, TargetPlatform, toTargetPlatform, WEB_EXTENSION_TAG } from 'vs/platform/extensionManagement/common/extensionManagement';
import { DefaultIconPath, getFallbackTargetPlarforms, getTargetPlatform, IExtensionGalleryService, IExtensionIdentifier, IExtensionIdentifierWithVersion, IGalleryExtension, IGalleryExtensionAsset, IGalleryExtensionAssets, IGalleryExtensionVersion, InstallOperation, IQueryOptions, IExtensionsControlManifest, isIExtensionIdentifier, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, ITranslation, SortBy, SortOrder, StatisticType, TargetPlatform, toTargetPlatform, WEB_EXTENSION_TAG } from 'vs/platform/extensionManagement/common/extensionManagement';
import { adoptToGalleryExtensionId, areSameExtensions, getGalleryExtensionId, getGalleryExtensionTelemetryData } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator';
@ -438,7 +438,7 @@ function toExtension(galleryExtension: IRawGalleryExtension, version: IRawGaller
};
}
interface IRawExtensionsReport {
interface IRawExtensionsControlManifest {
malicious: string[];
slow: string[];
}
@ -942,13 +942,13 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
return engine;
}
async getExtensionsReport(): Promise<IReportedExtension[]> {
async getExtensionsControlManifest(): Promise<IExtensionsControlManifest> {
if (!this.isEnabled()) {
throw new Error('No extension gallery service configured.');
}
if (!this.extensionsControlUrl) {
return [];
return { malicious: [] };
}
const context = await this.requestService.request({ type: 'GET', url: this.extensionsControlUrl }, CancellationToken.None);
@ -956,18 +956,16 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
throw new Error('Could not get extensions report.');
}
const result = await asJson<IRawExtensionsReport>(context);
const map = new Map<string, IReportedExtension>();
const result = await asJson<IRawExtensionsControlManifest>(context);
const malicious: IExtensionIdentifier[] = [];
if (result) {
for (const id of result.malicious) {
const ext = map.get(id) || { id: { id }, malicious: true, slow: false };
ext.malicious = true;
map.set(id, ext);
malicious.push({ id });
}
}
return [...map.values()];
return { malicious };
}
}

View file

@ -310,9 +310,8 @@ export const enum StatisticType {
Uninstall = 'uninstall'
}
export interface IReportedExtension {
id: IExtensionIdentifier;
malicious: boolean;
export interface IExtensionsControlManifest {
malicious: IExtensionIdentifier[];
}
export const enum InstallOperation {
@ -338,7 +337,7 @@ export interface IExtensionGalleryService {
getManifest(extension: IGalleryExtension, token: CancellationToken): Promise<IExtensionManifest | null>;
getChangelog(extension: IGalleryExtension, token: CancellationToken): Promise<string>;
getCoreTranslation(extension: IGalleryExtension, languageId: string): Promise<ITranslation | null>;
getExtensionsReport(): Promise<IReportedExtension[]>;
getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;
isExtensionCompatible(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<boolean>;
getCompatibleExtension(extension: IGalleryExtension, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtension | null>;
getCompatibleExtension(id: IExtensionIdentifier, includePreRelease: boolean, targetPlatform: TargetPlatform): Promise<IGalleryExtension | null>;
@ -412,7 +411,7 @@ export interface IExtensionManagementService {
uninstall(extension: ILocalExtension, options?: UninstallOptions): Promise<void>;
reinstallFromGallery(extension: ILocalExtension): Promise<void>;
getInstalled(type?: ExtensionType, donotIgnoreInvalidExtensions?: boolean): Promise<ILocalExtension[]>;
getExtensionsReport(): Promise<IReportedExtension[]>;
getExtensionsControlManifest(): Promise<IExtensionsControlManifest>;
updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata): Promise<ILocalExtension>;
updateExtensionScope(local: ILocalExtension, isMachineScoped: boolean): Promise<ILocalExtension>;

View file

@ -9,7 +9,7 @@ import { cloneAndChange } from 'vs/base/common/objects';
import { URI, UriComponents } from 'vs/base/common/uri';
import { DefaultURITransformer, IURITransformer, transformAndReviveIncomingURIs } from 'vs/base/common/uriIpc';
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
import { DidUninstallExtensionEvent, IExtensionIdentifier, IExtensionManagementService, IExtensionTipsService, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallExtensionEvent, InstallExtensionResult, InstallOptions, InstallVSIXOptions, IReportedExtension, isTargetPlatformCompatible, TargetPlatform, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
import { DidUninstallExtensionEvent, IExtensionIdentifier, IExtensionManagementService, IExtensionTipsService, IGalleryExtension, IGalleryMetadata, ILocalExtension, InstallExtensionEvent, InstallExtensionResult, InstallOptions, InstallVSIXOptions, IExtensionsControlManifest, isTargetPlatformCompatible, TargetPlatform, UninstallOptions } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionType, IExtensionManifest } from 'vs/platform/extensions/common/extensions';
function transformIncomingURI(uri: UriComponents, transformer: IURITransformer | null): URI {
@ -72,7 +72,7 @@ export class ExtensionManagementChannel implements IServerChannel {
case 'getInstalled': return this.service.getInstalled(args[0]).then(extensions => extensions.map(e => transformOutgoingExtension(e, uriTransformer)));
case 'updateMetadata': return this.service.updateMetadata(transformIncomingExtension(args[0], uriTransformer), args[1]).then(e => transformOutgoingExtension(e, uriTransformer));
case 'updateExtensionScope': return this.service.updateExtensionScope(transformIncomingExtension(args[0], uriTransformer), args[1]).then(e => transformOutgoingExtension(e, uriTransformer));
case 'getExtensionsReport': return this.service.getExtensionsReport();
case 'getExtensionsControlManifest': return this.service.getExtensionsControlManifest();
}
throw new Error('Invalid call');
@ -169,8 +169,8 @@ export class ExtensionManagementChannelClient extends Disposable implements IExt
.then(extension => transformIncomingExtension(extension, null));
}
getExtensionsReport(): Promise<IReportedExtension[]> {
return Promise.resolve(this.channel.call('getExtensionsReport'));
getExtensionsControlManifest(): Promise<IExtensionsControlManifest> {
return Promise.resolve(this.channel.call('getExtensionsControlManifest'));
}
registerParticipant() { throw new Error('Not Supported'); }

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { compareIgnoreCase } from 'vs/base/common/strings';
import { IExtensionIdentifier, IExtensionIdentifierWithVersion, IGalleryExtension, ILocalExtension, IReportedExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionIdentifier, IExtensionIdentifierWithVersion, IGalleryExtension, ILocalExtension, IExtensionsControlManifest } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionIdentifier, IExtension } from 'vs/platform/extensions/common/extensions';
export function areSameExtensions(a: IExtensionIdentifier, b: IExtensionIdentifier): boolean {
@ -117,12 +117,12 @@ export function getGalleryExtensionTelemetryData(extension: IGalleryExtension):
export const BetterMergeId = new ExtensionIdentifier('pprice.better-merge');
export function getMaliciousExtensionsSet(report: IReportedExtension[]): Set<string> {
export function getMaliciousExtensionsSet(manifest: IExtensionsControlManifest): Set<string> {
const result = new Set<string>();
for (const extension of report) {
if (extension.malicious) {
result.add(extension.id.id);
if (manifest.malicious) {
for (const extension of manifest.malicious) {
result.add(extension.id);
}
}

View file

@ -825,7 +825,7 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution {
}
private checkForMaliciousExtensions(): Promise<void> {
return this.extensionsManagementService.getExtensionsReport().then(report => {
return this.extensionsManagementService.getExtensionsControlManifest().then(report => {
const maliciousSet = getMaliciousExtensionsSet(report);
return this.extensionsManagementService.getInstalled(ExtensionType.User).then(installed => {

View file

@ -749,7 +749,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
options.text = options.text ? this.resolveQueryText(options.text) : options.text;
options.includePreRelease = isUndefined(options.includePreRelease) ? this.preferPreReleases : options.includePreRelease;
const report = await this.extensionManagementService.getExtensionsReport();
const report = await this.extensionManagementService.getExtensionsControlManifest();
const maliciousSet = getMaliciousExtensionsSet(report);
try {
const result = await this.galleryService.query(options, token);

View file

@ -218,7 +218,7 @@ suite('ExtensionRecommendationsService Test', () => {
onDidUninstallExtension: didUninstallEvent.event,
async getInstalled() { return []; },
async canInstall() { return true; },
async getExtensionsReport() { return []; },
async getExtensionsControlManifest() { return { malicious: [] }; },
async getTargetPlatform() { return getTargetPlatform(platform, arch); }
});
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{

View file

@ -101,7 +101,7 @@ async function setupTest() {
onUninstallExtension: uninstallEvent.event,
onDidUninstallExtension: didUninstallEvent.event,
async getInstalled() { return []; },
async getExtensionsReport() { return []; },
async getExtensionsControlManifest() { return { malicious: [] }; },
async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata) {
local.identifier.uuid = metadata.id;
local.publisherDisplayName = metadata.publisherDisplayName;

View file

@ -98,7 +98,7 @@ suite('ExtensionsListView Tests', () => {
onDidUninstallExtension: didUninstallEvent.event,
async getInstalled() { return []; },
async canInstall() { return true; },
async getExtensionsReport() { return []; },
async getExtensionsControlManifest() { return { malicious: [] }; },
async getTargetPlatform() { return getTargetPlatform(platform, arch); }
});
instantiationService.stub(IRemoteAgentService, RemoteAgentService);
@ -163,7 +163,7 @@ suite('ExtensionsListView Tests', () => {
setup(async () => {
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [localEnabledTheme, localEnabledLanguage, localRandom, localDisabledTheme, localDisabledLanguage, builtInTheme, builtInBasic]);
instantiationService.stubPromise(IExtensionManagementService, 'getExtensionsReport', []);
instantiationService.stubPromise(IExtensionManagementService, 'getExtensgetExtensionsControlManifestionsReport', {});
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage());
instantiationService.stubPromise(IExperimentService, 'getExperimentsByType', []);

View file

@ -94,7 +94,7 @@ suite('ExtensionsWorkbenchServiceTest', () => {
onUninstallExtension: uninstallEvent.event,
onDidUninstallExtension: didUninstallEvent.event,
async getInstalled() { return []; },
async getExtensionsReport() { return []; },
async getExtensionsControlManifest() { return { malicious: [] }; },
async updateMetadata(local: ILocalExtension, metadata: IGalleryMetadata) {
local.identifier.uuid = metadata.id;
local.publisherDisplayName = metadata.publisherDisplayName;

View file

@ -5,7 +5,7 @@
import { Event, EventMultiplexer } from 'vs/base/common/event';
import {
ILocalExtension, IGalleryExtension, IExtensionIdentifier, IReportedExtension, IGalleryMetadata, IExtensionGalleryService, InstallOptions, UninstallOptions, InstallVSIXOptions, InstallExtensionResult, TargetPlatform, ExtensionManagementError, ExtensionManagementErrorCode
ILocalExtension, IGalleryExtension, IExtensionIdentifier, IExtensionsControlManifest, IGalleryMetadata, IExtensionGalleryService, InstallOptions, UninstallOptions, InstallVSIXOptions, InstallExtensionResult, TargetPlatform, ExtensionManagementError, ExtensionManagementErrorCode
} from 'vs/platform/extensionManagement/common/extensionManagement';
import { DidUninstallExtensionOnServerEvent, IExtensionManagementServer, IExtensionManagementServerService, InstallExtensionOnServerEvent, IWorkbenchExtensionManagementService, UninstallExtensionOnServerEvent } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { ExtensionType, isLanguagePackExtension, IExtensionManifest, getWorkspaceSupportTypeMessage } from 'vs/platform/extensions/common/extensions';
@ -369,14 +369,17 @@ export class ExtensionManagementService extends Disposable implements IWorkbench
return false;
}
getExtensionsReport(): Promise<IReportedExtension[]> {
getExtensionsControlManifest(): Promise<IExtensionsControlManifest> {
if (this.extensionManagementServerService.localExtensionManagementServer) {
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getExtensionsReport();
return this.extensionManagementServerService.localExtensionManagementServer.extensionManagementService.getExtensionsControlManifest();
}
if (this.extensionManagementServerService.remoteExtensionManagementServer) {
return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.getExtensionsReport();
return this.extensionManagementServerService.remoteExtensionManagementServer.extensionManagementService.getExtensionsControlManifest();
}
return Promise.resolve([]);
if (this.extensionManagementServerService.webExtensionManagementServer) {
return this.extensionManagementServerService.webExtensionManagementServer.extensionManagementService.getExtensionsControlManifest();
}
return Promise.resolve({ malicious: [] });
}
private getServer(extension: ILocalExtension): IExtensionManagementServer | null {