diff --git a/extensions/sql-database-projects/src/common/constants.ts b/extensions/sql-database-projects/src/common/constants.ts index 123b19f4b4..658470b9d9 100644 --- a/extensions/sql-database-projects/src/common/constants.ts +++ b/extensions/sql-database-projects/src/common/constants.ts @@ -77,7 +77,6 @@ export const selectConnectionRadioButtonsTitle = localize('selectconnectionRadio export const dataSourceDropdownTitle = localize('dataSourceDropdownTitle', "Data source"); export const noDataSourcesText = localize('noDataSourcesText', "No data sources in this project"); export const loadProfileButtonText = localize('loadProfileButtonText', "Load Profile..."); -export const profileWarningText = localize('profileWarningText', "⚠ Warning: Connection strings using AAD Authentication are not supported at this time"); export const profileReadError = localize('profileReadError', "Could not load the profile file."); export const sqlCmdTableLabel = localize('sqlCmdTableLabel', "SQLCMD Variables"); export const sqlCmdVariableColumn = localize('sqlCmdVariableColumn', "Variable"); @@ -197,9 +196,16 @@ export const targetConnectionString = 'TargetConnectionString'; export const initialCatalogSetting = 'Initial Catalog'; export const dataSourceSetting = 'Data Source'; export const integratedSecuritySetting = 'Integrated Security'; +export const authenticationSetting = 'Authentication'; +export const activeDirectoryInteractive = 'active directory interactive'; export const userIdSetting = 'User ID'; export const passwordSetting = 'Password'; +// Authentication types +export const integratedAuth = 'Integrated'; +export const azureMfaAuth = 'AzureMFA'; +export const sqlAuth = 'SqlAuth'; + // Tree item types export enum DatabaseProjectItemType { project = 'databaseProject.itemType.project', diff --git a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts index 9eec789798..a0b5ba9b9f 100644 --- a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts +++ b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts @@ -122,7 +122,7 @@ export class PublishDatabaseDialog { title: constants.targetDatabaseSettings, components: [ { - title: constants.profileWarningText, + title: '', component: this.loadProfileButton }, /* TODO : enable using this when data source creation is enabled diff --git a/extensions/sql-database-projects/src/models/dataSources/sqlConnectionStringSource.ts b/extensions/sql-database-projects/src/models/dataSources/sqlConnectionStringSource.ts index 669da9cd36..2c139266a3 100644 --- a/extensions/sql-database-projects/src/models/dataSources/sqlConnectionStringSource.ts +++ b/extensions/sql-database-projects/src/models/dataSources/sqlConnectionStringSource.ts @@ -35,7 +35,21 @@ export class SqlConnectionDataSource extends DataSource { } public get integratedSecurity(): boolean { - return this.getSetting(constants.integratedSecuritySetting).toLowerCase() === 'true'; + return this.getSetting(constants.integratedSecuritySetting)?.toLowerCase() === 'true'; + } + + public get azureMFA(): boolean { + return this.getSetting(constants.authenticationSetting)?.toLowerCase().includes(constants.activeDirectoryInteractive); + } + + public get authType(): string { + if (this.azureMFA) { + return constants.azureMfaAuth; + } else if (this.integratedSecurity) { + return constants.integratedAuth; + } else { + return constants.sqlAuth; + } } public get username(): string { @@ -79,7 +93,7 @@ export class SqlConnectionDataSource extends DataSource { connectionName: this.name, userName: this.username, password: this.password, - authenticationType: this.integratedSecurity ? 'Integrated' : 'SqlAuth', + authenticationType: this.authType, savePassword: false, providerName: 'MSSQL', saveProfile: true, diff --git a/extensions/sql-database-projects/src/test/baselines/openDataSourcesBaseline.json b/extensions/sql-database-projects/src/test/baselines/openDataSourcesBaseline.json index 21d0f34f10..96c925f4f1 100644 --- a/extensions/sql-database-projects/src/test/baselines/openDataSourcesBaseline.json +++ b/extensions/sql-database-projects/src/test/baselines/openDataSourcesBaseline.json @@ -16,6 +16,14 @@ "data": { "connectionString": "Data Source=.;Initial Catalog=testDb2;Integrated Security=False" } + }, + { + "name": "AAD Interactive Data Source", + "type": "sql_connection_string", + "version": "0.0.0", + "data": { + "connectionString": "Data Source=.;Initial Catalog=testDb3;Authentication='Active Directory Interactive'" + } } ] } diff --git a/extensions/sql-database-projects/src/test/datasource.test.ts b/extensions/sql-database-projects/src/test/datasource.test.ts index f666ddc413..8aac591ba4 100644 --- a/extensions/sql-database-projects/src/test/datasource.test.ts +++ b/extensions/sql-database-projects/src/test/datasource.test.ts @@ -18,7 +18,7 @@ describe.skip('Data Sources: DataSource operations', function (): void { const dataSourcePath = await testUtils.createTestDataSources(baselines.openDataSourcesBaseline); const dataSourceList = await dataSources.load(dataSourcePath); - should(dataSourceList.length).equal(2); + should(dataSourceList.length).equal(3); should(dataSourceList[0].name).equal('Test Data Source 1'); should(dataSourceList[0].type).equal(sql.SqlConnectionDataSource.type); @@ -26,5 +26,9 @@ describe.skip('Data Sources: DataSource operations', function (): void { should(dataSourceList[1].name).equal('My Other Data Source'); should((dataSourceList[1] as sql.SqlConnectionDataSource).integratedSecurity).equal(false); + + should(dataSourceList[2].name).equal('AAD Interactive Data Source'); + should((dataSourceList[2] as sql.SqlConnectionDataSource).integratedSecurity).equal(false); + should((dataSourceList[2] as sql.SqlConnectionDataSource).azureMFA).equal(true); }); }); diff --git a/extensions/sql-database-projects/src/test/projectController.test.ts b/extensions/sql-database-projects/src/test/projectController.test.ts index 42738256e1..6c3d3ba76c 100644 --- a/extensions/sql-database-projects/src/test/projectController.test.ts +++ b/extensions/sql-database-projects/src/test/projectController.test.ts @@ -84,7 +84,7 @@ describe('ProjectsController', function (): void { const project = await projController.openProject(vscode.Uri.file(sqlProjPath)); should(project.files.length).equal(9); // detailed sqlproj tests in their own test file - should(project.dataSources.length).equal(2); // detailed datasources tests in their own test file + should(project.dataSources.length).equal(3); // detailed datasources tests in their own test file }); it('Should load both project and referenced project', async function (): Promise {