From 40283ff7f174ab83b7df5446afdd881a07c186bc Mon Sep 17 00:00:00 2001 From: Senthamil Sindhu Date: Fri, 19 Jul 2024 07:28:39 -0700 Subject: [PATCH] Add readOnlyKeys call for accounts with Reader role --- .../Panes/SettingsPane/SettingsPane.tsx | 31 +++++++++++----- src/hooks/useKnockoutExplorer.ts | 37 +++++++++++-------- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/Explorer/Panes/SettingsPane/SettingsPane.tsx b/src/Explorer/Panes/SettingsPane/SettingsPane.tsx index bb1435077..216deda25 100644 --- a/src/Explorer/Panes/SettingsPane/SettingsPane.tsx +++ b/src/Explorer/Panes/SettingsPane/SettingsPane.tsx @@ -27,7 +27,7 @@ import { } from "Shared/StorageUtility"; import * as StringUtility from "Shared/StringUtility"; import { updateUserContext, userContext } from "UserContext"; -import { logConsoleInfo } from "Utils/NotificationConsoleUtils"; +import { logConsoleError, logConsoleInfo } from "Utils/NotificationConsoleUtils"; import * as PriorityBasedExecutionUtils from "Utils/PriorityBasedExecutionUtils"; import { useQueryCopilot } from "hooks/useQueryCopilot"; import { useSidePanel } from "hooks/useSidePanel"; @@ -36,8 +36,7 @@ import Explorer from "../../Explorer"; import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm"; import { AuthType } from "AuthType"; import create, { UseStore } from "zustand"; -import { DatabaseAccountListKeysResult } from "@azure/arm-cosmosdb/esm/models"; -import { listKeys } from "Utils/arm/generatedClients/cosmos/databaseAccounts"; +import { getReadOnlyKeys, listKeys } from "Utils/arm/generatedClients/cosmos/databaseAccounts"; export interface DataPlaneRbacState { dataPlaneRbacEnabled: boolean; @@ -171,14 +170,26 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ hasDataPlaneRbacSettingChanged: true, }); const { databaseAccount: account, subscriptionId, resourceGroup } = userContext; - if (!userContext.features.enableAadDataPlane) { - const keys: DatabaseAccountListKeysResult = await listKeys(subscriptionId, resourceGroup, account.name); - - if (keys.primaryMasterKey) { - updateUserContext({ masterKey: keys.primaryMasterKey }); - - useDataPlaneRbac.setState({ dataPlaneRbacEnabled: false }); + if (!userContext.features.enableAadDataPlane && !userContext.masterKey) { + let keys; + try { + keys = await listKeys(subscriptionId, resourceGroup, account.name); + updateUserContext({ + masterKey: keys.primaryMasterKey, + }); + } catch (error) { + // if listKeys fail because of permissions issue, then make call to get ReadOnlyKeys + if (error.code === "AuthorizationFailed") { + keys = await getReadOnlyKeys(subscriptionId, resourceGroup, account.name); + updateUserContext({ + masterKey: keys.primaryReadonlyMasterKey, + }); + } else { + logConsoleError(`Error occurred fetching keys for the account." ${error.message}`); + throw error; + } } + useDataPlaneRbac.setState({ dataPlaneRbacEnabled: false }); } } diff --git a/src/hooks/useKnockoutExplorer.ts b/src/hooks/useKnockoutExplorer.ts index 22cc0b51d..fa4e5ca7f 100644 --- a/src/hooks/useKnockoutExplorer.ts +++ b/src/hooks/useKnockoutExplorer.ts @@ -40,7 +40,7 @@ import { DefaultExperienceUtility } from "../Shared/DefaultExperienceUtility"; import { Node, PortalEnv, updateUserContext, userContext } from "../UserContext"; import { acquireTokenWithMsal, getAuthorizationHeader, getMsalInstance } from "../Utils/AuthorizationUtils"; import { isInvalidParentFrameOrigin, shouldProcessMessage } from "../Utils/MessageValidation"; -import { listKeys } from "../Utils/arm/generatedClients/cosmos/databaseAccounts"; +import { getReadOnlyKeys, listKeys } from "../Utils/arm/generatedClients/cosmos/databaseAccounts"; import { applyExplorerBindings } from "../applyExplorerBindings"; import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane"; import * as Logger from "../Common/Logger"; @@ -465,26 +465,33 @@ function configureEmulator(): Explorer { return explorer; } -async function fetchAndUpdateKeys(subscriptionId: string, resourceGroup: string, account: string) { +export async function fetchAndUpdateKeys(subscriptionId: string, resourceGroup: string, account: string) { + Logger.logInfo(`Fetching keys for ${userContext.apiType} account ${account}`, "Explorer/fetchAndUpdateKeys"); + let keys; try { - Logger.logInfo(`Fetching keys for ${userContext.apiType} account ${account}`, "Explorer/fetchAndUpdateKeys"); - const keys = await listKeys(subscriptionId, resourceGroup, account); + keys = await listKeys(subscriptionId, resourceGroup, account); Logger.logInfo(`Keys fetched for ${userContext.apiType} account ${account}`, "Explorer/fetchAndUpdateKeys"); - updateUserContext({ masterKey: keys.primaryMasterKey, }); - Logger.logInfo( - `User context updated with Master key for ${userContext.apiType} account ${account}`, - "Explorer/fetchAndUpdateKeys", - ); } catch (error) { - console.error("Error during fetching keys or updating user context:", error); - Logger.logError( - `Error during fetching keys or updating user context: ${error} for ${userContext.apiType} account ${account}`, - "Explorer/fetchAndUpdateKeys", - ); - throw error; + if (error.code === "AuthorizationFailed") { + keys = await getReadOnlyKeys(subscriptionId, resourceGroup, account); + Logger.logInfo( + `Read only Keys fetched for ${userContext.apiType} account ${account}`, + "Explorer/fetchAndUpdateKeys", + ); + updateUserContext({ + masterKey: keys.primaryReadonlyMasterKey, + }); + } else { + logConsoleError(`Error occurred fetching keys for the account." ${error.message}`); + Logger.logError( + `Error during fetching keys or updating user context: ${error} for ${userContext.apiType} account ${account}`, + "Explorer/fetchAndUpdateKeys", + ); + throw error; + } } }