Path: blob/main/extensions/microsoft-authentication/src/extensionV1.ts
3314 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as vscode from 'vscode';6import { Environment, EnvironmentParameters } from '@azure/ms-rest-azure-env';7import { AzureActiveDirectoryService, IStoredSession } from './AADHelper';8import { BetterTokenStorage } from './betterSecretStorage';9import { UriEventHandler } from './UriEventHandler';10import TelemetryReporter from '@vscode/extension-telemetry';11import Logger from './logger';1213async function initMicrosoftSovereignCloudAuthProvider(context: vscode.ExtensionContext, telemetryReporter: TelemetryReporter, uriHandler: UriEventHandler, tokenStorage: BetterTokenStorage<IStoredSession>): Promise<vscode.Disposable | undefined> {14const environment = vscode.workspace.getConfiguration('microsoft-sovereign-cloud').get<string | undefined>('environment');15let authProviderName: string | undefined;16if (!environment) {17return undefined;18}1920if (environment === 'custom') {21const customEnv = vscode.workspace.getConfiguration('microsoft-sovereign-cloud').get<EnvironmentParameters>('customEnvironment');22if (!customEnv) {23const res = await vscode.window.showErrorMessage(vscode.l10n.t('You must also specify a custom environment in order to use the custom environment auth provider.'), vscode.l10n.t('Open settings'));24if (res) {25await vscode.commands.executeCommand('workbench.action.openSettingsJson', 'microsoft-sovereign-cloud.customEnvironment');26}27return undefined;28}29try {30Environment.add(customEnv);31} catch (e) {32const res = await vscode.window.showErrorMessage(vscode.l10n.t('Error validating custom environment setting: {0}', e.message), vscode.l10n.t('Open settings'));33if (res) {34await vscode.commands.executeCommand('workbench.action.openSettings', 'microsoft-sovereign-cloud.customEnvironment');35}36return undefined;37}38authProviderName = customEnv.name;39} else {40authProviderName = environment;41}4243const env = Environment.get(authProviderName);44if (!env) {45const res = await vscode.window.showErrorMessage(vscode.l10n.t('The environment `{0}` is not a valid environment.', authProviderName), vscode.l10n.t('Open settings'));46return undefined;47}4849const aadService = new AzureActiveDirectoryService(50vscode.window.createOutputChannel(vscode.l10n.t('Microsoft Sovereign Cloud Authentication'), { log: true }),51context,52uriHandler,53tokenStorage,54telemetryReporter,55env);56await aadService.initialize();5758const disposable = vscode.authentication.registerAuthenticationProvider('microsoft-sovereign-cloud', authProviderName, {59onDidChangeSessions: aadService.onDidChangeSessions,60getSessions: (scopes: string[]) => aadService.getSessions(scopes),61createSession: async (scopes: string[]) => {62try {63/* __GDPR__64"loginMicrosoftSovereignCloud" : {65"owner": "TylerLeonhardt",66"comment": "Used to determine the usage of the Microsoft Sovereign Cloud Auth Provider.",67"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }68}69*/70telemetryReporter.sendTelemetryEvent('loginMicrosoftSovereignCloud', {71// Get rid of guids from telemetry.72scopes: JSON.stringify(scopes.map(s => s.replace(/[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/i, '{guid}'))),73});7475return await aadService.createSession(scopes);76} catch (e) {77/* __GDPR__78"loginMicrosoftSovereignCloudFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into issues with the login flow." }79*/80telemetryReporter.sendTelemetryEvent('loginMicrosoftSovereignCloudFailed');8182throw e;83}84},85removeSession: async (id: string) => {86try {87/* __GDPR__88"logoutMicrosoftSovereignCloud" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out." }89*/90telemetryReporter.sendTelemetryEvent('logoutMicrosoftSovereignCloud');9192await aadService.removeSessionById(id);93} catch (e) {94/* __GDPR__95"logoutMicrosoftSovereignCloudFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often fail to log out." }96*/97telemetryReporter.sendTelemetryEvent('logoutMicrosoftSovereignCloudFailed');98}99}100}, { supportsMultipleAccounts: true });101102context.subscriptions.push(disposable);103return disposable;104}105106export async function activate(context: vscode.ExtensionContext, telemetryReporter: TelemetryReporter) {107// If we ever activate the old flow, then mark that we will need to migrate when the user upgrades to v2.108// TODO: MSAL Migration. Remove this when we remove the old flow.109context.globalState.update('msalMigration', false);110111const uriHandler = new UriEventHandler();112context.subscriptions.push(uriHandler);113const betterSecretStorage = new BetterTokenStorage<IStoredSession>('microsoft.login.keylist', context);114115const loginService = new AzureActiveDirectoryService(116Logger,117context,118uriHandler,119betterSecretStorage,120telemetryReporter,121Environment.AzureCloud);122await loginService.initialize();123124context.subscriptions.push(vscode.authentication.registerAuthenticationProvider(125'microsoft',126'Microsoft',127{128onDidChangeSessions: loginService.onDidChangeSessions,129getSessions: (scopes: string[], options?: vscode.AuthenticationProviderSessionOptions) => loginService.getSessions(scopes, options),130createSession: async (scopes: string[], options?: vscode.AuthenticationProviderSessionOptions) => {131try {132/* __GDPR__133"login" : {134"owner": "TylerLeonhardt",135"comment": "Used to determine the usage of the Microsoft Auth Provider.",136"scopes": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight", "comment": "Used to determine what scope combinations are being requested." }137}138*/139telemetryReporter.sendTelemetryEvent('login', {140// Get rid of guids from telemetry.141scopes: JSON.stringify(scopes.map(s => s.replace(/[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}/i, '{guid}'))),142});143144return await loginService.createSession(scopes, options);145} catch (e) {146/* __GDPR__147"loginFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users run into issues with the login flow." }148*/149telemetryReporter.sendTelemetryEvent('loginFailed');150151throw e;152}153},154removeSession: async (id: string) => {155try {156/* __GDPR__157"logout" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often users log out." }158*/159telemetryReporter.sendTelemetryEvent('logout');160161await loginService.removeSessionById(id);162} catch (e) {163/* __GDPR__164"logoutFailed" : { "owner": "TylerLeonhardt", "comment": "Used to determine how often fail to log out." }165*/166telemetryReporter.sendTelemetryEvent('logoutFailed');167}168}169},170{171supportsMultipleAccounts: true,172supportedAuthorizationServers: [173vscode.Uri.parse('https://login.microsoftonline.com/*'),174vscode.Uri.parse('https://login.microsoftonline.com/*/v2.0')175]176}177));178179let microsoftSovereignCloudAuthProviderDisposable = await initMicrosoftSovereignCloudAuthProvider(context, telemetryReporter, uriHandler, betterSecretStorage);180181context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(async e => {182if (e.affectsConfiguration('microsoft-sovereign-cloud')) {183microsoftSovereignCloudAuthProviderDisposable?.dispose();184microsoftSovereignCloudAuthProviderDisposable = await initMicrosoftSovereignCloudAuthProvider(context, telemetryReporter, uriHandler, betterSecretStorage);185}186}));187188return;189}190191// this method is called when your extension is deactivated192export function deactivate() { }193194195