diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 706ebf4325dc6..442e2651a96c3 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -35,7 +35,7 @@ declare module 'vscode' { readonly added: string[]; /** - * The ids of the [authenticationProvider](#AuthenticationProvider)s that have been removed.. + * The ids of the [authenticationProvider](#AuthenticationProvider)s that have been removed. */ readonly removed: string[]; } @@ -50,7 +50,7 @@ declare module 'vscode' { readonly displayName: string; /** - * A [enent](#Event) which fires when the array of sessions has changed, or data + * A [event](#Event) which fires when the array of sessions has changed, or data * within a session has changed. */ readonly onDidChangeSessions: Event; @@ -75,7 +75,31 @@ declare module 'vscode' { */ export const onDidChangeAuthenticationProviders: Event; - export const providers: ReadonlyArray; + /** + * Returns whether a provider with providerId is currently registered. + */ + export function hasProvider(providerId: string): boolean; + + /** + * Get existing authentication sessions. Rejects if a provider with providerId is not + * registered, or if the user does not consent to sharing authentication information with + * the extension. + */ + export function getSessions(providerId: string): Thenable; + + /** + * Prompt a user to login to create a new authenticaiton session. Rejects if a provider with + * providerId is not registered, or if the user does not consent to sharing authentication + * information with the extension. + */ + export function login(providerId: string, scopes: string[]): Thenable; + + /** + * A [event](#Event) which fires when the array of sessions has changed, or data + * within a session has changed for a provider. Fires with the ids of the providers + * that have had session data change. + */ + export const onDidChangeSessions: Event; } //#endregion diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index c57fae94bbd31..409da2f66d367 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -185,12 +185,21 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I registerAuthenticationProvider(provider: vscode.AuthenticationProvider): vscode.Disposable { return extHostAuthentication.registerAuthenticationProvider(provider); }, - get providers() { - return extHostAuthentication.providers(extension); - }, get onDidChangeAuthenticationProviders(): Event { return extHostAuthentication.onDidChangeAuthenticationProviders; - } + }, + hasProvider(providerId: string): boolean { + return extHostAuthentication.hasProvider(providerId); + }, + getSessions(providerId: string): Thenable { + return extHostAuthentication.getSessions(extension, providerId); + }, + login(providerId: string, scopes: string[]): Thenable { + return extHostAuthentication.login(extension, providerId, scopes); + }, + get onDidChangeSessions(): Event { + return extHostAuthentication.onDidChangeSessions; + }, }; // namespace: commands diff --git a/src/vs/workbench/api/common/extHostAuthentication.ts b/src/vs/workbench/api/common/extHostAuthentication.ts index b3b2d4d0f4a04..88ce55c51ea49 100644 --- a/src/vs/workbench/api/common/extHostAuthentication.ts +++ b/src/vs/workbench/api/common/extHostAuthentication.ts @@ -10,36 +10,41 @@ import { IMainContext, MainContext, MainThreadAuthenticationShape, ExtHostAuthen import { Disposable } from 'vs/workbench/api/common/extHostTypes'; import { IExtensionDescription, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; -export class AuthenticationProviderWrapper implements vscode.AuthenticationProvider { - readonly onDidChangeSessions: vscode.Event; +export class ExtHostAuthentication implements ExtHostAuthenticationShape { + private _proxy: MainThreadAuthenticationShape; + private _authenticationProviders: Map = new Map(); - constructor(private _requestingExtension: IExtensionDescription, - private _provider: vscode.AuthenticationProvider, - private _proxy: MainThreadAuthenticationShape) { + private _onDidChangeAuthenticationProviders = new Emitter(); + readonly onDidChangeAuthenticationProviders: Event = this._onDidChangeAuthenticationProviders.event; - this.onDidChangeSessions = this._provider.onDidChangeSessions; - } + private _onDidChangeSessions = new Emitter(); + readonly onDidChangeSessions: Event = this._onDidChangeSessions.event; - get id(): string { - return this._provider.id; + constructor(mainContext: IMainContext) { + this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication); } - get displayName(): string { - return this._provider.displayName; + hasProvider(providerId: string): boolean { + return !!this._authenticationProviders.get(providerId); } - async getSessions(): Promise> { - return (await this._provider.getSessions()).map(session => { + async getSessions(requestingExtension: IExtensionDescription, providerId: string): Promise { + const provider = this._authenticationProviders.get(providerId); + if (!provider) { + throw new Error(`No authentication provider with id '${providerId}' is currently registered.`); + } + + return (await provider.getSessions()).map(session => { return { id: session.id, accountName: session.accountName, scopes: session.scopes, getAccessToken: async () => { const isAllowed = await this._proxy.$getSessionsPrompt( - this._provider.id, - this.displayName, - ExtensionIdentifier.toKey(this._requestingExtension.identifier), - this._requestingExtension.displayName || this._requestingExtension.name); + provider.id, + provider.displayName, + ExtensionIdentifier.toKey(requestingExtension.identifier), + requestingExtension.displayName || requestingExtension.name); if (!isAllowed) { throw new Error('User did not consent to token access.'); @@ -51,35 +56,18 @@ export class AuthenticationProviderWrapper implements vscode.AuthenticationProvi }); } - async login(scopes: string[]): Promise { - const isAllowed = await this._proxy.$loginPrompt(this._provider.id, this.displayName, ExtensionIdentifier.toKey(this._requestingExtension.identifier), this._requestingExtension.displayName || this._requestingExtension.name); + async login(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise { + const provider = this._authenticationProviders.get(providerId); + if (!provider) { + throw new Error(`No authentication provider with id '${providerId}' is currently registered.`); + } + + const isAllowed = await this._proxy.$loginPrompt(provider.id, provider.displayName, ExtensionIdentifier.toKey(requestingExtension.identifier), requestingExtension.displayName || requestingExtension.name); if (!isAllowed) { throw new Error('User did not consent to login.'); } - return this._provider.login(scopes); - } - - logout(sessionId: string): Thenable { - return this._provider.logout(sessionId); - } -} - -export class ExtHostAuthentication implements ExtHostAuthenticationShape { - private _proxy: MainThreadAuthenticationShape; - private _authenticationProviders: Map = new Map(); - - private _onDidChangeAuthenticationProviders = new Emitter(); - readonly onDidChangeAuthenticationProviders: Event = this._onDidChangeAuthenticationProviders.event; - - constructor(mainContext: IMainContext) { - this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication); - } - - providers(requestingExtension: IExtensionDescription): vscode.AuthenticationProvider[] { - let providers: vscode.AuthenticationProvider[] = []; - this._authenticationProviders.forEach(provider => providers.push(new AuthenticationProviderWrapper(requestingExtension, provider, this._proxy))); - return providers; + return provider.login(scopes); } registerAuthenticationProvider(provider: vscode.AuthenticationProvider): vscode.Disposable { @@ -91,6 +79,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape { const listener = provider.onDidChangeSessions(_ => { this._proxy.$onDidChangeSessions(provider.id); + this._onDidChangeSessions.fire([provider.id]); }); this._proxy.$registerAuthenticationProvider(provider.id, provider.displayName);