From cfa1131f7399ff026931012f78922e73fb4a8dd0 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com> Date: Fri, 14 Jul 2023 09:29:11 -0700 Subject: [PATCH] Clean encryption keys with cache clear command (#23875) --- .../src/account-provider/auths/azureAuth.ts | 3 +++ .../azureAccountProviderService.ts | 5 +++-- .../utils/fileEncryptionHelper.ts | 12 ++++++++---- .../account-provider/utils/msalCachePlugin.ts | 4 ++++ extensions/azurecore/src/extension.ts | 16 +--------------- extensions/azurecore/src/localizedConstants.ts | 1 + extensions/azurecore/src/utils.ts | 14 ++++++++++++++ 7 files changed, 34 insertions(+), 21 deletions(-) diff --git a/extensions/azurecore/src/account-provider/auths/azureAuth.ts b/extensions/azurecore/src/account-provider/auths/azureAuth.ts index a3410ce16e24..6c9a25dca181 100644 --- a/extensions/azurecore/src/account-provider/auths/azureAuth.ts +++ b/extensions/azurecore/src/account-provider/auths/azureAuth.ts @@ -883,6 +883,9 @@ export abstract class AzureAuth implements vscode.Disposable { // unlink both cache files await this.msalCacheProvider.unlinkMsalCache(); await this.msalCacheProvider.unlinkLocalCache(); + + // Delete Encryption Keys + await this.msalCacheProvider.clearCacheEncryptionKeys(); } public async deleteAllCacheAdal(): Promise { diff --git a/extensions/azurecore/src/account-provider/azureAccountProviderService.ts b/extensions/azurecore/src/account-provider/azureAccountProviderService.ts index f052723a5bef..428215e09c35 100644 --- a/extensions/azurecore/src/account-provider/azureAccountProviderService.ts +++ b/extensions/azurecore/src/account-provider/azureAccountProviderService.ts @@ -20,6 +20,8 @@ import { Configuration, PublicClientApplication } from '@azure/msal-node'; import * as Constants from '../constants'; import { Logger } from '../utils/Logger'; import { ILoggerCallback, LogLevel as MsalLogLevel } from "@azure/msal-common"; +import { displayReloadAds } from '../utils'; +import { reloadPromptCacheClear } from '../localizedConstants'; let localize = nls.loadMessageBundle(); @@ -108,8 +110,7 @@ export class AzureAccountProviderService implements vscode.Disposable { return Promise.all(promises) .then( () => { - let message = localize('clearTokenCacheSuccess', "Token cache successfully cleared"); - void vscode.window.showInformationMessage(`${loc.extensionName}: ${message}`); + void displayReloadAds(reloadPromptCacheClear); }, err => { let message = localize('clearTokenCacheFailure', "Failed to clear token cache"); diff --git a/extensions/azurecore/src/account-provider/utils/fileEncryptionHelper.ts b/extensions/azurecore/src/account-provider/utils/fileEncryptionHelper.ts index e588ca3f89c4..fc92b5ccfafb 100644 --- a/extensions/azurecore/src/account-provider/utils/fileEncryptionHelper.ts +++ b/extensions/azurecore/src/account-provider/utils/fileEncryptionHelper.ts @@ -100,10 +100,7 @@ export class FileEncryptionHelper { if (resetOnError) { // Reset IV/Keys if crypto cannot encrypt/decrypt data. // This could be a possible case of corruption of expected iv/key combination - await this.deleteEncryptionKey(this._ivCredId); - await this.deleteEncryptionKey(this._keyCredId); - this._ivBuffer = undefined; - this._keyBuffer = undefined; + await this.clearEncryptionKeys(); await this.init(); } // Throw error so cache file can be reset to empty. @@ -111,6 +108,13 @@ export class FileEncryptionHelper { } } + public async clearEncryptionKeys(): Promise { + await this.deleteEncryptionKey(this._ivCredId); + await this.deleteEncryptionKey(this._keyCredId); + this._ivBuffer = undefined; + this._keyBuffer = undefined; + } + protected async readEncryptionKey(credentialId: string): Promise { return (await this._credentialService.readCredential(credentialId))?.password; } diff --git a/extensions/azurecore/src/account-provider/utils/msalCachePlugin.ts b/extensions/azurecore/src/account-provider/utils/msalCachePlugin.ts index 559bf0f31af6..566241d35096 100644 --- a/extensions/azurecore/src/account-provider/utils/msalCachePlugin.ts +++ b/extensions/azurecore/src/account-provider/utils/msalCachePlugin.ts @@ -62,6 +62,10 @@ export class MsalCachePluginProvider { return this._fileEncryptionHelper.getEncryptionKeys(); } + public async clearCacheEncryptionKeys(): Promise { + await this._fileEncryptionHelper.clearEncryptionKeys(); + } + public getCachePlugin(): ICachePlugin { const beforeCacheAccess = async (cacheContext: TokenCacheContext): Promise => { try { diff --git a/extensions/azurecore/src/extension.ts b/extensions/azurecore/src/extension.ts index 38b09ebe9326..71689e2a9c70 100644 --- a/extensions/azurecore/src/extension.ts +++ b/extensions/azurecore/src/extension.ts @@ -293,7 +293,7 @@ async function onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent): Pro if (vscode.workspace.getConfiguration(Constants.AzureSection).get('authenticationLibrary') === 'ADAL') { void vscode.window.showInformationMessage(loc.deprecatedOption); } - await displayReloadAds(); + await utils.displayReloadAds(loc.reloadPrompt); } } @@ -301,17 +301,3 @@ function updatePiiLoggingLevel(): void { const piiLogging: boolean = vscode.workspace.getConfiguration(Constants.AzureSection).get('piiLogging', false); Logger.piiLogging = piiLogging; } - -// Display notification with button to reload -// return true if button clicked -// return false if button not clicked -async function displayReloadAds(): Promise { - const result = await vscode.window.showInformationMessage(loc.reloadPrompt, loc.reloadChoice); - if (result === loc.reloadChoice) { - await vscode.commands.executeCommand('workbench.action.reloadWindow'); - return true; - } else { - return false; - } - -} diff --git a/extensions/azurecore/src/localizedConstants.ts b/extensions/azurecore/src/localizedConstants.ts index b9ea7f8a9d25..59fc2a532098 100644 --- a/extensions/azurecore/src/localizedConstants.ts +++ b/extensions/azurecore/src/localizedConstants.ts @@ -64,6 +64,7 @@ export const subscription = localize('azurecore.subscription', "Subscription"); export const typeIcon = localize('azurecore.typeIcon', "Type Icon"); export const reloadPrompt = localize('azurecore.reloadPrompt', "Authentication Library has changed, please reload Azure Data Studio."); +export const reloadPromptCacheClear = localize('azurecore.reloadPromptCacheClear', "Token cache has been cleared successfully, please reload Azure Data Studio."); export const reloadChoice = localize('azurecore.reloadChoice', "Reload Azure Data Studio"); export const deprecatedOption = localize('azurecore.deprecated', "Warning: ADAL has been deprecated, and is scheduled to be removed in the next release. Please use MSAL instead."); diff --git a/extensions/azurecore/src/utils.ts b/extensions/azurecore/src/utils.ts index 5a74b77054b0..0d4d1ffa88e2 100644 --- a/extensions/azurecore/src/utils.ts +++ b/extensions/azurecore/src/utils.ts @@ -200,3 +200,17 @@ export function getProxyEnabledHttpClient(): HttpClient { return new HttpClient(proxy, agentOptions); } + +/* Display notification with button to reload + * return true if button clicked + * return false if button not clicked + */ +export async function displayReloadAds(message: string): Promise { + const result = await vscode.window.showInformationMessage(message, loc.reloadChoice); + if (result === loc.reloadChoice) { + await vscode.commands.executeCommand('workbench.action.reloadWindow'); + return true; + } else { + return false; + } +}