mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-10 02:02:35 -05:00
Migrate cert validation error handling to mssql extension (#21829)
This commit is contained in:
@@ -3,5 +3,21 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
// Error code reference comes from here: https://learn.microsoft.com/en-us/sql/relational-databases/errors-events/database-engine-events-and-errors?view=sql-server-ver16
|
||||
export const MssqlPasswordResetErrorCode: number = 18488;
|
||||
export const MssqlCertValidationFailedErrorCode: number = -2146893019;
|
||||
|
||||
export const MssqlConnectionTelemetryView = 'MssqlConnectionErrorDialog';
|
||||
export const ConnectionErrorDialogTitle = localize('connectionError', "Connection error");
|
||||
|
||||
// Trust Server certificate custom dialog constants.
|
||||
export const TSC_ActionId = 'enableTrustServerCertificate';
|
||||
export const TSC_OptionName = 'trustServerCertificate';
|
||||
export const TSC_EnableTrustServerCert = localize('enableTrustServerCertificate', "Enable Trust server certificate");
|
||||
export const TSC_InstructionText = localize('trustServerCertInstructionText', `Encryption was enabled on this connection, review your SSL and certificate configuration for the target SQL Server, or enable 'Trust server certificate' in the connection dialog.
|
||||
|
||||
Note: A self-signed certificate offers only limited protection and is not a recommended practice for production environments. Do you want to enable 'Trust server certificate' on this connection and retry? `);
|
||||
export const TSC_ReadMoreLink = "https://learn.microsoft.com/sql/database-engine/configure-windows/enable-encrypted-connections-to-the-database-engine"
|
||||
|
||||
@@ -51,13 +51,18 @@ export class ErrorDiagnosticsProvider extends SqlOpsFeature<any> {
|
||||
}
|
||||
|
||||
protected override registerProvider(options: any): Disposable {
|
||||
let handleConnectionError = async (errorCode: number, errorMessage: string, connection: azdata.connection.ConnectionProfile): Promise<azdata.diagnostics.ConnectionDiagnosticsResult> => {
|
||||
let handleConnectionError = async (errorInfo: azdata.diagnostics.IErrorInformation, connection: azdata.connection.ConnectionProfile): Promise<azdata.diagnostics.ConnectionDiagnosticsResult> => {
|
||||
let restoredProfile = this.convertToIConnectionProfile(connection);
|
||||
if (errorCode === ErrorDiagnosticsConstants.MssqlPasswordResetErrorCode) {
|
||||
logDebug(`Error Code ${errorCode} requires user to change their password, launching change password dialog.`)
|
||||
|
||||
if (errorInfo.errorCode === ErrorDiagnosticsConstants.MssqlPasswordResetErrorCode) {
|
||||
logDebug(`ErrorDiagnosticsProvider: Error Code ${errorInfo.errorCode} requires user to change their password, launching change password dialog.`);
|
||||
return await this.handleChangePassword(restoredProfile);
|
||||
}
|
||||
logDebug(`No error handler found for errorCode ${errorCode}.`);
|
||||
else if (errorInfo.errorCode === ErrorDiagnosticsConstants.MssqlCertValidationFailedErrorCode) {
|
||||
logDebug(`ErrorDiagnosticsProvider: Error Code ${errorInfo.errorCode} indicates certificate validation has failed, launching error dialog with instructionText.`);
|
||||
return await this.showCertValidationDialog(restoredProfile, errorInfo.errorMessage, errorInfo.messageDetails);
|
||||
}
|
||||
logDebug(`ErrorDiagnosticsProvider: No error handler found for errorCode ${errorInfo.errorCode}.`);
|
||||
return { handled: false };
|
||||
}
|
||||
|
||||
@@ -68,6 +73,43 @@ export class ErrorDiagnosticsProvider extends SqlOpsFeature<any> {
|
||||
});
|
||||
}
|
||||
|
||||
private async showCertValidationDialog(connection: azdata.IConnectionProfile, errorMessage: string, callStack: string): Promise<azdata.diagnostics.ConnectionDiagnosticsResult> {
|
||||
try {
|
||||
let actions: azdata.window.IDialogAction[] = [];
|
||||
let trustServerCertAction: azdata.window.IDialogAction = {
|
||||
id: ErrorDiagnosticsConstants.TSC_ActionId,
|
||||
label: ErrorDiagnosticsConstants.TSC_EnableTrustServerCert,
|
||||
isPrimary: true
|
||||
};
|
||||
|
||||
actions.push(trustServerCertAction);
|
||||
const result = await azdata.window.openCustomErrorDialog(
|
||||
{
|
||||
severity: azdata.window.MessageLevel.Error,
|
||||
headerTitle: ErrorDiagnosticsConstants.ConnectionErrorDialogTitle,
|
||||
message: errorMessage,
|
||||
messageDetails: callStack,
|
||||
telemetryView: ErrorDiagnosticsConstants.MssqlConnectionTelemetryView,
|
||||
instructionText: ErrorDiagnosticsConstants.TSC_InstructionText,
|
||||
readMoreLink: ErrorDiagnosticsConstants.TSC_ReadMoreLink,
|
||||
actions: actions
|
||||
}
|
||||
);
|
||||
|
||||
// Result represents id of action taken by user.
|
||||
if (result === ErrorDiagnosticsConstants.TSC_ActionId) {
|
||||
connection.options[ErrorDiagnosticsConstants.TSC_OptionName] = true;
|
||||
return { handled: true, reconnect: true, options: connection.options };
|
||||
} else {
|
||||
return { handled: true, reconnect: false };
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
console.error(`Unexpected exception occurred when showing certificate validation custom dialog: ${e}`);
|
||||
}
|
||||
return { handled: false };
|
||||
}
|
||||
|
||||
private async handleChangePassword(connection: azdata.IConnectionProfile): Promise<azdata.diagnostics.ConnectionDiagnosticsResult> {
|
||||
try {
|
||||
const result = await azdata.connection.openChangePasswordDialog(connection);
|
||||
@@ -75,7 +117,7 @@ export class ErrorDiagnosticsProvider extends SqlOpsFeature<any> {
|
||||
if (result) {
|
||||
// MSSQL uses 'password' as the option key for connection profile.
|
||||
connection.options['password'] = result;
|
||||
return { handled: true, options: connection.options };
|
||||
return { handled: true, reconnect: true, options: connection.options };
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
||||
Reference in New Issue
Block a user