From 25ed721e4895edd02d1671ba010f6fb106406026 Mon Sep 17 00:00:00 2001 From: Alex Dima Date: Wed, 3 Apr 2019 22:50:21 +0200 Subject: [PATCH] More support for keytar --- .../workbench/api/browser/mainThreadKeytar.ts | 61 +++++++++++++++++++ .../workbench/api/common/extHost.protocol.ts | 8 +++ .../extensionHost.contribution.ts | 1 + src/vs/workbench/api/node/extHost.api.impl.ts | 36 ++++++++++- .../api/node/extHostExtensionService.ts | 3 +- 5 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/vs/workbench/api/browser/mainThreadKeytar.ts diff --git a/src/vs/workbench/api/browser/mainThreadKeytar.ts b/src/vs/workbench/api/browser/mainThreadKeytar.ts new file mode 100644 index 00000000000..49551459664 --- /dev/null +++ b/src/vs/workbench/api/browser/mainThreadKeytar.ts @@ -0,0 +1,61 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; +import { MainContext, MainThreadKeytarShape, IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; + +interface IKeytarModule { + getPassword(service: string, account: string): Promise; + setPassword(service: string, account: string, password: string): Promise; + deletePassword(service: string, account: string): Promise; + findPassword(service: string): Promise; +} + +@extHostNamedCustomer(MainContext.MainThreadKeytar) +export class MainThreadKeytar implements MainThreadKeytarShape { + + private _keytar: IKeytarModule | null; + + constructor( + extHostContext: IExtHostContext + ) { + try { + this._keytar = require.__$__nodeRequire('keytar'); + } catch (e) { + this._keytar = null; + } + } + + dispose(): void { + // + } + + async $getPassword(service: string, account: string): Promise { + if (this._keytar) { + return this._keytar.getPassword(service, account); + } + return null; + } + + async $setPassword(service: string, account: string, password: string): Promise { + if (this._keytar) { + return this._keytar.setPassword(service, account, password); + } + } + + async $deletePassword(service: string, account: string): Promise { + if (this._keytar) { + return this._keytar.deletePassword(service, account); + } + return false; + } + + async $findPassword(service: string): Promise { + if (this._keytar) { + return this._keytar.findPassword(service); + } + return null; + } +} diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index c0a895e562e..56a5f3050bc 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -253,6 +253,13 @@ export interface MainThreadConsoleShape extends IDisposable { $logExtensionHostMessage(msg: IRemoteConsoleLog): void; } +export interface MainThreadKeytarShape extends IDisposable { + $getPassword(service: string, account: string): Promise; + $setPassword(service: string, account: string, password: string): Promise; + $deletePassword(service: string, account: string): Promise; + $findPassword(service: string): Promise; +} + export interface ISerializedRegExp { pattern: string; flags?: string; @@ -1197,6 +1204,7 @@ export const MainContext = { MainThreadTextEditors: createMainId('MainThreadTextEditors'), MainThreadErrors: createMainId('MainThreadErrors'), MainThreadTreeViews: createMainId('MainThreadTreeViews'), + MainThreadKeytar: createMainId('MainThreadKeytar'), MainThreadLanguageFeatures: createMainId('MainThreadLanguageFeatures'), MainThreadLanguages: createMainId('MainThreadLanguages'), MainThreadMessageService: createMainId('MainThreadMessageService'), diff --git a/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts b/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts index 8bf6243507c..b399416d0ab 100644 --- a/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts +++ b/src/vs/workbench/api/electron-browser/extensionHost.contribution.ts @@ -32,6 +32,7 @@ import '../browser/mainThreadExtensionService'; import '../browser/mainThreadFileSystem'; import '../browser/mainThreadFileSystemEventService'; import '../browser/mainThreadHeapService'; +import '../browser/mainThreadKeytar'; import '../browser/mainThreadLanguageFeatures'; import '../browser/mainThreadLanguages'; import '../browser/mainThreadLogService'; diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 07e96c7fd1d..b0ad096168b 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -19,7 +19,7 @@ import { score } from 'vs/editor/common/modes/languageSelector'; import * as files from 'vs/platform/files/common/files'; import pkg from 'vs/platform/product/node/package'; import product from 'vs/platform/product/node/product'; -import { ExtHostContext, IInitData, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; +import { ExtHostContext, IInitData, IMainContext, MainContext, MainThreadKeytarShape } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostApiCommands } from 'vs/workbench/api/node/extHostApiCommands'; import { ExtHostClipboard } from 'vs/workbench/api/node/extHostClipboard'; import { ExtHostCommands } from 'vs/workbench/api/node/extHostCommands'; @@ -945,3 +945,37 @@ export class VSCodeNodeModuleFactory implements INodeModuleFactory { return this._defaultApiImpl; } } + +interface IKeytarModule { + getPassword(service: string, account: string): Promise; + setPassword(service: string, account: string, password: string): Promise; + deletePassword(service: string, account: string): Promise; + findPassword(service: string): Promise; +} + +export class KeytarNodeModuleFactory implements INodeModuleFactory { + public readonly nodeModuleName = 'keytar'; + + private _impl: IKeytarModule; + + constructor(mainThreadKeytar: MainThreadKeytarShape) { + this._impl = { + getPassword: (service: string, account: string): Promise => { + return mainThreadKeytar.$getPassword(service, account); + }, + setPassword: (service: string, account: string, password: string): Promise => { + return mainThreadKeytar.$setPassword(service, account, password); + }, + deletePassword: (service: string, account: string): Promise => { + return mainThreadKeytar.$deletePassword(service, account); + }, + findPassword: (service: string): Promise => { + return mainThreadKeytar.$findPassword(service); + } + }; + } + + public load(request: string, parent: { filename: string; }): any { + return this._impl; + } +} diff --git a/src/vs/workbench/api/node/extHostExtensionService.ts b/src/vs/workbench/api/node/extHostExtensionService.ts index 9c5a7259524..2b95f1b96cb 100644 --- a/src/vs/workbench/api/node/extHostExtensionService.ts +++ b/src/vs/workbench/api/node/extHostExtensionService.ts @@ -12,7 +12,7 @@ import { TernarySearchTree } from 'vs/base/common/map'; import { URI } from 'vs/base/common/uri'; import * as pfs from 'vs/base/node/pfs'; import { ILogService } from 'vs/platform/log/common/log'; -import { createApiFactory, IExtensionApiFactory, NodeModuleRequireInterceptor, VSCodeNodeModuleFactory } from 'vs/workbench/api/node/extHost.api.impl'; +import { createApiFactory, IExtensionApiFactory, NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory } from 'vs/workbench/api/node/extHost.api.impl'; import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IStaticWorkspaceData } from 'vs/workbench/api/common/extHost.protocol'; import { ExtHostConfiguration } from 'vs/workbench/api/node/extHostConfiguration'; import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionMemento, IExtensionModule, HostExtension } from 'vs/workbench/api/node/extHostExtensionActivator'; @@ -244,6 +244,7 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape { const configProvider = await this._extHostConfiguration.getConfigProvider(); const extensionPaths = await this.getExtensionPathIndex(); NodeModuleRequireInterceptor.INSTANCE.register(new VSCodeNodeModuleFactory(this._extensionApiFactory, extensionPaths, this._registry, configProvider)); + NodeModuleRequireInterceptor.INSTANCE.register(new KeytarNodeModuleFactory(this._extHostContext.getProxy(MainContext.MainThreadKeytar))); // Do this when extension service exists, but extensions are not being activated yet. await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._extHostLogService, this._mainThreadTelemetryProxy); -- GitLab