From 0299fd433f7f10a003ff3e1428b785c84958c86a Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Thu, 24 Sep 2020 08:43:37 +0200 Subject: [PATCH] sandbox - move keytar into native host service (#107292) --- .../sharedProcess/sharedProcessMain.ts | 3 -- .../credentials/common/credentials.ts | 20 ---------- .../credentials/node/credentialsService.ts | 40 ------------------- src/vs/platform/native/common/native.ts | 7 ++++ .../electron-main/nativeHostMainService.ts | 36 +++++++++++++++++ .../workbench/api/browser/mainThreadKeytar.ts | 2 +- .../credentials/browser/credentialsService.ts | 2 +- .../credentials/common/credentials.ts | 11 ++--- .../electron-sandbox/credentialsService.ts | 37 +++++++++++++++++ .../electron-browser/workbenchTestServices.ts | 5 +++ src/vs/workbench/workbench.desktop.main.ts | 3 -- src/vs/workbench/workbench.sandbox.main.ts | 1 + src/vs/workbench/workbench.web.api.ts | 2 +- 13 files changed, 95 insertions(+), 74 deletions(-) delete mode 100644 src/vs/platform/credentials/common/credentials.ts delete mode 100644 src/vs/platform/credentials/node/credentialsService.ts create mode 100644 src/vs/workbench/services/credentials/electron-sandbox/credentialsService.ts diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts index e71a0ace313..411b06ca70d 100644 --- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts @@ -55,8 +55,6 @@ import { UserDataSyncChannel, UserDataSyncUtilServiceClient, UserDataAutoSyncCha import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; import { LoggerService } from 'vs/platform/log/node/loggerService'; import { UserDataSyncLogService } from 'vs/platform/userDataSync/common/userDataSyncLog'; -import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; -import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; import { UserDataAutoSyncService } from 'vs/platform/userDataSync/electron-sandbox/userDataAutoSyncService'; import { NativeStorageService } from 'vs/platform/storage/node/storageService'; import { GlobalStorageDatabaseChannelClient } from 'vs/platform/storage/node/storageIpc'; @@ -198,7 +196,6 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService)); services.set(IExtensionTipsService, new SyncDescriptor(ExtensionTipsService)); - services.set(ICredentialsService, new SyncDescriptor(KeytarCredentialsService)); services.set(IUserDataSyncAccountService, new SyncDescriptor(UserDataSyncAccountService)); services.set(IUserDataSyncLogService, new SyncDescriptor(UserDataSyncLogService)); services.set(IUserDataSyncUtilService, new UserDataSyncUtilServiceClient(server.getChannel('userDataSyncUtil', client => client.ctx !== 'main'))); diff --git a/src/vs/platform/credentials/common/credentials.ts b/src/vs/platform/credentials/common/credentials.ts deleted file mode 100644 index 06af1a01af5..00000000000 --- a/src/vs/platform/credentials/common/credentials.ts +++ /dev/null @@ -1,20 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; - -export interface ICredentialsProvider { - getPassword(service: string, account: string): Promise; - setPassword(service: string, account: string, password: string): Promise; - deletePassword(service: string, account: string): Promise; - findPassword(service: string): Promise; - findCredentials(service: string): Promise>; -} - -export const ICredentialsService = createDecorator('ICredentialsService'); - -export interface ICredentialsService extends ICredentialsProvider { - readonly _serviceBrand: undefined; -} diff --git a/src/vs/platform/credentials/node/credentialsService.ts b/src/vs/platform/credentials/node/credentialsService.ts deleted file mode 100644 index 0960eb9a542..00000000000 --- a/src/vs/platform/credentials/node/credentialsService.ts +++ /dev/null @@ -1,40 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -import type * as keytar from 'keytar'; -import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; -import { IdleValue } from 'vs/base/common/async'; - -export class KeytarCredentialsService implements ICredentialsService { - - declare readonly _serviceBrand: undefined; - - private readonly _keytar = new IdleValue>(() => import('keytar')); - - async getPassword(service: string, account: string): Promise { - const keytar = await this._keytar.value; - return keytar.getPassword(service, account); - } - - async setPassword(service: string, account: string, password: string): Promise { - const keytar = await this._keytar.value; - return keytar.setPassword(service, account, password); - } - - async deletePassword(service: string, account: string): Promise { - const keytar = await this._keytar.value; - return keytar.deletePassword(service, account); - } - - async findPassword(service: string): Promise { - const keytar = await this._keytar.value; - return keytar.findPassword(service); - } - - async findCredentials(service: string): Promise> { - const keytar = await this._keytar.value; - return keytar.findCredentials(service); - } -} diff --git a/src/vs/platform/native/common/native.ts b/src/vs/platform/native/common/native.ts index 2bbd77ee057..df1f6ee5fd9 100644 --- a/src/vs/platform/native/common/native.ts +++ b/src/vs/platform/native/common/native.ts @@ -141,4 +141,11 @@ export interface ICommonNativeHostService { // Registry (windows only) windowsGetStringRegKey(hive: 'HKEY_CURRENT_USER' | 'HKEY_LOCAL_MACHINE' | 'HKEY_CLASSES_ROOT' | 'HKEY_USERS' | 'HKEY_CURRENT_CONFIG', path: string, name: string): Promise; + + // Credentials + getPassword(service: string, account: string): Promise; + setPassword(service: string, account: string, password: string): Promise; + deletePassword(service: string, account: string): Promise; + findPassword(service: string): Promise; + findCredentials(service: string): Promise> } diff --git a/src/vs/platform/native/electron-main/nativeHostMainService.ts b/src/vs/platform/native/electron-main/nativeHostMainService.ts index 2d154708f3a..7fa482c7e03 100644 --- a/src/vs/platform/native/electron-main/nativeHostMainService.ts +++ b/src/vs/platform/native/electron-main/nativeHostMainService.ts @@ -610,6 +610,42 @@ export class NativeHostMainService implements INativeHostMainService { } } + //#endregion + + //#region Credentials + + async getPassword(windowId: number | undefined, service: string, account: string): Promise { + const keytar = await import('keytar'); + + return keytar.getPassword(service, account); + } + + async setPassword(windowId: number | undefined, service: string, account: string, password: string): Promise { + const keytar = await import('keytar'); + + return keytar.setPassword(service, account, password); + } + + async deletePassword(windowId: number | undefined, service: string, account: string): Promise { + const keytar = await import('keytar'); + + return keytar.deletePassword(service, account); + } + + async findPassword(windowId: number | undefined, service: string): Promise { + const keytar = await import('keytar'); + + return keytar.findPassword(service); + } + + async findCredentials(windowId: number | undefined, service: string): Promise> { + const keytar = await import('keytar'); + + return keytar.findCredentials(service); + } + + //#endregion + private windowById(windowId: number | undefined): ICodeWindow | undefined { if (typeof windowId !== 'number') { return undefined; diff --git a/src/vs/workbench/api/browser/mainThreadKeytar.ts b/src/vs/workbench/api/browser/mainThreadKeytar.ts index 5312a9aad19..ddcf676a10c 100644 --- a/src/vs/workbench/api/browser/mainThreadKeytar.ts +++ b/src/vs/workbench/api/browser/mainThreadKeytar.ts @@ -5,7 +5,7 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { MainContext, MainThreadKeytarShape, IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; -import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; +import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials'; @extHostNamedCustomer(MainContext.MainThreadKeytar) export class MainThreadKeytar implements MainThreadKeytarShape { diff --git a/src/vs/workbench/services/credentials/browser/credentialsService.ts b/src/vs/workbench/services/credentials/browser/credentialsService.ts index 3d394b6f38d..aff3526121e 100644 --- a/src/vs/workbench/services/credentials/browser/credentialsService.ts +++ b/src/vs/workbench/services/credentials/browser/credentialsService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { ICredentialsProvider, ICredentialsService } from 'vs/platform/credentials/common/credentials'; +import { ICredentialsService, ICredentialsProvider } from 'vs/workbench/services/credentials/common/credentials'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; diff --git a/src/vs/workbench/services/credentials/common/credentials.ts b/src/vs/workbench/services/credentials/common/credentials.ts index 2799abeed19..b6dd9404b41 100644 --- a/src/vs/workbench/services/credentials/common/credentials.ts +++ b/src/vs/workbench/services/credentials/common/credentials.ts @@ -5,15 +5,16 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -export const ICredentialsService = createDecorator('ICredentialsService'); - -export interface ICredentialsService { - - readonly _serviceBrand: undefined; +export const ICredentialsService = createDecorator('credentialsService'); +export interface ICredentialsProvider { getPassword(service: string, account: string): Promise; setPassword(service: string, account: string, password: string): Promise; deletePassword(service: string, account: string): Promise; findPassword(service: string): Promise; findCredentials(service: string): Promise>; } + +export interface ICredentialsService extends ICredentialsProvider { + readonly _serviceBrand: undefined; +} diff --git a/src/vs/workbench/services/credentials/electron-sandbox/credentialsService.ts b/src/vs/workbench/services/credentials/electron-sandbox/credentialsService.ts new file mode 100644 index 00000000000..a6e9361b42d --- /dev/null +++ b/src/vs/workbench/services/credentials/electron-sandbox/credentialsService.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials'; +import { INativeHostService } from 'vs/platform/native/electron-sandbox/native'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; + +export class KeytarCredentialsService implements ICredentialsService { + + declare readonly _serviceBrand: undefined; + + constructor(@INativeHostService private readonly nativeHostService: INativeHostService) { } + + getPassword(service: string, account: string): Promise { + return this.nativeHostService.getPassword(service, account); + } + + setPassword(service: string, account: string, password: string): Promise { + return this.nativeHostService.setPassword(service, account, password); + } + + deletePassword(service: string, account: string): Promise { + return this.nativeHostService.deletePassword(service, account); + } + + findPassword(service: string): Promise { + return this.nativeHostService.findPassword(service); + } + + findCredentials(service: string): Promise> { + return this.nativeHostService.findCredentials(service); + } +} + +registerSingleton(ICredentialsService, KeytarCredentialsService, true); diff --git a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts index 0446d3c0cad..7989ce9a26d 100644 --- a/src/vs/workbench/test/electron-browser/workbenchTestServices.ts +++ b/src/vs/workbench/test/electron-browser/workbenchTestServices.ts @@ -232,6 +232,11 @@ export class TestNativeHostService implements INativeHostService { async hasClipboard(format: string, type?: 'selection' | 'clipboard' | undefined): Promise { return false; } async sendInputEvent(event: MouseInputEvent): Promise { } async windowsGetStringRegKey(hive: 'HKEY_CURRENT_USER' | 'HKEY_LOCAL_MACHINE' | 'HKEY_CLASSES_ROOT' | 'HKEY_USERS' | 'HKEY_CURRENT_CONFIG', path: string, name: string): Promise { return undefined; } + async getPassword(service: string, account: string): Promise { return null; } + async setPassword(service: string, account: string, password: string): Promise { } + async deletePassword(service: string, account: string): Promise { return false; } + async findPassword(service: string): Promise { return null; } + async findCredentials(service: string): Promise<{ account: string; password: string; }[]> { return []; } } export function workbenchInstantiationService(): ITestInstantiationService { diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index 856afbd2bf1..5f08dc5d96d 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -97,12 +97,9 @@ import 'vs/workbench/services/diagnostics/electron-browser/diagnosticsService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { ICredentialsService } from 'vs/platform/credentials/common/credentials'; -import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService'; import { ITunnelService } from 'vs/platform/remote/common/tunnel'; import { TunnelService } from 'vs/platform/remote/node/tunnelService'; -registerSingleton(ICredentialsService, KeytarCredentialsService, true); registerSingleton(ITunnelService, TunnelService); //#endregion diff --git a/src/vs/workbench/workbench.sandbox.main.ts b/src/vs/workbench/workbench.sandbox.main.ts index 70725dd5561..65090679243 100644 --- a/src/vs/workbench/workbench.sandbox.main.ts +++ b/src/vs/workbench/workbench.sandbox.main.ts @@ -41,6 +41,7 @@ import 'vs/workbench/services/accessibility/electron-sandbox/accessibilityServic import 'vs/workbench/services/path/electron-sandbox/pathService'; import 'vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService'; import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementService'; +import 'vs/workbench/services/credentials/electron-sandbox/credentialsService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { ITimerService } from 'vs/workbench/services/timer/browser/timerService'; diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts index 9776a5a1453..16b5f29dd36 100644 --- a/src/vs/workbench/workbench.web.api.ts +++ b/src/vs/workbench/workbench.web.api.ts @@ -18,7 +18,7 @@ import { IWorkspaceProvider, IWorkspace } from 'vs/workbench/services/host/brows import { CommandsRegistry } from 'vs/platform/commands/common/commands'; import { IProductConfiguration } from 'vs/platform/product/common/productService'; import { mark } from 'vs/base/common/performance'; -import { ICredentialsProvider } from 'vs/platform/credentials/common/credentials'; +import { ICredentialsProvider } from 'vs/workbench/services/credentials/common/credentials'; interface IResourceUriProvider { (uri: URI): URI;