diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts index c5fc473e4..cde5e9462 100644 --- a/src/Common/Constants.ts +++ b/src/Common/Constants.ts @@ -186,9 +186,6 @@ export class CassandraProxyAPIs { export class Queries { public static CustomPageOption: string = "custom"; public static UnlimitedPageOption: string = "unlimited"; - public static setAutomaticRBACOption: string = "Automatic"; - public static setTrueRBACOption: string = "True"; - public static setFalseRBACOption: string = "False"; public static itemsPerPage: number = 100; public static unlimitedItemsPerPage: number = 100; // TODO: Figure out appropriate value so it works for accounts with a large number of partitions public static containersPerPage: number = 50; diff --git a/src/Common/CosmosClient.ts b/src/Common/CosmosClient.ts index 72facd197..682ab4e39 100644 --- a/src/Common/CosmosClient.ts +++ b/src/Common/CosmosClient.ts @@ -31,18 +31,9 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => { } const AUTH_PREFIX = `type=aad&ver=1.0&sig=`; const authorizationToken = `${AUTH_PREFIX}${userContext.aadToken}`; - console.log(`Returning Auth token`); return authorizationToken; } - if ((userContext.dataPlaneRbacEnabled) && userContext.authorizationToken) { - console.log(` Getting Portal Auth token `) - const AUTH_PREFIX = `type=aad&ver=1.0&sig=`; - const authorizationToken = `${AUTH_PREFIX}${userContext.authorizationToken}`; - console.log(`Returning Portal Auth token`); - return authorizationToken; - } - if (configContext.platform === Platform.Emulator) { // TODO This SDK method mutates the headers object. Find a better one or fix the SDK. await Cosmos.setAuthorizationTokenHeaderUsingMasterKey(verb, resourceId, resourceType, headers, EmulatorMasterKey); @@ -90,6 +81,12 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => { } } + let retryAttempts: number = 50; + while (retryAttempts > 0 && userContext.listKeysFetchInProgress) { + retryAttempts--; + await sleep(100); + } + if (userContext.masterKey) { // TODO This SDK method mutates the headers object. Find a better one or fix the SDK. await Cosmos.setAuthorizationTokenHeaderUsingMasterKey( @@ -127,6 +124,10 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => { return decodeURIComponent(result.PrimaryReadWriteToken); }; +function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + export const requestPlugin: Cosmos.Plugin = async (requestContext, diagnosticNode, next) => { requestContext.endpoint = new URL(configContext.PROXY_PATH, window.location.href).href; requestContext.headers["x-ms-proxy-target"] = endpoint(); diff --git a/src/Common/MongoProxyClient.ts b/src/Common/MongoProxyClient.ts index 860be2bee..d9aa0fb4c 100644 --- a/src/Common/MongoProxyClient.ts +++ b/src/Common/MongoProxyClient.ts @@ -710,4 +710,3 @@ async function errorHandling(response: Response, action: string, params: unknown export function getARMCreateCollectionEndpoint(params: DataModels.MongoParameters): string { return `subscriptions/${params.sid}/resourceGroups/${params.rg}/providers/Microsoft.DocumentDB/databaseAccounts/${userContext.databaseAccount.name}/mongodbDatabases/${params.db}/collections/${params.coll}`; } - diff --git a/src/Explorer/Tables/TableDataClient.ts b/src/Explorer/Tables/TableDataClient.ts index e40ddef6f..25a43f56b 100644 --- a/src/Explorer/Tables/TableDataClient.ts +++ b/src/Explorer/Tables/TableDataClient.ts @@ -755,10 +755,6 @@ export class CassandraAPIDataClient extends TableDataClient { CassandraProxyEndpoints.Prod, ]; let canAccessCassandraProxy: boolean = userContext.databaseAccount.properties.publicNetworkAccess === "Enabled"; - if ( - configContext.CASSANDRA_PROXY_ENDPOINT !== CassandraProxyEndpoints.Development && - userContext.databaseAccount.properties.ipRules?.length > 0 - ) { if ( configContext.CASSANDRA_PROXY_ENDPOINT !== CassandraProxyEndpoints.Development && userContext.databaseAccount.properties.ipRules?.length > 0 @@ -773,4 +769,3 @@ export class CassandraAPIDataClient extends TableDataClient { ); } } -} diff --git a/src/Platform/Hosted/extractFeatures.ts b/src/Platform/Hosted/extractFeatures.ts index 28723e475..5bd84516e 100644 --- a/src/Platform/Hosted/extractFeatures.ts +++ b/src/Platform/Hosted/extractFeatures.ts @@ -14,7 +14,6 @@ export type Features = { readonly enableTtl: boolean; readonly executeSproc: boolean; readonly enableAadDataPlane: boolean; - readonly enableDataPlaneRbac: boolean; readonly enableResourceGraph: boolean; readonly enableKoResourceTree: boolean; readonly hostedDataExplorer: boolean; @@ -70,7 +69,6 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear canExceedMaximumValue: "true" === get("canexceedmaximumvalue"), cosmosdb: "true" === get("cosmosdb"), enableAadDataPlane: "true" === get("enableaaddataplane"), - enableDataPlaneRbac: "true" === get("enabledataplanerbac"), enableResourceGraph: "true" === get("enableresourcegraph"), enableChangeFeedPolicy: "true" === get("enablechangefeedpolicy"), enableFixedCollectionWithSharedThroughput: "true" === get("enablefixedcollectionwithsharedthroughput"), diff --git a/src/UserContext.ts b/src/UserContext.ts index 4718e3915..fcf690560 100644 --- a/src/UserContext.ts +++ b/src/UserContext.ts @@ -73,6 +73,7 @@ export interface UserContext { readonly fabricContext?: FabricContext; readonly authType?: AuthType; readonly masterKey?: string; + readonly listKeysFetchInProgress?: boolean; readonly subscriptionId?: string; readonly resourceGroup?: string; readonly databaseAccount?: DatabaseAccount; diff --git a/src/hooks/useKnockoutExplorer.ts b/src/hooks/useKnockoutExplorer.ts index e5237daa1..b98341b63 100644 --- a/src/hooks/useKnockoutExplorer.ts +++ b/src/hooks/useKnockoutExplorer.ts @@ -421,10 +421,8 @@ async function configurePortal(): Promise { updateUserContext({ authType: AuthType.AAD, }); - - let explorer: Explorer; - return new Promise(async (resolve) => { + return new Promise((resolve) => { // In development mode, try to load the iframe message from session storage. // This allows webpack hot reload to function properly in the portal if (process.env.NODE_ENV === "development" && !window.location.search.includes("disablePortalInitCache")) { @@ -437,8 +435,6 @@ async function configurePortal(): Promise { console.dir(message); updateContextsFromPortalMessage(message); explorer = new Explorer(); - - // In development mode, save the iframe message from the portal in session storage. // This allows webpack hot reload to funciton properly if (process.env.NODE_ENV === "development") { @@ -462,7 +458,7 @@ async function configurePortal(): Promise { // Check for init message const message: PortalMessage = event.data?.data; - const inputs = message?.inputs; + const inputs = message?.inputs; const openAction = message?.openAction; if (inputs) { if ( @@ -503,10 +499,9 @@ async function configurePortal(): Promise { useDataPlaneRbac.setState({ dataPlaneRbacEnabled: dataPlaneRbacEnabled }); } } else { - const keys: DatabaseAccountListKeysResult = await listKeys(subscriptionId, resourceGroup, account.name); - updateUserContext({ - masterKey: keys.primaryMasterKey, - }); + (async () => { + await fetchAndUpdateKeys(subscriptionId, resourceGroup, account.name); + })(); } if (openAction) { @@ -529,11 +524,21 @@ async function configurePortal(): Promise { }, false, ); - + sendReadyMessage(); - }); +} +async function fetchAndUpdateKeys(subscriptionId: string, resourceGroup: string, account: string) { + try { + updateUserContext({ listKeysFetchInProgress: true }); + const keys = await listKeys(subscriptionId, resourceGroup, account); + + updateUserContext({ masterKey: keys.primaryMasterKey, listKeysFetchInProgress: false }); + } catch (error) { + updateUserContext({ listKeysFetchInProgress: false }); + console.error("Error during fetching keys or updating user context:", error); + } } function shouldForwardMessage(message: PortalMessage, messageOrigin: string) { @@ -573,6 +578,7 @@ function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) { collectionCreationDefaults: inputs.defaultCollectionThroughput, isTryCosmosDBSubscription: inputs.isTryCosmosDBSubscription, feedbackPolicies: inputs.feedbackPolicies, + listKeysFetchInProgress: false, }); if (inputs.isPostgresAccount) {