refactor extensions report to extensions control manifest
This commit is contained in:
parent
10d3e93db5
commit
dd19b1d50b
|
@ -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: [] };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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'); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>>{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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', []);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue