From 8917025c14d1925894b00a311a1c2454e93aadb9 Mon Sep 17 00:00:00 2001 From: martincostello Date: Mon, 31 Oct 2022 10:04:10 +0000 Subject: [PATCH 01/11] Support resolving config from service provider Support resolving the `IdentityConfiguration` instance using the `IServiceProvider`. --- .../IdentityAzureTableBuilderExtensions.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/IdentityAzureTableBuilderExtensions.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/IdentityAzureTableBuilderExtensions.cs index 0d82290..efc4280 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/IdentityAzureTableBuilderExtensions.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/IdentityAzureTableBuilderExtensions.cs @@ -12,21 +12,37 @@ public static class IdentityAzureTableBuilderExtensions { /// /// Use this to load and configure the Identity Azure Tables into the aspnet identity pipeline. - /// Note: prior to calling this methiod in the pipeline if you need Roles functionality, otherwise the RoleStore will not be loaded. + /// Note: prior to calling this method in the pipeline if you need Roles functionality, otherwise the RoleStore will not be loaded. /// /// Use or extend /// aspnet identity pipeline /// - /// Use that uses SHA1, or a custom keyhelper that implements + /// Use that uses SHA1, or a custom keyhelper that implements /// public static IdentityBuilder AddAzureTableStores(this IdentityBuilder builder, Func configAction, IKeyHelper keyHelper = null) where TContext : IdentityCloudContext { + return builder.AddAzureTableStores(_ => configAction(), keyHelper); + } + + /// + /// Use this to load and configure the Identity Azure Tables into the aspnet identity pipeline. + /// Note: prior to calling this method in the pipeline if you need Roles functionality, otherwise the RoleStore will not be loaded. + /// + /// Use or extend + /// aspnet identity pipeline + /// + /// Use that uses SHA1, or a custom keyhelper that implements + /// + public static IdentityBuilder AddAzureTableStores(this IdentityBuilder builder, Func configAction, + IKeyHelper keyHelper = null) + where TContext : IdentityCloudContext + { builder.Services.AddSingleton(keyHelper ?? new DefaultKeyHelper()); - builder.Services.AddSingleton(new Func(p => configAction())); + builder.Services.AddSingleton(configAction); Type contextType = typeof(TContext); builder.Services.AddSingleton(contextType, contextType); From caca923d0255f2ed80ab9e02802969d9b986700f Mon Sep 17 00:00:00 2001 From: martincostello Date: Mon, 31 Oct 2022 10:16:49 +0000 Subject: [PATCH 02/11] Use new hashing functionality for .NET 6 When targeting `net6.0`, use new hashing related functionality to improve the performance and reduce the amount of code (modulo the hash define). --- .../Helpers/BaseKeyHelper.cs | 4 ++++ .../Helpers/DefaultKeyHelper.cs | 12 +++++++++++- .../Helpers/SHA256KeyHelper.cs | 12 +++++++++++- src/ElCamino.Azure.Data.Tables/TableQuery.cs | 9 ++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs index 3f432a6..11bb599 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs @@ -151,6 +151,9 @@ protected virtual string GetHash(HashAlgorithm shaHash, string input, Encoding e { // Convert the input string to a byte array and compute the hash. byte[] data = shaHash.ComputeHash(encoding.GetBytes(input)); +#if NET6_0_OR_GREATER + return Convert.ToHexString(data).ToLowerInvariant(); +#else Debug.WriteLine(string.Format("Key Size before hash: {0} bytes", encoding.GetBytes(input).Length)); // Create a new StringBuilder to collect the bytes @@ -167,6 +170,7 @@ protected virtual string GetHash(HashAlgorithm shaHash, string input, Encoding e // Return the hexadecimal string. return sBuilder.ToString(); +#endif } } } diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs index 2784f19..064fb84 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs @@ -1,5 +1,6 @@ // MIT License Copyright 2020 (c) David Melendez. All rights reserved. See License.txt in the project root for license information. +using System; using System.Security.Cryptography; using System.Text; @@ -11,8 +12,17 @@ public override string ConvertKeyToHash(string input) { if (input != null) { + var encoding = Encoding.Unicode; +#if NET6_0_OR_GREATER + // We can elide the SHA1 allocation if this isn't a derived type + if (GetType() == typeof(DefaultKeyHelper)) + { + byte[] data = SHA1.HashData(encoding.GetBytes(input)); + return Convert.ToHexString(data).ToLowerInvariant(); + } +#endif using SHA1 sha = SHA1.Create(); - return GetHash(sha, input, Encoding.Unicode, 40); + return GetHash(sha, input, encoding, 40); } return null; } diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs index dab34ee..eaa69b0 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs @@ -1,5 +1,6 @@ // MIT License Copyright 2020 (c) David Melendez. All rights reserved. See License.txt in the project root for license information. +using System; using System.Security.Cryptography; using System.Text; @@ -14,8 +15,17 @@ public override string ConvertKeyToHash(string input) { if (input != null) { + var encoding = Encoding.UTF8; +#if NET6_0_OR_GREATER + // We can elide the SHA256 allocation if this isn't a derived type + if (GetType() == typeof(SHA256KeyHelper)) + { + byte[] data = SHA256.HashData(encoding.GetBytes(input)); + return Convert.ToHexString(data).ToLowerInvariant(); + } +#endif using SHA256 sha = SHA256.Create(); - return GetHash(sha, input, Encoding.UTF8, 64); + return GetHash(sha, input, encoding, 64); } return null; } diff --git a/src/ElCamino.Azure.Data.Tables/TableQuery.cs b/src/ElCamino.Azure.Data.Tables/TableQuery.cs index 2c6fda9..893df16 100644 --- a/src/ElCamino.Azure.Data.Tables/TableQuery.cs +++ b/src/ElCamino.Azure.Data.Tables/TableQuery.cs @@ -69,7 +69,11 @@ public static string GenerateFilterConditionForBinary( string operation, byte[] givenValue) { + string hash; +#if NET6_0_OR_GREATER + hash = Convert.ToHexString(givenValue).ToLowerInvariant(); +#else StringBuilder sb = new StringBuilder(); foreach (byte b in givenValue) @@ -77,7 +81,10 @@ public static string GenerateFilterConditionForBinary( sb.AppendFormat("{0:x2}", b); } - return GenerateFilterCondition(propertyName, operation, sb.ToString(), EdmType.Binary); + hash = sb.ToString(); +#endif + + return GenerateFilterCondition(propertyName, operation, hash, EdmType.Binary); } /// From 8a9eb9e7f15a2aaa9cd0abc993a1c0ccae289dbf Mon Sep 17 00:00:00 2001 From: David Melendez Date: Sat, 5 Nov 2022 11:32:23 -0500 Subject: [PATCH 03/11] #98 --- .../ElCamino.AspNetCore.Identity.AzureTable.Model.csproj | 4 ++-- .../ElCamino.AspNetCore.Identity.AzureTable.csproj | 4 ++-- .../Helpers/BaseKeyHelper.cs | 2 +- .../ElCamino.Azure.Data.Tables.csproj | 4 ++-- .../ElCamino.Identity.AzureTable.DataUtility.csproj | 6 +++--- ...ElCamino.AspNetCore.Identity.AzureTable.Templates.csproj | 4 ++-- .../templates/StarterWebMvc-CSharp/samplemvccore.csproj | 2 +- .../StarterWebRazorPages-CSharp/samplerazorpagescore.csproj | 2 +- .../ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj | 6 +++--- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable.Model/ElCamino.AspNetCore.Identity.AzureTable.Model.csproj b/src/ElCamino.AspNetCore.Identity.AzureTable.Model/ElCamino.AspNetCore.Identity.AzureTable.Model.csproj index dc5aa2a..047cf0c 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable.Model/ElCamino.AspNetCore.Identity.AzureTable.Model.csproj +++ b/src/ElCamino.AspNetCore.Identity.AzureTable.Model/ElCamino.AspNetCore.Identity.AzureTable.Model.csproj @@ -5,7 +5,7 @@ Copyright © 2022 David Melendez, MIT License Azure Table Storage Provider for ASP.NET Identity Core Models David Melendez - netstandard2.0;net6.0 + netstandard2.0;net6.0;net7.0 9.0 ElCamino.AspNetCore.Identity.AzureTable.Model ../../tools/Key.snk @@ -22,7 +22,7 @@ git https://github.com/dlmelendez/identityazuretable.git True - 6.2 + 7.0 https://dlmelendez.github.io/identityazuretable diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/ElCamino.AspNetCore.Identity.AzureTable.csproj b/src/ElCamino.AspNetCore.Identity.AzureTable/ElCamino.AspNetCore.Identity.AzureTable.csproj index fb380c1..f72c68f 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/ElCamino.AspNetCore.Identity.AzureTable.csproj +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/ElCamino.AspNetCore.Identity.AzureTable.csproj @@ -5,7 +5,7 @@ Copyright © 2022 David Melendez, MIT License Azure Table Storage Provider for ASP.NET Identity Core David Melendez - netstandard2.0;net6.0 + netstandard2.0;net6.0;net7.0 10.0 ElCamino.AspNetCore.Identity.AzureTable ../../tools/Key.snk @@ -21,7 +21,7 @@ git https://github.com/dlmelendez/identityazuretable.git True - 6.2 + 7.0 https://dlmelendez.github.io/identityazuretable diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs index 11bb599..1673cd9 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs @@ -143,7 +143,7 @@ public virtual string GenerateRowKeyIdentityUserLogin(string loginProvider, stri return string.Format(FormatterIdentityUserLogin, hash); } - public double KeyVersion => 6.2; + public double KeyVersion => 7.0; public abstract string ConvertKeyToHash(string input); diff --git a/src/ElCamino.Azure.Data.Tables/ElCamino.Azure.Data.Tables.csproj b/src/ElCamino.Azure.Data.Tables/ElCamino.Azure.Data.Tables.csproj index c9ce106..1229919 100644 --- a/src/ElCamino.Azure.Data.Tables/ElCamino.Azure.Data.Tables.csproj +++ b/src/ElCamino.Azure.Data.Tables/ElCamino.Azure.Data.Tables.csproj @@ -5,7 +5,7 @@ Copyright © 2022 David Melendez, MIT License Azure Table Storage Extensions David Melendez - netstandard2.0;net6.0 + netstandard2.0;net6.0;net7.0 10.0 ElCamino.Azure.Data.Tables ../../tools/Key.snk @@ -20,7 +20,7 @@ git https://github.com/dlmelendez/identityazuretable.git True - 6.2 + 7.0 https://dlmelendez.github.io/identityazuretable diff --git a/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj b/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj index cc33bf5..1d192ff 100644 --- a/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj +++ b/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj @@ -1,8 +1,8 @@  - net6.0 - 9.0 + net7.0 + 10.0 ElCamino.Identity.AzureTable.DataUtility Exe ElCamino.Identity.AzureTable.DataUtility @@ -11,7 +11,7 @@ false false false - 6.2 + 7.0 diff --git a/templates/ElCamino.AspNetCore.Identity.AzureTable.Templates.csproj b/templates/ElCamino.AspNetCore.Identity.AzureTable.Templates.csproj index 9033797..8f06d85 100644 --- a/templates/ElCamino.AspNetCore.Identity.AzureTable.Templates.csproj +++ b/templates/ElCamino.AspNetCore.Identity.AzureTable.Templates.csproj @@ -3,7 +3,7 @@ Web Project Templates for Azure Table Storage Provider for ASP.NET Identity Core David Melendez - net6.0 + net7.0 ElCamino.AspNetCore.Identity.AzureTable.Templates ElCamino.AspNetCore.Identity.AzureTable.Templates ASP.NET Core Web Template Pack for ElCamino Identity Azure Table Storage @@ -19,7 +19,7 @@ git https://github.com/dlmelendez/identityazuretable.git True - 6.2 + 7.0 https://dlmelendez.github.io/identityazuretable MIT true diff --git a/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj b/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj index 6fb3632..176fd5f 100644 --- a/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj +++ b/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj @@ -1,7 +1,7 @@ - net6.0 + net7.0 enable enable aspnet-samplemvccore-FECFB455-D41D-47DD-B371-2C0F71AC101F diff --git a/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj b/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj index ad1f8f5..dacd915 100644 --- a/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj +++ b/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj @@ -1,7 +1,7 @@  - net6.0 + net7.0 enable enable aspnet-samplerazorpagescore-9339924A-3037-4518-866A-C28CC554EA47 diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj index 37938bf..099705b 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj @@ -3,11 +3,11 @@ Testing David Melendez - net6.0 - 9.0 + net6.0;net7.0 + 10.0 ElCamino.AspNetCore.Identity.AzureTable.Tests false - 6.2 + 7.0 Full From 5c50da47883554fe6e509faaf2622a8505ffe261 Mon Sep 17 00:00:00 2001 From: David Melendez Date: Sat, 5 Nov 2022 16:57:43 -0500 Subject: [PATCH 04/11] fixing data protection error in test prj --- ...lCamino.AspNetCore.Identity.AzureTable.Tests.csproj | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj index 099705b..e7069af 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj @@ -22,7 +22,17 @@ + + + + + + + + + + From 17f5be9ead940ce7b408c7d3d3f2d19979e8e6b6 Mon Sep 17 00:00:00 2001 From: David Melendez Date: Sat, 5 Nov 2022 17:41:35 -0500 Subject: [PATCH 05/11] #99 fixing client libs --- .../StarterWebMvc-CSharp/appsettings.json | 2 +- .../StarterWebMvc-CSharp/libman.json | 44 +++++++++++++++++++ .../appsettings.json | 2 +- .../StarterWebRazorPages-CSharp/libman.json | 44 +++++++++++++++++++ 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 templates/templates/StarterWebMvc-CSharp/libman.json create mode 100644 templates/templates/StarterWebRazorPages-CSharp/libman.json diff --git a/templates/templates/StarterWebMvc-CSharp/appsettings.json b/templates/templates/StarterWebMvc-CSharp/appsettings.json index b710823..d497f2c 100644 --- a/templates/templates/StarterWebMvc-CSharp/appsettings.json +++ b/templates/templates/StarterWebMvc-CSharp/appsettings.json @@ -1,7 +1,7 @@ { "IdentityAzureTable": { "IdentityConfiguration": { - "TablePrefix": "v6", + "TablePrefix": "v7", "StorageConnectionString": "UseDevelopmentStorage=true;", "IndexTableName": "AspNetIndex", "RoleTableName": "AspNetRoles", diff --git a/templates/templates/StarterWebMvc-CSharp/libman.json b/templates/templates/StarterWebMvc-CSharp/libman.json new file mode 100644 index 0000000..df16d77 --- /dev/null +++ b/templates/templates/StarterWebMvc-CSharp/libman.json @@ -0,0 +1,44 @@ +{ + "version": "1.0", + "defaultProvider": "cdnjs", + "libraries": [ + { + "provider": "unpkg", + "library": "jquery-validation@1.19.5", + "destination": "wwwroot/lib/jquery-validation/", + "files": [ + "dist/jquery.validate.js", + "dist/jquery.validate.min.js" + ] + }, + { + "provider": "unpkg", + "library": "bootstrap@5.2.2", + "destination": "wwwroot/lib/bootstrap/", + "files": [ + "dist/css/bootstrap.css", + "dist/css/bootstrap.css.map", + "dist/css/bootstrap.min.css", + "dist/css/bootstrap.min.css.map", + "dist/js/bootstrap.bundle.js", + "dist/js/bootstrap.bundle.js.map", + "dist/js/bootstrap.bundle.min.js", + "dist/js/bootstrap.bundle.min.js.map", + "dist/js/bootstrap.js", + "dist/js/bootstrap.js.map", + "dist/js/bootstrap.min.js", + "dist/js/bootstrap.min.js.map" + ] + }, + { + "provider": "unpkg", + "library": "jquery@3.6.1", + "destination": "wwwroot/lib/jquery/", + "files": [ + "dist/jquery.js", + "dist/jquery.min.js", + "dist/jquery.min.map" + ] + } + ] +} \ No newline at end of file diff --git a/templates/templates/StarterWebRazorPages-CSharp/appsettings.json b/templates/templates/StarterWebRazorPages-CSharp/appsettings.json index b710823..d497f2c 100644 --- a/templates/templates/StarterWebRazorPages-CSharp/appsettings.json +++ b/templates/templates/StarterWebRazorPages-CSharp/appsettings.json @@ -1,7 +1,7 @@ { "IdentityAzureTable": { "IdentityConfiguration": { - "TablePrefix": "v6", + "TablePrefix": "v7", "StorageConnectionString": "UseDevelopmentStorage=true;", "IndexTableName": "AspNetIndex", "RoleTableName": "AspNetRoles", diff --git a/templates/templates/StarterWebRazorPages-CSharp/libman.json b/templates/templates/StarterWebRazorPages-CSharp/libman.json new file mode 100644 index 0000000..2d9b12b --- /dev/null +++ b/templates/templates/StarterWebRazorPages-CSharp/libman.json @@ -0,0 +1,44 @@ +{ + "version": "1.0", + "defaultProvider": "cdnjs", + "libraries": [ + { + "provider": "unpkg", + "library": "jquery-validation@1.19.5", + "destination": "wwwroot/lib/jquery-validation/", + "files": [ + "dist/jquery.validate.js", + "dist/jquery.validate.min.js" + ] + }, + { + "provider": "unpkg", + "library": "bootstrap@5.2.2", + "destination": "wwwroot/lib/bootstrap/", + "files": [ + "dist/css/bootstrap.css", + "dist/css/bootstrap.css.map", + "dist/css/bootstrap.min.css", + "dist/css/bootstrap.min.css.map", + "dist/js/bootstrap.bundle.js", + "dist/js/bootstrap.bundle.js.map", + "dist/js/bootstrap.bundle.min.js", + "dist/js/bootstrap.bundle.min.js.map", + "dist/js/bootstrap.js", + "dist/js/bootstrap.js.map", + "dist/js/bootstrap.min.js", + "dist/js/bootstrap.min.js.map" + ] + }, + { + "provider": "unpkg", + "library": "jquery@3.6.1", + "destination": "wwwroot/lib/jquery/", + "files": [ + "dist/jquery.js", + "dist/jquery.min.js", + "dist/jquery.min.map" + ] + } + ] +} \ No newline at end of file From 7b3c1c4f395496456eb57bb628fed93bcfef7263 Mon Sep 17 00:00:00 2001 From: David Melendez Date: Sat, 5 Nov 2022 17:43:36 -0500 Subject: [PATCH 06/11] client side template --- templates/templates/StarterWebRazorPages-CSharp/libman.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/templates/StarterWebRazorPages-CSharp/libman.json b/templates/templates/StarterWebRazorPages-CSharp/libman.json index 2d9b12b..df16d77 100644 --- a/templates/templates/StarterWebRazorPages-CSharp/libman.json +++ b/templates/templates/StarterWebRazorPages-CSharp/libman.json @@ -3,7 +3,7 @@ "defaultProvider": "cdnjs", "libraries": [ { - "provider": "unpkg", + "provider": "unpkg", "library": "jquery-validation@1.19.5", "destination": "wwwroot/lib/jquery-validation/", "files": [ From 11d33e9daef57f3c2a2979938a689655f2a6e0fc Mon Sep 17 00:00:00 2001 From: David Melendez Date: Tue, 8 Nov 2022 21:12:35 -0600 Subject: [PATCH 07/11] .net7 package update --- ...ino.Identity.AzureTable.DataUtility.csproj | 10 +++++----- .../StarterWebMvc-CSharp/samplemvccore.csproj | 10 +++++----- .../samplerazorpagescore.csproj | 10 +++++----- ...spNetCore.Identity.AzureTable.Tests.csproj | 20 +++++++++---------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj b/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj index 1d192ff..89666d1 100644 --- a/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj +++ b/src/ElCamino.Identity.AzureTable.DataUtility/ElCamino.Identity.AzureTable.DataUtility.csproj @@ -43,12 +43,12 @@ - - + + - - - + + + diff --git a/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj b/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj index 176fd5f..3c653f3 100644 --- a/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj +++ b/templates/templates/StarterWebMvc-CSharp/samplemvccore.csproj @@ -8,11 +8,11 @@ - - - - - + + + + + diff --git a/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj b/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj index dacd915..0c033e3 100644 --- a/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj +++ b/templates/templates/StarterWebRazorPages-CSharp/samplerazorpagescore.csproj @@ -8,11 +8,11 @@ - - - - - + + + + + diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj index e7069af..a03e230 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/ElCamino.AspNetCore.Identity.AzureTable.Tests.csproj @@ -23,15 +23,15 @@ - - + + - - - - - - + + + + + + @@ -57,8 +57,8 @@ - - + + From 1fa2691fdb55800e9a19fb0355b505add4852d98 Mon Sep 17 00:00:00 2001 From: David Melendez Date: Wed, 9 Nov 2022 10:00:41 -0600 Subject: [PATCH 08/11] adding key tests to insure backwards compat --- .../Helpers/BaseKeyHelper.cs | 21 ++++-- .../Helpers/DefaultKeyHelper.cs | 26 ++++--- .../Helpers/SHA256KeyHelper.cs | 28 +++++--- .../Fakes/HashTestKeyHelperFake.cs | 38 ++++++++++ .../KeyHelperTests.cs | 72 +++++++++++++++++++ 5 files changed, 159 insertions(+), 26 deletions(-) create mode 100644 tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs create mode 100644 tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs index 1673cd9..022aa72 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/BaseKeyHelper.cs @@ -147,13 +147,18 @@ public virtual string GenerateRowKeyIdentityUserLogin(string loginProvider, stri public abstract string ConvertKeyToHash(string input); + /// + /// Left only for backwards compat for older frameworks. + /// + /// + /// + /// + /// + /// protected virtual string GetHash(HashAlgorithm shaHash, string input, Encoding encoding, int hashHexLength) { // Convert the input string to a byte array and compute the hash. byte[] data = shaHash.ComputeHash(encoding.GetBytes(input)); -#if NET6_0_OR_GREATER - return Convert.ToHexString(data).ToLowerInvariant(); -#else Debug.WriteLine(string.Format("Key Size before hash: {0} bytes", encoding.GetBytes(input).Length)); // Create a new StringBuilder to collect the bytes @@ -170,7 +175,15 @@ protected virtual string GetHash(HashAlgorithm shaHash, string input, Encoding e // Return the hexadecimal string. return sBuilder.ToString(); -#endif } + +#if NET6_0_OR_GREATER + protected static string FormatHashedData(byte[] hashedData) + { + // Convert the input string to a byte array and compute the hash. + return Convert.ToHexString(hashedData).ToLowerInvariant(); + } +#endif + } } diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs index 064fb84..a169661 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/DefaultKeyHelper.cs @@ -8,23 +8,27 @@ namespace ElCamino.AspNetCore.Identity.AzureTable.Helpers { public class DefaultKeyHelper : BaseKeyHelper { - public override string ConvertKeyToHash(string input) +#if NET6_0_OR_GREATER + + public sealed override string ConvertKeyToHash(string input) + { + if (input != null) + { + byte[] data = SHA1.HashData(Encoding.Unicode.GetBytes(input)); + return FormatHashedData(data); + } + return null; + } +#else + public sealed override string ConvertKeyToHash(string input) { if (input != null) { - var encoding = Encoding.Unicode; -#if NET6_0_OR_GREATER - // We can elide the SHA1 allocation if this isn't a derived type - if (GetType() == typeof(DefaultKeyHelper)) - { - byte[] data = SHA1.HashData(encoding.GetBytes(input)); - return Convert.ToHexString(data).ToLowerInvariant(); - } -#endif using SHA1 sha = SHA1.Create(); - return GetHash(sha, input, encoding, 40); + return GetHash(sha, input, Encoding.Unicode, 40); } return null; } +#endif } } diff --git a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs index eaa69b0..4fc3bee 100644 --- a/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs +++ b/src/ElCamino.AspNetCore.Identity.AzureTable/Helpers/SHA256KeyHelper.cs @@ -11,24 +11,30 @@ namespace ElCamino.AspNetCore.Identity.AzureTable.Helpers /// public class SHA256KeyHelper : BaseKeyHelper { - public override string ConvertKeyToHash(string input) + +#if NET6_0_OR_GREATER + public sealed override string ConvertKeyToHash(string input) + { + if (input != null) + { + byte[] data = SHA256.HashData(Encoding.UTF8.GetBytes(input)); + return FormatHashedData(data); + } + return null; + } + +#else + + public sealed override string ConvertKeyToHash(string input) { if (input != null) { - var encoding = Encoding.UTF8; -#if NET6_0_OR_GREATER - // We can elide the SHA256 allocation if this isn't a derived type - if (GetType() == typeof(SHA256KeyHelper)) - { - byte[] data = SHA256.HashData(encoding.GetBytes(input)); - return Convert.ToHexString(data).ToLowerInvariant(); - } -#endif using SHA256 sha = SHA256.Create(); - return GetHash(sha, input, encoding, 64); + return GetHash(sha, input, Encoding.UTF8, 64); } return null; } +#endif public override string GenerateRowKeyUserId(string plainUserId) { diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs new file mode 100644 index 0000000..f1285c8 --- /dev/null +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using ElCamino.AspNetCore.Identity.AzureTable.Helpers; + +namespace ElCamino.AspNetCore.Identity.AzureTable.Tests.Fakes +{ + internal class HashTestKeyHelperFake : BaseKeyHelper + { + public override string ConvertKeyToHash(string input) + { + throw new NotImplementedException(); + } + + public string ConvertKeyToHashBackwardCompatSHA1(string input) + { + if (input != null) + { + using SHA1 sha = SHA1.Create(); + return GetHash(sha, input, Encoding.Unicode, 40); + } + return null; + } + + public string ConvertKeyToHashBackwardCompatSHA256(string input) + { + if (input != null) + { + using SHA256 sha = SHA256.Create(); + return GetHash(sha, input, Encoding.UTF8, 64); + } + return null; + } + } +} diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs new file mode 100644 index 0000000..fb42242 --- /dev/null +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs @@ -0,0 +1,72 @@ +// MIT License Copyright 2020 (c) David Melendez. All rights reserved. See License.txt in the project root for license information. +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ElCamino.AspNetCore.Identity.AzureTable.Helpers; +using ElCamino.AspNetCore.Identity.AzureTable.Tests.Fakes; +using Microsoft.VisualStudio.TestPlatform.Utilities; +using NuGet.Frameworks; +using Xunit; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace ElCamino.AspNetCore.Identity.AzureTable.Tests +{ + public class KeyHelperTests + { + private DefaultKeyHelper _defaultKeyHelper = new DefaultKeyHelper(); + private SHA256KeyHelper _sha256KeyHelper = new SHA256KeyHelper(); + private HashTestKeyHelperFake _fakeKeyHelper = new HashTestKeyHelperFake(); + protected readonly ITestOutputHelper _output; + + public KeyHelperTests(ITestOutputHelper output) + { + _output = output; + } + + [Theory] + [InlineData("HashTestKeyHelperFake _fakeKeyHelper = new HashTestKeyHelperFake();")] + [InlineData("thisIs Some Test Text123323 for Hashing")] + [InlineData("{F1FFCC02-83E0-4347-8377-72D6007E3D93}")] + public void SHA1FormatBackwardCompat(string textToHash) + { + _output.WriteLine($"plain text: {textToHash}"); + var sw = new Stopwatch(); + sw.Start(); + string expected = _fakeKeyHelper.ConvertKeyToHashBackwardCompatSHA1(textToHash); + sw.Stop(); + _output.WriteLine($"expected {sw.Elapsed.TotalMilliseconds} ms: {expected}"); + + sw.Reset(); + sw.Start(); + string returned = _defaultKeyHelper.ConvertKeyToHash(textToHash); + sw.Stop(); + _output.WriteLine($"returned {sw.Elapsed.TotalMilliseconds} ms: {returned}"); + Assert.Equal(expected, returned, StringComparer.InvariantCulture); + } + + [Theory] + [InlineData("HashTestKeyHelperFake _fakeKeyHelper = new HashTestKeyHelperFake();")] + [InlineData("thisIs Some Test Text123323 for Hashing")] + [InlineData("{F1FFCC02-83E0-4347-8377-72D6007E3D93}")] + public void SHA256FormatBackwardCompat(string textToHash) + { + _output.WriteLine($"plain text: {textToHash}"); + var sw = new Stopwatch(); + sw.Start(); + string expected = _fakeKeyHelper.ConvertKeyToHashBackwardCompatSHA256(textToHash); + sw.Stop(); + _output.WriteLine($"expected {sw.Elapsed.TotalMilliseconds} ms: {expected}"); + + sw.Reset(); + sw.Start(); + string returned = _sha256KeyHelper.ConvertKeyToHash(textToHash); + sw.Stop(); + _output.WriteLine($"returned {sw.Elapsed.TotalMilliseconds} ms: {returned}"); + Assert.Equal(expected, returned, StringComparer.InvariantCulture); + } + } +} From 7faa811ea03f1f51368e038efed246d4b67f5ff3 Mon Sep 17 00:00:00 2001 From: David Melendez Date: Wed, 9 Nov 2022 10:16:13 -0600 Subject: [PATCH 09/11] code cleanup --- src/ElCamino.Azure.Data.Tables/TableClientExtensions.cs | 4 ++-- .../BaseRoleStoreTests.cs | 4 ++-- .../BaseUserStoreTests.cs | 4 ++-- .../KeyHelperTests.cs | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ElCamino.Azure.Data.Tables/TableClientExtensions.cs b/src/ElCamino.Azure.Data.Tables/TableClientExtensions.cs index 1d169c7..98bb25f 100644 --- a/src/ElCamino.Azure.Data.Tables/TableClientExtensions.cs +++ b/src/ElCamino.Azure.Data.Tables/TableClientExtensions.cs @@ -93,8 +93,8 @@ public static async Task GetEntityOrDefaultAsync( TableQuery.GenerateFilterCondition(nameof(TableEntity.RowKey), QueryComparisons.Equal, rowKey)); var page = await table.QueryAsync(filter: filterString, maxPerPage: 1, select: select, cancellationToken) - .AsPages(continuationToken: null, pageSizeHint: 1).FirstOrDefaultAsync().ConfigureAwait(false); - return page?.Values.FirstOrDefault(); + .AsPages(continuationToken: null, pageSizeHint: 1).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); + return page?.Values.Count > 0 ? page.Values[0] : null; } /// diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseRoleStoreTests.cs b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseRoleStoreTests.cs index 907eeb0..e50691f 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseRoleStoreTests.cs +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseRoleStoreTests.cs @@ -248,9 +248,9 @@ public virtual async Task FindRoleByName() Assert.Equal(role.Name, result1.SingleOrDefault().Name); } - private void WriteLineObject(t obj) where t : class + private void WriteLineObject(T obj) where T : class { - _output.WriteLine(typeof(t).Name); + _output.WriteLine(typeof(T).Name); string strLine = obj == null ? "Null" : Newtonsoft.Json.JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented); _output.WriteLine("{0}", strLine); } diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseUserStoreTests.cs b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseUserStoreTests.cs index b644a4b..3e7d823 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseUserStoreTests.cs +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/BaseUserStoreTests.cs @@ -391,9 +391,9 @@ public void Initialize() //-- } - protected void WriteLineObject(t obj) where t : class + protected void WriteLineObject(T obj) where T : class { - _output.WriteLine(typeof(t).Name); + _output.WriteLine(typeof(T).Name); string strLine = obj == null ? "Null" : Newtonsoft.Json.JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.Indented); _output.WriteLine("{0}", strLine); } diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs index fb42242..4e1121b 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/KeyHelperTests.cs @@ -17,9 +17,9 @@ namespace ElCamino.AspNetCore.Identity.AzureTable.Tests { public class KeyHelperTests { - private DefaultKeyHelper _defaultKeyHelper = new DefaultKeyHelper(); - private SHA256KeyHelper _sha256KeyHelper = new SHA256KeyHelper(); - private HashTestKeyHelperFake _fakeKeyHelper = new HashTestKeyHelperFake(); + private readonly DefaultKeyHelper _defaultKeyHelper = new(); + private readonly SHA256KeyHelper _sha256KeyHelper = new(); + private readonly HashTestKeyHelperFake _fakeKeyHelper = new(); protected readonly ITestOutputHelper _output; public KeyHelperTests(ITestOutputHelper output) From 72741072d6cf4a222639aca33dd9b08a86ff70cf Mon Sep 17 00:00:00 2001 From: David Melendez Date: Wed, 9 Nov 2022 10:34:08 -0600 Subject: [PATCH 10/11] copyright --- .../Fakes/HashTestKeyHelperFake.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs index f1285c8..dcd337e 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using ElCamino.AspNetCore.Identity.AzureTable.Helpers; +// MIT License Copyright 2022 (c) David Melendez. All rights reserved. See License.txt in the project root for license information. namespace ElCamino.AspNetCore.Identity.AzureTable.Tests.Fakes { internal class HashTestKeyHelperFake : BaseKeyHelper From 06430746c7d9ea3d8990020b8bec76e52eb7ca83 Mon Sep 17 00:00:00 2001 From: David Melendez Date: Wed, 9 Nov 2022 10:36:49 -0600 Subject: [PATCH 11/11] fix copyright --- .../Fakes/HashTestKeyHelperFake.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs index dcd337e..de11e48 100644 --- a/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs +++ b/tests/ElCamino.AspNetCore.Identity.AzureTable.Tests/Fakes/HashTestKeyHelperFake.cs @@ -1,4 +1,6 @@ -using System; +// MIT License Copyright 2022 (c) David Melendez. All rights reserved. See License.txt in the project root for license information. + +using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; @@ -6,7 +8,6 @@ using System.Threading.Tasks; using ElCamino.AspNetCore.Identity.AzureTable.Helpers; -// MIT License Copyright 2022 (c) David Melendez. All rights reserved. See License.txt in the project root for license information. namespace ElCamino.AspNetCore.Identity.AzureTable.Tests.Fakes { internal class HashTestKeyHelperFake : BaseKeyHelper