mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-23 01:25:38 -05:00
Hide tenant dropdown from Connection Dialog (#22973)
This commit is contained in:
10
src/sql/workbench/contrib/welcome/constants.ts
Normal file
10
src/sql/workbench/contrib/welcome/constants.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const NOTIFY_ENCRYPT_SHOWN = 'workbench.notifyEncryptionShown';
|
||||
export const NOTIFY_HIDETENANT_SHOWN = 'workbench.notifyHiddenTenantShown';
|
||||
|
||||
// Link is regularly updated with new information from release.
|
||||
export const NOTIFY_READMORE_LINK = 'https://aka.ms/azuredatastudio-connection';
|
||||
@@ -21,10 +21,9 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { TelemetryView } from 'sql/platform/telemetry/common/telemetryKeys';
|
||||
import { NOTIFY_ENCRYPT_SHOWN, NOTIFY_READMORE_LINK } from 'sql/workbench/contrib/welcome/constants';
|
||||
|
||||
export class NotifyEncryptionDialog extends ErrorMessageDialog {
|
||||
private static NOTIFY_ENCRYPT_SHOWN = 'workbench.notifyEncryptionShown';
|
||||
private static NOTIFY_ENCRYPT_LINK = 'https://aka.ms/azuredatastudio-connection';
|
||||
|
||||
constructor(
|
||||
@IThemeService themeService: IThemeService,
|
||||
@@ -43,11 +42,11 @@ export class NotifyEncryptionDialog extends ErrorMessageDialog {
|
||||
}
|
||||
|
||||
public override open(): void {
|
||||
if (this._storageService.get(NotifyEncryptionDialog.NOTIFY_ENCRYPT_SHOWN, StorageScope.APPLICATION)) {
|
||||
if (this._storageService.get(NOTIFY_ENCRYPT_SHOWN, StorageScope.APPLICATION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._storageService.store(NotifyEncryptionDialog.NOTIFY_ENCRYPT_SHOWN, true, StorageScope.APPLICATION, StorageTarget.MACHINE);
|
||||
this._storageService.store(NOTIFY_ENCRYPT_SHOWN, true, StorageScope.APPLICATION, StorageTarget.MACHINE);
|
||||
|
||||
if (!this._connectionManagementService.getConnections()?.some(conn => conn.providerName === mssqlProviderName)) {
|
||||
return;
|
||||
@@ -64,7 +63,7 @@ export class NotifyEncryptionDialog extends ErrorMessageDialog {
|
||||
this._instantiationService.createInstance(Link, moreInfoLink,
|
||||
{
|
||||
label: localize('notifyEncryption.moreInfoLink', 'More information'),
|
||||
href: NotifyEncryptionDialog.NOTIFY_ENCRYPT_LINK
|
||||
href: NOTIFY_READMORE_LINK
|
||||
}, undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { NotifyHiddenTenantDialog } from 'sql/workbench/contrib/welcome/notifyHiddenTenant/notifyHiddenTenantDialog';
|
||||
|
||||
export class NotifyHiddenTenant extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
) {
|
||||
super();
|
||||
const dialog = this._instantiationService.createInstance(NotifyHiddenTenantDialog);
|
||||
dialog.render();
|
||||
dialog.open();
|
||||
}
|
||||
}
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(NotifyHiddenTenant, LifecyclePhase.Starting);
|
||||
@@ -0,0 +1,74 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { localize } from 'vs/nls';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/textResourceConfiguration';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ErrorMessageDialog } from 'sql/workbench/services/errorMessage/browser/errorMessageDialog';
|
||||
import { Link } from 'vs/platform/opener/browser/link';
|
||||
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IConnectionManagementService } from 'sql/platform/connection/common/connectionManagement';
|
||||
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { TelemetryView } from 'sql/platform/telemetry/common/telemetryKeys';
|
||||
import { NOTIFY_HIDETENANT_SHOWN, NOTIFY_READMORE_LINK } from 'sql/workbench/contrib/welcome/constants';
|
||||
import { IAccountManagementService } from 'sql/platform/accounts/common/interfaces';
|
||||
|
||||
export class NotifyHiddenTenantDialog extends ErrorMessageDialog {
|
||||
|
||||
constructor(
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IClipboardService clipboardService: IClipboardService,
|
||||
@ILayoutService layoutService: ILayoutService,
|
||||
@IAdsTelemetryService telemetryService: IAdsTelemetryService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@ILogService logService: ILogService,
|
||||
@ITextResourcePropertiesService textResourcePropertiesService: ITextResourcePropertiesService,
|
||||
@IOpenerService openerService: IOpenerService,
|
||||
@IInstantiationService private _instantiationService: IInstantiationService,
|
||||
@IStorageService private _storageService: IStorageService,
|
||||
@IConnectionManagementService private _connectionManagementService: IConnectionManagementService,
|
||||
@IAccountManagementService private _accountManagementService: IAccountManagementService
|
||||
) {
|
||||
super(themeService, clipboardService, layoutService, telemetryService, contextKeyService, logService, textResourcePropertiesService, openerService);
|
||||
}
|
||||
|
||||
public override open(): void {
|
||||
if (this._storageService.get(NOTIFY_HIDETENANT_SHOWN, StorageScope.APPLICATION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._storageService.store(NOTIFY_HIDETENANT_SHOWN, true, StorageScope.APPLICATION, StorageTarget.MACHINE);
|
||||
this._accountManagementService.getAccounts().then(accounts => {
|
||||
// Do not notify users who don't have any Azure connection in their list of connections and no Azure accounts registered.
|
||||
if (!this._connectionManagementService.getConnections()?.some(conn => conn.providerName === mssqlProviderName
|
||||
&& conn.authenticationType === 'AzureMFA') && (!accounts || accounts.length === 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.open(TelemetryView.NotifyHiddenTenantDialog, Severity.Info,
|
||||
localize('notifyHiddenTenant.title', 'Important Update'),
|
||||
localize('notifyHiddenTenant.message', `Connections using Azure Active Directory authentication will now retrieve tenant information from the server during login. The 'Azure AD Tenant' entry no longer needs to be provided when connecting to Azure SQL instances.`, '\n\n'));
|
||||
});
|
||||
}
|
||||
|
||||
protected override updateDialogBody(): void {
|
||||
super.updateDialogBody();
|
||||
let moreInfoLink = DOM.append(this.getBody()!, DOM.$('.more-info'));
|
||||
this._instantiationService.createInstance(Link, moreInfoLink,
|
||||
{
|
||||
label: localize('notifyHiddenTenant.moreInfoLink', 'More information'),
|
||||
href: NOTIFY_READMORE_LINK
|
||||
}, undefined);
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ import { VIEWLET_ID as ExtensionsViewletID } from 'vs/workbench/contrib/extensio
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { IErrorDiagnosticsService } from 'sql/workbench/services/diagnostics/common/errorDiagnosticsService';
|
||||
import { PasswordChangeDialog } from 'sql/workbench/services/connection/browser/passwordChangeDialog';
|
||||
import { enableSqlAuthenticationProviderConfig, mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
import { isMssqlAuthProviderEnabled } from 'sql/workbench/services/connection/browser/utils';
|
||||
|
||||
export class ConnectionManagementService extends Disposable implements IConnectionManagementService {
|
||||
|
||||
@@ -1141,7 +1141,7 @@ export class ConnectionManagementService extends Disposable implements IConnecti
|
||||
if (connectionProfile && connectionProfile.authenticationType === Constants.AuthenticationType.AzureMFA) {
|
||||
// We do not need to reconnect for MSSQL Provider, if 'SQL Authentication Provider' setting is enabled.
|
||||
// Update the token in case it needs refreshing/reauthentication.
|
||||
if (connectionProfile.providerName === mssqlProviderName && this.getEnableSqlAuthenticationProviderConfig()) {
|
||||
if (isMssqlAuthProviderEnabled(connectionProfile.providerName, this._configurationService)) {
|
||||
await this.fillInOrClearToken(connectionProfile);
|
||||
return true;
|
||||
}
|
||||
@@ -1181,10 +1181,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti
|
||||
}
|
||||
}
|
||||
|
||||
private getEnableSqlAuthenticationProviderConfig(): boolean {
|
||||
return this._configurationService.getValue(enableSqlAuthenticationProviderConfig) ?? true;
|
||||
}
|
||||
|
||||
// Request Senders
|
||||
private async sendConnectRequest(connection: interfaces.IConnectionProfile, uri: string): Promise<boolean> {
|
||||
let connectionInfo = Object.assign({}, {
|
||||
|
||||
@@ -43,6 +43,7 @@ import { AdsWidget } from 'sql/base/browser/ui/adsWidget';
|
||||
import { createCSSRule } from 'vs/base/browser/dom';
|
||||
import { AuthLibrary, getAuthLibrary } from 'sql/workbench/services/accountManagement/utils';
|
||||
import { adjustForMssqlAppName } from 'sql/platform/connection/common/utils';
|
||||
import { isMssqlAuthProviderEnabled } from 'sql/workbench/services/connection/browser/utils';
|
||||
import { RequiredIndicatorClassName } from 'sql/base/browser/ui/label/label';
|
||||
|
||||
const ConnectionStringText = localize('connectionWidget.connectionString', "Connection string");
|
||||
@@ -75,6 +76,7 @@ export class ConnectionWidget extends lifecycle.Disposable {
|
||||
private _trueInputValue: string = localize('boolean.true', 'True');
|
||||
private _falseInputValue: string = localize('boolean.false', 'False');
|
||||
private _token: string;
|
||||
private _mssqlAuthProviderEnabled: boolean;
|
||||
private _connectionStringOptions: ConnectionStringOptions;
|
||||
protected _container: HTMLElement;
|
||||
protected _serverGroupSelectBox: SelectBox;
|
||||
@@ -144,6 +146,7 @@ export class ConnectionWidget extends lifecycle.Disposable {
|
||||
this._register(this._authTypeSelectBox);
|
||||
}
|
||||
this._providerName = providerName;
|
||||
this._mssqlAuthProviderEnabled = isMssqlAuthProviderEnabled(this._providerName, this._configurationService)
|
||||
this._connectionStringOptions = this._connectionManagementService.getProviderProperties(this._providerName).connectionStringOptions;
|
||||
}
|
||||
|
||||
@@ -648,6 +651,9 @@ export class ConnectionWidget extends lifecycle.Disposable {
|
||||
this._passwordInputBox.hideMessage();
|
||||
this._azureAccountDropdown.hideMessage();
|
||||
this._azureTenantDropdown.hideMessage();
|
||||
if (this._mssqlAuthProviderEnabled) {
|
||||
this._tableContainer.classList.add('hide-azure-tenants');
|
||||
}
|
||||
this._tableContainer.classList.add('hide-username');
|
||||
this._tableContainer.classList.add('hide-password');
|
||||
this._tableContainer.classList.add('hide-azure-accounts');
|
||||
@@ -795,7 +801,9 @@ export class ConnectionWidget extends lifecycle.Disposable {
|
||||
// There are multiple tenants available so let the user select one
|
||||
let options = selectedAccount.properties.tenants.map(tenant => tenant.displayName);
|
||||
this._azureTenantDropdown.setOptions(options);
|
||||
this._tableContainer.classList.remove(hideTenantsClassName);
|
||||
if (!this._mssqlAuthProviderEnabled) {
|
||||
this._tableContainer.classList.remove(hideTenantsClassName);
|
||||
}
|
||||
|
||||
// If we have a tenant ID available, select that instead of the first one
|
||||
if (this._azureTenantId) {
|
||||
@@ -820,7 +828,9 @@ export class ConnectionWidget extends lifecycle.Disposable {
|
||||
this._azureTenantId = selectedAccount.properties.tenants[0].id;
|
||||
this.onAzureTenantSelected(0);
|
||||
}
|
||||
this._tableContainer.classList.add(hideTenantsClassName);
|
||||
if (!this._mssqlAuthProviderEnabled) {
|
||||
this._tableContainer.classList.add(hideTenantsClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,6 +982,9 @@ export class ConnectionWidget extends lifecycle.Disposable {
|
||||
account = this._azureAccountList?.find(account => account.key.accountId === this.getModelValue(accountName)
|
||||
|| account.key.accountId.split('.')[0] === this.getModelValue(accountName));
|
||||
if (account) {
|
||||
if (!account.properties.tenants?.find(tenant => tenant.id === this._azureTenantId)) {
|
||||
this._azureTenantId = account.properties.tenants[0].id;
|
||||
}
|
||||
this._azureAccountDropdown.selectWithOptionName(account.key.accountId);
|
||||
}
|
||||
}
|
||||
|
||||
18
src/sql/workbench/services/connection/browser/utils.ts
Normal file
18
src/sql/workbench/services/connection/browser/utils.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { enableSqlAuthenticationProviderConfig, mssqlProviderName } from 'sql/platform/connection/common/constants';
|
||||
|
||||
/**
|
||||
* Reads setting 'mssql.enableSqlAuthenticationProvider' returns true if it's enabled.
|
||||
* Returns false for other providers.
|
||||
* @param provider Connection provider name
|
||||
* @param configService Configuration service instance
|
||||
* @returns True if provider is MSSQL and Sql Auth provider is enabled.
|
||||
*/
|
||||
export function isMssqlAuthProviderEnabled(provider: string, configService: IConfigurationService): boolean {
|
||||
return provider === mssqlProviderName && (configService?.getValue(enableSqlAuthenticationProviderConfig) ?? true);
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import { getErrorMessage, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { AsyncServerTree, ConnectionError as AsyncTreeConnectionError, ServerTreeElement } from 'sql/workbench/services/objectExplorer/browser/asyncServerTree';
|
||||
import { ObjectExplorerRequestStatus } from 'sql/workbench/services/objectExplorer/browser/treeSelectionHandler';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
export interface IExpandableTree extends ITree {
|
||||
/**
|
||||
@@ -217,11 +218,11 @@ export class TreeUpdateUtils {
|
||||
}
|
||||
|
||||
const result = await connectionManagementService.connect(connection, undefined, options, callbacks);
|
||||
if (result.connected) {
|
||||
if (result?.connected) {
|
||||
let existingConnection = connectionManagementService.findExistingConnection(connection);
|
||||
return existingConnection;
|
||||
} else {
|
||||
throw new Error(result.errorMessage);
|
||||
throw new Error(result ? result.errorMessage : localize('connectionFailedError', 'Failed to connect, please try again.'));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user