Remove AdHoc Access and Token Renewal Pane (#445)

This commit is contained in:
Steve Faulkner 2021-02-23 11:16:00 -06:00 committed by GitHub
parent 3777b6922e
commit f0c82a430b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 8 additions and 654 deletions

View File

@ -67,7 +67,6 @@ ko.components.register("table-query-select-pane", new PaneComponents.TableQueryS
ko.components.register("cassandra-add-collection-pane", new PaneComponents.CassandraAddCollectionPaneComponent());
ko.components.register("settings-pane", new PaneComponents.SettingsPaneComponent());
ko.components.register("execute-sproc-params-pane", new PaneComponents.ExecuteSprocParamsComponent());
ko.components.register("renew-adhoc-access-pane", new PaneComponents.RenewAdHocAccessPane());
ko.components.register("upload-items-pane", new PaneComponents.UploadItemsPaneComponent());
ko.components.register("load-query-pane", new PaneComponents.LoadQueryPaneComponent());
ko.components.register("save-query-pane", new PaneComponents.SaveQueryPaneComponent());

View File

@ -32,10 +32,8 @@ exports[`SettingsComponent renders 1`] = `
"_closeModalDialog": [Function],
"_closeSynapseLinkModalDialog": [Function],
"_dialogProps": [Function],
"_importExplorerConfigComplete": false,
"_isAfecFeatureRegistered": [Function],
"_isInitializingNotebooks": false,
"_isInitializingSparkConnectionInfo": false,
"_isSystemDatabasePredicate": [Function],
"_openShareDialog": [Function],
"_panes": Array [
@ -440,22 +438,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function],
"visible": [Function],
},
RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
UploadItemsPane {
"container": [Circular],
"fileUploadSummaryText": [Function],
@ -1051,22 +1033,6 @@ exports[`SettingsComponent renders 1`] = `
"refreshDatabaseAccount": [Function],
"refreshNotebookList": [Function],
"refreshTreeTitle": [Function],
"renewAdHocAccessPane": RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"renewToken": [Function],
"renewTokenError": [Function],
"resourceTokenCollection": [Function],
@ -1169,8 +1135,6 @@ exports[`SettingsComponent renders 1`] = `
"shareAccessUrl": [Function],
"shareTokenCopyHelperText": [Function],
"shareUrlCopyHelperText": [Function],
"shouldShowContextSwitchPrompt": [Function],
"shouldShowDataAccessExpiryDialog": [Function],
"shouldShowShareDialogContents": [Function],
"signInAad": [Function],
"sparkClusterConnectionInfo": [Function],
@ -1313,10 +1277,8 @@ exports[`SettingsComponent renders 1`] = `
"_closeModalDialog": [Function],
"_closeSynapseLinkModalDialog": [Function],
"_dialogProps": [Function],
"_importExplorerConfigComplete": false,
"_isAfecFeatureRegistered": [Function],
"_isInitializingNotebooks": false,
"_isInitializingSparkConnectionInfo": false,
"_isSystemDatabasePredicate": [Function],
"_openShareDialog": [Function],
"_panes": Array [
@ -1721,22 +1683,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function],
"visible": [Function],
},
RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
UploadItemsPane {
"container": [Circular],
"fileUploadSummaryText": [Function],
@ -2332,22 +2278,6 @@ exports[`SettingsComponent renders 1`] = `
"refreshDatabaseAccount": [Function],
"refreshNotebookList": [Function],
"refreshTreeTitle": [Function],
"renewAdHocAccessPane": RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"renewToken": [Function],
"renewTokenError": [Function],
"resourceTokenCollection": [Function],
@ -2450,8 +2380,6 @@ exports[`SettingsComponent renders 1`] = `
"shareAccessUrl": [Function],
"shareTokenCopyHelperText": [Function],
"shareUrlCopyHelperText": [Function],
"shouldShowContextSwitchPrompt": [Function],
"shouldShowDataAccessExpiryDialog": [Function],
"shouldShowShareDialogContents": [Function],
"signInAad": [Function],
"sparkClusterConnectionInfo": [Function],
@ -2607,10 +2535,8 @@ exports[`SettingsComponent renders 1`] = `
"_closeModalDialog": [Function],
"_closeSynapseLinkModalDialog": [Function],
"_dialogProps": [Function],
"_importExplorerConfigComplete": false,
"_isAfecFeatureRegistered": [Function],
"_isInitializingNotebooks": false,
"_isInitializingSparkConnectionInfo": false,
"_isSystemDatabasePredicate": [Function],
"_openShareDialog": [Function],
"_panes": Array [
@ -3015,22 +2941,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function],
"visible": [Function],
},
RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
UploadItemsPane {
"container": [Circular],
"fileUploadSummaryText": [Function],
@ -3626,22 +3536,6 @@ exports[`SettingsComponent renders 1`] = `
"refreshDatabaseAccount": [Function],
"refreshNotebookList": [Function],
"refreshTreeTitle": [Function],
"renewAdHocAccessPane": RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"renewToken": [Function],
"renewTokenError": [Function],
"resourceTokenCollection": [Function],
@ -3744,8 +3638,6 @@ exports[`SettingsComponent renders 1`] = `
"shareAccessUrl": [Function],
"shareTokenCopyHelperText": [Function],
"shareUrlCopyHelperText": [Function],
"shouldShowContextSwitchPrompt": [Function],
"shouldShowDataAccessExpiryDialog": [Function],
"shouldShowShareDialogContents": [Function],
"signInAad": [Function],
"sparkClusterConnectionInfo": [Function],
@ -3888,10 +3780,8 @@ exports[`SettingsComponent renders 1`] = `
"_closeModalDialog": [Function],
"_closeSynapseLinkModalDialog": [Function],
"_dialogProps": [Function],
"_importExplorerConfigComplete": false,
"_isAfecFeatureRegistered": [Function],
"_isInitializingNotebooks": false,
"_isInitializingSparkConnectionInfo": false,
"_isSystemDatabasePredicate": [Function],
"_openShareDialog": [Function],
"_panes": Array [
@ -4296,22 +4186,6 @@ exports[`SettingsComponent renders 1`] = `
"validPartitionKeyValue": [Function],
"visible": [Function],
},
RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
UploadItemsPane {
"container": [Circular],
"fileUploadSummaryText": [Function],
@ -4907,22 +4781,6 @@ exports[`SettingsComponent renders 1`] = `
"refreshDatabaseAccount": [Function],
"refreshNotebookList": [Function],
"refreshTreeTitle": [Function],
"renewAdHocAccessPane": RenewAdHocAccessPane {
"_renewShareAccess": [Function],
"accessKey": [Function],
"container": [Circular],
"firstFieldHasFocus": [Function],
"formErrors": [Function],
"formErrorsDetails": [Function],
"id": "renewadhocaccesspane",
"isExecuting": [Function],
"isHelperImageVisible": [Function],
"isTemplateReady": [Function],
"onShowHelperImageClick": [Function],
"onShowHelperImageKeyPress": [Function],
"title": [Function],
"visible": [Function],
},
"renewToken": [Function],
"renewTokenError": [Function],
"resourceTokenCollection": [Function],
@ -5025,8 +4883,6 @@ exports[`SettingsComponent renders 1`] = `
"shareAccessUrl": [Function],
"shareTokenCopyHelperText": [Function],
"shareUrlCopyHelperText": [Function],
"shouldShowContextSwitchPrompt": [Function],
"shouldShowDataAccessExpiryDialog": [Function],
"shouldShowShareDialogContents": [Function],
"signInAad": [Function],
"sparkClusterConnectionInfo": [Function],

View File

@ -21,7 +21,6 @@ import { readDatabases } from "../Common/dataAccess/readDatabases";
import EditTableEntityPane from "./Panes/Tables/EditTableEntityPane";
import { normalizeArmEndpoint } from "../Common/EnvironmentUtility";
import GraphStylingPane from "./Panes/GraphStylingPane";
import hasher from "hasher";
import NewVertexPane from "./Panes/NewVertexPane";
import NotebookV2Tab, { NotebookTabOptions } from "./Tabs/NotebookV2Tab";
import Q from "q";
@ -29,7 +28,7 @@ import ResourceTokenCollection from "./Tree/ResourceTokenCollection";
import * as TelemetryProcessor from "../Shared/Telemetry/TelemetryProcessor";
import TerminalTab from "./Tabs/TerminalTab";
import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants";
import { ActionContracts, MessageTypes } from "../Contracts/ExplorerContracts";
import { MessageTypes } from "../Contracts/ExplorerContracts";
import { ArcadiaResourceManager } from "../SparkClusterManager/ArcadiaResourceManager";
import { ArcadiaWorkspaceItem } from "./Controls/Arcadia/ArcadiaMenuPicker";
import { AuthType } from "../AuthType";
@ -47,18 +46,16 @@ import { ExecuteSprocParamsPane } from "./Panes/ExecuteSprocParamsPane";
import { ExplorerMetrics } from "../Common/Constants";
import { ExplorerSettings } from "../Shared/ExplorerSettings";
import { FileSystemUtil } from "./Notebook/FileSystemUtil";
import { handleOpenAction } from "./OpenActions";
import { IGalleryItem } from "../Juno/JunoClient";
import { LoadQueryPane } from "./Panes/LoadQueryPane";
import * as Logger from "../Common/Logger";
import { sendMessage, sendCachedDataMessage, handleCachedDataMessage } from "../Common/MessageHandler";
import { sendMessage, sendCachedDataMessage } from "../Common/MessageHandler";
import { NotebookContentItem, NotebookContentItemType } from "./Notebook/NotebookContentItem";
import { NotebookUtil } from "./Notebook/NotebookUtil";
import { NotebookWorkspaceManager } from "../NotebookWorkspaceManager/NotebookWorkspaceManager";
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
import { QueriesClient } from "../Common/QueriesClient";
import { QuerySelectPane } from "./Panes/Tables/QuerySelectPane";
import { RenewAdHocAccessPane } from "./Panes/RenewAdHocAccessPane";
import { ResourceProviderClientFactory } from "../ResourceProvider/ResourceProviderClientFactory";
import { ResourceTreeAdapter } from "./Tree/ResourceTreeAdapter";
import { ResourceTreeAdapterForResourceToken } from "./Tree/ResourceTreeAdapterForResourceToken";
@ -204,7 +201,6 @@ export default class Explorer {
public cassandraAddCollectionPane: CassandraAddCollectionPane;
public settingsPane: SettingsPane;
public executeSprocParamsPane: ExecuteSprocParamsPane;
public renewAdHocAccessPane: RenewAdHocAccessPane;
public uploadItemsPane: UploadItemsPane;
public uploadItemsPaneAdapter: UploadItemsPaneAdapter;
public loadQueryPane: LoadQueryPane;
@ -238,8 +234,6 @@ export default class Explorer {
public shareAccessUrl: ko.Observable<string>;
public shareUrlCopyHelperText: ko.Observable<string>;
public shareTokenCopyHelperText: ko.Observable<string>;
public shouldShowDataAccessExpiryDialog: ko.Observable<boolean>;
public shouldShowContextSwitchPrompt: ko.Observable<boolean>;
public isSchemaEnabled: ko.Computed<boolean>;
// Notebooks
@ -258,10 +252,8 @@ export default class Explorer {
public notebookManager?: any; // This is dynamically loaded
private _panes: ContextualPaneBase[] = [];
private _importExplorerConfigComplete: boolean = false;
private _isSystemDatabasePredicate: (database: ViewModels.Database) => boolean = (database) => false;
private _isInitializingNotebooks: boolean;
private _isInitializingSparkConnectionInfo: boolean;
private notebookBasePath: ko.Observable<string>;
private _arcadiaManager: ArcadiaResourceManager;
private notebookToImport: {
@ -320,7 +312,6 @@ export default class Explorer {
this.isAccountReady = ko.observable<boolean>(false);
this.selfServeType = ko.observable<SelfServeType>(undefined);
this._isInitializingNotebooks = false;
this._isInitializingSparkConnectionInfo = false;
this.arcadiaToken = ko.observable<string>();
this.arcadiaToken.subscribe((token: string) => {
if (token) {
@ -429,8 +420,6 @@ export default class Explorer {
}
});
this.shouldShowShareDialogContents = ko.observable<boolean>(false);
this.shouldShowDataAccessExpiryDialog = ko.observable<boolean>(false);
this.shouldShowContextSwitchPrompt = ko.observable<boolean>(false);
this.isGalleryPublishEnabled = ko.computed<boolean>(
() => configContext.ENABLE_GALLERY_PUBLISH || this.isFeatureEnabled(Constants.Features.enableGalleryPublish)
);
@ -715,13 +704,6 @@ export default class Explorer {
container: this,
});
this.renewAdHocAccessPane = new RenewAdHocAccessPane({
id: "renewadhocaccesspane",
visible: ko.observable<boolean>(false),
container: this,
});
this.uploadItemsPane = new UploadItemsPane({
id: "uploaditemspane",
visible: ko.observable<boolean>(false),
@ -790,7 +772,6 @@ export default class Explorer {
this.cassandraAddCollectionPane,
this.settingsPane,
this.executeSprocParamsPane,
this.renewAdHocAccessPane,
this.uploadItemsPane,
this.loadQueryPane,
this.saveQueryPane,
@ -1173,138 +1154,10 @@ export default class Explorer {
);
}
public renewShareAccess(token: string): Q.Promise<void> {
if (!this.renewExplorerShareAccess) {
return Q.reject("Not implemented");
}
const deferred: Q.Deferred<void> = Q.defer<void>();
const id: string = NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.InProgress,
"Initiating connection to account"
);
this.renewExplorerShareAccess(this, token)
.then(
() => {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Info, "Connection successful");
this.renewAdHocAccessPane && this.renewAdHocAccessPane.close();
deferred.resolve();
},
(error: any) => {
NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Failed to connect: ${getErrorMessage(error)}`
);
deferred.reject(error);
}
)
.finally(() => {
NotificationConsoleUtils.clearInProgressMessageWithId(id);
});
return deferred.promise;
}
public displayGuestAccessTokenRenewalPrompt(): void {
if (!$("#dataAccessTokenModal").dialog("instance")) {
const connectButton = {
text: "Connect",
class: "connectDialogButtons connectButton connectOkBtns",
click: () => {
this.renewAdHocAccessPane.open();
$("#dataAccessTokenModal").dialog("close");
},
};
const cancelButton = {
text: "Cancel",
class: "connectDialogButtons cancelBtn",
click: () => {
$("#dataAccessTokenModal").dialog("close");
},
};
$("#dataAccessTokenModal").dialog({
autoOpen: false,
buttons: [connectButton, cancelButton],
closeOnEscape: false,
draggable: false,
dialogClass: "no-close",
height: 180,
modal: true,
position: { my: "center center", at: "center center", of: window },
resizable: false,
title: "Temporary access expired",
width: 435,
close: (event: Event, ui: JQueryUI.DialogUIParams) => this.shouldShowDataAccessExpiryDialog(false),
});
$("#dataAccessTokenModal").dialog("option", "classes", {
"ui-dialog-titlebar": "connectTitlebar",
});
}
this.shouldShowDataAccessExpiryDialog(true);
$("#dataAccessTokenModal").dialog("open");
}
public isConnectExplorerVisible(): boolean {
return $("#connectExplorer").is(":visible") || false;
}
public displayContextSwitchPromptForConnectionString(connectionString: string): void {
const yesButton = {
text: "OK",
class: "connectDialogButtons okBtn connectOkBtns",
click: () => {
$("#contextSwitchPrompt").dialog("close");
this.tabsManager.closeTabs(); // clear all tabs so we dont leave any tabs from previous session open
this.renewShareAccess(connectionString);
},
};
const noButton = {
text: "Cancel",
class: "connectDialogButtons cancelBtn",
click: () => {
$("#contextSwitchPrompt").dialog("close");
},
};
if (!$("#contextSwitchPrompt").dialog("instance")) {
$("#contextSwitchPrompt").dialog({
autoOpen: false,
buttons: [yesButton, noButton],
closeOnEscape: false,
draggable: false,
dialogClass: "no-close",
height: 255,
modal: true,
position: { my: "center center", at: "center center", of: window },
resizable: false,
title: "Switch account",
width: 440,
close: (event: Event, ui: JQueryUI.DialogUIParams) => this.shouldShowDataAccessExpiryDialog(false),
});
$("#contextSwitchPrompt").dialog("option", "classes", {
"ui-dialog-titlebar": "connectTitlebar",
});
$("#contextSwitchPrompt").dialog("option", "open", (event: Event, ui: JQueryUI.DialogUIParams) => {
$(".ui-dialog ").css("z-index", 1001);
$("#contextSwitchPrompt").parent().siblings(".ui-widget-overlay").css("z-index", 1000);
});
}
$("#contextSwitchPrompt").dialog("option", "buttons", [yesButton, noButton]); // rebind buttons so callbacks accept current connection string
this.shouldShowContextSwitchPrompt(true);
$("#contextSwitchPrompt").dialog("open");
}
public displayConnectExplorerForm(): void {
$("#divExplorer").hide();
$("#connectExplorer").css("display", "flex");
}
public hideConnectExplorerForm(): void {
$("#connectExplorer").hide();
$("#divExplorer").show();
}
public isReadWriteToggled: () => boolean = (): boolean => {
return this.shareAccessToggleState() === ShareAccessToggleState.ReadWrite;
};
@ -1728,60 +1581,6 @@ export default class Explorer {
this._addSynapseLinkDialogProps.valueHasMutated();
};
public handleMessage(message: any) {
const openAction: ActionContracts.DataExplorerAction = message.openAction;
if (!!openAction) {
if (this.isRefreshingExplorer()) {
const subscription = this.databases.subscribe((databases: ViewModels.Database[]) => {
handleOpenAction(openAction, this.nonSystemDatabases(), this);
subscription.dispose();
});
} else {
handleOpenAction(openAction, this.nonSystemDatabases(), this);
}
}
if (message.actionType === ActionContracts.ActionType.TransmitCachedData) {
handleCachedDataMessage(message);
return;
}
if (message.type) {
switch (message.type) {
case MessageTypes.UpdateLocationHash:
if (!message.locationHash) {
break;
}
hasher.replaceHash(message.locationHash);
RouteHandler.getInstance().parseHash(message.locationHash);
break;
case MessageTypes.SendNotification:
if (!message.message) {
break;
}
NotificationConsoleUtils.logConsoleMessage(
message.consoleDataType || ConsoleDataType.Info,
message.message,
message.id
);
break;
case MessageTypes.ClearNotification:
if (!message.id) {
break;
}
NotificationConsoleUtils.clearInProgressMessageWithId(message.id);
break;
case MessageTypes.LoadingStatus:
if (!message.text) {
break;
}
this._setLoadingStatusText(message.text, message.title);
break;
}
return;
}
this.splashScreenAdapter.forceRender();
}
public findSelectedDatabase(): ViewModels.Database {
if (!this.selectedNode()) {
return null;
@ -1859,7 +1658,6 @@ export default class Explorer {
this.isAuthWithResourceToken(inputs.isAuthWithresourceToken ?? false);
this.setFeatureFlagsFromFlights(inputs.flights);
this.setSelfServeType(inputs);
this._importExplorerConfigComplete = true;
updateConfigContext({
BACKEND_ENDPOINT: inputs.extensionEndpoint || configContext.BACKEND_ENDPOINT,

View File

@ -146,12 +146,6 @@ function openPane(action: ActionContracts.OpenPane, explorer: Explorer) {
) {
explorer.closeAllPanes();
!explorer.isConnectExplorerVisible() && explorer.settingsPane.open();
} else if (
action.paneKind === ActionContracts.PaneKind.AdHocAccess ||
(<any>action).paneKind === ActionContracts.PaneKind[ActionContracts.PaneKind.AdHocAccess]
) {
explorer.closeAllPanes();
!explorer.isConnectExplorerVisible() && explorer.renewAdHocAccessPane.open();
}
}

View File

@ -11,7 +11,6 @@ import TableQuerySelectPaneTemplate from "./Tables/TableQuerySelectPane.html";
import CassandraAddCollectionPaneTemplate from "./CassandraAddCollectionPane.html";
import SettingsPaneTemplate from "./SettingsPane.html";
import ExecuteSprocParamsPaneTemplate from "./ExecuteSprocParamsPane.html";
import RenewAdHocAccessPaneTemplate from "./RenewAdHocAccessPane.html";
import UploadItemsPaneTemplate from "./UploadItemsPane.html";
import LoadQueryPaneTemplate from "./LoadQueryPane.html";
import SaveQueryPaneTemplate from "./SaveQueryPane.html";
@ -144,15 +143,6 @@ export class ExecuteSprocParamsComponent {
}
}
export class RenewAdHocAccessPane {
constructor() {
return {
viewModel: PaneComponent,
template: RenewAdHocAccessPaneTemplate,
};
}
}
export class UploadItemsPaneComponent {
constructor() {
return {

View File

@ -1,90 +0,0 @@
<div data-bind="visible: visible, event: { keydown: onPaneKeyDown }">
<div
class="contextual-pane-out"
data-bind="
click: cancel,
clickBubble: false"
></div>
<div class="contextual-pane" id="renewadhocaccesspane">
<!-- Renew ad-hoc access form - Start -->
<div class="contextual-pane-in">
<form class="paneContentContainer" data-bind="submit: submit">
<!-- Renew ad-hoc access header - Start -->
<div class="firstdivbg headerline">
<span role="heading" aria-level="2" data-bind="text: title"></span>
<div
class="closeImg"
role="button"
aria-label="Close pane"
tabindex="0"
data-bind="
click: cancel"
>
<img src="../../../images/close-black.svg" title="Close" alt="Close" />
</div>
</div>
<!-- Renew ad-hoc access header - End -->
<!-- Renew ad-hoc access errors - Start -->
<div
class="warningErrorContainer"
aria-live="assertive"
data-bind="visible: formErrors() && formErrors() !== ''"
>
<div class="warningErrorContent">
<span><img class="paneErrorIcon" src="/error_red.svg" alt="Error" /></span>
<span class="warningErrorDetailsLinkContainer">
<span class="formErrors" data-bind="text: formErrors, attr: { title: formErrors }"></span>
<a
class="errorLink"
role="link"
data-bind="
visible: formErrorsDetails() && formErrorsDetails() !== '',
click: showErrorDetails"
>More details</a
>
</span>
</div>
</div>
<!-- Renew ad-hoc access errors - End -->
<!-- Renew ad-hoc access inputs - Start -->
<div class="paneMainContent">
<div class="renewUploadItemsHeader">Provide a valid account connection string</div>
<input
class="accessKeyInput"
type="text"
placeholder="Enter a connection string"
required
data-bind="value: accessKey"
/>
<div
class="renewAccessExpandCollapse"
data-bind="click: onShowHelperImageClick, event: { keypress: onShowHelperImageKeyPress }"
>
<img src="/Triangle-right.svg" alt="Show renew access image" data-bind="visible: !isHelperImageVisible()" />
<img src="/Triangle-down.svg" alt="Hide renew access image" data-bind="visible: isHelperImageVisible()" />
<span class="AccountNavigationText">Where do I find the Connection String?</span>
</div>
<div class="renewAccessImg" data-bind="visible: isHelperImageVisible()">
<span class="AccountNavigationText"
>To get the connection string, navigate to your Azure Cosmos DB account in Azure Portal, select Keys and
copy the connection string.</span
>
<img src="/ConnectionString_Artwork.png" />
</div>
</div>
<div class="paneFooter">
<div class="leftpanel-okbut"><input type="submit" value="Connect" class="btncreatecoll1" /></div>
</div>
<!-- Renew ad-hoc access - End -->
</form>
</div>
<!-- Renew ad-hoc access form - Start -->
<!-- Loader - Start -->
<div class="dataExplorerLoaderContainer dataExplorerPaneLoaderContainer" data-bind="visible: isExecuting">
<img class="dataExplorerLoader" src="/LoadingIndicator_3Squares.gif" />
</div>
<!-- Loader - End -->
</div>
</div>

View File

@ -1,101 +0,0 @@
import * as ko from "knockout";
import * as Constants from "../../Common/Constants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
import { parseConnectionString } from "../../Platform/Hosted/Helpers/ConnectionStringParser";
import { ContextualPaneBase } from "./ContextualPaneBase";
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export class RenewAdHocAccessPane extends ContextualPaneBase {
public accessKey: ko.Observable<string>;
public isHelperImageVisible: ko.Observable<boolean>;
constructor(options: ViewModels.PaneOptions) {
super(options);
this.title("Connect to Azure Cosmos DB");
this.accessKey = ko.observable<string>();
this.isHelperImageVisible = ko.observable<boolean>(false);
}
public submit(): void {
this.formErrors("");
this.formErrorsDetails("");
if (this._shouldShowContextSwitchPrompt()) {
this.container.displayContextSwitchPromptForConnectionString(this.accessKey());
} else if (!!this.formErrors()) {
return;
} else {
this.isExecuting(true);
this._renewShareAccess();
}
}
public onShowHelperImageClick = (src: any, event: MouseEvent): void => {
this.isHelperImageVisible(!this.isHelperImageVisible());
};
public onShowHelperImageKeyPress = (src: any, event: KeyboardEvent): boolean => {
if (event.keyCode === Constants.KeyCodes.Enter || event.keyCode === Constants.KeyCodes.Space) {
this.onShowHelperImageClick(src, null);
return false;
}
return true;
};
private _shouldShowContextSwitchPrompt(): boolean {
const inputMetadata: DataModels.AccessInputMetadata = parseConnectionString(this.accessKey());
const apiKind: DataModels.ApiKind =
this.container && DefaultExperienceUtility.getApiKindFromDefaultExperience(this.container.defaultExperience());
const hasOpenedTabs: boolean =
(this.container && this.container.tabsManager && this.container.tabsManager.openedTabs().length > 0) || false;
if (!inputMetadata || inputMetadata.apiKind == null || !inputMetadata.accountName) {
this.formErrors("Invalid connection string input");
this.formErrorsDetails("Please enter a valid connection string");
}
if (
!inputMetadata ||
this.formErrors() ||
!this.container ||
apiKind == null ||
!this.container.databaseAccount ||
!this.container.defaultExperience ||
!hasOpenedTabs ||
(this.container.databaseAccount().name === inputMetadata.accountName &&
apiKind === inputMetadata.apiKind &&
!hasOpenedTabs)
) {
return false;
}
return true;
}
private _renewShareAccess = (): void => {
this.container
.renewShareAccess(this.accessKey())
.fail((error: any) => {
const errorMessage: string = getErrorMessage(error);
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to connect: ${errorMessage}`);
this.formErrors(errorMessage);
this.formErrorsDetails(errorMessage);
})
.finally(() => {
this.isExecuting(false);
});
};
public close(): void {
super.close();
this.isHelperImageVisible(false);
this.formErrors("");
this.formErrorsDetails("");
this.accessKey("");
}
}

View File

@ -1,7 +1,7 @@
import * as ko from "knockout";
import Q from "q";
import { displayTokenRenewalPromptForStatus, getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
import { AuthType } from "../../AuthType";
import { ConsoleDataType } from "../../Explorer/Menus/NotificationConsole/NotificationConsoleComponent";
import { FeedOptions } from "@azure/cosmos";
@ -281,7 +281,6 @@ export class CassandraAPIDataClient extends TableDataClient {
paginationToken,
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false,
});
shouldNotify &&
@ -444,7 +443,6 @@ export class CassandraAPIDataClient extends TableDataClient {
tableId: collection.id(),
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false,
})
.then(
@ -494,7 +492,6 @@ export class CassandraAPIDataClient extends TableDataClient {
tableId: collection.id(),
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false,
})
.then(
@ -533,7 +530,6 @@ export class CassandraAPIDataClient extends TableDataClient {
query: query,
},
beforeSend: this.setAuthorizationHeader,
error: this.handleAjaxError,
cache: false,
}).then(
(data: any) => {
@ -582,12 +578,4 @@ export class CassandraAPIDataClient extends TableDataClient {
private getCassandraPartitionKeyProperty(collection: ViewModels.Collection): string {
return collection.cassandraKeys.partitionKeys[0].property;
}
private handleAjaxError = (xhrObj: XMLHttpRequest, textStatus: string, errorThrown: string): void => {
if (!xhrObj) {
return;
}
displayTokenRenewalPromptForStatus(xhrObj.status);
};
}

View File

@ -340,7 +340,6 @@ const App: React.FunctionComponent = () => {
<div data-bind='component: { name: "upload-items-pane", params: { data: uploadItemsPane} }' />
<div data-bind='component: { name: "load-query-pane", params: { data: loadQueryPane} }' />
<div data-bind='component: { name: "execute-sproc-params-pane", params: { data: executeSprocParamsPane} }' />
<div data-bind='component: { name: "renew-adhoc-access-pane", params: { data: renewAdHocAccessPane} }' />
<div data-bind='component: { name: "save-query-pane", params: { data: saveQueryPane} }' />
<div data-bind='component: { name: "browse-queries-pane", params: { data: browseQueriesPane} }' />
<div data-bind='component: { name: "upload-file-pane", params: { data: uploadFilePane} }' />
@ -355,33 +354,7 @@ const App: React.FunctionComponent = () => {
<KOCommentIfStart if="isCopyNotebookPaneEnabled" />
<div data-bind="react: copyNotebookPaneAdapter" />
<KOCommentEnd />
{/* Global access token expiration dialog - Start */}
<div
id="dataAccessTokenModal"
className="dataAccessTokenModal"
style={{ display: "none" }}
data-bind="visible: shouldShowDataAccessExpiryDialog"
>
<div className="dataAccessTokenModalContent">
<p className="dataAccessTokenExpireText">Please reconnect to the account using the connection string.</p>
</div>
</div>
{/* Global access token expiration dialog - End */}
{/* Context switch prompt - Start */}
<div
id="contextSwitchPrompt"
className="dataAccessTokenModal"
style={{ display: "none" }}
data-bind="visible: shouldShowContextSwitchPrompt"
>
<div className="dataAccessTokenModalContent">
<p className="dataAccessTokenExpireText">
Please save your work before you switch! When you switch to a different Azure Cosmos DB account, current
Data Explorer tabs will be closed.
</p>
<p className="dataAccessTokenExpireText">Proceed anyway?</p>
</div>
</div>
<div data-bind="react: dialogComponentAdapter" />
<div data-bind="react: addSynapseLinkDialog" />
</div>

View File

@ -58,48 +58,4 @@ describe("AuthorizationUtils", () => {
).toBeDefined();
});
});
describe("displayTokenRenewalPromptForStatus()", () => {
let explorer = new Explorer() as jest.Mocked<Explorer>;
beforeEach(() => {
jest.clearAllMocks();
window.dataExplorer = explorer;
updateConfigContext({
platform: Platform.Hosted,
});
});
afterEach(() => {
window.dataExplorer = undefined;
});
it("should not open token renewal prompt if status code is undefined", () => {
AuthorizationUtils.displayTokenRenewalPromptForStatus(undefined);
expect(explorer.displayGuestAccessTokenRenewalPrompt).not.toHaveBeenCalled();
});
it("should not open token renewal prompt if status code is null", () => {
AuthorizationUtils.displayTokenRenewalPromptForStatus(null);
expect(explorer.displayGuestAccessTokenRenewalPrompt).not.toHaveBeenCalled();
});
it("should not open token renewal prompt if status code is not 401", () => {
AuthorizationUtils.displayTokenRenewalPromptForStatus(Constants.HttpStatusCodes.Forbidden);
expect(explorer.displayGuestAccessTokenRenewalPrompt).not.toHaveBeenCalled();
});
it("should not open token renewal prompt if running on a different platform", () => {
updateConfigContext({
platform: Platform.Portal,
});
AuthorizationUtils.displayTokenRenewalPromptForStatus(Constants.HttpStatusCodes.Unauthorized);
expect(explorer.displayGuestAccessTokenRenewalPrompt).not.toHaveBeenCalled();
});
it("should open token renewal prompt if running on hosted platform and status code is 401", () => {
AuthorizationUtils.displayTokenRenewalPromptForStatus(Constants.HttpStatusCodes.Unauthorized);
expect(explorer.displayGuestAccessTokenRenewalPrompt).toHaveBeenCalled();
});
});
});

View File

@ -40,17 +40,3 @@ export function decryptJWTToken(token: string) {
return JSON.parse(tokenPayload);
}
export function displayTokenRenewalPromptForStatus(httpStatusCode: number): void {
const explorer = window.dataExplorer;
if (
httpStatusCode == null ||
httpStatusCode != Constants.HttpStatusCodes.Unauthorized ||
configContext.platform !== Platform.Hosted
) {
return;
}
explorer.displayGuestAccessTokenRenewalPrompt();
}

View File

@ -8,6 +8,7 @@ import { ActionType, DataExplorerAction } from "../Contracts/ActionContracts";
import { MessageTypes } from "../Contracts/ExplorerContracts";
import { DataExplorerInputsFrame } from "../Contracts/ViewModels";
import Explorer, { ExplorerParams } from "../Explorer/Explorer";
import { handleOpenAction } from "../Explorer/OpenActions";
import {
AAD,
ConnectionString,
@ -199,6 +200,7 @@ function configurePortal() {
// Check for init message
const message: PortalMessage = event.data?.data;
const inputs = message?.inputs;
const openAction = message?.openAction;
if (inputs) {
if (
configContext.BACKEND_ENDPOINT &&
@ -210,6 +212,9 @@ function configurePortal() {
explorer.configure(inputs);
applyExplorerBindings(explorer);
if (openAction) {
handleOpenAction(openAction, explorer.nonSystemDatabases(), explorer);
}
}
},
false