mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
[Azure Arc] Update MIAA model to include encryption properties (#21702)
This commit is contained in:
@@ -8,11 +8,15 @@ import * as vscode from 'vscode';
|
||||
import { Deferred } from '../../common/promise';
|
||||
import * as loc from '../../localizedConstants';
|
||||
import { createCredentialId } from '../../common/utils';
|
||||
import { credentialNamespace } from '../../constants';
|
||||
import * as constants from '../../constants';
|
||||
import { InitializingComponent } from '../components/initializingComponent';
|
||||
import { ResourceModel } from '../../models/resourceModel';
|
||||
import { ControllerModel } from '../../models/controllerModel';
|
||||
|
||||
export interface IReconnectAction {
|
||||
(profile: azdata.IConnectionProfile): Promise<boolean>;
|
||||
}
|
||||
|
||||
export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
protected modelBuilder!: azdata.ModelBuilder;
|
||||
|
||||
@@ -20,6 +24,9 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
protected usernameInputBox!: azdata.InputBoxComponent;
|
||||
protected passwordInputBox!: azdata.InputBoxComponent;
|
||||
protected rememberPwCheckBox!: azdata.CheckBoxComponent;
|
||||
protected encryptSelectBox!: azdata.DropDownComponent;
|
||||
protected trustServerCertificateSelectBox!: azdata.DropDownComponent;
|
||||
|
||||
private options: { [name: string]: any } = {};
|
||||
|
||||
protected _completionPromise = new Deferred<azdata.IConnectionProfile | undefined>();
|
||||
@@ -29,7 +36,11 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
}
|
||||
|
||||
public showDialog(dialogTitle: string, connectionProfile?: azdata.IConnectionProfile): azdata.window.Dialog {
|
||||
const dialog = azdata.window.createModelViewDialog(dialogTitle);
|
||||
const dialog = azdata.window.createModelViewDialog(dialogTitle, undefined, 'narrow');
|
||||
const trueCategory: azdata.CategoryValue = { displayName: loc.booleantrue, name: 'true' }
|
||||
const falseCategory: azdata.CategoryValue = { displayName: loc.booleanfalse, name: 'false' }
|
||||
const booleanCategoryValues: azdata.CategoryValue[] = [trueCategory, falseCategory];
|
||||
|
||||
dialog.cancelButton.onClick(() => this.handleCancel());
|
||||
dialog.registerContent(async view => {
|
||||
this.modelBuilder = view.modelBuilder;
|
||||
@@ -47,13 +58,22 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
.withProps({
|
||||
inputType: 'password',
|
||||
value: connectionProfile?.password
|
||||
})
|
||||
.component();
|
||||
}).component();
|
||||
this.rememberPwCheckBox = this.modelBuilder.checkBox()
|
||||
.withProps({
|
||||
label: loc.rememberPassword,
|
||||
checked: connectionProfile?.savePassword
|
||||
}).component();
|
||||
this.encryptSelectBox = this.modelBuilder.dropDown()
|
||||
.withProps({
|
||||
values: booleanCategoryValues,
|
||||
value: connectionProfile?.options[constants.encryptOption] ? trueCategory : falseCategory
|
||||
}).component();
|
||||
this.trustServerCertificateSelectBox = this.modelBuilder.dropDown()
|
||||
.withProps({
|
||||
values: booleanCategoryValues,
|
||||
value: connectionProfile?.options[constants.trustServerCertificateOption] ? trueCategory : falseCategory
|
||||
}).component();
|
||||
|
||||
let formModel = this.modelBuilder.formContainer()
|
||||
.withFormItems([{
|
||||
@@ -73,6 +93,18 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
}, {
|
||||
component: this.rememberPwCheckBox,
|
||||
title: ''
|
||||
}, {
|
||||
component: this.encryptSelectBox,
|
||||
title: loc.encrypt,
|
||||
layout: {
|
||||
info: loc.encryptDescription,
|
||||
}
|
||||
}, {
|
||||
component: this.trustServerCertificateSelectBox,
|
||||
title: loc.trustServerCertificate,
|
||||
layout: {
|
||||
info: loc.trustServerCertDescription,
|
||||
}
|
||||
}
|
||||
],
|
||||
title: ''
|
||||
@@ -94,6 +126,10 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
if (!this.serverNameInputBox.value || !this.usernameInputBox.value || !this.passwordInputBox.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.options.encrypt = this.encryptSelectBox.value;
|
||||
this.options.trustServerCertificate = this.trustServerCertificateSelectBox.value;
|
||||
|
||||
const connectionProfile: azdata.IConnectionProfile = {
|
||||
serverName: this.serverNameInputBox.value,
|
||||
databaseName: '',
|
||||
@@ -109,10 +145,15 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
groupId: undefined,
|
||||
options: this.options
|
||||
};
|
||||
|
||||
return await this.connect(connectionProfile);
|
||||
}
|
||||
|
||||
private async connect(connectionProfile: azdata.IConnectionProfile): Promise<boolean> {
|
||||
const result = await azdata.connection.connect(connectionProfile, false, false);
|
||||
if (result.connected) {
|
||||
connectionProfile.id = result.connectionId!;
|
||||
const credentialProvider = await azdata.credentials.getProvider(credentialNamespace);
|
||||
const credentialProvider = await azdata.credentials.getProvider(constants.credentialNamespace);
|
||||
if (connectionProfile.savePassword) {
|
||||
await credentialProvider.saveCredential(createCredentialId(this._controllerModel.info.id, this._model.info.resourceType, this._model.info.name), connectionProfile.password);
|
||||
} else {
|
||||
@@ -123,10 +164,40 @@ export abstract class ConnectToSqlDialog extends InitializingComponent {
|
||||
}
|
||||
else {
|
||||
vscode.window.showErrorMessage(this.connectionFailedMessage(result.errorMessage));
|
||||
return false;
|
||||
// Show error with instructions for MSSQL Provider Encryption error code -2146893019 thrown by SqlClient when certificate validation fails.
|
||||
if (result.errorCode === -2146893019) {
|
||||
return this.showInstructionTextAsWarning(connectionProfile, async updatedConnection => {
|
||||
return await this.connect(updatedConnection);
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async showInstructionTextAsWarning(profile: azdata.IConnectionProfile, reconnectAction: IReconnectAction): Promise<boolean> {
|
||||
while (true) {
|
||||
const selection = await vscode.window.showWarningMessage(
|
||||
loc.msgPromptSSLCertificateValidationFailed,
|
||||
{ modal: false },
|
||||
...[
|
||||
loc.enableTrustServerCert,
|
||||
loc.readMore,
|
||||
loc.cancel
|
||||
]);
|
||||
if (selection === loc.enableTrustServerCert) {
|
||||
profile.options.encrypt = true;
|
||||
profile.options.trustServerCertificate = true;
|
||||
return await reconnectAction(profile);
|
||||
} else if (selection === loc.readMore) {
|
||||
vscode.env.openExternal(vscode.Uri.parse(constants.encryptReadMoreLink));
|
||||
// Show the dialog again so the user can still pick yes or no after they've read the docs
|
||||
continue;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected abstract get providerName(): string;
|
||||
|
||||
protected abstract connectionFailedMessage(error: any): string;
|
||||
|
||||
Reference in New Issue
Block a user