Enable SQL Auth Provider support (#21903)

This commit is contained in:
Cheena Malhotra
2023-03-03 12:49:01 -08:00
committed by GitHub
parent 0ac6f40559
commit aa350f7e49
25 changed files with 198 additions and 59 deletions

View File

@@ -33,10 +33,10 @@ export class TelemetryParams {
// ------------------------------- < Security Token Request > ------------------------------------------
export interface RequestSecurityTokenParams {
authority: string;
provider: string;
authority: string;
resource: string;
scope: string;
scopes: string[];
}
export interface RequestSecurityTokenResponse {

View File

@@ -9,7 +9,7 @@ import * as Constants from './constants';
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as path from 'path';
import { getCommonLaunchArgsAndCleanupOldLogFiles, getConfigTracingLevel, getOrDownloadServer, getParallelMessageProcessingConfig, TracingLevel } from './utils';
import { getAzureAuthenticationLibraryConfig, getCommonLaunchArgsAndCleanupOldLogFiles, getConfigTracingLevel, getEnableSqlAuthenticationProviderConfig, getOrDownloadServer, getParallelMessageProcessingConfig, TracingLevel } from './utils';
import { TelemetryReporter, LanguageClientErrorHandler } from './telemetry';
import { SqlOpsDataClient, ClientOptions } from 'dataprotocol-client';
import { TelemetryFeature, AgentServicesFeature, SerializationFeature, AccountFeature, SqlAssessmentServicesFeature, ProfilerFeature, TableDesignerFeature, ExecutionPlanServiceFeature } from './features';
@@ -58,7 +58,7 @@ export class SqlToolsServer {
const serverPath = await this.download(context);
this.installDirectory = path.dirname(serverPath);
const installationComplete = Date.now();
let serverOptions = await generateServerOptions(context.extensionContext.logPath, serverPath);
let serverOptions = generateServerOptions(context.extensionContext.logPath, serverPath);
let clientOptions = getClientOptions(context);
this.client = new SqlOpsDataClient('mssql', Constants.serviceName, serverOptions, clientOptions);
const processStart = Date.now();
@@ -117,12 +117,17 @@ export class SqlToolsServer {
}
}
async function generateServerOptions(logPath: string, executablePath: string): Promise<ServerOptions> {
function generateServerOptions(logPath: string, executablePath: string): ServerOptions {
const launchArgs = getCommonLaunchArgsAndCleanupOldLogFiles(logPath, 'sqltools.log', executablePath);
const enableAsyncMessageProcessing = await getParallelMessageProcessingConfig();
const enableAsyncMessageProcessing = getParallelMessageProcessingConfig();
if (enableAsyncMessageProcessing) {
launchArgs.push('--parallel-message-processing');
}
const enableSqlAuthenticationProvider = getEnableSqlAuthenticationProviderConfig();
const azureAuthLibrary = getAzureAuthenticationLibraryConfig();
if (azureAuthLibrary === 'MSAL' && enableSqlAuthenticationProvider === true) {
launchArgs.push('--enable-sql-authentication-provider');
}
return { command: executablePath, args: launchArgs, transport: TransportKind.stdio };
}

View File

@@ -14,13 +14,17 @@ import { IConfig, ServerProvider } from '@microsoft/ads-service-downloader';
import { env } from 'process';
const configTracingLevel = 'tracingLevel';
const configPiiLogging = 'piiLogging';
const configLogRetentionMinutes = 'logRetentionMinutes';
const configLogFilesRemovalLimit = 'logFilesRemovalLimit';
const extensionConfigSectionName = 'mssql';
const configLogDebugInfo = 'logDebugInfo';
const parallelMessageProcessingConfig = 'parallelMessageProcessing';
const enableSqlAuthenticationProviderConfig = 'enableSqlAuthenticationProvider';
const tableDesignerPreloadConfig = 'tableDesigner.preloadDatabaseModel';
const azureExtensionConfigName = 'azure';
const azureAuthenticationLibraryConfig = 'authenticationLibrary';
/**
*
* @returns Whether the current OS is linux or not
@@ -62,7 +66,17 @@ export function removeOldLogFiles(logPath: string, prefix: string): JSON {
}
export function getConfiguration(config: string = extensionConfigSectionName): vscode.WorkspaceConfiguration {
return vscode.workspace.getConfiguration(extensionConfigSectionName);
return vscode.workspace.getConfiguration(config);
}
/**
* We need Azure core extension configuration for fetching Authentication Library setting in use.
* This is required for 'enableSqlAuthenticationProvider' to be enabled (as it applies to MSAL only).
* This can be removed in future when ADAL support is dropped.
* @param config Azure core extension configuration section name
* @returns Azure core extension config section
*/
export function getAzureCoreExtConfiguration(config: string = azureExtensionConfigName): vscode.WorkspaceConfiguration {
return vscode.workspace.getConfiguration(config);
}
export function getConfigLogFilesRemovalLimit(): number {
@@ -105,6 +119,15 @@ export function getConfigTracingLevel(): TracingLevel {
}
}
export function getConfigPiiLogging(): boolean {
let config = getConfiguration();
if (config) {
return config[configPiiLogging];
} else {
return false;
}
}
export function getConfigPreloadDatabaseModel(): boolean {
let config = getConfiguration();
if (config) {
@@ -121,23 +144,47 @@ export function setConfigPreloadDatabaseModel(enable: boolean): void {
}
}
export async function getParallelMessageProcessingConfig(): Promise<boolean> {
export function getParallelMessageProcessingConfig(): boolean {
const config = getConfiguration();
if (!config) {
return false;
}
const setting = config.inspect(parallelMessageProcessingConfig);
// For dev environment, we want to enable the feature by default unless it is set explicitely.
// Note: the quality property is not set for dev environment, we can use this to determine whether it is dev environment.
return (azdata.env.quality === azdata.env.AppQuality.dev && setting.globalValue === undefined && setting.workspaceValue === undefined) ? true : config[parallelMessageProcessingConfig];
}
export function getAzureAuthenticationLibraryConfig(): string {
const config = getAzureCoreExtConfiguration();
if (config) {
return config.has(azureAuthenticationLibraryConfig)
? config.get<string>(azureAuthenticationLibraryConfig)
: 'MSAL'; // default Auth library
}
else {
return 'MSAL';
}
}
export function getEnableSqlAuthenticationProviderConfig(): boolean {
const config = getConfiguration();
if (config) {
return config.has(enableSqlAuthenticationProviderConfig)
? config.get<boolean>(enableSqlAuthenticationProviderConfig)
: false; // disabled by default
}
else {
return false;
}
}
export function getLogFileName(prefix: string, pid: number): string {
return `${prefix}_${pid}.log`;
}
export function getCommonLaunchArgsAndCleanupOldLogFiles(logPath: string, fileName: string, executablePath: string): string[] {
let launchArgs = [];
// Application Name determines app storage location or user data path.
launchArgs.push('--application-name', 'azuredatastudio');
launchArgs.push(`--locale`, vscode.env.language);
launchArgs.push('--log-file');
@@ -151,6 +198,9 @@ export function getCommonLaunchArgsAndCleanupOldLogFiles(logPath: string, fileNa
console.log(`Old log files deletion report: ${JSON.stringify(deletedLogFiles)}`);
launchArgs.push('--tracing-level');
launchArgs.push(getConfigTracingLevel());
if (getConfigPiiLogging()) {
launchArgs.push('--pii-logging');
}
// Always enable autoflush so that log entries are written immediately to disk, otherwise we can end up with partial logs
launchArgs.push('--autoflush-log');
return launchArgs;