Add fetchAndUpdate Keys
This commit is contained in:
parent
22144982bd
commit
caf4e9f51f
|
@ -3,12 +3,10 @@ import { getAuthorizationTokenUsingResourceTokens } from "Common/getAuthorizatio
|
||||||
import { AuthorizationToken } from "Contracts/FabricMessageTypes";
|
import { AuthorizationToken } from "Contracts/FabricMessageTypes";
|
||||||
import { checkDatabaseResourceTokensValidity } from "Platform/Fabric/FabricUtil";
|
import { checkDatabaseResourceTokensValidity } from "Platform/Fabric/FabricUtil";
|
||||||
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||||
import { listKeys } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
|
||||||
import { DatabaseAccountListKeysResult } from "Utils/arm/generatedClients/cosmos/types";
|
|
||||||
import { AuthType } from "../AuthType";
|
import { AuthType } from "../AuthType";
|
||||||
import { PriorityLevel } from "../Common/Constants";
|
import { PriorityLevel } from "../Common/Constants";
|
||||||
import { Platform, configContext } from "../ConfigContext";
|
import { Platform, configContext } from "../ConfigContext";
|
||||||
import { updateUserContext, userContext } from "../UserContext";
|
import { userContext } from "../UserContext";
|
||||||
import { logConsoleError } from "../Utils/NotificationConsoleUtils";
|
import { logConsoleError } from "../Utils/NotificationConsoleUtils";
|
||||||
import * as PriorityBasedExecutionUtils from "../Utils/PriorityBasedExecutionUtils";
|
import * as PriorityBasedExecutionUtils from "../Utils/PriorityBasedExecutionUtils";
|
||||||
import { EmulatorMasterKey, HttpHeaders } from "./Constants";
|
import { EmulatorMasterKey, HttpHeaders } from "./Constants";
|
||||||
|
@ -81,12 +79,6 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let retryAttempts: number = 50;
|
|
||||||
while (retryAttempts > 0 && userContext.listKeysFetchInProgress) {
|
|
||||||
retryAttempts--;
|
|
||||||
await sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (userContext.masterKey) {
|
if (userContext.masterKey) {
|
||||||
// TODO This SDK method mutates the headers object. Find a better one or fix the SDK.
|
// TODO This SDK method mutates the headers object. Find a better one or fix the SDK.
|
||||||
await Cosmos.setAuthorizationTokenHeaderUsingMasterKey(
|
await Cosmos.setAuthorizationTokenHeaderUsingMasterKey(
|
||||||
|
@ -97,22 +89,6 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
|
||||||
userContext.masterKey,
|
userContext.masterKey,
|
||||||
);
|
);
|
||||||
return decodeURIComponent(headers.authorization);
|
return decodeURIComponent(headers.authorization);
|
||||||
} else if (userContext.dataPlaneRbacEnabled == false) {
|
|
||||||
const { databaseAccount: account, subscriptionId, resourceGroup } = userContext;
|
|
||||||
const keys: DatabaseAccountListKeysResult = await listKeys(subscriptionId, resourceGroup, account.name);
|
|
||||||
|
|
||||||
if (keys.primaryMasterKey) {
|
|
||||||
updateUserContext({ masterKey: keys.primaryMasterKey });
|
|
||||||
// TODO This SDK method mutates the headers object. Find a better one or fix the SDK.
|
|
||||||
await Cosmos.setAuthorizationTokenHeaderUsingMasterKey(
|
|
||||||
verb,
|
|
||||||
resourceId,
|
|
||||||
resourceType,
|
|
||||||
headers,
|
|
||||||
keys.primaryMasterKey,
|
|
||||||
);
|
|
||||||
return decodeURIComponent(headers.authorization);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userContext.resourceToken) {
|
if (userContext.resourceToken) {
|
||||||
|
@ -124,10 +100,6 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
|
||||||
return decodeURIComponent(result.PrimaryReadWriteToken);
|
return decodeURIComponent(result.PrimaryReadWriteToken);
|
||||||
};
|
};
|
||||||
|
|
||||||
function sleep(ms: number) {
|
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
||||||
}
|
|
||||||
|
|
||||||
export const requestPlugin: Cosmos.Plugin<any> = async (requestContext, diagnosticNode, next) => {
|
export const requestPlugin: Cosmos.Plugin<any> = async (requestContext, diagnosticNode, next) => {
|
||||||
requestContext.endpoint = new URL(configContext.PROXY_PATH, window.location.href).href;
|
requestContext.endpoint = new URL(configContext.PROXY_PATH, window.location.href).href;
|
||||||
requestContext.headers["x-ms-proxy-target"] = endpoint();
|
requestContext.headers["x-ms-proxy-target"] = endpoint();
|
||||||
|
@ -200,6 +172,7 @@ export function client(): Cosmos.CosmosClient {
|
||||||
|
|
||||||
const options: Cosmos.CosmosClientOptions = {
|
const options: Cosmos.CosmosClientOptions = {
|
||||||
endpoint: endpoint() || "https://cosmos.azure.com", // CosmosClient gets upset if we pass a bad URL. This should never actually get called
|
endpoint: endpoint() || "https://cosmos.azure.com", // CosmosClient gets upset if we pass a bad URL. This should never actually get called
|
||||||
|
key: userContext.dataPlaneRbacEnabled ? "" : userContext.masterKey,
|
||||||
tokenProvider,
|
tokenProvider,
|
||||||
userAgentSuffix: "Azure Portal",
|
userAgentSuffix: "Azure Portal",
|
||||||
defaultHeaders: _defaultHeaders,
|
defaultHeaders: _defaultHeaders,
|
||||||
|
|
|
@ -36,6 +36,8 @@ import Explorer from "../../Explorer";
|
||||||
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
import { RightPaneForm, RightPaneFormProps } from "../RightPaneForm/RightPaneForm";
|
||||||
import { AuthType } from "AuthType";
|
import { AuthType } from "AuthType";
|
||||||
import create, { UseStore } from "zustand";
|
import create, { UseStore } from "zustand";
|
||||||
|
import { DatabaseAccountListKeysResult } from "@azure/arm-cosmosdb/esm/models";
|
||||||
|
import { listKeys } from "Utils/arm/generatedClients/cosmos/databaseAccounts";
|
||||||
|
|
||||||
export interface DataPlaneRbacState {
|
export interface DataPlaneRbacState {
|
||||||
dataPlaneRbacEnabled: boolean;
|
dataPlaneRbacEnabled: boolean;
|
||||||
|
@ -166,8 +168,15 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({
|
||||||
updateUserContext({
|
updateUserContext({
|
||||||
dataPlaneRbacEnabled: false,
|
dataPlaneRbacEnabled: false,
|
||||||
});
|
});
|
||||||
|
const { databaseAccount: account, subscriptionId, resourceGroup } = userContext;
|
||||||
|
const keys: DatabaseAccountListKeysResult = await listKeys(subscriptionId, resourceGroup, account.name);
|
||||||
|
|
||||||
|
if (keys.primaryMasterKey) {
|
||||||
|
updateUserContext({ masterKey: keys.primaryMasterKey });
|
||||||
|
|
||||||
useDataPlaneRbac.setState({ dataPlaneRbacEnabled: false });
|
useDataPlaneRbac.setState({ dataPlaneRbacEnabled: false });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LocalStorageUtility.setEntryBoolean(StorageKey.RUThresholdEnabled, ruThresholdEnabled);
|
LocalStorageUtility.setEntryBoolean(StorageKey.RUThresholdEnabled, ruThresholdEnabled);
|
||||||
LocalStorageUtility.setEntryBoolean(StorageKey.QueryTimeoutEnabled, queryTimeoutEnabled);
|
LocalStorageUtility.setEntryBoolean(StorageKey.QueryTimeoutEnabled, queryTimeoutEnabled);
|
||||||
|
|
|
@ -417,11 +417,24 @@ function configureEmulator(): Explorer {
|
||||||
return explorer;
|
return explorer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function configurePortal(): Promise<Explorer> {
|
async function configurePortal(): Promise<Explorer> {
|
||||||
updateUserContext({
|
updateUserContext({
|
||||||
authType: AuthType.AAD,
|
authType: AuthType.AAD,
|
||||||
});
|
});
|
||||||
let explorer: Explorer;
|
let explorer: Explorer;
|
||||||
|
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
// In development mode, try to load the iframe message from session storage.
|
// In development mode, try to load the iframe message from session storage.
|
||||||
// This allows webpack hot reload to function properly in the portal
|
// This allows webpack hot reload to function properly in the portal
|
||||||
|
@ -489,16 +502,28 @@ async function configurePortal(): Promise<Explorer> {
|
||||||
} else {
|
} else {
|
||||||
dataPlaneRbacEnabled = isDataPlaneRbacSetting === Constants.RBACOptions.setTrueRBACOption;
|
dataPlaneRbacEnabled = isDataPlaneRbacSetting === Constants.RBACOptions.setTrueRBACOption;
|
||||||
}
|
}
|
||||||
|
if(!dataPlaneRbacEnabled) {
|
||||||
|
(async () => {
|
||||||
|
await fetchAndUpdateKeys(subscriptionId, resourceGroup, account.name);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
updateUserContext({ dataPlaneRbacEnabled });
|
updateUserContext({ dataPlaneRbacEnabled });
|
||||||
useDataPlaneRbac.setState({ dataPlaneRbacEnabled: dataPlaneRbacEnabled });
|
useDataPlaneRbac.setState({ dataPlaneRbacEnabled: dataPlaneRbacEnabled });
|
||||||
} else {
|
} else {
|
||||||
const dataPlaneRbacEnabled = account.properties.disableLocalAuth;
|
const dataPlaneRbacEnabled = account.properties.disableLocalAuth;
|
||||||
|
|
||||||
|
if(!dataPlaneRbacEnabled) {
|
||||||
|
(async () => {
|
||||||
|
await fetchAndUpdateKeys(subscriptionId, resourceGroup, account.name);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
|
||||||
updateUserContext({ dataPlaneRbacEnabled });
|
updateUserContext({ dataPlaneRbacEnabled });
|
||||||
useDataPlaneRbac.setState({ dataPlaneRbacEnabled: dataPlaneRbacEnabled });
|
useDataPlaneRbac.setState({ dataPlaneRbacEnabled: dataPlaneRbacEnabled });
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
(async () => {
|
(async () => {
|
||||||
await fetchAndUpdateKeys(subscriptionId, resourceGroup, account.name);
|
await fetchAndUpdateKeys(subscriptionId, resourceGroup, account.name);
|
||||||
})();
|
})();
|
||||||
|
@ -529,18 +554,6 @@ async function configurePortal(): Promise<Explorer> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
function shouldForwardMessage(message: PortalMessage, messageOrigin: string) {
|
||||||
// Only allow forwarding messages from the same origin
|
// Only allow forwarding messages from the same origin
|
||||||
return messageOrigin === window.document.location.origin && message.type === MessageTypes.TelemetryInfo;
|
return messageOrigin === window.document.location.origin && message.type === MessageTypes.TelemetryInfo;
|
||||||
|
@ -558,6 +571,11 @@ function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) {
|
||||||
const authorizationToken = inputs.authorizationToken || "";
|
const authorizationToken = inputs.authorizationToken || "";
|
||||||
const databaseAccount = inputs.databaseAccount;
|
const databaseAccount = inputs.databaseAccount;
|
||||||
|
|
||||||
|
if(userContext.apiType !== "SQL") {
|
||||||
|
const masterKey = inputs.masterKey || "";
|
||||||
|
updateUserContext({masterKey});
|
||||||
|
}
|
||||||
|
|
||||||
updateConfigContext({
|
updateConfigContext({
|
||||||
BACKEND_ENDPOINT: inputs.extensionEndpoint || configContext.BACKEND_ENDPOINT,
|
BACKEND_ENDPOINT: inputs.extensionEndpoint || configContext.BACKEND_ENDPOINT,
|
||||||
ARM_ENDPOINT: normalizeArmEndpoint(inputs.csmEndpoint || configContext.ARM_ENDPOINT),
|
ARM_ENDPOINT: normalizeArmEndpoint(inputs.csmEndpoint || configContext.ARM_ENDPOINT),
|
||||||
|
|
Loading…
Reference in New Issue