Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions extensions/mssql/l10n/bundle.l10n.json
Original file line number Diff line number Diff line change
Expand Up @@ -1783,6 +1783,7 @@
"Integrated": "Integrated",
"SQL Login": "SQL Login",
"Microsoft Entra Id - Universal w/ MFA Support": "Microsoft Entra Id - Universal w/ MFA Support",
"Microsoft Entra Id - Default": "Microsoft Entra Id - Default",
"Azure Code Grant": "Azure Code Grant",
"Azure Device Code": "Azure Device Code",
"MSSQL - Azure Auth Logs": "MSSQL - Azure Auth Logs",
Expand Down Expand Up @@ -2187,8 +2188,8 @@
"Clear cache and refresh token": "Clear cache and refresh token",
"Clear token cache": "Clear token cache",
"No workspaces found. Please change Fabric account or tenant to view available workspaces.": "No workspaces found. Please change Fabric account or tenant to view available workspaces.",
"Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, and Azure MFA authentication are supported./{0} is the authentication type": {
"message": "Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, and Azure MFA authentication are supported.",
"Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, Azure MFA, and Active Directory Default authentication are supported./{0} is the authentication type": {
"message": "Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, Azure MFA, and Active Directory Default authentication are supported.",
"comment": ["{0} is the authentication type"]
},
"Add Firewall Rule to {0}/{0} is the server name": {
Expand Down
2 changes: 1 addition & 1 deletion extensions/mssql/src/configurations/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const config = {
dotnetRuntimeVersion: "10.0",
downloadUrl:
"https://github.com/Microsoft/sqltoolsservice/releases/download/{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
version: "6.0.20260403.1",
version: "6.0.20260406.1",
downloadFileNames: {
Windows_64: "win-x64-net10.0.zip",
Windows_ARM64: "win-arm64-net10.0.zip",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ export class ConnectionDialogWebviewController extends FormWebviewController<
AuthenticationType.SqlLogin,
AuthenticationType.Integrated,
AuthenticationType.AzureMFA,
AuthenticationType.ActiveDirectoryDefault,
];

if (
Expand Down Expand Up @@ -925,9 +926,24 @@ export class ConnectionDialogWebviewController extends FormWebviewController<
async updateItemVisibility() {
let hiddenProperties: (keyof IConnectionDialogProfile)[] = [];

if (
this.state.connectionProfile.authenticationType !== AuthenticationType.SqlLogin &&
this.state.connectionProfile.authenticationType !==
AuthenticationType.ActiveDirectoryDefault
) {
hiddenProperties.push("user");
}
if (this.state.connectionProfile.authenticationType !== AuthenticationType.SqlLogin) {
hiddenProperties.push("user", "password", "savePassword");
hiddenProperties.push("password", "savePassword");
}

const userComponent = this.state.formComponents["user"];
if (userComponent) {
// userId is required for SQL Login, optional for AD Default, and hidden (above) for everything else
userComponent.required =
this.state.connectionProfile.authenticationType === AuthenticationType.SqlLogin;
}

if (this.state.connectionProfile.authenticationType !== AuthenticationType.AzureMFA) {
hiddenProperties.push("accountId", "tenantId");
}
Expand Down
3 changes: 2 additions & 1 deletion extensions/mssql/src/constants/locConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ export let authTypeName = l10n.t("authenticationType");
export let authTypeIntegrated = l10n.t("Integrated");
export let authTypeSql = l10n.t("SQL Login");
export let authTypeAzureActiveDirectory = l10n.t("Microsoft Entra Id - Universal w/ MFA Support");
export let authTypeAzureActiveDirectoryDefault = l10n.t("Microsoft Entra Id - Default");
export let azureAuthTypeCodeGrant = l10n.t("Azure Code Grant");
export let azureAuthTypeDeviceCode = l10n.t("Azure Device Code");
export let azureLogChannelName = l10n.t("MSSQL - Azure Auth Logs");
Expand Down Expand Up @@ -902,7 +903,7 @@ export class ConnectionDialog {
public static unsupportedAuthType(authenticationType: string) {
return l10n.t({
message:
"Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, and Azure MFA authentication are supported.",
"Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, Azure MFA, and Active Directory Default authentication are supported.",
args: [authenticationType],
comment: ["{0} is the authentication type"],
});
Expand Down
4 changes: 4 additions & 0 deletions extensions/mssql/src/models/connectionCredentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ export class ConnectionCredentials implements IConnectionInfo {
name: LocalizedConstants.authTypeAzureActiveDirectory,
value: utils.authTypeToString(AuthenticationTypes.AzureMFA),
},
{
name: LocalizedConstants.authTypeAzureActiveDirectoryDefault,
value: utils.authTypeToString(AuthenticationTypes.ActiveDirectoryDefault),
},
];

return choices;
Expand Down
4 changes: 3 additions & 1 deletion extensions/mssql/src/models/connectionProfile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ export class ConnectionProfile extends ConnectionCredentials implements IConnect
if (this.authenticationType) {
if (
this.authenticationType === AuthenticationTypes[AuthenticationTypes.Integrated] ||
this.authenticationType === AuthenticationTypes[AuthenticationTypes.AzureMFA]
this.authenticationType === AuthenticationTypes[AuthenticationTypes.AzureMFA] ||
this.authenticationType ===
AuthenticationTypes[AuthenticationTypes.ActiveDirectoryDefault]
) {
return utils.isNotEmpty(this.server);
} else {
Expand Down
1 change: 1 addition & 0 deletions extensions/mssql/src/models/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export enum AuthenticationTypes {
Integrated = 1,
SqlLogin = 2,
AzureMFA = 3,
ActiveDirectoryDefault = 4,
}

export enum EncryptOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ export class ObjectExplorerService {
);
if (choice === LocalizedConstants.ObjectExplorer.FailedOEConnectionErrorSignIn) {
try {
await VsCodeAzureHelper.signIn(); // User chose to sign in to the missing account; try again.
await VsCodeAzureHelper.signIn(true); // User chose to sign in to the missing account; try again.
return await prepareConnectionProfile();
} catch (retryError) {
this._logger.error(
Expand Down
4 changes: 4 additions & 0 deletions extensions/mssql/src/sharedInterfaces/connectionDialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ export enum AuthenticationType {
* Microsoft Entra Id - Universal with MFA support
*/
AzureMFA = "AzureMFA",
/**
* Microsoft Entra Id - Default
*/
ActiveDirectoryDefault = "ActiveDirectoryDefault",
/**
* Microsoft Entra Id - Password
*/
Expand Down
15 changes: 15 additions & 0 deletions extensions/mssql/test/unit/connectionCredentials.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,20 @@ suite("ConnectionCredentials Tests", () => {
).to.equal(originalConnInfo[key as keyof IConnectionInfo]);
}
});

test("createConnectionInfo preserves ActiveDirectoryDefault auth type", () => {
const connDetails: ConnectionDetails = {
options: {
server: "someServer",
authenticationType:
AuthenticationTypes[AuthenticationTypes.ActiveDirectoryDefault],
},
};

const connInfo = ConnectionCredentials.createConnectionInfo(connDetails);
expect(connInfo.authenticationType).to.equal(
AuthenticationTypes[AuthenticationTypes.ActiveDirectoryDefault],
);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,19 @@ suite("ConnectionDialogWebviewController Tests", () => {
expect(controller.state.isEditingConnection).to.be.true;
expect(controller.state.editingConnectionDisplayName).to.not.be.undefined;
});

test("should show optional user and hide password fields for ActiveDirectoryDefault", async () => {
controller.state.connectionProfile.authenticationType =
AuthenticationType.ActiveDirectoryDefault;

await controller.updateItemVisibility();

expect(controller.state.formComponents.user.hidden).to.not.be.true;
expect(controller.state.formComponents.password.hidden).to.be.true;
expect(controller.state.formComponents.savePassword.hidden).to.be.true;
expect(controller.state.formComponents.accountId.hidden).to.be.true;
expect(controller.state.formComponents.tenantId.hidden).to.be.true;
});
});

suite("Reducers", () => {
Expand Down Expand Up @@ -920,6 +933,25 @@ suite("ConnectionDialogWebviewController Tests", () => {
expect(controller.state.dialog, "dialog should be closed").to.be.undefined;
});

test("should load connection details from connection string with ActiveDirectoryDefault", async () => {
const parsedDetails = {
options: {
server: "myServer",
database: "myDB",
authenticationType: AuthenticationType.ActiveDirectoryDefault,
},
} as ConnectionDetails;

await runConnectionStringScenario(parsedDetails);

expect(controller.state.connectionProfile.server).to.equal("myServer");
expect(controller.state.connectionProfile.database).to.equal("myDB");
expect(controller.state.connectionProfile.authenticationType).to.equal(
AuthenticationType.ActiveDirectoryDefault,
);
expect(controller.state.dialog, "dialog should be closed").to.be.undefined;
});

test("should display error message if connection string has unsupported authentication type", async () => {
const parsedDetails = {
options: {
Expand Down
10 changes: 10 additions & 0 deletions extensions/mssql/test/unit/connectionProfile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import * as sinon from "sinon";
import { IConnectionInfo } from "vscode-mssql";
import { ConnectionCredentials } from "../../src/models/connectionCredentials";
import { ConnectionProfile } from "../../src/models/connectionProfile";
import { AuthenticationTypes } from "../../src/models/interfaces";
import { expect } from "chai";

Expand Down Expand Up @@ -115,4 +116,13 @@ suite("Connection Profile tests", () => {
expect(details.options["user"]).to.not.be.undefined;
expect(details.options["workstationId"]).to.not.be.undefined;
});

test("ActiveDirectoryDefault profile only requires server", () => {
const profile = new ConnectionProfile();
profile.server = "my-server";
profile.authenticationType =
AuthenticationTypes[AuthenticationTypes.ActiveDirectoryDefault];

expect(profile.isValidProfile()).to.be.true;
});
});
1 change: 1 addition & 0 deletions extensions/mssql/test/unit/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export function buildCapabilitiesResult(): CapabilitiesResult {
AuthenticationType.SqlLogin,
AuthenticationType.Integrated,
AuthenticationType.AzureMFA,
AuthenticationType.ActiveDirectoryDefault,
],
},
{
Expand Down
7 changes: 5 additions & 2 deletions localization/xliff/vscode-mssql.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -3807,6 +3807,9 @@
<trans-unit id="++CODE++4cca27a3569729f8e3fa178db33f438eaa136c7491a5c3d26c807c876a02c292">
<source xml:lang="en">Microsoft Entra Id</source>
</trans-unit>
<trans-unit id="++CODE++585389836e18976b372ada3cfd7a57608ccff88fc27ade1458fd968b3c089ff5">
<source xml:lang="en">Microsoft Entra Id - Default</source>
</trans-unit>
<trans-unit id="++CODE++d24b24ff2640e9b5731d40ac97ea534034176c1478b681eca122262c4d98a8a2">
<source xml:lang="en">Microsoft Entra Id - Universal w/ MFA Support</source>
</trans-unit>
Expand Down Expand Up @@ -6415,8 +6418,8 @@
<source xml:lang="en">Unsupported architecture for Docker: {0}</source>
<note>{0} is the architecture name of the machine</note>
</trans-unit>
<trans-unit id="++CODE++0fca84e49ac02af373521c99fb0ff436c7908bd09697d4ff09b570441e3d81d5">
<source xml:lang="en">Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, and Azure MFA authentication are supported.</source>
<trans-unit id="++CODE++3bd96350b569900406d2b6fcd6d41c1083c5dec9bd6052587c0a4657f831fe33">
<source xml:lang="en">Unsupported authentication type in connection string: {0}. Only SQL Login, Integrated, Azure MFA, and Active Directory Default authentication are supported.</source>
<note>{0} is the authentication type</note>
</trans-unit>
<trans-unit id="++CODE++59925dabae7544939136767d732ce4bd853e6a3822324777eb3615b997680c05">
Expand Down
Loading