Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 51bdece

Browse files
joelbraunsaurabh500
authored andcommitted
Ported System.Data.SqlCredential Class (#27311)
* Added SqlCredential class * Add tests for SqlCredential creation * Fixed csproj, added test, and made style changes
1 parent 62878f3 commit 51bdece

File tree

7 files changed

+163
-12
lines changed

7 files changed

+163
-12
lines changed

src/System.Data.SqlClient/ref/System.Data.SqlClient.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,13 @@ public override void Rollback() { }
845845
public void Rollback(string transactionName) { }
846846
public void Save(string savePointName) { }
847847
}
848+
849+
public sealed class SqlCredential
850+
{
851+
public SqlCredential(string userId, System.Security.SecureString password) { }
852+
public string UserId { get { throw null; } }
853+
public System.Security.SecureString Password { get { throw null; } }
854+
}
848855
}
849856
namespace System.Data
850857
{

src/System.Data.SqlClient/src/Resources/Strings.resx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,32 +1165,32 @@
11651165
<data name="SqlProvider_InvalidDataColumnMaxLength" xml:space="preserve">
11661166
<value>The size of column '{0}' is not supported. The size is {1}.</value>
11671167
</data>
1168-
<data name="MDF_InvalidXmlInvalidValue" xml:space="preserve">
1168+
<data name="MDF_InvalidXmlInvalidValue" xml:space="preserve">
11691169
<value>The metadata XML is invalid. The {1} column of the {0} collection must contain a non-empty string.</value>
11701170
</data>
1171-
<data name="MDF_CollectionNameISNotUnique" xml:space="preserve">
1171+
<data name="MDF_CollectionNameISNotUnique" xml:space="preserve">
11721172
<value>There are multiple collections named '{0}'.</value>
11731173
</data>
1174-
<data name="MDF_InvalidXmlMissingColumn" xml:space="preserve">
1174+
<data name="MDF_InvalidXmlMissingColumn" xml:space="preserve">
11751175
<value>The metadata XML is invalid. The {0} collection must contain a {1} column and it must be a string column.</value>
11761176
</data>
1177-
<data name="MDF_InvalidXml" xml:space="preserve">
1177+
<data name="MDF_InvalidXml" xml:space="preserve">
11781178
<value>The metadata XML is invalid.</value>
11791179
</data>
1180-
<data name="MDF_NoColumns" xml:space="preserve">
1180+
<data name="MDF_NoColumns" xml:space="preserve">
11811181
<value>The schema table contains no columns.</value>
11821182
</data>
1183-
<data name="MDF_QueryFailed" xml:space="preserve">
1183+
<data name="MDF_QueryFailed" xml:space="preserve">
11841184
<value>Unable to build the '{0}' collection because execution of the SQL query failed. See the inner exception for details.</value>
11851185
</data>
1186-
<data name="MDF_TooManyRestrictions" xml:space="preserve">
1186+
<data name="MDF_TooManyRestrictions" xml:space="preserve">
11871187
<value>More restrictions were provided than the requested schema ('{0}') supports.</value>
11881188
</data>
1189-
<data name="MDF_DataTableDoesNotExist" xml:space="preserve">
1189+
<data name="MDF_DataTableDoesNotExist" xml:space="preserve">
11901190
<value>The collection '{0}' is missing from the metadata XML.</value>
11911191
</data>
1192-
<data name="MDF_UndefinedCollection" xml:space="preserve">
1193-
<value>The requested collection ({0}) is not defined.</value>
1192+
<data name="MDF_UndefinedCollection" xml:space="preserve">
1193+
<value>The requested collection ({0}) is not defined.</value>
11941194
</data>
11951195
<data name="MDF_UnsupportedVersion" xml:space="preserve">
11961196
<value> requested collection ({0}) is not supported by this version of the provider.</value>
@@ -1213,4 +1213,10 @@
12131213
<data name="MDF_UnableToBuildCollection" xml:space="preserve">
12141214
<value>Unable to build schema collection '{0}';</value>
12151215
</data>
1216-
</root>
1216+
<data name="ADP_InvalidArgumentLength" xml:space="preserve">
1217+
<value>The length of argument '{0}' exceeds its limit of '{1}'.</value>
1218+
</data>
1219+
<data name="ADP_MustBeReadOnly" xml:space="preserve">
1220+
<value>{0} must be marked as read only.</value>
1221+
</data>
1222+
</root>

src/System.Data.SqlClient/src/System.Data.SqlClient.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
<Compile Include="System\Data\SqlClient\SNI\SSRP.cs" />
202202
<Compile Include="System\Data\SqlClient\TdsParserStateObjectManaged.cs" />
203203
<Compile Include="Interop\SNINativeMethodWrapper.Common.cs" />
204+
<Compile Include="System\Data\SqlClient\SqlCredential.cs" />
204205
</ItemGroup>
205206
<!-- Manage the SNI toggle for Windows netstandard and UWP -->
206207
<ItemGroup Condition="'$(TargetGroup)' == 'netstandard' AND '$(TargetsWindows)' == 'true'">

src/System.Data.SqlClient/src/System/Data/Common/AdapterUtil.SqlClient.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -880,5 +880,16 @@ internal static ArgumentOutOfRangeException ArgumentOutOfRange(string message, s
880880
TraceExceptionAsReturnValue(e);
881881
return e;
882882
}
883+
884+
internal static ArgumentException InvalidArgumentLength(string argumentName, int limit)
885+
{
886+
return Argument(SR.GetString(SR.ADP_InvalidArgumentLength, argumentName, limit));
887+
}
888+
889+
internal static ArgumentException MustBeReadOnly(string argumentName)
890+
{
891+
return Argument(SR.GetString(SR.ADP_MustBeReadOnly, argumentName));
892+
}
893+
883894
}
884-
}
895+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System.Data.Common;
6+
using System.Security;
7+
8+
namespace System.Data.SqlClient
9+
{
10+
public sealed class SqlCredential
11+
{
12+
string _userId;
13+
SecureString _password;
14+
15+
public SqlCredential(string userId, SecureString password)
16+
{
17+
if (userId == null)
18+
{
19+
throw ADP.ArgumentNull(nameof(userId));
20+
}
21+
22+
if (userId.Length > TdsEnums.MAXLEN_USERNAME)
23+
{
24+
throw ADP.InvalidArgumentLength(nameof(userId), TdsEnums.MAXLEN_USERNAME);
25+
}
26+
27+
if (password == null)
28+
{
29+
throw ADP.ArgumentNull(nameof(password));
30+
}
31+
32+
if (password.Length > TdsEnums.MAXLEN_PASSWORD)
33+
{
34+
throw ADP.InvalidArgumentLength(nameof(password), TdsEnums.MAXLEN_PASSWORD);
35+
}
36+
37+
if (!password.IsReadOnly())
38+
{
39+
throw ADP.MustBeReadOnly(nameof(password));
40+
}
41+
42+
_userId = userId;
43+
_password = password;
44+
}
45+
46+
public string UserId => _userId;
47+
48+
public SecureString Password => _password;
49+
50+
}
51+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Data.SqlClient;
8+
using System.Linq;
9+
using System.Security;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
using Xunit;
13+
14+
namespace System.Data.SqlClient.Tests
15+
{
16+
public static class SqlCredentialTest
17+
{
18+
[Fact]
19+
public static void Test_SqlCredential_Password_Requirements()
20+
{
21+
var userId = "user";
22+
23+
// Create password with value longer than max allowed length
24+
var longPassword = new SecureString();
25+
26+
var genPassword = string.Empty.PadLeft(129, '0');
27+
genPassword.ToCharArray().ToList().ForEach(c => longPassword.AppendChar(c));
28+
longPassword.MakeReadOnly();
29+
30+
// Verify non-null password requirement
31+
Assert.Throws<ArgumentNullException>(() => new SqlCredential(userId, null));
32+
33+
// Verify max length requirement
34+
Assert.Throws<ArgumentException>(() => new SqlCredential(userId, longPassword));
35+
36+
// Verify read only password requirement
37+
Assert.Throws<ArgumentException>(() => new SqlCredential(userId, new SecureString()));
38+
39+
}
40+
41+
[Fact]
42+
public static void Test_SqlCredential_UserId_Requirements()
43+
{
44+
var password = new SecureString();
45+
password.MakeReadOnly();
46+
47+
// Create userId longer than max allowed length
48+
var userId = string.Empty.PadLeft(129, '0');
49+
50+
// Verify max length requirement
51+
Assert.Throws<ArgumentException>(() => new SqlCredential(userId, password));
52+
53+
// Verify non-null userId requirement
54+
Assert.Throws<ArgumentNullException>(() => new SqlCredential(null, password));
55+
56+
}
57+
58+
[Fact]
59+
public static void Test_SqlCredential_Properties()
60+
{
61+
var userId = "user";
62+
var password = new SecureString();
63+
password.AppendChar('0');
64+
password.MakeReadOnly();
65+
66+
var credential = new SqlCredential(userId, password);
67+
68+
Assert.Equal(userId, credential.UserId);
69+
Assert.Equal(password, credential.Password);
70+
71+
}
72+
73+
}
74+
}

src/System.Data.SqlClient/tests/FunctionalTests/System.Data.SqlClient.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<Compile Include="BaseProviderAsyncTest\MockCommand.cs" />
1515
<Compile Include="BaseProviderAsyncTest\MockConnection.cs" />
1616
<Compile Include="BaseProviderAsyncTest\MockDataReader.cs" />
17+
<Compile Include="SqlCredentialTest.cs" />
1718
<Compile Include="DiagnosticTest.cs" />
1819
<Compile Include="AmbientTransactionFailureTest.cs" />
1920
<Compile Include="ExceptionTest.cs" />

0 commit comments

Comments
 (0)