Skip to content

Commit

Permalink
assign 'VSCode-SessionId' header in marketplace.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
prashantvc committed Jun 27, 2022
1 parent 68ec3ef commit d9ccb7e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,14 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi
const config = productService.extensionsGallery;
this.extensionsGalleryUrl = config && config.serviceUrl;
this.extensionsControlUrl = config && config.controlUrl;
this.commonHeadersPromise = resolveMarketplaceHeaders(productService.version, productService, this.environmentService, this.configurationService, this.fileService, storageService);
this.commonHeadersPromise = resolveMarketplaceHeaders(
productService.version,
productService,
this.environmentService,
this.configurationService,
this.fileService,
storageService,
this.telemetryService);
}

private api(path = ''): string {
Expand Down Expand Up @@ -923,14 +930,12 @@ abstract class AbstractExtensionGalleryService implements IExtensionGalleryServi

const commonHeaders = await this.commonHeadersPromise;
const data = JSON.stringify(query.raw);
const { sessionId } = await this.telemetryService.getTelemetryInfo();
const headers = {
...commonHeaders,
'Content-Type': 'application/json',
'Accept': 'application/json;api-version=3.0-preview.1',
'Accept-Encoding': 'gzip',
'Content-Length': String(data.length),
'VSCode-SessionId': sessionId
};

const startTime = new Date().getTime();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
import { resolveMarketplaceHeaders } from 'vs/platform/externalServices/common/marketplace';
import { InMemoryStorageService, IStorageService } from 'vs/platform/storage/common/storage';
import { TelemetryConfiguration, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry';
import { ITelemetryInfo, ITelemetryService, TelemetryConfiguration, TelemetryLevel, TELEMETRY_SETTING_ID } from 'vs/platform/telemetry/common/telemetry';
import { TargetPlatform } from 'vs/platform/extensions/common/extensions';
import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
import { staticObservableValue } from 'vs/base/common/observableValue';
import { Emitter, Event } from 'vs/base/common/event';

class EnvironmentServiceMock extends mock<IEnvironmentService>() {
override readonly serviceMachineIdResource: URI;
Expand All @@ -36,6 +39,7 @@ class EnvironmentServiceMock extends mock<IEnvironmentService>() {
suite('Extension Gallery Service', () => {
const disposables: DisposableStore = new DisposableStore();
let fileService: IFileService, environmentService: IEnvironmentService, storageService: IStorageService, productService: IProductService, configurationService: IConfigurationService;
let telemetryService: ITelemetryService;

setup(() => {
const serviceMachineIdResource = joinPath(URI.file('tests').with({ scheme: 'vscode-tests' }), 'machineid');
Expand All @@ -47,14 +51,15 @@ suite('Extension Gallery Service', () => {
configurationService = new TestConfigurationService({ [TELEMETRY_SETTING_ID]: TelemetryConfiguration.ON });
configurationService.updateValue(TELEMETRY_SETTING_ID, TelemetryConfiguration.ON);
productService = { _serviceBrand: undefined, ...product, enableTelemetry: true };
telemetryService = new MockTelemetryService();
});

teardown(() => disposables.clear());

test('marketplace machine id', async () => {
const headers = await resolveMarketplaceHeaders(product.version, productService, environmentService, configurationService, fileService, storageService);
const headers = await resolveMarketplaceHeaders(product.version, productService, environmentService, configurationService, fileService, storageService, telemetryService);
assert.ok(isUUID(headers['X-Market-User-Id']));
const headers2 = await resolveMarketplaceHeaders(product.version, productService, environmentService, configurationService, fileService, storageService);
const headers2 = await resolveMarketplaceHeaders(product.version, productService, environmentService, configurationService, fileService, storageService, telemetryService);
assert.strictEqual(headers['X-Market-User-Id'], headers2['X-Market-User-Id']);
});

Expand Down Expand Up @@ -153,3 +158,51 @@ suite('Extension Gallery Service', () => {
return { version, targetPlatform } as IRawGalleryExtensionVersion;
}
});

class MockTelemetryService implements ITelemetryService {
public _serviceBrand: undefined;
public telemetryLevel = staticObservableValue(TelemetryLevel.USAGE);
public sendErrorTelemetry = true;

public events: any[] = [];

private readonly emitter = new Emitter<any>();

public get eventLogged(): Event<any> {
return this.emitter.event;
}

public setEnabled(value: boolean): void {
}

public setExperimentProperty(name: string, value: string): void {
}

public publicLog(eventName: string, data?: any): Promise<void> {
const event = { name: eventName, data: data };
this.events.push(event);
this.emitter.fire(event);
return Promise.resolve();
}

public publicLog2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>) {
return this.publicLog(eventName, data as any);
}

public publicLogError(eventName: string, data?: any): Promise<void> {
return this.publicLog(eventName, data);
}

public publicLogError2<E extends ClassifiedEvent<T> = never, T extends GDPRClassification<T> = never>(eventName: string, data?: StrictPropertyCheck<T, E>) {
return this.publicLogError(eventName, data as any);
}

public getTelemetryInfo(): Promise<ITelemetryInfo> {
return Promise.resolve({
instanceId: 'someValue.instanceId',
sessionId: 'someValue.sessionId',
machineId: 'someValue.machineId',
firstSessionDate: 'someValue.firstSessionDate'
});
}
}
13 changes: 11 additions & 2 deletions src/vs/platform/externalServices/common/marketplace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,26 @@ import { getServiceMachineId } from 'vs/platform/externalServices/common/service
import { IFileService } from 'vs/platform/files/common/files';
import { IProductService } from 'vs/platform/product/common/productService';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';

export async function resolveMarketplaceHeaders(version: string, productService: IProductService, environmentService: IEnvironmentService, configurationService: IConfigurationService, fileService: IFileService, storageService: IStorageService | undefined): Promise<IHeaders> {
export async function resolveMarketplaceHeaders(version: string,
productService: IProductService,
environmentService: IEnvironmentService,
configurationService: IConfigurationService,
fileService: IFileService,
storageService: IStorageService | undefined,
telemetryService: ITelemetryService): Promise<IHeaders> {
const headers: IHeaders = {
'X-Market-Client-Id': `VSCode ${version}`,
'User-Agent': `VSCode ${version} (${productService.nameShort})`
};
const uuid = await getServiceMachineId(environmentService, fileService, storageService);
const { sessionId } = await telemetryService.getTelemetryInfo();

if (supportsTelemetry(productService, environmentService) && getTelemetryLevel(configurationService) === TelemetryLevel.USAGE) {
headers['X-Market-User-Id'] = uuid;
headers['VSCode-SessionId'] = sessionId;
}
return headers;
}
9 changes: 8 additions & 1 deletion src/vs/platform/windows/electron-main/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
private marketplaceHeadersPromise: Promise<object> | undefined;
private getMarketplaceHeaders(): Promise<object> {
if (!this.marketplaceHeadersPromise) {
this.marketplaceHeadersPromise = resolveMarketplaceHeaders(this.productService.version, this.productService, this.environmentMainService, this.configurationService, this.fileService, this.applicationStorageMainService);
this.marketplaceHeadersPromise = resolveMarketplaceHeaders(
this.productService.version,
this.productService,
this.environmentMainService,
this.configurationService,
this.fileService,
this.applicationStorageMainService,
this.telemetryService);
}

return this.marketplaceHeadersPromise;
Expand Down

0 comments on commit d9ccb7e

Please sign in to comment.