Update Microsoft.Data.SqlClient to v5.0.1 (#1708)

This commit is contained in:
Cheena Malhotra
2022-10-24 20:10:04 -07:00
committed by GitHub
parent 3be806ddce
commit c0f8482e26
30 changed files with 416 additions and 313 deletions

View File

@@ -6,8 +6,8 @@
<PackageReference Update="System.IO.Packaging" Version="4.7.0" /> <PackageReference Update="System.IO.Packaging" Version="4.7.0" />
<PackageReference Update="System.Runtime.Loader" Version="4.3.0" /> <PackageReference Update="System.Runtime.Loader" Version="4.3.0" />
<PackageReference Update="System.Composition" Version="1.4.1" /> <PackageReference Update="System.Composition" Version="1.4.1" />
<PackageReference Update="System.Security.Permissions" Version="4.7.0" /> <PackageReference Update="System.Security.Permissions" Version="5.0.0" />
<PackageReference Update="System.Text.Encoding.CodePages" Version="4.7.1" /> <PackageReference Update="System.Text.Encoding.CodePages" Version="5.0.0" />
<PackageReference Update="System.Text.Encodings.Web" Version="4.7.2" /> <PackageReference Update="System.Text.Encodings.Web" Version="4.7.2" />
<PackageReference Update="System.Reactive.Core" Version="5.0.0" /> <PackageReference Update="System.Reactive.Core" Version="5.0.0" />
@@ -19,14 +19,14 @@
<PackageReference Update="Microsoft.Azure.Management.Sql" Version="1.41.0-preview" /> <PackageReference Update="Microsoft.Azure.Management.Sql" Version="1.41.0-preview" />
<PackageReference Update="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="1.1.1" /> <PackageReference Update="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" Version="1.1.1" />
<PackageReference Update="Microsoft.Data.SqlClient" Version="3.1.1" /> <PackageReference Update="Microsoft.Data.SqlClient" Version="5.0.1" />
<PackageReference Update="Microsoft.SqlServer.SqlManagementObjects" Version="161.47021.0" /> <PackageReference Update="Microsoft.SqlServer.SqlManagementObjects" Version="170.8.0" />
<PackageReference Update="Microsoft.SqlServer.Management.SmoMetadataProvider" Version="161.47008.0" /> <PackageReference Update="Microsoft.SqlServer.Management.SmoMetadataProvider" Version="170.8.0" />
<PackageReference Update="Microsoft.SqlServer.DACFx" Version="160.6295.0-preview" /> <PackageReference Update="Microsoft.SqlServer.DacFx" Version="161.6337.0-preview" />
<PackageReference Update="Microsoft.Azure.Kusto.Data" Version="9.0.4" /> <PackageReference Update="Microsoft.Azure.Kusto.Data" Version="9.0.4" />
<PackageReference Update="Microsoft.Azure.Kusto.Language" Version="9.0.4" /> <PackageReference Update="Microsoft.Azure.Kusto.Language" Version="9.0.4" />
<PackageReference Update="Microsoft.SqlServer.Assessment" Version="[1.1.9]" /> <PackageReference Update="Microsoft.SqlServer.Assessment" Version="[1.1.9]" />
<PackageReference Update="Microsoft.SqlServer.Migration.Assessment" Version="1.0.20220816.40" /> <PackageReference Update="Microsoft.SqlServer.Migration.Assessment" Version="1.0.20221014.16" />
<PackageReference Update="Microsoft.SqlServer.Management.SqlParser" Version="160.22519.0" /> <PackageReference Update="Microsoft.SqlServer.Management.SqlParser" Version="160.22519.0" />
<PackageReference Update="Microsoft.Azure.OperationalInsights" Version="1.0.0" /> <PackageReference Update="Microsoft.Azure.OperationalInsights" Version="1.0.0" />
<PackageReference Update="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" /> <PackageReference Update="Microsoft.CodeAnalysis.CSharp" Version="3.10.0" />

View File

@@ -91,14 +91,6 @@ namespace Microsoft.Kusto.ServiceLayer.Connection
GroupName = "Initialization" GroupName = "Initialization"
}, },
new ConnectionOption new ConnectionOption
{
Name = "asynchronousProcessing",
DisplayName = "Asynchronous processing enabled",
Description = "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Initialization"
},
new ConnectionOption
{ {
Name = "connectTimeout", Name = "connectTimeout",
DisplayName = "Connect timeout", DisplayName = "Connect timeout",

View File

@@ -31,8 +31,9 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Azure.OperationalInsights" /> <PackageReference Include="Microsoft.Azure.OperationalInsights" />
<PackageReference Include="Microsoft.SqlServer.DACFx" /> <PackageReference Include="Microsoft.SqlServer.DacFx" />
<PackageReference Include="Microsoft.SqlServer.Management.SmoMetadataProvider" /> <PackageReference Include="Microsoft.SqlServer.Management.SmoMetadataProvider" />
<PackageReference Include="Microsoft.SqlServer.SqlManagementObjects" />
<PackageReference Include="System.Text.Encoding.CodePages" /> <PackageReference Include="System.Text.Encoding.CodePages" />
<PackageReference Include="Microsoft.Azure.Kusto.Data" /> <PackageReference Include="Microsoft.Azure.Kusto.Data" />
<PackageReference Include="System.Net.Http" /> <PackageReference Include="System.Net.Http" />

View File

@@ -155,12 +155,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode
} }
} }
if (fullFileName == null) return fullFileName ?? Path.GetFullPath(fileName);
{
fullFileName = Path.GetFullPath(fileName);
}
return fullFileName;
} }
catch (ArgumentException) catch (ArgumentException)
{ {

View File

@@ -128,15 +128,7 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser.ExecutionEngineCode
internal Dictionary<string, string> Variables internal Dictionary<string, string> Variables
{ {
get get => cmdVariables ??= new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
{
if (cmdVariables == null)
{
cmdVariables = new Dictionary<string, string>(StringComparer.CurrentCultureIgnoreCase);
}
return cmdVariables;
}
} }
#endregion #endregion
} }

View File

@@ -608,18 +608,10 @@ namespace Microsoft.SqlTools.ServiceLayer.BatchParser
} }
internal void RaiseError(ErrorCode errorCode, string message = null) internal void RaiseError(ErrorCode errorCode, string message = null)
{ => RaiseError(errorCode, LookaheadToken, message);
RaiseError(errorCode, LookaheadToken, message);
}
internal static void RaiseError(ErrorCode errorCode, Token token, string message = null) internal static void RaiseError(ErrorCode errorCode, Token token, string message = null)
{ => throw new BatchParserException(errorCode, token, message ?? string.Format(CultureInfo.CurrentCulture, SR.BatchParser_IncorrectSyntax, token.Text));
if (message == null)
{
message = string.Format(CultureInfo.CurrentCulture, SR.BatchParser_IncorrectSyntax, token.Text);
}
throw new BatchParserException(errorCode, token, message);
}
internal string ResolveVariables(Token inputToken, int offset, List<VariableReference> variableRefs) internal string ResolveVariables(Token inputToken, int offset, List<VariableReference> variableRefs)
{ {

View File

@@ -1,7 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<!-- Targeting netstandard2.0 so that other things such as PS cmdlets can use this which need to support a wider range of machines --> <!-- Targeting both net6.0 and net472 so that other things such as PS cmdlets can use this which need to support a wider range of machines -->
<TargetFramework>netstandard2.0</TargetFramework> <TargetFrameworks>net6.0;net472</TargetFrameworks>
<LangVersion>9.0</LangVersion>
<Nullable>disable</Nullable> <Nullable>disable</Nullable>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> <EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems>

View File

@@ -276,10 +276,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
Debug.Assert(conn.State == ConnectionState.Open, "connection passed to ExecuteNonQuery should be open."); Debug.Assert(conn.State == ConnectionState.Open, "connection passed to ExecuteNonQuery should be open.");
cmd = conn.CreateCommand(); cmd = conn.CreateCommand();
if (initializeCommand == null)
{ initializeCommand ??= SetCommandTimeout;
initializeCommand = SetCommandTimeout;
}
initializeCommand(cmd); initializeCommand(cmd);
cmd.CommandText = commandText; cmd.CommandText = commandText;
@@ -331,10 +329,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
Debug.Assert(conn.State == ConnectionState.Open, "connection passed to ExecuteScalar should be open."); Debug.Assert(conn.State == ConnectionState.Open, "connection passed to ExecuteScalar should be open.");
cmd = conn.CreateCommand(); cmd = conn.CreateCommand();
if (initializeCommand == null)
{ initializeCommand ??= SetCommandTimeout;
initializeCommand = SetCommandTimeout;
}
initializeCommand(cmd); initializeCommand(cmd);
cmd.CommandText = commandText; cmd.CommandText = commandText;
@@ -384,11 +380,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection
{ {
cmd = conn.CreateCommand(); cmd = conn.CreateCommand();
if (initializeCommand == null) initializeCommand ??= SetCommandTimeout;
{
initializeCommand = SetCommandTimeout;
}
initializeCommand(cmd); initializeCommand(cmd);
cmd.CommandText = commandText; cmd.CommandText = commandText;

View File

@@ -478,10 +478,7 @@ SET NUMERIC_ROUNDABORT OFF;";
{ {
// Verify whether or not the connection is valid and is open. This code may be retried therefore // Verify whether or not the connection is valid and is open. This code may be retried therefore
// it is important to ensure that a connection is re-established should it have previously failed. // it is important to ensure that a connection is re-established should it have previously failed.
if (command.Connection == null) command.Connection ??= this;
{
command.Connection = this;
}
if (command.Connection.State != ConnectionState.Open) if (command.Connection.State != ConnectionState.Open)
{ {

View File

@@ -91,14 +91,6 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
GroupName = "Initialization" GroupName = "Initialization"
}, },
new ConnectionOption new ConnectionOption
{
Name = "asynchronousProcessing",
DisplayName = "Asynchronous processing enabled",
Description = "When true, enables usage of the Asynchronous functionality in the .Net Framework Data Provider",
ValueType = ConnectionOption.ValueTypeBoolean,
GroupName = "Initialization"
},
new ConnectionOption
{ {
Name = "connectTimeout", Name = "connectTimeout",
DisplayName = "Connect timeout", DisplayName = "Connect timeout",
@@ -152,10 +144,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
{ {
Name = "encrypt", Name = "encrypt",
DisplayName = "Encrypt", DisplayName = "Encrypt",
Description = Description = "When set, SQL Server uses provided setting for SSL encryption for all data sent between the client and server.",
"When true, SQL Server uses SSL encryption for all data sent between the client and server if the servers has a certificate installed", ValueType = ConnectionOption.ValueTypeCategory,
GroupName = "Security", GroupName = "Security",
ValueType = ConnectionOption.ValueTypeBoolean CategoryValues = new CategoryValue[] {
new CategoryValue { DisplayName = "Optional", Name = "Optional" },
new CategoryValue { DisplayName = "Mandatory", Name = "Mandatory" },
new CategoryValue { DisplayName = "Strict", Name = "Strict" }
}
}, },
new ConnectionOption new ConnectionOption
{ {
@@ -174,6 +170,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
ValueType = ConnectionOption.ValueTypeBoolean ValueType = ConnectionOption.ValueTypeBoolean
}, },
new ConnectionOption new ConnectionOption
{
Name = "hostNameInCertificate",
DisplayName = "HostNameInCertificate",
Description = "Specifies host name in certificate to be used for certificate validation, when encryption is enabled.",
GroupName = "Security",
ValueType = ConnectionOption.ValueTypeString,
},
new ConnectionOption
{ {
Name = "attachedDBFileName", Name = "attachedDBFileName",
DisplayName = "Attached DB file name", DisplayName = "Attached DB file name",

View File

@@ -410,7 +410,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
if (response?.ErrorNumber == 40613) if (response?.ErrorNumber == 40613)
{ {
counter++; counter++;
if(counter != MaxServerlessReconnectTries) { if (counter != MaxServerlessReconnectTries)
{
Logger.Information($"Database for connection {connectionInfo.OwnerUri} is paused, retrying connection. Attempt #{counter}"); Logger.Information($"Database for connection {connectionInfo.OwnerUri} is paused, retrying connection. Attempt #{counter}");
} }
} }
@@ -1299,14 +1300,26 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
connectionBuilder.EnclaveAttestationUrl = connectionDetails.EnclaveAttestationUrl; connectionBuilder.EnclaveAttestationUrl = connectionDetails.EnclaveAttestationUrl;
} }
if (connectionDetails.Encrypt.HasValue)
if (!string.IsNullOrEmpty(connectionDetails.Encrypt))
{ {
connectionBuilder.Encrypt = connectionDetails.Encrypt.Value; connectionBuilder.Encrypt = connectionDetails.Encrypt.ToLowerInvariant() switch
{
"optional" or "false" or "no" => SqlConnectionEncryptOption.Optional,
"mandatory" or "true" or "yes" => SqlConnectionEncryptOption.Mandatory,
"strict" => SqlConnectionEncryptOption.Strict,
_ => throw new ArgumentException(SR.ConnectionServiceConnStringInvalidEncryptOption(connectionDetails.Encrypt))
};
} }
if (connectionDetails.TrustServerCertificate.HasValue) if (connectionDetails.TrustServerCertificate.HasValue)
{ {
connectionBuilder.TrustServerCertificate = connectionDetails.TrustServerCertificate.Value; connectionBuilder.TrustServerCertificate = connectionDetails.TrustServerCertificate.Value;
} }
if (!string.IsNullOrEmpty(connectionDetails.HostNameInCertificate))
{
connectionBuilder.HostNameInCertificate = connectionDetails.HostNameInCertificate;
}
if (connectionDetails.PersistSecurityInfo.HasValue) if (connectionDetails.PersistSecurityInfo.HasValue)
{ {
connectionBuilder.PersistSecurityInfo = connectionDetails.PersistSecurityInfo.Value; connectionBuilder.PersistSecurityInfo = connectionDetails.PersistSecurityInfo.Value;
@@ -1471,8 +1484,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
ColumnEncryptionSetting = builder.ColumnEncryptionSetting.ToString(), ColumnEncryptionSetting = builder.ColumnEncryptionSetting.ToString(),
EnclaveAttestationProtocol = builder.AttestationProtocol == SqlConnectionAttestationProtocol.NotSpecified ? null : builder.AttestationProtocol.ToString(), EnclaveAttestationProtocol = builder.AttestationProtocol == SqlConnectionAttestationProtocol.NotSpecified ? null : builder.AttestationProtocol.ToString(),
EnclaveAttestationUrl = builder.EnclaveAttestationUrl, EnclaveAttestationUrl = builder.EnclaveAttestationUrl,
Encrypt = builder.Encrypt, Encrypt = builder.Encrypt.ToString(),
FailoverPartner = builder.FailoverPartner, FailoverPartner = builder.FailoverPartner,
HostNameInCertificate = builder.HostNameInCertificate,
LoadBalanceTimeout = builder.LoadBalanceTimeout, LoadBalanceTimeout = builder.LoadBalanceTimeout,
MaxPoolSize = builder.MaxPoolSize, MaxPoolSize = builder.MaxPoolSize,
MinPoolSize = builder.MinPoolSize, MinPoolSize = builder.MinPoolSize,

View File

@@ -147,13 +147,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
} }
/// <summary> /// <summary>
/// Gets or sets a Boolean value that indicates whether SQL Server uses SSL encryption for all data sent between the client and server if the server has a certificate installed. /// Gets or sets a <see cref="string"/> value that indicates encryption mode that SQL Server should use to perform SSL encryption for all the data sent between the client and server. Supported values are: Optional, Mandatory, Strict.
/// </summary> /// </summary>
public bool? Encrypt public string Encrypt
{ {
get get
{ {
return GetOptionValue<bool?>("encrypt"); return GetOptionValue<string>("encrypt");
} }
set set
@@ -178,6 +178,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
} }
} }
/// <summary>
/// Gets or sets a value that indicates the host name in the certificate to be used for certificate validation when encryption is enabled.
/// </summary>
public string HostNameInCertificate
{
get
{
return GetOptionValue<string>("hostNameInCertificate");
}
set
{
SetOptionValue("hostNameInCertificate", value);
}
}
/// <summary> /// <summary>
/// Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state. /// Gets or sets a Boolean value that indicates if security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state.
/// </summary> /// </summary>

View File

@@ -27,6 +27,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection.Contracts
EnclaveAttestationUrl = details.EnclaveAttestationUrl, EnclaveAttestationUrl = details.EnclaveAttestationUrl,
Encrypt = details.Encrypt, Encrypt = details.Encrypt,
TrustServerCertificate = details.TrustServerCertificate, TrustServerCertificate = details.TrustServerCertificate,
HostNameInCertificate = details.HostNameInCertificate,
PersistSecurityInfo = details.PersistSecurityInfo, PersistSecurityInfo = details.PersistSecurityInfo,
ConnectTimeout = details.ConnectTimeout, ConnectTimeout = details.ConnectTimeout,
ConnectRetryCount = details.ConnectRetryCount, ConnectRetryCount = details.ConnectRetryCount,

View File

@@ -9641,6 +9641,11 @@ namespace Microsoft.SqlTools.ServiceLayer
return Keys.GetString(Keys.ConnectionServiceConnStringInvalidColumnEncryptionSetting, columnEncryptionSetting); return Keys.GetString(Keys.ConnectionServiceConnStringInvalidColumnEncryptionSetting, columnEncryptionSetting);
} }
public static string ConnectionServiceConnStringInvalidEncryptOption(string encrypt)
{
return Keys.GetString(Keys.ConnectionServiceConnStringInvalidEncryptOption, encrypt);
}
public static string ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(string enclaveAttestationProtocol) public static string ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(string enclaveAttestationProtocol)
{ {
return Keys.GetString(Keys.ConnectionServiceConnStringInvalidEnclaveAttestationProtocol, enclaveAttestationProtocol); return Keys.GetString(Keys.ConnectionServiceConnStringInvalidEnclaveAttestationProtocol, enclaveAttestationProtocol);
@@ -10062,6 +10067,9 @@ namespace Microsoft.SqlTools.ServiceLayer
public const string ConnectionServiceConnStringInvalidColumnEncryptionSetting = "ConnectionServiceConnStringInvalidColumnEncryptionSetting"; public const string ConnectionServiceConnStringInvalidColumnEncryptionSetting = "ConnectionServiceConnStringInvalidColumnEncryptionSetting";
public const string ConnectionServiceConnStringInvalidEncryptOption = "ConnectionServiceConnStringInvalidEncryptOption";
public const string ConnectionServiceConnStringInvalidEnclaveAttestationProtocol = "ConnectionServiceConnStringInvalidEnclaveAttestationProtocol"; public const string ConnectionServiceConnStringInvalidEnclaveAttestationProtocol = "ConnectionServiceConnStringInvalidEnclaveAttestationProtocol";

View File

@@ -144,6 +144,11 @@
<value>Invalid value &apos;{0}&apos; for ComlumEncryption. Valid values are &apos;Enabled&apos; and &apos;Disabled&apos;.</value> <value>Invalid value &apos;{0}&apos; for ComlumEncryption. Valid values are &apos;Enabled&apos; and &apos;Disabled&apos;.</value>
<comment>. <comment>.
Parameters: 0 - columnEncryptionSetting (string) </comment> Parameters: 0 - columnEncryptionSetting (string) </comment>
</data>
<data name="ConnectionServiceConnStringInvalidEncryptOption" xml:space="preserve">
<value>Invalid value &apos;{0}&apos; for Encrypt. Valid values are &apos;Optional&apos;, &apos;Mandatory&apos;, &apos;Strict&apos;, &apos;True&apos;, &apos;False&apos;, &apos;Yes&apos; and &apos;No&apos;.</value>
<comment>.
Parameters: 0 - encrypt (string) </comment>
</data> </data>
<data name="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol" xml:space="preserve"> <data name="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol" xml:space="preserve">
<value>Invalid value &apos;{0}&apos; for EnclaveAttestationProtocol. Valid values are &apos;AAS&apos; and &apos;HGS&apos;.</value> <value>Invalid value &apos;{0}&apos; for EnclaveAttestationProtocol. Valid values are &apos;AAS&apos; and &apos;HGS&apos;.</value>

View File

@@ -35,6 +35,8 @@ ConnectionServiceConnStringInvalidAuthType(string authType) = Invalid value '{0}
ConnectionServiceConnStringInvalidColumnEncryptionSetting(string columnEncryptionSetting) = Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'. ConnectionServiceConnStringInvalidColumnEncryptionSetting(string columnEncryptionSetting) = Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.
ConnectionServiceConnStringInvalidEncryptOption(string encrypt) = Invalid value '{0}' for Encrypt. Valid values are 'Optional', 'Mandatory', 'Strict', 'True', 'False', 'Yes' and 'No'.
ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(string enclaveAttestationProtocol) = Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'. ConnectionServiceConnStringInvalidEnclaveAttestationProtocol(string enclaveAttestationProtocol) = Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.
ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination = The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled. ConnectionServiceConnStringInvalidAlwaysEncryptedOptionCombination = The Attestation Protocol and Enclave Attestation URL requires Always Encrypted to be set to Enabled.

View File

@@ -2034,6 +2034,12 @@
<target state="new">Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</target> <target state="new">Invalid value '{0}' for ComlumEncryption. Valid values are 'Enabled' and 'Disabled'.</target>
<note>. <note>.
Parameters: 0 - columnEncryptionSetting (string) </note> Parameters: 0 - columnEncryptionSetting (string) </note>
</trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEncryptOption">
<source>Invalid value '{0}' for Encrypt. Valid values are 'Optional', 'Mandatory', 'Strict', 'True', 'False', 'Yes' and 'No'.</source>
<target state="new">Invalid value '{0}' for Encrypt. Valid values are 'Optional', 'Mandatory', 'Strict', 'True', 'False', 'Yes' and 'No'.</target>
<note>.
Parameters: 0 - encrypt (string) </note>
</trans-unit> </trans-unit>
<trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol"> <trans-unit id="ConnectionServiceConnStringInvalidEnclaveAttestationProtocol">
<source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source> <source>Invalid value '{0}' for EnclaveAttestationProtocol. Valid values are 'AAS' and 'HGS'.</source>

View File

@@ -49,11 +49,12 @@
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" /> <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" /> <PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" />
<PackageReference Include="Microsoft.SqlServer.DACFx" /> <PackageReference Include="Microsoft.SqlServer.DacFx" />
<PackageReference Include="Microsoft.Data.SqlClient" />
<PackageReference Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" /> <PackageReference Include="Microsoft.Data.SqlClient.AlwaysEncrypted.AzureKeyVaultProvider" />
<PackageReference Include="System.Text.Encoding.CodePages" />
<PackageReference Include="Microsoft.SqlServer.Assessment" /> <PackageReference Include="Microsoft.SqlServer.Assessment" />
<PackageReference Include="Microsoft.SqlServer.Management.SmoMetadataProvider" /> <PackageReference Include="Microsoft.SqlServer.Management.SmoMetadataProvider" />
<PackageReference Include="Microsoft.SqlServer.SqlManagementObjects" />
<PackageReference Include="Microsoft.SqlServer.Management.SqlParser" /> <PackageReference Include="Microsoft.SqlServer.Management.SqlParser" />
<PackageReference Include="System.Text.Encoding.CodePages" /> <PackageReference Include="System.Text.Encoding.CodePages" />
<PackageReference Include="Microsoft.SqlServer.TransactSql.ScriptDom.NRT"> <PackageReference Include="Microsoft.SqlServer.TransactSql.ScriptDom.NRT">

View File

@@ -11,10 +11,10 @@ namespace Microsoft.Kusto.ServiceLayer.UnitTests.Connection
public class ConnectionProviderOptionsHelperTests public class ConnectionProviderOptionsHelperTests
{ {
[Test] [Test]
public void BuildConnectionProviderOptions_Returns_31_Options() public void BuildConnectionProviderOptions_Returns_30_Options()
{ {
var providerOptions = ConnectionProviderOptionsHelper.BuildConnectionProviderOptions(); var providerOptions = ConnectionProviderOptionsHelper.BuildConnectionProviderOptions();
Assert.AreEqual(31, providerOptions.Options.Length); Assert.AreEqual(30, providerOptions.Options.Length);
} }
} }
} }

View File

@@ -242,8 +242,19 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Connection
csb.Password = connectParams.Connection.Password; csb.Password = connectParams.Connection.Password;
} }
csb.ConnectTimeout = connectParams.Connection.ConnectTimeout.HasValue ? connectParams.Connection.ConnectTimeout.Value: 30; csb.ConnectTimeout = connectParams.Connection.ConnectTimeout.HasValue ? connectParams.Connection.ConnectTimeout.Value: 30;
csb.Encrypt = connectParams.Connection.Encrypt.HasValue ? connectParams.Connection.Encrypt.Value : false;
csb.Encrypt = connectParams.Connection.Encrypt?.ToLowerInvariant() switch {
"optional" or "false" or "no" => SqlConnectionEncryptOption.Optional,
"mandatory" or "true" or "yes" => SqlConnectionEncryptOption.Mandatory,
"strict" => SqlConnectionEncryptOption.Strict,
_ => default
};
csb.TrustServerCertificate = connectParams.Connection.TrustServerCertificate.HasValue ? connectParams.Connection.TrustServerCertificate.Value : false; csb.TrustServerCertificate = connectParams.Connection.TrustServerCertificate.HasValue ? connectParams.Connection.TrustServerCertificate.Value : false;
if (!string.IsNullOrEmpty(connectParams.Connection.HostNameInCertificate))
{
csb.HostNameInCertificate = connectParams.Connection.HostNameInCertificate;
}
return csb; return csb;
} }

View File

@@ -956,7 +956,6 @@ Streaming query statement contains a reference to missing output stream 'Missing
} }
} }
} }
}
[TestFixture] [TestFixture]
public class TSqlModelRequestTests public class TSqlModelRequestTests
@@ -1111,3 +1110,4 @@ public class TSqlModelRequestTests
CollectionAssert.AreEquivalent(actualResponse.Select(o => o.Name), new[] { "[dbo].[table1]", "[dbo].[table2]" }, "Table names do not match"); CollectionAssert.AreEquivalent(actualResponse.Select(o => o.Name), new[] { "[dbo].[table1]", "[dbo].[table2]" }, "Table names do not match");
} }
} }
}

View File

@@ -46,11 +46,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility
} }
public static TestConnectionResult InitLiveConnectionInfo(string databaseName = null, string ownerUri = null) public static TestConnectionResult InitLiveConnectionInfo(string databaseName = null, string ownerUri = null)
{ => InitLiveConnectionInfoAsync(databaseName, ownerUri, ServiceLayer.Connection.ConnectionType.Default).ConfigureAwait(false).GetAwaiter().GetResult();
var task = InitLiveConnectionInfoAsync(databaseName, ownerUri, ServiceLayer.Connection.ConnectionType.Default);
task.Wait();
return task.Result;
}
public static async Task<TestConnectionResult> InitLiveConnectionInfoAsync(string databaseName = "master", string ownerUri = null, public static async Task<TestConnectionResult> InitLiveConnectionInfoAsync(string databaseName = "master", string ownerUri = null,
string connectionType = ServiceLayer.Connection.ConnectionType.Default, TestServerType serverType = TestServerType.OnPrem) string connectionType = ServiceLayer.Connection.ConnectionType.Default, TestServerType serverType = TestServerType.OnPrem)

View File

@@ -16,9 +16,9 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
public class ConnectionSetting public class ConnectionSetting
{ {
[JsonProperty("mssql.connections")] [JsonProperty("mssql.connections")]
public List<InstanceInfo> Connections { get; set; } public List<InstanceInfo>? Connections { get; set; }
public InstanceInfo GetConnectionProfile(string profileName, string serverName) public InstanceInfo? GetConnectionProfile(string profileName, string serverName)
{ {
if (!string.IsNullOrEmpty(profileName) && Connections != null) if (!string.IsNullOrEmpty(profileName) && Connections != null)
{ {
@@ -28,7 +28,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
return byProfileName; return byProfileName;
} }
} }
return Connections.FirstOrDefault(x => x.ServerName == serverName); return Connections?.FirstOrDefault(x => x.ServerName == serverName);
} }
} }
@@ -47,23 +47,29 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
public string ServerName { get; set; } public string ServerName { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Database { get; set; } public string? Database { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string User { get; set; } public string? User { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string Password { get; set; } public string? Password { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string ProfileName { get; set; } public string? ProfileName { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? Encrypt { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string? HostNameInCertificate { get; set; }
public TestServerType ServerType { get; set; } public TestServerType ServerType { get; set; }
public AuthenticationType AuthenticationType { get; set; } public AuthenticationType AuthenticationType { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string RemoteSharePath { get; set; } public string? RemoteSharePath { get; set; }
public int ConnectTimeout { get; set; } public int ConnectTimeout { get; set; }

View File

@@ -35,6 +35,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
{ {
DataSource = connectParams.Connection.ServerName, DataSource = connectParams.Connection.ServerName,
InitialCatalog = connectParams.Connection.DatabaseName, InitialCatalog = connectParams.Connection.DatabaseName,
TrustServerCertificate = true
}; };
if (connectParams.Connection.AuthenticationType == "Integrated") if (connectParams.Connection.AuthenticationType == "Integrated")
@@ -45,6 +46,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
{ {
builder.UserID = connectParams.Connection.UserName; builder.UserID = connectParams.Connection.UserName;
builder.Password = connectParams.Connection.Password; builder.Password = connectParams.Connection.Password;
builder.PersistSecurityInfo = true;
}
if (!string.IsNullOrEmpty(connectParams.Connection.Encrypt))
{
builder.Encrypt = connectParams.Connection.Encrypt switch
{
"optional" or "false" or "no" => SqlConnectionEncryptOption.Optional,
"mandatory" or "true" or "yes" => SqlConnectionEncryptOption.Mandatory,
"strict" => SqlConnectionEncryptOption.Strict,
_ => SqlConnectionEncryptOption.Optional
};
}
if (!string.IsNullOrEmpty(connectParams.Connection.HostNameInCertificate))
{
builder.HostNameInCertificate = connectParams.Connection.HostNameInCertificate;
} }
return builder.ToString(); return builder.ToString();

View File

@@ -6,6 +6,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using Microsoft.Data.SqlClient;
using Microsoft.SqlTools.Credentials.Contracts; using Microsoft.SqlTools.Credentials.Contracts;
using Microsoft.SqlTools.ServiceLayer.Connection.Contracts; using Microsoft.SqlTools.ServiceLayer.Connection.Contracts;
using NUnit.Framework; using NUnit.Framework;
@@ -37,12 +38,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
} }
} }
public static InstanceInfo SqlAzure public static InstanceInfo? SqlAzure
{ {
get { return GetInstance(SqlAzureInstanceKey); } get { return GetInstance(SqlAzureInstanceKey); }
} }
public static InstanceInfo SqlOnPrem public static InstanceInfo? SqlOnPrem
{ {
get { return GetInstance(SqlOnPremInstanceKey); } get { return GetInstance(SqlOnPremInstanceKey); }
} }
@@ -50,30 +51,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
/// <summary> /// <summary>
/// Returns the SQL connection info for given version key /// Returns the SQL connection info for given version key
/// </summary> /// </summary>
public static InstanceInfo GetInstance(string key) public static InstanceInfo? GetInstance(string key)
{ {
InstanceInfo instanceInfo; connectionProfilesCache.TryGetValue(key, out InstanceInfo? instanceInfo);
connectionProfilesCache.TryGetValue(key, out instanceInfo);
Assert.True(instanceInfo != null, string.Format(CultureInfo.InvariantCulture, "Cannot find any instance for version key: {0}", key)); Assert.True(instanceInfo != null, string.Format(CultureInfo.InvariantCulture, "Cannot find any instance for version key: {0}", key));
return instanceInfo; return instanceInfo;
} }
public ConnectParams GetConnectionParameters(string key = SqlOnPremInstanceKey, string databaseName = null) public ConnectParams? GetConnectionParameters(string key = SqlOnPremInstanceKey, string databaseName = null)
{ {
InstanceInfo instanceInfo = GetInstance(key); InstanceInfo? instanceInfo = GetInstance(key);
if (instanceInfo != null) return instanceInfo != null ? CreateConnectParams(instanceInfo, key, databaseName) : null;
{
ConnectParams connectParam = CreateConnectParams(instanceInfo, key, databaseName);
return connectParam;
}
return null;
} }
/// <summary> /// <summary>
/// Returns database connection parameters for given server type /// Returns database connection parameters for given server type
/// </summary> /// </summary>
public ConnectParams GetConnectionParameters(TestServerType serverType = TestServerType.OnPrem, string databaseName = null) public ConnectParams? GetConnectionParameters(TestServerType serverType = TestServerType.OnPrem, string databaseName = null)
{ {
string key = ConvertServerTypeToVersionKey(serverType); string key = ConvertServerTypeToVersionKey(serverType);
return GetConnectionParameters(key, databaseName); return GetConnectionParameters(key, databaseName);
@@ -94,11 +88,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
Console.WriteLine("DBTestInstance not configured. Run 'dotnet run Microsoft.SqlTools.ServiceLayer.TestEnvConfig' from the command line to configure"); Console.WriteLine("DBTestInstance not configured. Run 'dotnet run Microsoft.SqlTools.ServiceLayer.TestEnvConfig' from the command line to configure");
} }
if (testServers != null && settings != null) if (testServers != null)
{ {
foreach (var serverIdentity in testServers) foreach (var serverIdentity in testServers)
{ {
var instance = settings != null ? settings.GetConnectionProfile(serverIdentity.ProfileName, serverIdentity.ServerName) : null; var instance = settings?.GetConnectionProfile(serverIdentity.ProfileName, serverIdentity.ServerName);
if (instance?.ServerType == TestServerType.None) if (instance?.ServerType == TestServerType.None)
{ {
instance.ServerType = serverIdentity.ServerType; instance.ServerType = serverIdentity.ServerType;
@@ -106,7 +100,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
} }
} }
} }
if (settings != null) if (settings?.Connections != null)
{ {
foreach (var instance in settings.Connections) foreach (var instance in settings.Connections)
{ {
@@ -162,12 +156,38 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
ConnectParams connectParams = new ConnectParams(); ConnectParams connectParams = new ConnectParams();
connectParams.Connection = new ConnectionDetails(); connectParams.Connection = new ConnectionDetails();
connectParams.Connection.ServerName = connectionProfile.ServerName; connectParams.Connection.ServerName = connectionProfile.ServerName;
if (!string.IsNullOrEmpty(connectionProfile.Database))
{
connectParams.Connection.DatabaseName = connectionProfile.Database; connectParams.Connection.DatabaseName = connectionProfile.Database;
connectParams.Connection.DatabaseDisplayName = connectionProfile.Database; connectParams.Connection.DatabaseDisplayName = connectionProfile.Database;
}
if (!string.IsNullOrEmpty(connectionProfile.User))
{
connectParams.Connection.UserName = connectionProfile.User; connectParams.Connection.UserName = connectionProfile.User;
}
if (!string.IsNullOrEmpty(connectionProfile.Password))
{
connectParams.Connection.Password = connectionProfile.Password; connectParams.Connection.Password = connectionProfile.Password;
connectParams.Connection.MaxPoolSize = 200; }
connectParams.Connection.AuthenticationType = connectionProfile.AuthenticationType.ToString(); connectParams.Connection.AuthenticationType = connectionProfile.AuthenticationType.ToString();
connectParams.Connection.MaxPoolSize = 200;
if (!string.IsNullOrEmpty(connectionProfile.Encrypt))
{
connectParams.Connection.Encrypt = connectionProfile.Encrypt;
}
else
{
connectParams.Connection.Encrypt = SqlConnectionEncryptOption.Optional.ToString();
}
if (!string.IsNullOrEmpty(connectionProfile.HostNameInCertificate))
{
connectParams.Connection.HostNameInCertificate = connectionProfile.HostNameInCertificate;
}
if (!string.IsNullOrEmpty(databaseName)) if (!string.IsNullOrEmpty(databaseName))
{ {
connectParams.Connection.DatabaseName = databaseName; connectParams.Connection.DatabaseName = databaseName;
@@ -176,9 +196,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Common
if (key == SqlAzureInstanceKey || key == SqlAzureInstanceKey) if (key == SqlAzureInstanceKey || key == SqlAzureInstanceKey)
{ {
connectParams.Connection.ConnectTimeout = 30; connectParams.Connection.ConnectTimeout = 30;
connectParams.Connection.Encrypt = true; connectParams.Connection.Encrypt = SqlConnectionEncryptOption.Mandatory.ToString();
connectParams.Connection.TrustServerCertificate = false; connectParams.Connection.TrustServerCertificate = false;
} }
return connectParams; return connectParams;
} }
} }

View File

@@ -25,6 +25,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
var expectedForStrings = default(string); var expectedForStrings = default(string);
var expectedForInt = default(int?); var expectedForInt = default(int?);
var expectedForBoolean = default(bool?); var expectedForBoolean = default(bool?);
var expectedEncryptOption = default(string?);
Assert.AreEqual(details.ApplicationIntent, expectedForStrings); Assert.AreEqual(details.ApplicationIntent, expectedForStrings);
Assert.AreEqual(details.ApplicationName, expectedForStrings); Assert.AreEqual(details.ApplicationName, expectedForStrings);
@@ -48,13 +49,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
Assert.AreEqual(details.ColumnEncryptionSetting, expectedForStrings); Assert.AreEqual(details.ColumnEncryptionSetting, expectedForStrings);
Assert.AreEqual(details.EnclaveAttestationUrl, expectedForStrings); Assert.AreEqual(details.EnclaveAttestationUrl, expectedForStrings);
Assert.AreEqual(details.EnclaveAttestationProtocol, expectedForStrings); Assert.AreEqual(details.EnclaveAttestationProtocol, expectedForStrings);
Assert.AreEqual(details.Encrypt, expectedForBoolean); Assert.AreEqual(details.Encrypt, expectedEncryptOption);
Assert.AreEqual(details.MultipleActiveResultSets, expectedForBoolean); Assert.AreEqual(details.MultipleActiveResultSets, expectedForBoolean);
Assert.AreEqual(details.MultiSubnetFailover, expectedForBoolean); Assert.AreEqual(details.MultiSubnetFailover, expectedForBoolean);
Assert.AreEqual(details.PersistSecurityInfo, expectedForBoolean); Assert.AreEqual(details.PersistSecurityInfo, expectedForBoolean);
Assert.AreEqual(details.Pooling, expectedForBoolean); Assert.AreEqual(details.Pooling, expectedForBoolean);
Assert.AreEqual(details.Replication, expectedForBoolean); Assert.AreEqual(details.Replication, expectedForBoolean);
Assert.AreEqual(details.TrustServerCertificate, expectedForBoolean); Assert.AreEqual(details.TrustServerCertificate, expectedForBoolean);
Assert.AreEqual(details.HostNameInCertificate, expectedForStrings);
Assert.AreEqual(details.Port, expectedForInt); Assert.AreEqual(details.Port, expectedForInt);
} }
@@ -88,13 +90,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
details.ColumnEncryptionSetting = expectedForStrings + index++; details.ColumnEncryptionSetting = expectedForStrings + index++;
details.EnclaveAttestationProtocol = expectedForStrings + index++; details.EnclaveAttestationProtocol = expectedForStrings + index++;
details.EnclaveAttestationUrl = expectedForStrings + index++; details.EnclaveAttestationUrl = expectedForStrings + index++;
details.Encrypt = (index++ % 2 == 0); details.Encrypt = expectedForStrings + index++;
details.MultipleActiveResultSets = (index++ % 2 == 0); details.MultipleActiveResultSets = (index++ % 2 == 0);
details.MultiSubnetFailover = (index++ % 2 == 0); details.MultiSubnetFailover = (index++ % 2 == 0);
details.PersistSecurityInfo = (index++ % 2 == 0); details.PersistSecurityInfo = (index++ % 2 == 0);
details.Pooling = (index++ % 2 == 0); details.Pooling = (index++ % 2 == 0);
details.Replication = (index++ % 2 == 0); details.Replication = (index++ % 2 == 0);
details.TrustServerCertificate = (index++ % 2 == 0); details.TrustServerCertificate = (index++ % 2 == 0);
details.HostNameInCertificate = expectedForStrings + index++;
details.Port = expectedForInt + index++; details.Port = expectedForInt + index++;
index = 0; index = 0;
@@ -120,13 +123,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
Assert.AreEqual(details.ColumnEncryptionSetting, expectedForStrings + index++); Assert.AreEqual(details.ColumnEncryptionSetting, expectedForStrings + index++);
Assert.AreEqual(details.EnclaveAttestationProtocol, expectedForStrings + index++); Assert.AreEqual(details.EnclaveAttestationProtocol, expectedForStrings + index++);
Assert.AreEqual(details.EnclaveAttestationUrl, expectedForStrings + index++); Assert.AreEqual(details.EnclaveAttestationUrl, expectedForStrings + index++);
Assert.AreEqual(details.Encrypt, (index++ % 2 == 0)); Assert.AreEqual(details.Encrypt, expectedForStrings + index++);
Assert.AreEqual(details.MultipleActiveResultSets, (index++ % 2 == 0)); Assert.AreEqual(details.MultipleActiveResultSets, (index++ % 2 == 0));
Assert.AreEqual(details.MultiSubnetFailover, (index++ % 2 == 0)); Assert.AreEqual(details.MultiSubnetFailover, (index++ % 2 == 0));
Assert.AreEqual(details.PersistSecurityInfo, (index++ % 2 == 0)); Assert.AreEqual(details.PersistSecurityInfo, (index++ % 2 == 0));
Assert.AreEqual(details.Pooling, (index++ % 2 == 0)); Assert.AreEqual(details.Pooling, (index++ % 2 == 0));
Assert.AreEqual(details.Replication, (index++ % 2 == 0)); Assert.AreEqual(details.Replication, (index++ % 2 == 0));
Assert.AreEqual(details.TrustServerCertificate, (index++ % 2 == 0)); Assert.AreEqual(details.TrustServerCertificate, (index++ % 2 == 0));
Assert.AreEqual(details.HostNameInCertificate, expectedForStrings + index++);
Assert.AreEqual(details.Port, (expectedForInt + index++)); Assert.AreEqual(details.Port, (expectedForInt + index++));
} }
@@ -161,13 +165,14 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
details.ColumnEncryptionSetting = expectedForStrings + index++; details.ColumnEncryptionSetting = expectedForStrings + index++;
details.EnclaveAttestationProtocol = expectedForStrings + index++; details.EnclaveAttestationProtocol = expectedForStrings + index++;
details.EnclaveAttestationUrl = expectedForStrings + index++; details.EnclaveAttestationUrl = expectedForStrings + index++;
details.Encrypt = (index++ % 2 == 0); details.Encrypt = expectedForStrings + index++;
details.MultipleActiveResultSets = (index++ % 2 == 0); details.MultipleActiveResultSets = (index++ % 2 == 0);
details.MultiSubnetFailover = (index++ % 2 == 0); details.MultiSubnetFailover = (index++ % 2 == 0);
details.PersistSecurityInfo = (index++ % 2 == 0); details.PersistSecurityInfo = (index++ % 2 == 0);
details.Pooling = (index++ % 2 == 0); details.Pooling = (index++ % 2 == 0);
details.Replication = (index++ % 2 == 0); details.Replication = (index++ % 2 == 0);
details.TrustServerCertificate = (index++ % 2 == 0); details.TrustServerCertificate = (index++ % 2 == 0);
details.HostNameInCertificate = expectedForStrings + index++;
details.Port = expectedForInt + index++; details.Port = expectedForInt + index++;
if (optionMetadata.Options.Count() != details.Options.Count) if (optionMetadata.Options.Count() != details.Options.Count)
@@ -226,44 +231,21 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
} }
[Test] [Test]
public void SettingEncryptToStringShouldStillReturnBoolean() public void SettingEncrypShouldReturnExpectedEncryptOption()
{ {
ConnectionDetails details = new ConnectionDetails(); ConnectionDetails details = new ConnectionDetails();
details.Options["Encrypt"] = true.ToString();
Assert.That(details.Encrypt, Is.EqualTo(true.ToString()), "Encrypt should be Mandatory.");
string encrypt = "True"; details.Options["Encrypt"] = "Strict";
bool? expectedValue = true; Assert.That(details.Encrypt, Is.EqualTo("Strict"), "Encrypt should be Strict.");
details.Options["encrypt"] = encrypt;
Assert.AreEqual(details.Encrypt, expectedValue);
} }
[Test] [Test]
public void SettingEncryptToLowecaseStringShouldStillReturnBoolean() public void EncryptShouldReturnMandatoryIfNotSet()
{ {
ConnectionDetails details = new ConnectionDetails(); ConnectionDetails details = new ConnectionDetails();
Assert.That(details.Encrypt, Is.Null, "Encrypt should be null when set to null");
string encrypt = "true";
bool? expectedValue = true;
details.Options["encrypt"] = encrypt;
Assert.AreEqual(details.Encrypt, expectedValue);
}
[Test]
public void EncryptShouldReturnNullIfNotSet()
{
ConnectionDetails details = new ConnectionDetails();
bool? expectedValue = null;
Assert.AreEqual(details.Encrypt, expectedValue);
}
[Test]
public void EncryptShouldReturnNullIfSetToNull()
{
ConnectionDetails details = new ConnectionDetails();
details.Options["encrypt"] = null;
int? expectedValue = null;
Assert.AreEqual(details.ConnectTimeout, expectedValue);
} }
[Test] [Test]
@@ -273,11 +255,12 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
long timeout = long.MaxValue; long timeout = long.MaxValue;
int? expectedValue = null; int? expectedValue = null;
string? expectedEncryptValue = "Mandatory";
details.Options["connectTimeout"] = timeout; details.Options["connectTimeout"] = timeout;
details.Options["encrypt"] = true; details.Options["encrypt"] = expectedEncryptValue;
Assert.AreEqual(details.ConnectTimeout, expectedValue); Assert.That(details.ConnectTimeout, Is.EqualTo(expectedValue), "Connect Timeout not as expected");
Assert.AreEqual(true, details.Encrypt); Assert.That(details.Encrypt, Is.EqualTo("Mandatory"), "Encrypt should be mandatory.");
} }
} }
} }

View File

@@ -521,8 +521,9 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
{ {
new object[] {"AuthenticationType", "Integrated", "Integrated Security" }, new object[] {"AuthenticationType", "Integrated", "Integrated Security" },
new object[] {"AuthenticationType", "SqlLogin", ""}, new object[] {"AuthenticationType", "SqlLogin", ""},
new object[] {"Encrypt", true, "Encrypt"}, new object[] {"Encrypt", "Mandatory", "Encrypt"},
new object[] {"Encrypt", false, "Encrypt"}, new object[] {"Encrypt", "Optional", "Encrypt"},
new object[] {"Encrypt", "Strict", "Encrypt"},
new object[] {"ColumnEncryptionSetting", "Enabled", "Column Encryption Setting=Enabled"}, new object[] {"ColumnEncryptionSetting", "Enabled", "Column Encryption Setting=Enabled"},
new object[] {"ColumnEncryptionSetting", "Disabled", "Column Encryption Setting=Disabled"}, new object[] {"ColumnEncryptionSetting", "Disabled", "Column Encryption Setting=Disabled"},
new object[] {"ColumnEncryptionSetting", "enabled", "Column Encryption Setting=Enabled"}, new object[] {"ColumnEncryptionSetting", "enabled", "Column Encryption Setting=Enabled"},
@@ -533,6 +534,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
new object[] {"ColumnEncryptionSetting", "DiSaBlEd", "Column Encryption Setting=Disabled"}, new object[] {"ColumnEncryptionSetting", "DiSaBlEd", "Column Encryption Setting=Disabled"},
new object[] {"TrustServerCertificate", true, "Trust Server Certificate"}, new object[] {"TrustServerCertificate", true, "Trust Server Certificate"},
new object[] {"TrustServerCertificate", false, "Trust Server Certificate"}, new object[] {"TrustServerCertificate", false, "Trust Server Certificate"},
new object[] {"HostNameInCertificate", "hostname", "Host Name In Certificate"},
new object[] {"PersistSecurityInfo", true, "Persist Security Info"}, new object[] {"PersistSecurityInfo", true, "Persist Security Info"},
new object[] {"PersistSecurityInfo", false, "Persist Security Info"}, new object[] {"PersistSecurityInfo", false, "Persist Security Info"},
new object[] {"ConnectTimeout", 15, "Connect Timeout"}, new object[] {"ConnectTimeout", 15, "Connect Timeout"},
@@ -613,6 +615,7 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
new object[] {"ColumnEncryptionSetting", "NotAValidColumnEncryptionSetting" }, new object[] {"ColumnEncryptionSetting", "NotAValidColumnEncryptionSetting" },
new object[] {"EnclaveAttestationProtocol", "NotAValidEnclaveAttestationProtocol" }, new object[] {"EnclaveAttestationProtocol", "NotAValidEnclaveAttestationProtocol" },
}; };
/// <summary> /// <summary>
/// Build connection string with an invalid property type /// Build connection string with an invalid property type
/// </summary> /// </summary>
@@ -647,6 +650,29 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
} }
}; };
private static readonly object[] EncryptionCombinations =
{
new object[] { SqlConnectionEncryptOption.Optional, SqlConnectionEncryptOption.Optional },
new object[] { SqlConnectionEncryptOption.Mandatory, SqlConnectionEncryptOption.Mandatory },
new object[] { SqlConnectionEncryptOption.Strict, SqlConnectionEncryptOption.Strict },
};
/// <summary>
/// Verify that Strict Encryption parameters can be built into a connection string for connecting.
/// </summary>
[Test, TestCaseSource(nameof(EncryptionCombinations))]
public void ConnectingWithStrictEncryptionBuildsConnectionString(SqlConnectionEncryptOption encryptValue, SqlConnectionEncryptOption expected)
{
// Create a test connection details object and set the property to a specific value
ConnectionDetails details = TestObjects.GetTestConnectionDetails();
details.Encrypt = encryptValue.ToString();
// Test that a connection string can be created without exceptions
string connectionString = ConnectionService.BuildConnectionString(details);
Assert.That(connectionString, Contains.Substring("Encrypt=" + expected.ToString()), "Encrypt not as expected.");
}
/// <summary> /// <summary>
/// Build connection string with an invalid property combinations /// Build connection string with an invalid property combinations
/// </summary> /// </summary>
@@ -1643,19 +1669,43 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.Connection
// If we make a connection to a live database // If we make a connection to a live database
ConnectionService service = ConnectionService.Instance; ConnectionService service = ConnectionService.Instance;
var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"; var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;HostNameInCertificate={servername}";
var details = service.ParseConnectionString(connectionString); var details = service.ParseConnectionString(connectionString);
Assert.That(details.ServerName, Is.EqualTo("tcp:{servername},1433"), "Unexpected server name");
Assert.That(details.DatabaseName, Is.EqualTo("{databasename}"), "Unexpected database name");
Assert.That(details.UserName, Is.EqualTo("{your_username}"), "Unexpected username");
Assert.That(details.Password, Is.EqualTo("{your_password}"), "Unexpected password");
Assert.That(details.PersistSecurityInfo, Is.False, "Unexpected Persist Security Info");
Assert.That(details.MultipleActiveResultSets, Is.False, "Unexpected Multiple Active Result Sets value");
Assert.That(details.Encrypt, Is.EqualTo("True"), "Unexpected Encrypt value");
Assert.That(details.TrustServerCertificate, Is.False, "Unexpected database name value");
Assert.That(details.HostNameInCertificate, Is.EqualTo("{servername}"), "Unexpected Host Name in Certificate value");
Assert.That(details.ConnectTimeout, Is.EqualTo(30), "Unexpected Connect Timeout value");
}
Assert.AreEqual("tcp:{servername},1433", details.ServerName); /// <summary>
Assert.AreEqual("{databasename}", details.DatabaseName); /// Test ParseConnectionString
Assert.AreEqual("{your_username}", details.UserName); /// </summary>
Assert.AreEqual("{your_password}", details.Password); [Test]
Assert.AreEqual(false, details.PersistSecurityInfo); public void ParseConnectionStringTest_StrictEncryption()
Assert.AreEqual(false, details.MultipleActiveResultSets); {
Assert.AreEqual(true, details.Encrypt); // If we make a connection to a live database
Assert.AreEqual(false, details.TrustServerCertificate); ConnectionService service = ConnectionService.Instance;
Assert.AreEqual(30, details.ConnectTimeout);
var connectionString = "Server=tcp:{servername},1433;Initial Catalog={databasename};Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=Strict;TrustServerCertificate=False;Connection Timeout=30;HostNameInCertificate={servername}";
var details = service.ParseConnectionString(connectionString);
Assert.That(details.ServerName, Is.EqualTo("tcp:{servername},1433"), "Unexpected server name");
Assert.That(details.DatabaseName, Is.EqualTo("{databasename}"), "Unexpected database name");
Assert.That(details.UserName, Is.EqualTo("{your_username}"), "Unexpected username");
Assert.That(details.Password, Is.EqualTo("{your_password}"), "Unexpected password");
Assert.That(details.PersistSecurityInfo, Is.False, "Unexpected Persist Security Info");
Assert.That(details.MultipleActiveResultSets, Is.False, "Unexpected Multiple Active Result Sets value");
Assert.That(details.Encrypt, Is.EqualTo(SqlConnectionEncryptOption.Strict.ToString()), "Unexpected Encrypt value");
Assert.That(details.TrustServerCertificate, Is.False, "Unexpected database name value");
Assert.That(details.HostNameInCertificate, Is.EqualTo("{servername}"), "Unexpected Host Name in Certificate value");
Assert.That(details.ConnectTimeout, Is.EqualTo(30), "Unexpected Connect Timeout value");
} }
[Test] [Test]

View File

@@ -169,7 +169,6 @@ namespace Microsoft.SqlTools.ServiceLayer.UnitTests.ResourceProvider.Fakes
// connectionStringBuilder.ConnectTimeout = 123; // connectionStringBuilder.ConnectTimeout = 123;
// connectionStringBuilder.Encrypt = true; // connectionStringBuilder.Encrypt = true;
// connectionStringBuilder.ApplicationIntent = ApplicationIntent.ReadWrite; // connectionStringBuilder.ApplicationIntent = ApplicationIntent.ReadWrite;
// connectionStringBuilder.AsynchronousProcessing = true;
// connectionStringBuilder.MaxPoolSize = 45; // connectionStringBuilder.MaxPoolSize = 45;
// connectionStringBuilder.MinPoolSize = 3; // connectionStringBuilder.MinPoolSize = 3;
// connectionStringBuilder.PacketSize = 600; // connectionStringBuilder.PacketSize = 600;