From 674ad22c8fd55f729402fe75549f75de01a5e34a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Herceg?= Date: Fri, 5 Apr 2024 15:59:53 +0200 Subject: [PATCH 1/6] Ported to .NET Standard 2.1 --- .gitignore | 3 +- Microsoft.AspNet.Identity.sln | 52 +- Microsoft.AspNet.Identity.vssscc | 10 - .../35MSSharedLib1024.snk | Bin 160 -> 0 bytes .../Microsoft.AspNet.Identity.Core.csproj | 119 +- .../Properties/AssemblyInfo.cs | 33 +- .../Resources.Designer.cs | 4 +- .../35MSSharedLib1024.snk | Bin 160 -> 0 bytes .../App.config | 18 - .../IdentityResources.Designer.cs | 7 +- ...oft.AspNet.Identity.EntityFramework.csproj | 112 +- .../Properties/AssemblyInfo.cs | 25 - .../RoleStore.cs | 1 + .../UserStore.cs | 1 + .../packages.config | 4 - .../Microsoft.AspNet.Identity.Owin.csproj | 5 +- src/Microsoft.AspNet.Identity.Owin/app.config | 12 +- .../packages.config | 1 - test/Identity.Test/35MSSharedLib1024.snk | Bin 160 -> 0 bytes test/Identity.Test/App.config | 41 - test/Identity.Test/ApplicationUserTest.cs | 164 +- .../AuthenticationManagerExtensionsTest.cs | 612 +++--- test/Identity.Test/CustomGuidKeyTest.cs | 238 +-- test/Identity.Test/CustomIntKeyTest.cs | 104 +- test/Identity.Test/ExceptionHelper.cs | 8 +- test/Identity.Test/Identity.Test.csproj | 193 +- .../OwinContextExtensionsTest.cs | 21 - test/Identity.Test/Properties/AssemblyInfo.cs | 25 - test/Identity.Test/SecurityStampTest.cs | 352 ++-- test/Identity.Test/SignInManagerTest.cs | 38 +- test/Identity.Test/TestUtil.cs | 57 +- test/Identity.Test/UserManagerTest.cs | 1737 ----------------- test/Identity.Test/packages.config | 12 - unittest.testsettings | 31 - 34 files changed, 850 insertions(+), 3190 deletions(-) delete mode 100644 Microsoft.AspNet.Identity.vssscc delete mode 100644 src/Microsoft.AspNet.Identity.Core/35MSSharedLib1024.snk delete mode 100644 src/Microsoft.AspNet.Identity.EntityFramework/35MSSharedLib1024.snk delete mode 100644 src/Microsoft.AspNet.Identity.EntityFramework/App.config delete mode 100644 src/Microsoft.AspNet.Identity.EntityFramework/packages.config delete mode 100644 test/Identity.Test/35MSSharedLib1024.snk delete mode 100644 test/Identity.Test/App.config delete mode 100644 test/Identity.Test/OwinContextExtensionsTest.cs delete mode 100644 test/Identity.Test/packages.config delete mode 100644 unittest.testsettings diff --git a/.gitignore b/.gitignore index 4266ce8..639fa55 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ [Oo]bj/ [Bb]in/ -packages/ \ No newline at end of file +packages/ +/.vs diff --git a/Microsoft.AspNet.Identity.sln b/Microsoft.AspNet.Identity.sln index b869386..b92237e 100644 --- a/Microsoft.AspNet.Identity.sln +++ b/Microsoft.AspNet.Identity.sln @@ -1,57 +1,23 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30408.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34616.47 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Core", "src\Microsoft.AspNet.Identity.Core\Microsoft.AspNet.Identity.Core.csproj", "{D2F24972-0F56-4C18-BD65-C26A320A0C68}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.Core", "src\Microsoft.AspNet.Identity.Core\Microsoft.AspNet.Identity.Core.csproj", "{D2F24972-0F56-4C18-BD65-C26A320A0C68}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0C1D4BD7-0771-4899-AF55-43D8791660A0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.EntityFramework", "src\Microsoft.AspNet.Identity.EntityFramework\Microsoft.AspNet.Identity.EntityFramework.csproj", "{D7298DAD-AB04-4502-9567-0461D0AD059E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.EntityFramework", "src\Microsoft.AspNet.Identity.EntityFramework\Microsoft.AspNet.Identity.EntityFramework.csproj", "{D7298DAD-AB04-4502-9567-0461D0AD059E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{FD5D1AFD-204F-4504-B8F3-74C2E1EEC848}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8883A4C2-A8DF-4F24-ADF7-DAEBFBEFD21B}" ProjectSection(SolutionItems) = preProject License.txt = License.txt - unittest.testsettings = unittest.testsettings EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Owin", "src\Microsoft.AspNet.Identity.Owin\Microsoft.AspNet.Identity.Owin.csproj", "{943170EB-F4E7-4A6D-989E-2CF6C681DD89}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{A7082BDD-985B-47B9-915B-7FA4CF541B5E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{99DB175F-B1B4-4C9B-9D4A-C21F1ED2FB86}" - ProjectSection(SolutionItems) = preProject - .nuget\NuGet.Config = .nuget\NuGet.Config - .nuget\NuGet.exe = .nuget\NuGet.exe - .nuget\NuGet.targets = .nuget\NuGet.targets - .nuget\packages.config = .nuget\packages.config - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{A7082BDD-985B-47B9-915B-7FA4CF541B5E}" EndProject Global - GlobalSection(TeamFoundationVersionControl) = preSolution - SccNumberOfProjects = 5 - SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C} - SccTeamFoundationServer = https://tfs.codeplex.com/tfs/tfs18 - SccLocalPath0 = . - SccProjectUniqueName1 = src\\Microsoft.AspNet.Identity.Core\\Microsoft.AspNet.Identity.Core.csproj - SccProjectTopLevelParentUniqueName1 = Microsoft.AspNet.Identity.sln - SccProjectName1 = src/Microsoft.AspNet.Identity.Core - SccLocalPath1 = src\\Microsoft.AspNet.Identity.Core - SccProjectUniqueName2 = src\\Microsoft.AspNet.Identity.EntityFramework\\Microsoft.AspNet.Identity.EntityFramework.csproj - SccProjectTopLevelParentUniqueName2 = Microsoft.AspNet.Identity.sln - SccProjectName2 = src/Microsoft.AspNet.Identity.EntityFramework - SccLocalPath2 = src\\Microsoft.AspNet.Identity.EntityFramework - SccProjectUniqueName3 = src\\Microsoft.AspNet.Identity.Owin\\Microsoft.AspNet.Identity.Owin.csproj - SccProjectTopLevelParentUniqueName3 = Microsoft.AspNet.Identity.sln - SccProjectName3 = src/Microsoft.AspNet.Identity.Owin - SccLocalPath3 = src\\Microsoft.AspNet.Identity.Owin - SccProjectUniqueName4 = test\\Identity.Test\\Identity.Test.csproj - SccProjectTopLevelParentUniqueName4 = Microsoft.AspNet.Identity.sln - SccProjectName4 = test/Identity.Test - SccLocalPath4 = test\\Identity.Test - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU @@ -65,10 +31,6 @@ Global {D7298DAD-AB04-4502-9567-0461D0AD059E}.Debug|Any CPU.Build.0 = Debug|Any CPU {D7298DAD-AB04-4502-9567-0461D0AD059E}.Release|Any CPU.ActiveCfg = Release|Any CPU {D7298DAD-AB04-4502-9567-0461D0AD059E}.Release|Any CPU.Build.0 = Release|Any CPU - {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.Build.0 = Debug|Any CPU - {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.ActiveCfg = Release|Any CPU - {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.Build.0 = Release|Any CPU {A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -80,9 +42,11 @@ Global GlobalSection(NestedProjects) = preSolution {D2F24972-0F56-4C18-BD65-C26A320A0C68} = {0C1D4BD7-0771-4899-AF55-43D8791660A0} {D7298DAD-AB04-4502-9567-0461D0AD059E} = {0C1D4BD7-0771-4899-AF55-43D8791660A0} - {943170EB-F4E7-4A6D-989E-2CF6C681DD89} = {0C1D4BD7-0771-4899-AF55-43D8791660A0} {A7082BDD-985B-47B9-915B-7FA4CF541B5E} = {FD5D1AFD-204F-4504-B8F3-74C2E1EEC848} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {18A616DC-B136-4FD9-B3BC-DCE7D07D0693} + EndGlobalSection GlobalSection(TestCaseManagementSettings) = postSolution CategoryFile = Microsoft.AspNet.Identity.vsmdi EndGlobalSection diff --git a/Microsoft.AspNet.Identity.vssscc b/Microsoft.AspNet.Identity.vssscc deleted file mode 100644 index 6cb031b..0000000 --- a/Microsoft.AspNet.Identity.vssscc +++ /dev/null @@ -1,10 +0,0 @@ -"" -{ -"FILE_VERSION" = "9237" -"ENLISTMENT_CHOICE" = "NEVER" -"PROJECT_FILE_RELATIVE_PATH" = "" -"NUMBER_OF_EXCLUDED_FILES" = "0" -"ORIGINAL_PROJECT_FILE_PATH" = "" -"NUMBER_OF_NESTED_PROJECTS" = "0" -"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT" -} diff --git a/src/Microsoft.AspNet.Identity.Core/35MSSharedLib1024.snk b/src/Microsoft.AspNet.Identity.Core/35MSSharedLib1024.snk deleted file mode 100644 index 695f1b38774e839e5b90059bfb7f32df1dff4223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZ - - + - Debug - AnyCPU - {D2F24972-0F56-4C18-BD65-C26A320A0C68} + netstandard2.0 Library - Properties Microsoft.AspNet.Identity - Microsoft.AspNet.Identity.Core - v4.5 - 512 - SAK - SAK - SAK - SAK - - bin\$(Configuration) - - - true - full - false - DEBUG;TRACE - prompt - 4 - false - bin\Debug\Microsoft.AspNet.Identity.Core.XML - true - Sdl6.1.ruleset - - - pdbonly - true - TRACE - prompt - 4 - false - bin\Release\Microsoft.AspNet.Identity.Core.XML - - - true - - - true + false - 35MSSharedLib1024.snk + Microsoft.AspNet.Identity.Core + Microsoft + Microsoft.AspNet.Identity.Core + Copyright © Microsoft 2012 + 2.0.0.0 + 2.1.0.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + True True Resources.resx - - - - - - - - - - - - + ResXFileCodeGenerator Resources.Designer.cs - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs index ac3397a..708098e 100644 --- a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs @@ -5,17 +5,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("Microsoft.AspNet.Identity.Core")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Microsoft.AspNet.Identity.Core")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2012")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: CLSCompliant(true)] @@ -29,30 +18,12 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e318dfc7-3a02-42a5-bb45-16c143f61c30")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] - -[assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.1.0.0")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: InternalsVisibleTo( - "Microsoft.AspNet.Identity.Owin, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" - )] -[assembly: - InternalsVisibleTo( - "Microsoft.AspNet.Identity.EntityFramework, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + "Microsoft.AspNet.Identity.EntityFramework" )] [assembly: InternalsVisibleTo( - "Identity.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + "Identity.Test" )] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs b/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs index 26b1e45..764da92 100644 --- a/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Identity.Core/Resources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34011 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -19,7 +19,7 @@ namespace Microsoft.AspNet.Identity { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/35MSSharedLib1024.snk b/src/Microsoft.AspNet.Identity.EntityFramework/35MSSharedLib1024.snk deleted file mode 100644 index 695f1b38774e839e5b90059bfb7f32df1dff4223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZ - - - -
- - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs b/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs index feff65b..943d01c 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/IdentityResources.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.34003 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -9,6 +9,9 @@ //------------------------------------------------------------------------------ namespace Microsoft.AspNet.Identity.EntityFramework { + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -16,7 +19,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class IdentityResources { diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj b/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj index 86aa2d8..ff7620f 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj +++ b/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj @@ -1,114 +1,36 @@ - - - + - Debug - AnyCPU - {D7298DAD-AB04-4502-9567-0461D0AD059E} + netstandard2.1 Library - bin\$(Configuration) - Properties - Microsoft.AspNet.Identity.EntityFramework - Microsoft.AspNet.Identity.EntityFramework - v4.5 - 512 - SAK - SAK - SAK - SAK - ..\..\ - true - - - true - full - false - DEBUG;TRACE - prompt - 4 - bin\Debug\Microsoft.AspNet.Identity.EntityFramework.XML - true - Sdl6.1.ruleset - - - pdbonly - true - TRACE - prompt - 4 - bin\Release\Microsoft.AspNet.Identity.EntityFramework.XML - - - true - - - true + false - 35MSSharedLib1024.snk + Microsoft.AspNet.Identity.EntityFramework + Microsoft + Microsoft.AspNet.Identity.EntityFramework + Copyright © Microsoft 2013 + 2.0.0.0 + 2.1.0.0 - - False - ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll - - - False - ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll - - - - - - - - - - - - - - - - - - - + True True IdentityResources.resx - - - - - - - - - {d2f24972-0f56-4c18-bd65-c26a320a0c68} - Microsoft.AspNet.Identity.Core - - - - + - + ResXFileCodeGenerator IdentityResources.Designer.cs - - - - + + + + + \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs index 888e2f5..d57e3f3 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs @@ -5,17 +5,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("Microsoft.AspNet.Identity.EntityFramework")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Microsoft.AspNet.Identity.EntityFramework")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2013")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -29,20 +18,6 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("17d56636-0d8d-401e-9484-da7965dcf45a")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] - -[assembly: AssemblyVersion("2.0.0.0")] -[assembly: AssemblyFileVersion("2.1.0.0")] [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: InternalsVisibleTo( diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs index 8ecbaee..da68219 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs @@ -3,6 +3,7 @@ using System; using System.Data.Entity; +using System.Data.Entity.Utilities; using System.Linq; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs index 2087cb8..7f0ea17 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Data.Entity; +using System.Data.Entity.Utilities; using System.Globalization; using System.Linq; using System.Linq.Expressions; diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/packages.config b/src/Microsoft.AspNet.Identity.EntityFramework/packages.config deleted file mode 100644 index 04b3bca..0000000 --- a/src/Microsoft.AspNet.Identity.EntityFramework/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj b/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj index 13cce96..55d1ebd 100644 --- a/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj +++ b/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj @@ -1,5 +1,5 @@  - + Debug @@ -10,7 +10,7 @@ Properties Microsoft.AspNet.Identity.Owin Microsoft.AspNet.Identity.Owin - v4.5 + v4.8 512 SAK SAK @@ -18,6 +18,7 @@ SAK ..\..\ true + true diff --git a/src/Microsoft.AspNet.Identity.Owin/app.config b/src/Microsoft.AspNet.Identity.Owin/app.config index bf90bf8..9aabd76 100644 --- a/src/Microsoft.AspNet.Identity.Owin/app.config +++ b/src/Microsoft.AspNet.Identity.Owin/app.config @@ -1,15 +1,15 @@ - + - - + + - - + + - \ No newline at end of file + diff --git a/src/Microsoft.AspNet.Identity.Owin/packages.config b/src/Microsoft.AspNet.Identity.Owin/packages.config index b803355..cc40c21 100644 --- a/src/Microsoft.AspNet.Identity.Owin/packages.config +++ b/src/Microsoft.AspNet.Identity.Owin/packages.config @@ -1,5 +1,4 @@  - diff --git a/test/Identity.Test/35MSSharedLib1024.snk b/test/Identity.Test/35MSSharedLib1024.snk deleted file mode 100644 index 695f1b38774e839e5b90059bfb7f32df1dff4223..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZ - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/Identity.Test/ApplicationUserTest.cs b/test/Identity.Test/ApplicationUserTest.cs index a2ba0ed..a11a599 100644 --- a/test/Identity.Test/ApplicationUserTest.cs +++ b/test/Identity.Test/ApplicationUserTest.cs @@ -7,40 +7,40 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security.DataProtection; +//using Microsoft.AspNet.Identity.Owin; +//using Microsoft.Owin; +//using Microsoft.Owin.Security.DataProtection; using Xunit; namespace Identity.Test { public class ApplicationUserTest { - private async Task CreateManager(OwinContext context) - { - var options = new IdentityFactoryOptions - { - DataProtectionProvider = new DpapiDataProtectionProvider(), - Provider = new IdentityFactoryProvider - { - OnCreate = (o, c) => ApplicationUserManager.Create(o, c) - } - }; - var middleware = - new IdentityFactoryMiddleware>( - null, options); - var dbMiddle = - new IdentityFactoryMiddleware>( - middleware, - new IdentityFactoryOptions - { - Provider = new IdentityFactoryProvider - { - OnCreate = (o, c) => CreateDb() - } - }); - await dbMiddle.Invoke(context); - } + //private async Task CreateManager(OwinContext context) + //{ + // var options = new IdentityFactoryOptions + // { + // DataProtectionProvider = new DpapiDataProtectionProvider(), + // Provider = new IdentityFactoryProvider + // { + // OnCreate = (o, c) => ApplicationUserManager.Create(o, c) + // } + // }; + // var middleware = + // new IdentityFactoryMiddleware>( + // null, options); + // var dbMiddle = + // new IdentityFactoryMiddleware>( + // middleware, + // new IdentityFactoryOptions + // { + // Provider = new IdentityFactoryProvider + // { + // OnCreate = (o, c) => CreateDb() + // } + // }); + // await dbMiddle.Invoke(context); + //} [Fact] public void EnsureDefaultSchemaWithApplicationUser() @@ -48,30 +48,30 @@ public void EnsureDefaultSchemaWithApplicationUser() IdentityDbContextTest.VerifyDefaultSchema(CreateDb()); } - [Fact] - public async Task ApplicationUserCreateTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager(); - ApplicationUser[] users = - { - new ApplicationUser {UserName = "test", Email = "test@test.com"}, - new ApplicationUser {UserName = "test1", Email = "test1@test.com"}, - new ApplicationUser {UserName = "test2", Email = "test2@test.com"}, - new ApplicationUser {UserName = "test3", Email = "test3@test.com"} - }; - foreach (ApplicationUser user in users) - { - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - } - foreach (ApplicationUser user in users) - { - var u = await manager.FindByIdAsync(user.Id); - Assert.NotNull(u); - Assert.Equal(u.UserName, user.UserName); - } - } + //[Fact] + //public async Task ApplicationUserCreateTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager(); + // ApplicationUser[] users = + // { + // new ApplicationUser {UserName = "test", Email = "test@test.com"}, + // new ApplicationUser {UserName = "test1", Email = "test1@test.com"}, + // new ApplicationUser {UserName = "test2", Email = "test2@test.com"}, + // new ApplicationUser {UserName = "test3", Email = "test3@test.com"} + // }; + // foreach (ApplicationUser user in users) + // { + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // } + // foreach (ApplicationUser user in users) + // { + // var u = await manager.FindByIdAsync(user.Id); + // Assert.NotNull(u); + // Assert.Equal(u.UserName, user.UserName); + // } + //} private static ApplicationDbContext CreateDb() { @@ -167,36 +167,36 @@ public ApplicationUserManager(IUserStore store) { } - public static ApplicationUserManager Create(IdentityFactoryOptions options, - IOwinContext context) - { - var manager = - new ApplicationUserManager(new UserStore(context.Get())); - manager.UserValidator = new UserValidator(manager) - { - AllowOnlyAlphanumericUserNames = false, - RequireUniqueEmail = true - }; - manager.PasswordValidator = new MinimumLengthValidator(6); - manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider - { - MessageFormat = "Your security code is: {0}" - }); - manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider - { - Subject = "SecurityCode", - BodyFormat = "Your security code is {0}" - }); - manager.EmailService = new EmailService(); - manager.SmsService = new SMSService(); - var dataProtectionProvider = options.DataProtectionProvider; - if (dataProtectionProvider != null) - { - manager.UserTokenProvider = - new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); - } - return manager; - } + //public static ApplicationUserManager Create(IdentityFactoryOptions options, + // IOwinContext context) + //{ + // var manager = + // new ApplicationUserManager(new UserStore(context.Get())); + // manager.UserValidator = new UserValidator(manager) + // { + // AllowOnlyAlphanumericUserNames = false, + // RequireUniqueEmail = true + // }; + // manager.PasswordValidator = new MinimumLengthValidator(6); + // manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider + // { + // MessageFormat = "Your security code is: {0}" + // }); + // manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider + // { + // Subject = "SecurityCode", + // BodyFormat = "Your security code is {0}" + // }); + // manager.EmailService = new EmailService(); + // manager.SmsService = new SMSService(); + // var dataProtectionProvider = options.DataProtectionProvider; + // if (dataProtectionProvider != null) + // { + // manager.UserTokenProvider = + // new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); + // } + // return manager; + //} } public class EmailService : IIdentityMessageService diff --git a/test/Identity.Test/AuthenticationManagerExtensionsTest.cs b/test/Identity.Test/AuthenticationManagerExtensionsTest.cs index f0d3712..5d22c97 100644 --- a/test/Identity.Test/AuthenticationManagerExtensionsTest.cs +++ b/test/Identity.Test/AuthenticationManagerExtensionsTest.cs @@ -4,8 +4,8 @@ using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Identity; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin.Security; +//using Microsoft.AspNet.Identity.Owin; +//using Microsoft.Owin.Security; using Moq; using Xunit; @@ -13,331 +13,331 @@ namespace Identity.Test { public class AuthenticationManagerExtensionsTest { - [Fact] - public void ExtensionsNullCheckTest() - { - IAuthenticationManager manager = null; - ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalAuthenticationTypes(), "manager"); - ExceptionHelper.ThrowsArgumentNull( - () => AsyncHelper.RunSync(() => manager.GetExternalIdentityAsync("whatever")), "manager"); - ExceptionHelper.ThrowsArgumentNull(() => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync()), - "manager"); - ExceptionHelper.ThrowsArgumentNull( - () => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync("key", "blah")), "manager"); - ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo(), "manager"); - ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo("key", "blah"), "manager"); - ExceptionHelper.ThrowsArgumentNull(() => manager.CreateTwoFactorRememberBrowserIdentity("foo"), "manager"); - ExceptionHelper.ThrowsArgumentNull( - () => AsyncHelper.RunSync(() => manager.TwoFactorBrowserRememberedAsync("foo")), "manager"); - } + //[Fact] + //public void ExtensionsNullCheckTest() + //{ + // IAuthenticationManager manager = null; + // ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalAuthenticationTypes(), "manager"); + // ExceptionHelper.ThrowsArgumentNull( + // () => AsyncHelper.RunSync(() => manager.GetExternalIdentityAsync("whatever")), "manager"); + // ExceptionHelper.ThrowsArgumentNull(() => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync()), + // "manager"); + // ExceptionHelper.ThrowsArgumentNull( + // () => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync("key", "blah")), "manager"); + // ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo(), "manager"); + // ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo("key", "blah"), "manager"); + // ExceptionHelper.ThrowsArgumentNull(() => manager.CreateTwoFactorRememberBrowserIdentity("foo"), "manager"); + // ExceptionHelper.ThrowsArgumentNull( + // () => AsyncHelper.RunSync(() => manager.TwoFactorBrowserRememberedAsync("foo")), "manager"); + //} - [Fact] - public async Task GetExternalLoginReturnsNullIfNoNameIdentifierTest() - { - var manager = new Mock(); - manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), - new AuthenticationProperties(), new AuthenticationDescription()))); - Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); - } + //[Fact] + //public async Task GetExternalLoginReturnsNullIfNoNameIdentifierTest() + //{ + // var manager = new Mock(); + // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), + // new AuthenticationProperties(), new AuthenticationDescription()))); + // Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); + //} - [Fact] - public async Task GetExternalLoginDoesNotBlowUpWithNullName() - { - var manager = new Mock(); - var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ExternalCookie); - identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "foo")); - manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(identity, - new AuthenticationProperties(), new AuthenticationDescription()))); - var externalInfo = await manager.Object.GetExternalLoginInfoAsync(); - Assert.NotNull(externalInfo); - } + //[Fact] + //public async Task GetExternalLoginDoesNotBlowUpWithNullName() + //{ + // var manager = new Mock(); + // var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ExternalCookie); + // identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "foo")); + // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(identity, + // new AuthenticationProperties(), new AuthenticationDescription()))); + // var externalInfo = await manager.Object.GetExternalLoginInfoAsync(); + // Assert.NotNull(externalInfo); + //} - [Fact] - public async Task GetExternalLoginReturnsNullIfNoExternalIdTest() - { - var manager = new Mock(); - manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns(Task.FromResult(null)); - Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); - } + //[Fact] + //public async Task GetExternalLoginReturnsNullIfNoExternalIdTest() + //{ + // var manager = new Mock(); + // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns(Task.FromResult(null)); + // Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); + //} - [Fact] - public async Task GetExternalLoginWithXsrfReturnsNullIfNoNameIdentifierTest() - { - var manager = new Mock(); - manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), - new AuthenticationProperties(), new AuthenticationDescription()))); - Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); - } + //[Fact] + //public async Task GetExternalLoginWithXsrfReturnsNullIfNoNameIdentifierTest() + //{ + // var manager = new Mock(); + // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), + // new AuthenticationProperties(), new AuthenticationDescription()))); + // Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); + //} - [Fact] - public async Task GetExternalLoginWithXsrfReturnsNullIfNoClaimsIdentityTest() - { - var manager = new Mock(); - manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(null, new AuthenticationProperties(), - new AuthenticationDescription()))); - Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); - } + //[Fact] + //public async Task GetExternalLoginWithXsrfReturnsNullIfNoClaimsIdentityTest() + //{ + // var manager = new Mock(); + // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(null, new AuthenticationProperties(), + // new AuthenticationDescription()))); + // Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); + //} - [Fact] - public async Task GetExternalLoginTest() - { - var mockManager = new Mock(); - var props = new AuthenticationProperties(); - var loginInfo = new ExternalLoginInfo - { - Login = new UserLoginInfo("loginProvider", "key"), - DefaultUserName = "Hao Kung" - }; - var identity = CreateIdentity(loginInfo); - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription()))); - var manager = mockManager.Object; - var externalInfo = await manager.GetExternalLoginInfoAsync(); - Assert.NotNull(externalInfo); - Assert.Equal(identity, externalInfo.ExternalIdentity); - Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - Assert.Equal("HaoKung", externalInfo.DefaultUserName); - } + //[Fact] + //public async Task GetExternalLoginTest() + //{ + // var mockManager = new Mock(); + // var props = new AuthenticationProperties(); + // var loginInfo = new ExternalLoginInfo + // { + // Login = new UserLoginInfo("loginProvider", "key"), + // DefaultUserName = "Hao Kung" + // }; + // var identity = CreateIdentity(loginInfo); + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription()))); + // var manager = mockManager.Object; + // var externalInfo = await manager.GetExternalLoginInfoAsync(); + // Assert.NotNull(externalInfo); + // Assert.Equal(identity, externalInfo.ExternalIdentity); + // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + // Assert.Equal("HaoKung", externalInfo.DefaultUserName); + //} - [Fact] - public void GetExternalLoginSyncTest() - { - var mockManager = new Mock(); - var props = new AuthenticationProperties(); - var loginInfo = new ExternalLoginInfo - { - Login = new UserLoginInfo("loginProvider", "key"), - DefaultUserName = "Hao Kung" - }; - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - new AuthenticationDescription()))); - var manager = mockManager.Object; - var externalInfo = manager.GetExternalLoginInfo(); - Assert.NotNull(externalInfo); - Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - Assert.Equal("HaoKung", externalInfo.DefaultUserName); - } + //[Fact] + //public void GetExternalLoginSyncTest() + //{ + // var mockManager = new Mock(); + // var props = new AuthenticationProperties(); + // var loginInfo = new ExternalLoginInfo + // { + // Login = new UserLoginInfo("loginProvider", "key"), + // DefaultUserName = "Hao Kung" + // }; + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, + // new AuthenticationDescription()))); + // var manager = mockManager.Object; + // var externalInfo = manager.GetExternalLoginInfo(); + // Assert.NotNull(externalInfo); + // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + // Assert.Equal("HaoKung", externalInfo.DefaultUserName); + //} - [Fact] - public async Task GetExternalLoginWithXsrfTest() - { - var mockManager = new Mock(); - var props = new AuthenticationProperties(); - props.Dictionary["xsrfKey"] = "Hao"; - var loginInfo = new ExternalLoginInfo - { - Login = new UserLoginInfo("loginProvider", "key"), - DefaultUserName = "Hao Kung" - }; - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - new AuthenticationDescription()))); - var manager = mockManager.Object; - var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "Hao"); - Assert.NotNull(externalInfo); - Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - Assert.Equal("HaoKung", externalInfo.DefaultUserName); - } + //[Fact] + //public async Task GetExternalLoginWithXsrfTest() + //{ + // var mockManager = new Mock(); + // var props = new AuthenticationProperties(); + // props.Dictionary["xsrfKey"] = "Hao"; + // var loginInfo = new ExternalLoginInfo + // { + // Login = new UserLoginInfo("loginProvider", "key"), + // DefaultUserName = "Hao Kung" + // }; + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, + // new AuthenticationDescription()))); + // var manager = mockManager.Object; + // var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "Hao"); + // Assert.NotNull(externalInfo); + // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + // Assert.Equal("HaoKung", externalInfo.DefaultUserName); + //} - [Fact] - public void GetExternalLoginWithXsrfSyncTest() - { - var mockManager = new Mock(); - var props = new AuthenticationProperties(); - props.Dictionary["xsrfKey"] = "Hao"; - var loginInfo = new ExternalLoginInfo - { - Login = new UserLoginInfo("loginProvider", "key"), - DefaultUserName = "Hao Kung" - }; - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - new AuthenticationDescription()))); - var manager = mockManager.Object; - var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "Hao"); - Assert.NotNull(externalInfo); - Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - Assert.Equal("HaoKung", externalInfo.DefaultUserName); - } + //[Fact] + //public void GetExternalLoginWithXsrfSyncTest() + //{ + // var mockManager = new Mock(); + // var props = new AuthenticationProperties(); + // props.Dictionary["xsrfKey"] = "Hao"; + // var loginInfo = new ExternalLoginInfo + // { + // Login = new UserLoginInfo("loginProvider", "key"), + // DefaultUserName = "Hao Kung" + // }; + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, + // new AuthenticationDescription()))); + // var manager = mockManager.Object; + // var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "Hao"); + // Assert.NotNull(externalInfo); + // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + // Assert.Equal("HaoKung", externalInfo.DefaultUserName); + //} - [Fact] - public async Task GetExternalLoginNullIfXsrfFailsTest() - { - var mockManager = new Mock(); - var props = new AuthenticationProperties(); - props.Dictionary["xsrfKey"] = "Hao"; - var loginInfo = new ExternalLoginInfo - { - Login = new UserLoginInfo("loginProvider", "key"), - DefaultUserName = "Hao Kung" - }; - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - new AuthenticationDescription()))); - var manager = mockManager.Object; - var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "NotHao"); - Assert.Null(externalInfo); - } + //[Fact] + //public async Task GetExternalLoginNullIfXsrfFailsTest() + //{ + // var mockManager = new Mock(); + // var props = new AuthenticationProperties(); + // props.Dictionary["xsrfKey"] = "Hao"; + // var loginInfo = new ExternalLoginInfo + // { + // Login = new UserLoginInfo("loginProvider", "key"), + // DefaultUserName = "Hao Kung" + // }; + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, + // new AuthenticationDescription()))); + // var manager = mockManager.Object; + // var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "NotHao"); + // Assert.Null(externalInfo); + //} - [Fact] - public void GetExternalLoginNullIfXsrfFailsSyncTest() - { - var mockManager = new Mock(); - var props = new AuthenticationProperties(); - props.Dictionary["xsrfKey"] = "Hao"; - var loginInfo = new ExternalLoginInfo - { - Login = new UserLoginInfo("loginProvider", "key"), - DefaultUserName = "Hao Kung" - }; - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - new AuthenticationDescription()))); - var manager = mockManager.Object; - var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "NotHao"); - Assert.Null(externalInfo); - } + //[Fact] + //public void GetExternalLoginNullIfXsrfFailsSyncTest() + //{ + // var mockManager = new Mock(); + // var props = new AuthenticationProperties(); + // props.Dictionary["xsrfKey"] = "Hao"; + // var loginInfo = new ExternalLoginInfo + // { + // Login = new UserLoginInfo("loginProvider", "key"), + // DefaultUserName = "Hao Kung" + // }; + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, + // new AuthenticationDescription()))); + // var manager = mockManager.Object; + // var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "NotHao"); + // Assert.Null(externalInfo); + //} - [Fact] - public async Task GetExternalIdentityReturnsNullIfNoNameIdentifierTest() - { - var manager = new Mock(); - manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), - new AuthenticationProperties(), new AuthenticationDescription()))); - Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); - } + //[Fact] + //public async Task GetExternalIdentityReturnsNullIfNoNameIdentifierTest() + //{ + // var manager = new Mock(); + // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), + // new AuthenticationProperties(), new AuthenticationDescription()))); + // Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); + //} - [Fact] - public async Task GetExternalIdentityReturnsNullIfNullNameTest() - { - var manager = new Mock(); - manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateNoClaimIdentity("authtype"), - new AuthenticationProperties(), new AuthenticationDescription()))); - Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); - } + //[Fact] + //public async Task GetExternalIdentityReturnsNullIfNullNameTest() + //{ + // var manager = new Mock(); + // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateNoClaimIdentity("authtype"), + // new AuthenticationProperties(), new AuthenticationDescription()))); + // Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); + //} - [Fact] - public async Task GetExternalIdentityTest() - { - var mockManager = new Mock(); - var props = new AuthenticationProperties(); - var loginInfo = new ExternalLoginInfo - { - Login = new UserLoginInfo("loginProvider", "key"), - DefaultUserName = "Hao Kung" - }; - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - new AuthenticationDescription()))); - var manager = mockManager.Object; - var id = await manager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); - Assert.NotNull(id); - var idClaim = id.FindFirst(ClaimTypes.NameIdentifier); - Assert.NotNull(idClaim); - Assert.Equal(loginInfo.Login.LoginProvider, idClaim.Issuer); - Assert.Equal(loginInfo.Login.ProviderKey, idClaim.Value); - Assert.Equal(loginInfo.DefaultUserName, id.Name); - } + //[Fact] + //public async Task GetExternalIdentityTest() + //{ + // var mockManager = new Mock(); + // var props = new AuthenticationProperties(); + // var loginInfo = new ExternalLoginInfo + // { + // Login = new UserLoginInfo("loginProvider", "key"), + // DefaultUserName = "Hao Kung" + // }; + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, + // new AuthenticationDescription()))); + // var manager = mockManager.Object; + // var id = await manager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); + // Assert.NotNull(id); + // var idClaim = id.FindFirst(ClaimTypes.NameIdentifier); + // Assert.NotNull(idClaim); + // Assert.Equal(loginInfo.Login.LoginProvider, idClaim.Issuer); + // Assert.Equal(loginInfo.Login.ProviderKey, idClaim.Value); + // Assert.Equal(loginInfo.DefaultUserName, id.Name); + //} - [Fact] - public void CreateRememberBrowserIdentityTest() - { - var mockManager = new Mock(); - var manager = mockManager.Object; - var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); - Assert.NotNull(identity); - Assert.Equal("userId", identity.GetUserId()); - Assert.Equal(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie, identity.AuthenticationType); - } + //[Fact] + //public void CreateRememberBrowserIdentityTest() + //{ + // var mockManager = new Mock(); + // var manager = mockManager.Object; + // var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); + // Assert.NotNull(identity); + // Assert.Equal("userId", identity.GetUserId()); + // Assert.Equal(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie, identity.AuthenticationType); + //} - [Fact] - public async Task BrowserRemeberedTest() - { - var mockManager = new Mock(); - var manager = mockManager.Object; - var props = new AuthenticationProperties(); - var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) - .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription()))); - Assert.True(await manager.TwoFactorBrowserRememberedAsync("userId")); - Assert.False(await manager.TwoFactorBrowserRememberedAsync("userNotId")); - } + //[Fact] + //public async Task BrowserRemeberedTest() + //{ + // var mockManager = new Mock(); + // var manager = mockManager.Object; + // var props = new AuthenticationProperties(); + // var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) + // .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription()))); + // Assert.True(await manager.TwoFactorBrowserRememberedAsync("userId")); + // Assert.False(await manager.TwoFactorBrowserRememberedAsync("userNotId")); + //} - [Fact] - public async Task BrowserRemeberedFailWithNoIdentityTest() - { - var mockManager = new Mock(); - var manager = mockManager.Object; - var props = new AuthenticationProperties(); - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) - .Returns(Task.FromResult(new AuthenticateResult(null, props, new AuthenticationDescription()))); - Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); - } + //[Fact] + //public async Task BrowserRemeberedFailWithNoIdentityTest() + //{ + // var mockManager = new Mock(); + // var manager = mockManager.Object; + // var props = new AuthenticationProperties(); + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) + // .Returns(Task.FromResult(new AuthenticateResult(null, props, new AuthenticationDescription()))); + // Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); + //} - [Fact] - public async Task BrowserRemeberedFailWithWrongIdentityTest() - { - var mockManager = new Mock(); - var manager = mockManager.Object; - var props = new AuthenticationProperties(); - mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) - .Returns( - Task.FromResult(new AuthenticateResult(new ClaimsIdentity("whatever"), props, - new AuthenticationDescription()))); - Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); - } + //[Fact] + //public async Task BrowserRemeberedFailWithWrongIdentityTest() + //{ + // var mockManager = new Mock(); + // var manager = mockManager.Object; + // var props = new AuthenticationProperties(); + // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) + // .Returns( + // Task.FromResult(new AuthenticateResult(new ClaimsIdentity("whatever"), props, + // new AuthenticationDescription()))); + // Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); + //} - public static ClaimsIdentity CreateNoNameIdentifierIdentity(string name, string authenticationType) - { - return new ClaimsIdentity( - new[] - { - new Claim(ClaimTypes.Name, name) - }, - authenticationType); - } + //public static ClaimsIdentity CreateNoNameIdentifierIdentity(string name, string authenticationType) + //{ + // return new ClaimsIdentity( + // new[] + // { + // new Claim(ClaimTypes.Name, name) + // }, + // authenticationType); + //} - public static ClaimsIdentity CreateNoClaimIdentity(string authenticationType) - { - return new ClaimsIdentity( - new Claim[] {}, - authenticationType); - } + //public static ClaimsIdentity CreateNoClaimIdentity(string authenticationType) + //{ + // return new ClaimsIdentity( + // new Claim[] {}, + // authenticationType); + //} - public static ClaimsIdentity CreateIdentity(ExternalLoginInfo info) - { - return new ClaimsIdentity( - new[] - { - new Claim(ClaimTypes.NameIdentifier, info.Login.ProviderKey, null, info.Login.LoginProvider), - new Claim(ClaimTypes.Name, info.DefaultUserName) - }, - info.Login.LoginProvider); - } + //public static ClaimsIdentity CreateIdentity(ExternalLoginInfo info) + //{ + // return new ClaimsIdentity( + // new[] + // { + // new Claim(ClaimTypes.NameIdentifier, info.Login.ProviderKey, null, info.Login.LoginProvider), + // new Claim(ClaimTypes.Name, info.DefaultUserName) + // }, + // info.Login.LoginProvider); + //} } } \ No newline at end of file diff --git a/test/Identity.Test/CustomGuidKeyTest.cs b/test/Identity.Test/CustomGuidKeyTest.cs index 023f500..db42090 100644 --- a/test/Identity.Test/CustomGuidKeyTest.cs +++ b/test/Identity.Test/CustomGuidKeyTest.cs @@ -8,11 +8,11 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Cookies; -using Microsoft.Owin.Security.DataProtection; +//using Microsoft.AspNet.Identity.Owin; +//using Microsoft.Owin; +//using Microsoft.Owin.Security; +//using Microsoft.Owin.Security.Cookies; +//using Microsoft.Owin.Security.DataProtection; using Xunit; namespace Identity.Test @@ -82,104 +82,104 @@ public async Task CustomGuidGetRolesForUserTest() } } - [Fact] - public async Task CustomGuidConfirmEmailTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new GuidUser("test"); - Assert.False(user.EmailConfirmed); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); - Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); - UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); - Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - } + //[Fact] + //public async Task CustomGuidConfirmEmailTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new GuidUser("test"); + // Assert.False(user.EmailConfirmed); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); + // Assert.NotNull(token); + // UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); + // Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); + // UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); + // Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); + //} - [Fact] - public async Task CustomGuidEmailTokenFactorWithFormatTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - var factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - { - Subject = "Security Code", - BodyFormat = "Your code is: {0}" - }); - var user = new GuidUser("EmailCodeTest"); - user.Email = "foo@foo.com"; - var password = "password"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token); - Assert.NotNull(messageService.Message); - Assert.Equal("Security Code", messageService.Message.Subject); - Assert.Equal("Your code is: " + token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - } + //[Fact] + //public async Task CustomGuidEmailTokenFactorWithFormatTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var messageService = new TestMessageService(); + // manager.EmailService = messageService; + // var factorId = "EmailCode"; + // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider + // { + // Subject = "Security Code", + // BodyFormat = "Your code is: {0}" + // }); + // var user = new GuidUser("EmailCodeTest"); + // user.Email = "foo@foo.com"; + // var password = "password"; + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + // var stamp = user.SecurityStamp; + // Assert.NotNull(stamp); + // var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + // Assert.NotNull(token); + // Assert.Null(messageService.Message); + // await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token); + // Assert.NotNull(messageService.Message); + // Assert.Equal("Security Code", messageService.Message.Subject); + // Assert.Equal("Your code is: " + token, messageService.Message.Body); + // Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + //} - [Fact] - public async Task OnValidateIdentityWithGuidTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new GuidUser {UserName = "test"}; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var id = await SignIn(manager, user); - var ticket = new AuthenticationTicket(id, new AuthenticationProperties {IssuedUtc = DateTimeOffset.UtcNow}); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - await - SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, - SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); - Assert.NotNull(context.Identity); - Assert.Equal(user.Id.ToString(), id.GetUserId()); + //[Fact] + //public async Task OnValidateIdentityWithGuidTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new GuidUser {UserName = "test"}; + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var id = await SignIn(manager, user); + // var ticket = new AuthenticationTicket(id, new AuthenticationProperties {IssuedUtc = DateTimeOffset.UtcNow}); + // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + // await + // SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, + // SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); + // Assert.NotNull(context.Identity); + // Assert.Equal(user.Id.ToString(), id.GetUserId()); - // change stamp and make sure it fails - UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - await - SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, - SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); - Assert.Null(context.Identity); - } + // // change stamp and make sure it fails + // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + // await + // SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, + // SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); + // Assert.Null(context.Identity); + //} - private Task SignIn(UserManager manager, GuidUser user) - { - return manager.ClaimsIdentityFactory.CreateAsync(manager, user, DefaultAuthenticationTypes.ApplicationCookie); - } + //private Task SignIn(UserManager manager, GuidUser user) + //{ + // return manager.ClaimsIdentityFactory.CreateAsync(manager, user, DefaultAuthenticationTypes.ApplicationCookie); + //} - private async Task CreateManager(OwinContext context) - { - var options = new IdentityFactoryOptions> - { - Provider = new TestProvider(), - DataProtectionProvider = new DpapiDataProtectionProvider() - }; - var middleware = - new IdentityFactoryMiddleware - , IdentityFactoryOptions>>(null, options); - var dbMiddle = new IdentityFactoryMiddleware>(middleware, - new IdentityFactoryOptions - { - Provider = new IdentityFactoryProvider - { - OnCreate = (o, c) => GuidUserContext.Create(), - } - }); - await dbMiddle.Invoke(context); - } + //private async Task CreateManager(OwinContext context) + //{ + // var options = new IdentityFactoryOptions> + // { + // Provider = new TestProvider(), + // DataProtectionProvider = new DpapiDataProtectionProvider() + // }; + // var middleware = + // new IdentityFactoryMiddleware + // , IdentityFactoryOptions>>(null, options); + // var dbMiddle = new IdentityFactoryMiddleware>(middleware, + // new IdentityFactoryOptions + // { + // Provider = new IdentityFactoryProvider + // { + // OnCreate = (o, c) => GuidUserContext.Create(), + // } + // }); + // await dbMiddle.Invoke(context); + //} public class GuidRole : IdentityRole { @@ -247,27 +247,27 @@ public GuidUserStore(DbContext context) } } - private class TestProvider : IdentityFactoryProvider> - { - public TestProvider() - { - OnCreate = ((options, context) => - { - var manager = new UserManager(new GuidUserStore(context.Get())); - manager.UserValidator = new UserValidator(manager) - { - AllowOnlyAlphanumericUserNames = true, - RequireUniqueEmail = false - }; - if (options.DataProtectionProvider != null) - { - manager.UserTokenProvider = - new DataProtectorTokenProvider( - options.DataProtectionProvider.Create("ASP.NET Identity")); - } - return manager; - }); - } - } + //private class TestProvider : IdentityFactoryProvider> + //{ + // public TestProvider() + // { + // OnCreate = ((options, context) => + // { + // var manager = new UserManager(new GuidUserStore(context.Get())); + // manager.UserValidator = new UserValidator(manager) + // { + // AllowOnlyAlphanumericUserNames = true, + // RequireUniqueEmail = false + // }; + // if (options.DataProtectionProvider != null) + // { + // manager.UserTokenProvider = + // new DataProtectorTokenProvider( + // options.DataProtectionProvider.Create("ASP.NET Identity")); + // } + // return manager; + // }); + // } + //} } } \ No newline at end of file diff --git a/test/Identity.Test/CustomIntKeyTest.cs b/test/Identity.Test/CustomIntKeyTest.cs index 7c6622a..acbf272 100644 --- a/test/Identity.Test/CustomIntKeyTest.cs +++ b/test/Identity.Test/CustomIntKeyTest.cs @@ -6,9 +6,9 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security.DataProtection; +//using Microsoft.AspNet.Identity.Owin; +//using Microsoft.Owin; +//using Microsoft.Owin.Security.DataProtection; using Xunit; namespace Identity.Test @@ -89,30 +89,30 @@ public async Task CustomIntGetRolesForUserTest() } } - [Fact] - public async Task IntKeyConfirmEmailTest() - { - var manager = CreateManager(); - var user = new CustomUser("testEmailConfirm"); - Assert.False(user.EmailConfirmed); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); - Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); - UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); - Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - } - - private UserManager CreateManager() - { - var options = new IdentityFactoryOptions> - { - Provider = new TestProvider(), - DataProtectionProvider = new DpapiDataProtectionProvider() - }; - return options.Provider.Create(options, new OwinContext()); - } + //[Fact] + //public async Task IntKeyConfirmEmailTest() + //{ + // var manager = CreateManager(); + // var user = new CustomUser("testEmailConfirm"); + // Assert.False(user.EmailConfirmed); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); + // Assert.NotNull(token); + // UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); + // Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); + // UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); + // Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); + //} + + //private UserManager CreateManager() + //{ + // var options = new IdentityFactoryOptions> + // { + // Provider = new TestProvider(), + // DataProtectionProvider = new DpapiDataProtectionProvider() + // }; + // return options.Provider.Create(options, new OwinContext()); + //} public class CustomRole : IdentityRole { @@ -172,30 +172,30 @@ public CustomUserStore(DbContext context) } } - private class TestProvider : IdentityFactoryProvider> - { - public TestProvider() - { - OnCreate = ((options, context) => - { - Database.SetInitializer(new DropCreateDatabaseAlways()); - var db = new CustomUserContext(); - db.Database.Initialize(true); - var manager = new UserManager(new CustomUserStore(db)); - manager.UserValidator = new UserValidator(manager) - { - AllowOnlyAlphanumericUserNames = true, - RequireUniqueEmail = false - }; - if (options.DataProtectionProvider != null) - { - manager.UserTokenProvider = - new DataProtectorTokenProvider( - options.DataProtectionProvider.Create("ASP.NET Identity")); - } - return manager; - }); - } - } + //private class TestProvider : IdentityFactoryProvider> + //{ + // public TestProvider() + // { + // OnCreate = ((options, context) => + // { + // Database.SetInitializer(new DropCreateDatabaseAlways()); + // var db = new CustomUserContext(); + // db.Database.Initialize(true); + // var manager = new UserManager(new CustomUserStore(db)); + // manager.UserValidator = new UserValidator(manager) + // { + // AllowOnlyAlphanumericUserNames = true, + // RequireUniqueEmail = false + // }; + // if (options.DataProtectionProvider != null) + // { + // manager.UserTokenProvider = + // new DataProtectorTokenProvider( + // options.DataProtectionProvider.Create("ASP.NET Identity")); + // } + // return manager; + // }); + // } + //} } } \ No newline at end of file diff --git a/test/Identity.Test/ExceptionHelper.cs b/test/Identity.Test/ExceptionHelper.cs index b8627bc..368badb 100644 --- a/test/Identity.Test/ExceptionHelper.cs +++ b/test/Identity.Test/ExceptionHelper.cs @@ -8,7 +8,7 @@ namespace Identity.Test { public static class ExceptionHelper { - public static TException ThrowsWithError(Assert.ThrowsDelegate act, string error) + public static TException ThrowsWithError(Action act, string error) where TException : Exception { var e = Assert.Throws(act); @@ -19,7 +19,7 @@ public static TException ThrowsWithError(Assert.ThrowsDelegate act, return e; } - public static ArgumentException ThrowsArgumentException(Assert.ThrowsDelegate del, string exceptionMessage, + public static ArgumentException ThrowsArgumentException(Action del, string exceptionMessage, string paramName) { var e = Assert.Throws(del); @@ -33,13 +33,13 @@ public static ArgumentException ThrowsArgumentException(Assert.ThrowsDelegate de return e; } - public static ArgumentException ThrowsArgumentNullOrEmpty(Assert.ThrowsDelegate del, string paramName) + public static ArgumentException ThrowsArgumentNullOrEmpty(Action del, string paramName) { return ThrowsArgumentException(del, "Value cannot be null or empty.\r\nParameter name: " + paramName, paramName); } - public static ArgumentNullException ThrowsArgumentNull(Assert.ThrowsDelegate del, string paramName) + public static ArgumentNullException ThrowsArgumentNull(Action del, string paramName) { var e = Assert.Throws(del); Assert.Equal(paramName, e.ParamName); diff --git a/test/Identity.Test/Identity.Test.csproj b/test/Identity.Test/Identity.Test.csproj index 9e2b927..431f760 100644 --- a/test/Identity.Test/Identity.Test.csproj +++ b/test/Identity.Test/Identity.Test.csproj @@ -1,177 +1,30 @@ - - + - Debug - AnyCPU - {A7082BDD-985B-47B9-915B-7FA4CF541B5E} - Library - bin\$(Configuration) - Properties - Identity.Test - Identity.Test - v4.5 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - SAK - SAK - SAK - SAK - ..\..\ - true + net8.0 + enable + enable + false + true + false + Identity.SystemWeb.Test + Microsoft + Identity.SystemWeb.Test + Copyright © Microsoft 2013 + 1.0.0.0 + 1.0.0.0 - - true - full - false - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - TRACE - prompt - 4 - - - true - - - true - - - 35MSSharedLib1024.snk - - - - False - ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll - - - False - ..\..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll - - - ..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll - - - ..\..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll - - - ..\..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll - - - ..\..\packages\Moq.4.0.10827\lib\NET40\Moq.dll - - - - - - - - - - - - False - ..\..\packages\xunit.1.9.2\lib\net20\xunit.dll - - - ..\..\packages\xunit.extensions.1.9.2\lib\net20\xunit.extensions.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - + + - - {d2f24972-0f56-4c18-bd65-c26a320a0c68} - Microsoft.AspNet.Identity.Core - - - {d7298dad-ab04-4502-9567-0461d0ad059e} - Microsoft.AspNet.Identity.EntityFramework - - - {943170eb-f4e7-4a6d-989e-2cf6c681dd89} - Microsoft.AspNet.Identity.Owin - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - - - - - False - - - False - - - False - - - False - - - - - - - - \ No newline at end of file diff --git a/test/Identity.Test/OwinContextExtensionsTest.cs b/test/Identity.Test/OwinContextExtensionsTest.cs deleted file mode 100644 index dda09fe..0000000 --- a/test/Identity.Test/OwinContextExtensionsTest.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) Microsoft Corporation, Inc. All rights reserved. -// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. - -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Xunit; - -namespace Identity.Test -{ - public class OwinContextExtensionsTest - { - [Fact] - public void MiddlewareExtensionsNullCheckTest() - { - IOwinContext context = null; - ExceptionHelper.ThrowsArgumentNull(() => context.Get(), "context"); - ExceptionHelper.ThrowsArgumentNull(() => context.GetUserManager(), "context"); - ExceptionHelper.ThrowsArgumentNull(() => context.Set(null), "context"); - } - } -} \ No newline at end of file diff --git a/test/Identity.Test/Properties/AssemblyInfo.cs b/test/Identity.Test/Properties/AssemblyInfo.cs index 9c41958..d65672f 100644 --- a/test/Identity.Test/Properties/AssemblyInfo.cs +++ b/test/Identity.Test/Properties/AssemblyInfo.cs @@ -3,17 +3,6 @@ using System.Reflection; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. - -[assembly: AssemblyTitle("Identity.SystemWeb.Test")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("Microsoft")] -[assembly: AssemblyProduct("Identity.SystemWeb.Test")] -[assembly: AssemblyCopyright("Copyright © Microsoft 2013")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -26,17 +15,3 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("227caea7-5b0c-42be-91d6-c395febe58ef")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] - -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/test/Identity.Test/SecurityStampTest.cs b/test/Identity.Test/SecurityStampTest.cs index 83738c0..ddfb9b1 100644 --- a/test/Identity.Test/SecurityStampTest.cs +++ b/test/Identity.Test/SecurityStampTest.cs @@ -6,193 +6,193 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security; -using Microsoft.Owin.Security.Cookies; -using Microsoft.Owin.Security.DataProtection; +//using Microsoft.AspNet.Identity.Owin; +//using Microsoft.Owin; +//using Microsoft.Owin.Security; +//using Microsoft.Owin.Security.Cookies; +//using Microsoft.Owin.Security.DataProtection; using Xunit; namespace Identity.Test { public class SecurityStampTest { - [Fact] - public async Task OnValidateIdentityNoBoomWithNullManagerTest() - { - var owinContext = new OwinContext(); - var id = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie); - var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - .Invoke(context); - Assert.NotNull(context.Identity); - } - - [Fact] - public void OnValidateIdentityThrowsOnNullGetIdCallback() - { - ExceptionHelper.ThrowsArgumentNull( - () => AsyncHelper.RunSync(() => SecurityStampValidator.OnValidateIdentity, IdentityUser, string>(TimeSpan.Zero, SignIn, null) - .Invoke(null)), "getUserIdCallback"); - } - - [Fact] - public async Task OnValidateIdentityTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var id = await SignIn(manager, user); - var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - .Invoke(context); - Assert.NotNull(context.Identity); - Assert.Equal(user.Id, id.GetUserId()); - - // change stamp and make sure it fails - UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - .Invoke(context); - Assert.Null(context.Identity); - } - - [Fact] - public async Task OnValidateRejectsUnknownUserIdentityTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var id = await SignIn(manager, user); - UnitTestHelper.IsSuccess(await manager.DeleteAsync(user)); - var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - .Invoke(context); - Assert.Null(context.Identity); - } - - [Fact] - public async Task OnValidateIdentityRejectsWithNoIssuedUtcTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var id = await SignIn(manager, user); - var ticket = new AuthenticationTicket(id, new AuthenticationProperties()); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - .Invoke(context); - Assert.NotNull(context.Identity); - Assert.Equal(user.Id, id.GetUserId()); - - // change stamp does fail validation when no utc - UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - .Invoke(context); - Assert.Null(context.Identity); - } - - [Fact] - public async Task OnValidateIdentityDoesNotRejectRightAwayTest() - { - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var id = await SignIn(manager, user); - var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - - // change stamp does not fail validation when not enough time elapsed - UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>( - TimeSpan.FromDays(1), SignIn).Invoke(context); - Assert.NotNull(context.Identity); - Assert.Equal(user.Id, id.GetUserId()); - } - - [Fact] - public async Task OnValidateIdentityResetsContextPropertiesDatesTest() - { - // Arrange - var owinContext = new OwinContext(); - await CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new IdentityUser(string.Format("{0}{1}", "test", new Random().Next())); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var id = await SignIn(manager, user); - var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromHours(1)), IsPersistent = true }); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - - await - SecurityStampValidator.OnValidateIdentity, IdentityUser>( - TimeSpan.Zero, SignIn).Invoke(context); - - // Assert - Assert.NotNull(context.Identity); - Assert.NotNull(context.Properties); - Assert.Null(context.Properties.IssuedUtc); - Assert.Null(context.Properties.ExpiresUtc); - Assert.True(context.Properties.IsPersistent); - } + //[Fact] + //public async Task OnValidateIdentityNoBoomWithNullManagerTest() + //{ + // var owinContext = new OwinContext(); + // var id = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie); + // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + // .Invoke(context); + // Assert.NotNull(context.Identity); + //} + + //[Fact] + //public void OnValidateIdentityThrowsOnNullGetIdCallback() + //{ + // ExceptionHelper.ThrowsArgumentNull( + // () => AsyncHelper.RunSync(() => SecurityStampValidator.OnValidateIdentity, IdentityUser, string>(TimeSpan.Zero, SignIn, null) + // .Invoke(null)), "getUserIdCallback"); + //} + + //[Fact] + //public async Task OnValidateIdentityTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new IdentityUser("test"); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var id = await SignIn(manager, user); + // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + // .Invoke(context); + // Assert.NotNull(context.Identity); + // Assert.Equal(user.Id, id.GetUserId()); + + // // change stamp and make sure it fails + // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + // .Invoke(context); + // Assert.Null(context.Identity); + //} + + //[Fact] + //public async Task OnValidateRejectsUnknownUserIdentityTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new IdentityUser("test"); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var id = await SignIn(manager, user); + // UnitTestHelper.IsSuccess(await manager.DeleteAsync(user)); + // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + // .Invoke(context); + // Assert.Null(context.Identity); + //} + + //[Fact] + //public async Task OnValidateIdentityRejectsWithNoIssuedUtcTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new IdentityUser("test"); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var id = await SignIn(manager, user); + // var ticket = new AuthenticationTicket(id, new AuthenticationProperties()); + // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + // .Invoke(context); + // Assert.NotNull(context.Identity); + // Assert.Equal(user.Id, id.GetUserId()); + + // // change stamp does fail validation when no utc + // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + // .Invoke(context); + // Assert.Null(context.Identity); + //} + + //[Fact] + //public async Task OnValidateIdentityDoesNotRejectRightAwayTest() + //{ + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new IdentityUser("test"); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var id = await SignIn(manager, user); + // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + + // // change stamp does not fail validation when not enough time elapsed + // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>( + // TimeSpan.FromDays(1), SignIn).Invoke(context); + // Assert.NotNull(context.Identity); + // Assert.Equal(user.Id, id.GetUserId()); + //} + + //[Fact] + //public async Task OnValidateIdentityResetsContextPropertiesDatesTest() + //{ + // // Arrange + // var owinContext = new OwinContext(); + // await CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new IdentityUser(string.Format("{0}{1}", "test", new Random().Next())); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var id = await SignIn(manager, user); + // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromHours(1)), IsPersistent = true }); + // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + + // await + // SecurityStampValidator.OnValidateIdentity, IdentityUser>( + // TimeSpan.Zero, SignIn).Invoke(context); + + // // Assert + // Assert.NotNull(context.Identity); + // Assert.NotNull(context.Properties); + // Assert.Null(context.Properties.IssuedUtc); + // Assert.Null(context.Properties.ExpiresUtc); + // Assert.True(context.Properties.IsPersistent); + //} private Task SignIn(UserManager manager, IdentityUser user) { return manager.ClaimsIdentityFactory.CreateAsync(manager, user, DefaultAuthenticationTypes.ApplicationCookie); } - private async Task CreateManager(OwinContext context) - { - var options = new IdentityFactoryOptions> - { - Provider = new TestProvider(), - DataProtectionProvider = new DpapiDataProtectionProvider() - }; - var middleware = - new IdentityFactoryMiddleware - , IdentityFactoryOptions>>(null, options); - await middleware.Invoke(context); - } - - private class TestProvider : IdentityFactoryProvider> - { - public TestProvider() - { - OnCreate = ((options, context) => - { - var manager = - new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); - manager.UserValidator = new UserValidator(manager) - { - AllowOnlyAlphanumericUserNames = true, - RequireUniqueEmail = false - }; - if (options.DataProtectionProvider != null) - { - manager.UserTokenProvider = - new DataProtectorTokenProvider( - options.DataProtectionProvider.Create("ASP.NET Identity")); - } - return manager; - }); - OnDispose = (options, manager) => { }; - } - } + //private async Task CreateManager(OwinContext context) + //{ + // var options = new IdentityFactoryOptions> + // { + // Provider = new TestProvider(), + // DataProtectionProvider = new DpapiDataProtectionProvider() + // }; + // var middleware = + // new IdentityFactoryMiddleware + // , IdentityFactoryOptions>>(null, options); + // await middleware.Invoke(context); + //} + + //private class TestProvider : IdentityFactoryProvider> + //{ + // public TestProvider() + // { + // OnCreate = ((options, context) => + // { + // var manager = + // new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); + // manager.UserValidator = new UserValidator(manager) + // { + // AllowOnlyAlphanumericUserNames = true, + // RequireUniqueEmail = false + // }; + // if (options.DataProtectionProvider != null) + // { + // manager.UserTokenProvider = + // new DataProtectorTokenProvider( + // options.DataProtectionProvider.Create("ASP.NET Identity")); + // } + // return manager; + // }); + // OnDispose = (options, manager) => { }; + // } + //} } } \ No newline at end of file diff --git a/test/Identity.Test/SignInManagerTest.cs b/test/Identity.Test/SignInManagerTest.cs index 03c815e..8b6adeb 100644 --- a/test/Identity.Test/SignInManagerTest.cs +++ b/test/Identity.Test/SignInManagerTest.cs @@ -5,9 +5,9 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security.DataProtection; +//using Microsoft.AspNet.Identity.Owin; +//using Microsoft.Owin; +//using Microsoft.Owin.Security.DataProtection; using Xunit; using Xunit.Extensions; @@ -15,24 +15,24 @@ namespace Identity.Test { public class SignInManagerTest { - [Theory] - [InlineData(true, true)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(false, false)] - public async Task SignInAsyncCookiePersistenceTest(bool isPersistent, bool rememberBrowser) - { - var owinContext = new OwinContext(); - await TestUtil.CreateManager(owinContext); - var manager = owinContext.GetUserManager>(); - var user = new IdentityUser("SignInTest"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var signInManager = new SignInManager(manager, owinContext.Authentication); + //[Theory] + //[InlineData(true, true)] + //[InlineData(true, false)] + //[InlineData(false, true)] + //[InlineData(false, false)] + //public async Task SignInAsyncCookiePersistenceTest(bool isPersistent, bool rememberBrowser) + //{ + // var owinContext = new OwinContext(); + // await TestUtil.CreateManager(owinContext); + // var manager = owinContext.GetUserManager>(); + // var user = new IdentityUser("SignInTest"); + // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + // var signInManager = new SignInManager(manager, owinContext.Authentication); - await signInManager.SignInAsync(user, isPersistent, rememberBrowser); + // await signInManager.SignInAsync(user, isPersistent, rememberBrowser); - Assert.Equal(isPersistent, owinContext.Authentication.AuthenticationResponseGrant.Properties.IsPersistent); - } + // Assert.Equal(isPersistent, owinContext.Authentication.AuthenticationResponseGrant.Properties.IsPersistent); + //} } } diff --git a/test/Identity.Test/TestUtil.cs b/test/Identity.Test/TestUtil.cs index 34aec5c..23253a3 100644 --- a/test/Identity.Test/TestUtil.cs +++ b/test/Identity.Test/TestUtil.cs @@ -6,9 +6,6 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin; -using Microsoft.Owin.Security.DataProtection; namespace Identity.Test { @@ -22,57 +19,25 @@ public static void SetupDatabase(string dataDirectory) where TDbCont public static UserManager CreateManager(DbContext db) { - var options = new IdentityFactoryOptions> + var manager = + new UserManager(new UserStore(db)); + manager.UserValidator = new UserValidator(manager) { - Provider = new TestProvider(db), - DataProtectionProvider = new DpapiDataProtectionProvider() + AllowOnlyAlphanumericUserNames = true, + RequireUniqueEmail = false }; - return options.Provider.Create(options, new OwinContext()); + manager.EmailService = new TestMessageService(); + manager.SmsService = new TestMessageService(); + //manager.UserTokenProvider = + // new DataProtectorTokenProvider( + // options.DataProtectionProvider.Create("ASP.NET Identity")); + return manager; } public static UserManager CreateManager() { return CreateManager(UnitTestHelper.CreateDefaultDb()); } - - public static async Task CreateManager(OwinContext context) - { - var options = new IdentityFactoryOptions> - { - Provider = new TestProvider(UnitTestHelper.CreateDefaultDb()), - DataProtectionProvider = new DpapiDataProtectionProvider() - }; - var middleware = - new IdentityFactoryMiddleware - , IdentityFactoryOptions>>(null, options); - await middleware.Invoke(context); - } - } - - public class TestProvider : IdentityFactoryProvider> - { - public TestProvider(DbContext db) - { - OnCreate = ((options, context) => - { - var manager = - new UserManager(new UserStore(db)); - manager.UserValidator = new UserValidator(manager) - { - AllowOnlyAlphanumericUserNames = true, - RequireUniqueEmail = false - }; - manager.EmailService = new TestMessageService(); - manager.SmsService = new TestMessageService(); - if (options.DataProtectionProvider != null) - { - manager.UserTokenProvider = - new DataProtectorTokenProvider( - options.DataProtectionProvider.Create("ASP.NET Identity")); - } - return manager; - }); - } } public class TestMessageService : IIdentityMessageService diff --git a/test/Identity.Test/UserManagerTest.cs b/test/Identity.Test/UserManagerTest.cs index 0ea90b0..5db39e5 100644 --- a/test/Identity.Test/UserManagerTest.cs +++ b/test/Identity.Test/UserManagerTest.cs @@ -10,8 +10,6 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -using Microsoft.AspNet.Identity.Owin; -using Microsoft.Owin.Security.DataProtection; using Xunit; using Moq; @@ -196,97 +194,6 @@ public void ManagerPublicNullCheckTest() ExceptionHelper.ThrowsArgumentNull(() => manager.RegisterTwoFactorProvider("bogus", null), "provider"); } - [Fact] - public void MethodsFailWithUnknownUserTest() - { - var db = UnitTestHelper.CreateDefaultDb(); - var manager = new UserManager(new UserStore(db)); - manager.UserTokenProvider = new NoOpTokenProvider(); - var error = "UserId not found."; - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.AddClaimAsync(null, new Claim("a", "b"))), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.AddLoginAsync(null, new UserLoginInfo("", ""))), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.AddPasswordAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.AddToRoleAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.AddToRolesAsync(null, "")), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.ChangePasswordAsync(null, null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetClaimsAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetLoginsAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetRolesAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.IsInRoleAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.RemoveClaimAsync(null, new Claim("a", "b"))), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.RemoveLoginAsync(null, new UserLoginInfo("", ""))), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.RemovePasswordAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.RemoveFromRoleAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.RemoveFromRolesAsync(null, "")), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.UpdateSecurityStampAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetSecurityStampAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.HasPasswordAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GeneratePasswordResetTokenAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.ResetPasswordAsync(null, null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.IsEmailConfirmedAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GenerateEmailConfirmationTokenAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.ConfirmEmailAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetEmailAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.SetEmailAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.IsPhoneNumberConfirmedAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.ChangePhoneNumberAsync(null, null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.VerifyChangePhoneNumberTokenAsync(null, null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetPhoneNumberAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.SetPhoneNumberAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetTwoFactorEnabledAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.SetTwoFactorEnabledAsync(null, true)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GenerateTwoFactorTokenAsync(null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.VerifyTwoFactorTokenAsync(null, null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.NotifyTwoFactorTokenAsync(null, null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.GetValidTwoFactorProvidersAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.VerifyUserTokenAsync(null, null, null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.AccessFailedAsync(null)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.SetLockoutEnabledAsync(null, false)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.SetLockoutEndDateAsync(null, DateTimeOffset.UtcNow)), error); - ExceptionHelper.ThrowsWithError( - () => AsyncHelper.RunSync(() => manager.IsLockedOutAsync(null)), error); - } - [Fact] public void MethodsThrowWhenDisposedTest() { @@ -463,1650 +370,6 @@ public async Task PasswordTooShortValidatorTest() "Passwords must be at least 6 characters."); } - [Fact] - public async Task CustomPasswordValidatorTest() - { - var manager = TestUtil.CreateManager(); - manager.PasswordValidator = new AlwaysBadValidator(); - UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser("Hao"), "password"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task PasswordValidatorTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("passwordValidator"); - manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true }; - const string alphaError = "Passwords must have at least one non letter or digit character."; - const string lengthError = "Passwords must be at least 6 characters."; - UnitTestHelper.IsFailure(await manager.CreateAsync(user, "ab@de"), lengthError); - UnitTestHelper.IsFailure(await manager.CreateAsync(user, "abcdef"), alphaError); - UnitTestHelper.IsFailure(await manager.CreateAsync(user, "___"), lengthError); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "abcd@e!ld!kajfd")); - UnitTestHelper.IsFailure(await manager.CreateAsync(user, "abcde"), lengthError + " " + alphaError); - } - - [Fact] - public async Task CustomPasswordValidatorBlocksAddPasswordTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - manager.PasswordValidator = new AlwaysBadValidator(); - UnitTestHelper.IsFailure(await manager.AddPasswordAsync(user.Id, "password"), - AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task CustomUserNameValidatorTest() - { - var manager = TestUtil.CreateManager(); - manager.UserValidator = new AlwaysBadValidator(); - var result = await manager.CreateAsync(new IdentityUser("Hao")); - UnitTestHelper.IsFailure(result, AlwaysBadValidator.ErrorMessage); - } - - [Fact] - public async Task BadValidatorBlocksAllUpdatesTest() - { - var db = UnitTestHelper.CreateDefaultDb(); - var manager = new UserManager(new UserStore(db)); - var user = new IdentityUser("poorguy"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - const string error = AlwaysBadValidator.ErrorMessage; - manager.UserValidator = new AlwaysBadValidator(); - manager.PasswordValidator = new NoopValidator(); - UnitTestHelper.IsFailure(await manager.AddClaimAsync(user.Id, new Claim("a", "b")), error); - UnitTestHelper.IsFailure(await manager.AddLoginAsync(user.Id, new UserLoginInfo("", "")), error); - UnitTestHelper.IsFailure(await manager.AddPasswordAsync(user.Id, "a"), error); - UnitTestHelper.IsFailure(await manager.ChangePasswordAsync(user.Id, "a", "b"), error); - UnitTestHelper.IsFailure(await manager.RemoveClaimAsync(user.Id, new Claim("a", "b")), error); - UnitTestHelper.IsFailure(await manager.RemoveLoginAsync(user.Id, new UserLoginInfo("aa", "bb")), error); - UnitTestHelper.IsFailure(await manager.RemovePasswordAsync(user.Id), error); - UnitTestHelper.IsFailure(await manager.UpdateSecurityStampAsync(user.Id), error); - } - - [Fact] - public async Task CreateLocalUserWithOnlyWhitespaceUserNameFails() - { - var manager = new UserManager(new UserStore()); - var result = await manager.CreateAsync(new IdentityUser { UserName = " " }, "password"); - UnitTestHelper.IsFailure(result, "Name cannot be null or empty."); - } - - [Fact] - public async Task CreateLocalUserWithInvalidUserNameFails() - { - var manager = TestUtil.CreateManager(); - var result = await manager.CreateAsync(new IdentityUser { UserName = "a\0b" }, "password"); - UnitTestHelper.IsFailure(result, "User name a\0b is invalid, can only contain letters or digits."); - } - - [Fact] - public async Task CreateLocalUserWithInvalidPasswordThrows() - { - var manager = TestUtil.CreateManager(); - var result = await manager.CreateAsync(new IdentityUser("Hao"), "aa"); - UnitTestHelper.IsFailure(result, "Passwords must be at least 6 characters."); - } - - [Fact] - public async Task CreateExternalUserWithNullFails() - { - var manager = TestUtil.CreateManager(); - UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser { UserName = null }), - "Name cannot be null or empty."); - } - - [Fact] - public async Task AddPasswordWhenPasswordSetFails() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("HasPassword"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "password")); - UnitTestHelper.IsFailure(await manager.AddPasswordAsync(user.Id, "User already has a password.")); - } - - private async Task LazyLoadTestSetup(DbContext db, IdentityUser user) - { - var manager = new UserManager(new UserStore(db)); - var role = new RoleManager(new RoleStore(db)); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, new UserLoginInfo("provider", "key"))); - UnitTestHelper.IsSuccess(await role.CreateAsync(new IdentityRole("Admin"))); - UnitTestHelper.IsSuccess(await role.CreateAsync(new IdentityRole("Local"))); - UnitTestHelper.IsSuccess(await manager.AddToRoleAsync(user.Id, "Admin")); - UnitTestHelper.IsSuccess(await manager.AddToRoleAsync(user.Id, "Local")); - Claim[] userClaims = - { - new Claim("Whatever", "Value"), - new Claim("Whatever2", "Value2") - }; - foreach (var c in userClaims) - { - UnitTestHelper.IsSuccess(await manager.AddClaimAsync(user.Id, c)); - } - } - - [Fact] - public async Task LazyLoadDisabledFindByIdTest() - { - var db = UnitTestHelper.CreateDefaultDb(); - var user = new IdentityUser("Hao"); - user.Email = "hao@foo.com"; - await LazyLoadTestSetup(db, user); - - // Ensure lazy loading is not broken - db = new IdentityDbContext(); - db.Configuration.LazyLoadingEnabled = false; - db.Configuration.ProxyCreationEnabled = false; - var manager = new UserManager(new UserStore(db)); - var userById = await manager.FindByIdAsync(user.Id); - Assert.True(userById.Claims.Count == 2); - Assert.True(userById.Logins.Count == 1); - Assert.True(userById.Roles.Count == 2); - } - - [Fact] - public async Task LazyLoadDisabledFindByNameTest() - { - var db = UnitTestHelper.CreateDefaultDb(); - var user = new IdentityUser("Hao") { Email = "hao@foo.com" }; - await LazyLoadTestSetup(db, user); - - // Ensure lazy loading is not broken - db = new IdentityDbContext(); - db.Configuration.LazyLoadingEnabled = false; - db.Configuration.ProxyCreationEnabled = false; - var manager = new UserManager(new UserStore(db)); - var userByName = await manager.FindByNameAsync(user.UserName); - Assert.True(userByName.Claims.Count == 2); - Assert.True(userByName.Logins.Count == 1); - Assert.True(userByName.Roles.Count == 2); - } - - [Fact] - public async Task LazyLoadDisabledFindByLoginTest() - { - var db = UnitTestHelper.CreateDefaultDb(); - var user = new IdentityUser("Hao") { Email = "hao@foo.com" }; - await LazyLoadTestSetup(db, user); - - // Ensure lazy loading is not broken - db = new IdentityDbContext(); - db.Configuration.LazyLoadingEnabled = false; - db.Configuration.ProxyCreationEnabled = false; - var manager = new UserManager(new UserStore(db)); - var userByLogin = await manager.FindAsync(new UserLoginInfo("provider", "key")); - Assert.True(userByLogin.Claims.Count == 2); - Assert.True(userByLogin.Logins.Count == 1); - Assert.True(userByLogin.Roles.Count == 2); - } - - [Fact] - public async Task LazyLoadDisabledFindByEmailTest() - { - var db = UnitTestHelper.CreateDefaultDb(); - var user = new IdentityUser("Hao") { Email = "hao@foo.com" }; - await LazyLoadTestSetup(db, user); - - // Ensure lazy loading is not broken - db = new IdentityDbContext(); - db.Configuration.LazyLoadingEnabled = false; - db.Configuration.ProxyCreationEnabled = false; - var manager = new UserManager(new UserStore(db)); - var userByEmail = await manager.FindByEmailAsync(user.Email); - Assert.True(userByEmail.Claims.Count == 2); - Assert.True(userByEmail.Logins.Count == 1); - Assert.True(userByEmail.Roles.Count == 2); - } - - [Fact] - public async Task FindNullIdTest() - { - var manager = TestUtil.CreateManager(); - Assert.Null(await manager.FindByIdAsync(null)); - } - - [Fact] - public async Task CreateLocalUserTest() - { - var manager = TestUtil.CreateManager(); - const string password = "password"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("CreateLocalUserTest"), password)); - var user = await manager.FindByNameAsync("CreateLocalUserTest"); - Assert.NotNull(user); - Assert.NotNull(user.PasswordHash); - Assert.True(await manager.HasPasswordAsync(user.Id)); - var logins = await manager.GetLoginsAsync(user.Id); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - } - - [Fact] - public void CreateLocalUserTestSync() - { - var manager = TestUtil.CreateManager(); - const string password = "password"; - UnitTestHelper.IsSuccess(manager.Create(new IdentityUser("CreateLocalUserTest"), password)); - var user = manager.FindByName("CreateLocalUserTest"); - Assert.NotNull(user); - Assert.NotNull(user.PasswordHash); - Assert.True(manager.HasPassword(user.Id)); - var logins = manager.GetLogins(user.Id); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - } - - [Fact] - public async Task DeleteUserTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("Delete"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - UnitTestHelper.IsSuccess(await manager.DeleteAsync(user)); - Assert.Null(await manager.FindByIdAsync(user.Id)); - } - - [Fact] - public void DeleteUserSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("Delete"); - UnitTestHelper.IsSuccess(manager.Create(user)); - UnitTestHelper.IsSuccess(manager.Delete(user)); - Assert.Null(manager.FindById(user.Id)); - } - - [Fact] - public async Task CreateUserAddLoginTest() - { - var manager = TestUtil.CreateManager(); - const string userName = "CreateExternalUserTest"; - const string provider = "ZzAuth"; - const string providerKey = "HaoKey"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser(userName))); - var user = await manager.FindByNameAsync(userName); - var login = new UserLoginInfo(provider, providerKey); - UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); - var logins = await manager.GetLoginsAsync(user.Id); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(provider, logins.First().LoginProvider); - Assert.Equal(providerKey, logins.First().ProviderKey); - } - - [Fact] - public void CreateUserAddLoginSyncTest() - { - var manager = TestUtil.CreateManager(); - const string userName = "CreateExternalUserTest"; - const string provider = "ZzAuth"; - const string providerKey = "HaoKey"; - UnitTestHelper.IsSuccess(manager.Create(new IdentityUser(userName))); - var user = manager.FindByName(userName); - var login = new UserLoginInfo(provider, providerKey); - UnitTestHelper.IsSuccess(manager.AddLogin(user.Id, login)); - var logins = manager.GetLogins(user.Id); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(provider, logins.First().LoginProvider); - Assert.Equal(providerKey, logins.First().ProviderKey); - } - - [Fact] - public async Task CreateUserLoginAndAddPasswordTest() - { - var manager = TestUtil.CreateManager(); - var login = new UserLoginInfo("Provider", "key"); - var user = new IdentityUser("CreateUserLoginAddPasswordTest"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); - UnitTestHelper.IsSuccess(await manager.AddPasswordAsync(user.Id, "password")); - var logins = await manager.GetLoginsAsync(user.Id); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(user, await manager.FindAsync(login)); - Assert.Equal(user, await manager.FindAsync(user.UserName, "password")); - Assert.True(await manager.CheckPasswordAsync(user, "password")); - } - - [Fact] - public void CreateUserLoginAndAddPasswordSyncTest() - { - var manager = TestUtil.CreateManager(); - var login = new UserLoginInfo("Provider", "key"); - var user = new IdentityUser("CreateUserLoginAddPasswordTest"); - UnitTestHelper.IsSuccess(manager.Create(user)); - UnitTestHelper.IsSuccess(manager.AddLogin(user.Id, login)); - UnitTestHelper.IsSuccess(manager.AddPassword(user.Id, "password")); - var logins = manager.GetLogins(user.Id); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(user, manager.Find(login)); - Assert.Equal(user, manager.Find(user.UserName, "password")); - Assert.True(manager.CheckPassword(user, "password")); - } - - [Fact] - public async Task CreateUserAddRemoveLoginTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("CreateUserAddRemoveLoginTest"); - var login = new UserLoginInfo("Provider", "key"); - const string password = "password"; - var result = await manager.CreateAsync(user, password); - Assert.NotNull(user); - UnitTestHelper.IsSuccess(result); - UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); - Assert.Equal(user, await manager.FindAsync(login)); - var logins = await manager.GetLoginsAsync(user.Id); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); - Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); - var stamp = await manager.GetSecurityStampAsync(user.Id); - UnitTestHelper.IsSuccess(await manager.RemoveLoginAsync(user.Id, login)); - Assert.Null(await manager.FindAsync(login)); - logins = await manager.GetLoginsAsync(user.Id); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public void CreateUserAddRemoveLoginSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("CreateUserAddRemoveLoginTest"); - var login = new UserLoginInfo("Provider", "key"); - const string password = "password"; - var result = manager.Create(user, password); - Assert.NotNull(user); - UnitTestHelper.IsSuccess(result); - UnitTestHelper.IsSuccess(manager.AddLogin(user.Id, login)); - Assert.Equal(user, manager.Find(login)); - var logins = manager.GetLogins(user.Id); - Assert.NotNull(logins); - Assert.Equal(1, logins.Count()); - Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); - Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); - var stamp = manager.GetSecurityStamp(user.Id); - UnitTestHelper.IsSuccess(manager.RemoveLogin(user.Id, login)); - Assert.Null(manager.Find(login)); - logins = manager.GetLogins(user.Id); - Assert.NotNull(logins); - Assert.Equal(0, logins.Count()); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task RemovePasswordTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("RemovePasswordTest"); - const string password = "password"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = await manager.GetSecurityStampAsync(user.Id); - UnitTestHelper.IsSuccess(await manager.RemovePasswordAsync(user.Id)); - var u = await manager.FindByNameAsync(user.UserName); - Assert.NotNull(u); - Assert.Null(u.PasswordHash); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public void RemovePasswordSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("RemovePasswordTest"); - const string password = "password"; - UnitTestHelper.IsSuccess(manager.Create(user, password)); - var stamp = manager.GetSecurityStamp(user.Id); - UnitTestHelper.IsSuccess(manager.RemovePassword(user.Id)); - var u = manager.FindByName(user.UserName); - Assert.NotNull(u); - Assert.Null(u.PasswordHash); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ChangePasswordTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ChangePasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - UnitTestHelper.IsSuccess(await manager.ChangePasswordAsync(user.Id, password, newPassword)); - Assert.Null(await manager.FindAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindAsync(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public void ChangePasswordSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ChangePasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - UnitTestHelper.IsSuccess(manager.Create(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - UnitTestHelper.IsSuccess(manager.ChangePassword(user.Id, password, newPassword)); - Assert.Null(manager.Find(user.UserName, password)); - Assert.Equal(user, manager.Find(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ResetPasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.ResetPasswordAsync(user.Id, token, newPassword)); - Assert.Null(await manager.FindAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindAsync(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordWithNoStampTest() - { - var manager = new NoStampUserManager(); - var user = new IdentityUser("ResetPasswordTest"); - const string password = "password"; - const string newPassword = "newpassword"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var token = await manager.GeneratePasswordResetTokenAsync(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.ResetPasswordAsync(user.Id, token, newPassword)); - Assert.Null(await manager.FindAsync(user.UserName, password)); - Assert.Equal(user, await manager.FindAsync(user.UserName, newPassword)); - } - - [Fact] - public async Task GenerateUserTokenTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("UserTokenTest"); - var user2 = new IdentityUser("UserTokenTest2"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user2)); - var token = await manager.GenerateUserTokenAsync("test", user.Id); - Assert.True(await manager.VerifyUserTokenAsync(user.Id, "test", token)); - Assert.False(await manager.VerifyUserTokenAsync(user.Id, "test2", token)); - Assert.False(await manager.VerifyUserTokenAsync(user.Id, "test", token + "a")); - Assert.False(await manager.VerifyUserTokenAsync(user2.Id, "test", token)); - } - - [Fact] - public void GenerateUserTokenSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("UserTokenTest"); - var user2 = new IdentityUser("UserTokenTest2"); - UnitTestHelper.IsSuccess(manager.Create(user)); - UnitTestHelper.IsSuccess(manager.Create(user2)); - var token = manager.GenerateUserToken("test", user.Id); - Assert.True(manager.VerifyUserToken(user.Id, "test", token)); - Assert.False(manager.VerifyUserToken(user.Id, "test2", token)); - Assert.False(manager.VerifyUserToken(user.Id, "test", token + "a")); - Assert.False(manager.VerifyUserToken(user2.Id, "test", token)); - } - - [Fact] - public async Task GetTwoFactorEnabledTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("TwoFactorEnabledTest"); - UnitTestHelper.IsSuccess(manager.Create(user)); - Assert.False(await manager.GetTwoFactorEnabledAsync(user.Id)); - UnitTestHelper.IsSuccess(await manager.SetTwoFactorEnabledAsync(user.Id, true)); - Assert.True(await manager.GetTwoFactorEnabledAsync(user.Id)); - UnitTestHelper.IsSuccess(await manager.SetTwoFactorEnabledAsync(user.Id, false)); - Assert.False(await manager.GetTwoFactorEnabledAsync(user.Id)); - } - - [Fact] - public void GetTwoFactorEnabledSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("TwoFactorEnabledTest"); - UnitTestHelper.IsSuccess(manager.Create(user)); - Assert.False(manager.GetTwoFactorEnabled(user.Id)); - UnitTestHelper.IsSuccess(manager.SetTwoFactorEnabled(user.Id, true)); - Assert.True(manager.GetTwoFactorEnabled(user.Id)); - UnitTestHelper.IsSuccess(manager.SetTwoFactorEnabled(user.Id, false)); - Assert.False(manager.GetTwoFactorEnabled(user.Id)); - } - - [Fact] - public async Task ResetPasswordWithConfirmTokenFailsTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ResetPasswordTest"); - var password = "password"; - var newPassword = "newpassword"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, token, newPassword)); - Assert.Null(await manager.FindAsync(user.UserName, newPassword)); - Assert.Equal(user, await manager.FindAsync(user.UserName, password)); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordWithExpiredTokenFailsTest() - { - var manager = TestUtil.CreateManager(); - var provider = new DpapiDataProtectionProvider(); - //manager.PasswordResetTokens = new DataProtectorTokenProvider(provider.Create("ResetPassword")) { TokenLifespan = TimeSpan.FromTicks(0) }; - manager.UserTokenProvider = new DataProtectorTokenProvider(provider.Create("ResetPassword")) - { - TokenLifespan = TimeSpan.FromTicks(0) - }; - var user = new IdentityUser("ResetPasswordTest"); - var password = "password"; - var newPassword = "newpassword"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GeneratePasswordResetTokenAsync(user.Id); - Assert.NotNull(token); - Thread.Sleep(10); - UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, token, newPassword)); - Assert.Null(await manager.FindAsync(user.UserName, newPassword)); - Assert.Equal(user, await manager.FindAsync(user.UserName, password)); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public void ResetPasswordSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ResetPasswordTest"); - var password = "password"; - var newPassword = "newpassword"; - UnitTestHelper.IsSuccess(manager.Create(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = manager.GeneratePasswordResetToken(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(manager.ResetPassword(user.Id, token, newPassword)); - Assert.Null(manager.Find(user.UserName, password)); - Assert.Equal(user, manager.Find(user.UserName, newPassword)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordFailsWithWrongTokenTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ResetPasswordTest"); - var password = "password"; - var newPassword = "newpassword"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, "bogus", newPassword), "Invalid token."); - Assert.Null(await manager.FindAsync(user.UserName, newPassword)); - Assert.Equal(user, await manager.FindAsync(user.UserName, password)); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ResetPasswordFailsAfterPasswordChangeTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ResetPasswordTest"); - var password = "password"; - var newPassword = "newpassword"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = manager.GeneratePasswordResetToken(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.ChangePasswordAsync(user.Id, password, "bogus1")); - UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, token, newPassword), "Invalid token."); - Assert.Null(await manager.FindAsync(user.UserName, newPassword)); - Assert.Equal(user, await manager.FindAsync(user.UserName, "bogus1")); - } - - [Fact] - public async Task AddRemoveUserClaimTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ClaimsAddRemove"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; - foreach (Claim c in claims) - { - UnitTestHelper.IsSuccess(await manager.AddClaimAsync(user.Id, c)); - } - var userClaims = await manager.GetClaimsAsync(user.Id); - Assert.Equal(3, userClaims.Count); - UnitTestHelper.IsSuccess(await manager.RemoveClaimAsync(user.Id, claims[0])); - userClaims = await manager.GetClaimsAsync(user.Id); - Assert.Equal(2, userClaims.Count); - UnitTestHelper.IsSuccess(await manager.RemoveClaimAsync(user.Id, claims[1])); - userClaims = await manager.GetClaimsAsync(user.Id); - Assert.Equal(1, userClaims.Count); - UnitTestHelper.IsSuccess(await manager.RemoveClaimAsync(user.Id, claims[2])); - userClaims = await manager.GetClaimsAsync(user.Id); - Assert.Equal(0, userClaims.Count); - } - - [Fact] - public void AddRemoveUserClaimSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("ClaimsAddRemove"); - UnitTestHelper.IsSuccess(manager.Create(user)); - Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; - foreach (Claim c in claims) - { - UnitTestHelper.IsSuccess(manager.AddClaim(user.Id, c)); - } - var userClaims = manager.GetClaims(user.Id); - Assert.Equal(3, userClaims.Count); - UnitTestHelper.IsSuccess(manager.RemoveClaim(user.Id, claims[0])); - userClaims = manager.GetClaims(user.Id); - Assert.Equal(2, userClaims.Count); - UnitTestHelper.IsSuccess(manager.RemoveClaim(user.Id, claims[1])); - userClaims = manager.GetClaims(user.Id); - Assert.Equal(1, userClaims.Count); - UnitTestHelper.IsSuccess(manager.RemoveClaim(user.Id, claims[2])); - userClaims = manager.GetClaims(user.Id); - Assert.Equal(0, userClaims.Count); - } - - [Fact] - public async Task ChangePasswordFallsIfPasswordTooShortTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("user"); - var password = "password"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var result = await manager.ChangePasswordAsync(user.Id, password, "n"); - UnitTestHelper.IsFailure(result, "Passwords must be at least 6 characters."); - } - - [Fact] - public async Task ChangePasswordFallsIfPasswordWrongTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("user"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "password")); - var result = await manager.ChangePasswordAsync(user.Id, "bogus", "newpassword"); - UnitTestHelper.IsFailure(result, "Incorrect password."); - } - - [Fact] - public void ChangePasswordFallsIfPasswordWrongSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("user"); - UnitTestHelper.IsSuccess(manager.Create(user, "password")); - var result = manager.ChangePassword(user.Id, "bogus", "newpassword"); - UnitTestHelper.IsFailure(result, "Incorrect password."); - } - - [Fact] - public async Task CanRelaxUserNameAndPasswordValidationTest() - { - var manager = TestUtil.CreateManager(); - manager.UserValidator = new UserValidator(manager) { AllowOnlyAlphanumericUserNames = false }; - manager.PasswordValidator = new MinimumLengthValidator(1); - UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("Some spaces"), "pwd")); - } - - [Fact] - public async Task CanUseEmailAsUserNameTest() - { - var manager = TestUtil.CreateManager(); - UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("test_email@foo.com"))); - } - - [Fact] - public async Task AddDupeUserFailsTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("dupe"); - var user2 = new IdentityUser("dupe"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - UnitTestHelper.IsFailure(await manager.CreateAsync(user2), "Name dupe is already taken."); - } - - [Fact] - public async Task FindWithPasswordUnknownUserReturnsNullTest() - { - var manager = TestUtil.CreateManager(); - Assert.Null(await manager.FindAsync("bogus", "sdlkfsadf")); - Assert.Null(manager.Find("bogus", "sdlkfsadf")); - } - - [Fact] - public async Task UpdateSecurityStampTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("stampMe"); - Assert.Null(user.SecurityStamp); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public void UpdateSecurityStampSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("stampMe"); - Assert.Null(user.SecurityStamp); - UnitTestHelper.IsSuccess(manager.Create(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - UnitTestHelper.IsSuccess(manager.UpdateSecurityStamp(user.Id)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - //[Fact] - //public async Task AddPasswordToUnknownUserFailsTest() { - // UnitTestHelper.IsFailure(await CreateManager().Users.UpdatePasswordAsync("bogus", "password"), "User bogus does not exist."); - //} - - //[Fact] - //public async Task CreateLocalUserNameTooLongThrowsTest() { - // var manager = CreateManager(); - // var userNameTooLong = new IdentityUser("baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); - // var result = await manager.CreateAsync(userNameTooLong, "password"); - // Assert.False(result.Succeeded); - // Assert.True(result.Errors.First().Contains("maximum length")); // Should say something about max length in the error msg - //} - - ////[Fact] - ////public async Task CreateExternalUserNameTooLongThrowsTest() { - //// IdentityStoreContext noop = CreateManagerSync(); - //// string userNameTooLong = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; - //// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => context.CreateWithLoginAsync(new IdentityUser(userNameTooLong), "whatever", "blah"))); - ////} - - [Fact] - public async Task AddDupeLoginFailsTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("DupeLogin"); - var login = new UserLoginInfo("provder", "key"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); - var result = await manager.AddLoginAsync(user.Id, login); - UnitTestHelper.IsFailure(result, "A user with that external login already exists."); - } - - [Fact] - public async Task AddLoginDoesNotChangeStampTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("stampTest"); - var login = new UserLoginInfo("provder", "key"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user.Id); - UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); - Assert.Equal(stamp, await manager.GetSecurityStampAsync(user.Id)); - } - - [Fact] - public async Task MixManagerAndEfTest() - { - var db = UnitTestHelper.CreateDefaultDb(); - var manager = new UserManager(new UserStore(db)); - var user = new IdentityUser("MixEFManagerTest"); - var password = "password"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - user.SecurityStamp = "bogus"; - UnitTestHelper.IsSuccess(await manager.UpdateAsync(user)); - Assert.Equal("bogus", db.Users.Find(user.Id).SecurityStamp); - //var login = new UserLoginInfo("login", "key"); - //user.Logins.Add(new IdentityUserLogin() { User = user, LoginProvider = login.LoginProvider, ProviderKey = login.ProviderKey }); - //UnitTestHelper.IsSuccess(manager.Update(user)); - //Assert.Equal(login.LoginProvider, db.Users.Find(user.Id).Logins.First().LoginProvider); - //Assert.Equal(login.ProviderKey, db.Users.Find(user.Id).Logins.First().ProviderKey); - } - - [Fact] - public async Task CreateUserBasicStoreTest() - { - var manager = new UserManager(new NoopUserStore()); - UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("test"))); - } - - [Fact] - public async Task GetAllUsersTest() - { - var mgr = TestUtil.CreateManager(); - var users = new[] - { - new IdentityUser("user1"), - new IdentityUser("user2"), - new IdentityUser("user3") - }; - foreach (IdentityUser u in users) - { - UnitTestHelper.IsSuccess(await mgr.CreateAsync(u)); - } - IQueryable usersQ = mgr.Users; - Assert.Equal(3, usersQ.Count()); - Assert.NotNull(usersQ.Where(u => u.UserName == "user1").FirstOrDefault()); - Assert.NotNull(usersQ.Where(u => u.UserName == "user2").FirstOrDefault()); - Assert.NotNull(usersQ.Where(u => u.UserName == "user3").FirstOrDefault()); - Assert.Null(usersQ.Where(u => u.UserName == "bogus").FirstOrDefault()); - } - - [Fact] - public async Task ConfirmEmailFalseByDefaultTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - } - - [Fact] - public async Task ConfirmEmailTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("test"); - Assert.False(user.EmailConfirmed); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); - Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); - UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); - Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - } - - [Fact] - public void ConfirmEmailSyncTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("test"); - Assert.False(user.EmailConfirmed); - UnitTestHelper.IsSuccess(manager.Create(user)); - var token = manager.GenerateEmailConfirmationToken(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(manager.ConfirmEmail(user.Id, token)); - Assert.True(manager.IsEmailConfirmed(user.Id)); - UnitTestHelper.IsSuccess(manager.SetEmail(user.Id, null)); - Assert.False(manager.IsEmailConfirmed(user.Id)); - } - - [Fact] - public async Task ConfirmTokenFailsAfterPasswordChangeTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("test"); - Assert.False(user.EmailConfirmed); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "password")); - var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.ChangePasswordAsync(user.Id, "password", "newpassword")); - UnitTestHelper.IsFailure(await manager.ConfirmEmailAsync(user.Id, token), "Invalid token."); - Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - } - - [Fact] - public async Task FindByEmailTest() - { - var manager = TestUtil.CreateManager(); - const string userName = "EmailTest"; - const string email = "email@test.com"; - var user = new IdentityUser(userName) { Email = email }; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var fetch = await manager.FindByEmailAsync(email); - Assert.Equal(user, fetch); - } - - [Fact] - public void FindByEmailSyncTest() - { - var manager = TestUtil.CreateManager(); - var userName = "EmailTest"; - var email = "email@test.com"; - var user = new IdentityUser(userName) { Email = email }; - UnitTestHelper.IsSuccess(manager.Create(user)); - var fetch = manager.FindByEmail(email); - Assert.Equal(user, fetch); - } - - [Fact] - public async Task SetEmailTest() - { - var manager = TestUtil.CreateManager(); - var userName = "EmailTest"; - var email = "email@test.com"; - var user = new IdentityUser(userName); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - Assert.Null(await manager.FindByEmailAsync(email)); - var stamp = await manager.GetSecurityStampAsync(user.Id); - UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, email)); - var fetch = await manager.FindByEmailAsync(email); - Assert.Equal(user, fetch); - Assert.Equal(email, await manager.GetEmailAsync(user.Id)); - Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task CreateDupeEmailFailsTest() - { - var manager = TestUtil.CreateManager(); - manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; - var userName = "EmailTest"; - var email = "email@test.com"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser(userName) { Email = email })); - var user = new IdentityUser("two") { Email = email }; - UnitTestHelper.IsFailure(await manager.CreateAsync(user), "Email 'email@test.com' is already taken."); - } - - [Fact] - public async Task SetEmailToDupeFailsTest() - { - var manager = TestUtil.CreateManager(); - manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; - var email = "email@test.com"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("emailtest") { Email = email })); - var user = new IdentityUser("two") { Email = "something@else.com" }; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - UnitTestHelper.IsFailure(await manager.SetEmailAsync(user.Id, email), - "Email 'email@test.com' is already taken."); - } - - [Fact] - public async Task RequireUniqueEmailBlocksBasicCreateTest() - { - var manager = TestUtil.CreateManager(); - manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; - UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser("emailtest"), "Email is too short.")); - } - - [Fact] - public async Task RequireUniqueEmailBlocksInvalidEmailTest() - { - var manager = TestUtil.CreateManager(); - manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; - UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser("emailtest") { Email = "hi" }), - "Email 'hi' is invalid."); - } - - [Fact] - public async Task SetPhoneNumberTest() - { - var manager = TestUtil.CreateManager(); - var userName = "PhoneTest"; - var user = new IdentityUser(userName); - user.PhoneNumber = "123-456-7890"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = await manager.GetSecurityStampAsync(user.Id); - Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "123-456-7890"); - UnitTestHelper.IsSuccess(await manager.SetPhoneNumberAsync(user.Id, "111-111-1111")); - Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public void SetPhoneNumberSyncTest() - { - var manager = TestUtil.CreateManager(); - var userName = "PhoneTest"; - var user = new IdentityUser(userName); - user.PhoneNumber = "123-456-7890"; - UnitTestHelper.IsSuccess(manager.Create(user)); - var stamp = manager.GetSecurityStamp(user.Id); - Assert.Equal(manager.GetPhoneNumber(user.Id), "123-456-7890"); - UnitTestHelper.IsSuccess(manager.SetPhoneNumber(user.Id, "111-111-1111")); - Assert.Equal(manager.GetPhoneNumber(user.Id), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ChangePhoneNumberTest() - { - var manager = TestUtil.CreateManager(); - var userName = "PhoneTest"; - var user = new IdentityUser(userName); - user.PhoneNumber = "123-456-7890"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user.Id)); - var stamp = await manager.GetSecurityStampAsync(user.Id); - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user.Id, "111-111-1111"); - UnitTestHelper.IsSuccess(await manager.ChangePhoneNumberAsync(user.Id, "111-111-1111", token1)); - Assert.True(await manager.IsPhoneNumberConfirmedAsync(user.Id)); - Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public void ChangePhoneNumberSyncTest() - { - var manager = TestUtil.CreateManager(); - var userName = "PhoneTest"; - var user = new IdentityUser(userName); - user.PhoneNumber = "123-456-7890"; - UnitTestHelper.IsSuccess(manager.Create(user)); - var stamp = manager.GetSecurityStamp(user.Id); - Assert.False(manager.IsPhoneNumberConfirmed(user.Id)); - var token1 = manager.GenerateChangePhoneNumberToken(user.Id, "111-111-1111"); - UnitTestHelper.IsSuccess(manager.ChangePhoneNumber(user.Id, "111-111-1111", token1)); - Assert.True(manager.IsPhoneNumberConfirmed(user.Id)); - Assert.Equal(manager.GetPhoneNumber(user.Id), "111-111-1111"); - Assert.NotEqual(stamp, user.SecurityStamp); - } - - [Fact] - public async Task ChangePhoneNumberFailsWithWrongTokenTest() - { - var manager = TestUtil.CreateManager(); - var userName = "PhoneTest"; - var user = new IdentityUser(userName); - user.PhoneNumber = "123-456-7890"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user.Id)); - var stamp = await manager.GetSecurityStampAsync(user.Id); - UnitTestHelper.IsFailure(await manager.ChangePhoneNumberAsync(user.Id, "111-111-1111", "bogus"), - "Invalid token."); - Assert.False(await manager.IsPhoneNumberConfirmedAsync(user.Id)); - Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "123-456-7890"); - Assert.Equal(stamp, user.SecurityStamp); - } - - [Fact] - public async Task VerifyPhoneNumberTest() - { - var manager = TestUtil.CreateManager(); - var userName = "VerifyPhoneTest"; - var user = new IdentityUser(userName); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var num1 = "111-123-4567"; - var num2 = "111-111-1111"; - var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user.Id, num1); - var token2 = await manager.GenerateChangePhoneNumberTokenAsync(user.Id, num2); - Assert.NotEqual(token1, token2); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token1, num1)); - Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token2, num2)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token2, num1)); - Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token1, num2)); - } - - [Fact] - public void VerifyPhoneNumberSyncTest() - { - var manager = TestUtil.CreateManager(); - const string userName = "VerifyPhoneTest"; - var user = new IdentityUser(userName); - UnitTestHelper.IsSuccess(manager.Create(user)); - const string num1 = "111-123-4567"; - const string num2 = "111-111-1111"; - Assert.False(manager.IsPhoneNumberConfirmed(user.Id)); - var token1 = manager.GenerateChangePhoneNumberToken(user.Id, num1); - var token2 = manager.GenerateChangePhoneNumberToken(user.Id, num2); - Assert.NotEqual(token1, token2); - Assert.True(manager.VerifyChangePhoneNumberToken(user.Id, token1, num1)); - Assert.True(manager.VerifyChangePhoneNumberToken(user.Id, token2, num2)); - Assert.False(manager.VerifyChangePhoneNumberToken(user.Id, token2, num1)); - Assert.False(manager.VerifyChangePhoneNumberToken(user.Id, token1, num2)); - } - - [Fact] - public async Task EmailTokenFactorTest() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - const string password = "password"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(String.Empty, messageService.Message.Subject); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - } - - [Fact] - public async Task EmailTokenFactorWithFormatTest() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - { - Subject = "Security Code", - BodyFormat = "Your code is: {0}" - }); - var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - const string password = "password"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal("Security Code", messageService.Message.Subject); - Assert.Equal("Your code is: " + token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - } - - [Fact] - public void EmailTokenFactorWithFormatSyncTest() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - { - Subject = "Security Code", - BodyFormat = "Your code is: {0}" - }); - var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - const string password = "password"; - UnitTestHelper.IsSuccess(manager.Create(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = manager.GenerateTwoFactorToken(user.Id, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - UnitTestHelper.IsSuccess(manager.NotifyTwoFactorToken(user.Id, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal("Security Code", messageService.Message.Subject); - Assert.Equal("Your code is: " + token, messageService.Message.Body); - Assert.True(manager.VerifyTwoFactorToken(user.Id, factorId, token)); - } - - [Fact] - public async Task EmailFactorFailsAfterSecurityStampChangeTest() - { - var manager = TestUtil.CreateManager(); - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - } - - [Fact] - public void EmailTokenFactorSyncTest() - { - var manager = TestUtil.CreateManager(); - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - const string password = "password"; - UnitTestHelper.IsSuccess(manager.Create(user, password)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = manager.GenerateTwoFactorToken(user.Id, factorId); - Assert.NotNull(token); - Assert.True(manager.VerifyTwoFactorToken(user.Id, factorId, token)); - } - - [Fact] - public void EmailFactorFailsAfterSecurityStampChangeSyncTest() - { - var manager = TestUtil.CreateManager(); - const string factorId = "EmailCode"; - manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); - var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; - UnitTestHelper.IsSuccess(manager.Create(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = manager.GenerateTwoFactorToken(user.Id, factorId); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(manager.UpdateSecurityStamp(user.Id)); - Assert.False(manager.VerifyTwoFactorToken(user.Id, factorId, token)); - } - - [Fact] - public async Task UserTwoFactorProviderTest() - { - var manager = TestUtil.CreateManager(); - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new IdentityUser("PhoneCodeTest"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - UnitTestHelper.IsSuccess(await manager.SetTwoFactorEnabledAsync(user.Id, true)); - Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user.Id)); - Assert.True(await manager.GetTwoFactorEnabledAsync(user.Id)); - } - - [Fact] - public async Task SendSms() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - var user = new IdentityUser("SmsTest") { PhoneNumber = "4251234567" }; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - await manager.SendSmsAsync(user.Id, "Hi"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Body); - } - - [Fact] - public async Task SendEmail() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - var user = new IdentityUser("EmailTest") { Email = "foo@foo.com" }; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - await manager.SendEmailAsync(user.Id, "Hi", "Body"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Subject); - Assert.Equal("Body", messageService.Message.Body); - } - - [Fact] - public void SendSmsSync() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - var user = new IdentityUser("SmsTest") { PhoneNumber = "4251234567" }; - UnitTestHelper.IsSuccess(manager.Create(user)); - manager.SendSms(user.Id, "Hi"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Body); - } - - [Fact] - public void SendEmailSync() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.EmailService = messageService; - var user = new IdentityUser("EmailTest") { Email = "foo@foo.com" }; - UnitTestHelper.IsSuccess(manager.Create(user)); - manager.SendEmail(user.Id, "Hi", "Body"); - Assert.NotNull(messageService.Message); - Assert.Equal("Hi", messageService.Message.Subject); - Assert.Equal("Body", messageService.Message.Body); - } - - - [Fact] - public async Task PhoneTokenFactorTest() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new IdentityUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - } - - [Fact] - public void PhoneTokenFactorSyncTest() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new IdentityUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; - UnitTestHelper.IsSuccess(manager.Create(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = manager.GenerateTwoFactorToken(user.Id, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - UnitTestHelper.IsSuccess(manager.NotifyTwoFactorToken(user.Id, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal(token, messageService.Message.Body); - Assert.True(manager.VerifyTwoFactorToken(user.Id, factorId, token)); - } - - [Fact] - public async Task PhoneTokenFactorFormatTest() - { - var manager = TestUtil.CreateManager(); - var messageService = new TestMessageService(); - manager.SmsService = messageService; - const string factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider - { - MessageFormat = "Your code is: {0}" - }); - var user = new IdentityUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - Assert.Null(messageService.Message); - UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); - Assert.NotNull(messageService.Message); - Assert.Equal("Your code is: " + token, messageService.Message.Body); - Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - } - - [Fact] - public async Task NoFactorProviderTest() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("PhoneCodeTest"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - const string error = "No IUserTwoFactorProvider for 'bogus' is registered."; - ExceptionHelper.ThrowsWithError( - () => manager.GenerateTwoFactorToken(user.Id, "bogus"), error); - ExceptionHelper.ThrowsWithError( - () => manager.VerifyTwoFactorToken(user.Id, "bogus", "bogus"), error); - } - - [Fact] - public async Task GetValidTwoFactorTestEmptyWithNoProviders() - { - var manager = TestUtil.CreateManager(); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); - Assert.NotNull(factors); - Assert.True(!factors.Any()); - } - - [Fact] - public async Task GetValidTwoFactorTest() - { - var manager = TestUtil.CreateManager(); - manager.RegisterTwoFactorProvider("phone", new PhoneNumberTokenProvider()); - manager.RegisterTwoFactorProvider("email", new EmailTokenProvider()); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); - Assert.NotNull(factors); - UnitTestHelper.IsSuccess(await manager.SetPhoneNumberAsync(user.Id, "111-111-1111")); - factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); - Assert.False(factors.Any()); - // Need to confirm - user.PhoneNumberConfirmed = true; - UnitTestHelper.IsSuccess(manager.Update(user)); - factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, "test@test.com")); - factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - // Need to confirm - user.EmailConfirmed = true; - UnitTestHelper.IsSuccess(await manager.UpdateAsync(user)); - factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); - Assert.NotNull(factors); - Assert.True(factors.Count() == 2); - UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, "somethingelse")); - factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - } - - [Fact] - public void GetValidTwoFactorSyncTest() - { - var manager = TestUtil.CreateManager(); - manager.RegisterTwoFactorProvider("phone", new PhoneNumberTokenProvider()); - manager.RegisterTwoFactorProvider("email", new EmailTokenProvider()); - var user = new IdentityUser("test"); - UnitTestHelper.IsSuccess(manager.Create(user)); - var factors = manager.GetValidTwoFactorProviders(user.Id); - Assert.NotNull(factors); - Assert.False(factors.Any()); - UnitTestHelper.IsSuccess(manager.SetPhoneNumber(user.Id, "111-111-1111")); - factors = manager.GetValidTwoFactorProviders(user.Id); - Assert.NotNull(factors); - Assert.False(factors.Any()); - // Need to confirm - user.PhoneNumberConfirmed = true; - UnitTestHelper.IsSuccess(manager.Update(user)); - factors = manager.GetValidTwoFactorProviders(user.Id); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - UnitTestHelper.IsSuccess(manager.SetEmail(user.Id, "test@test.com")); - factors = manager.GetValidTwoFactorProviders(user.Id); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - // Need to confirm - user.EmailConfirmed = true; - UnitTestHelper.IsSuccess(manager.Update(user)); - factors = manager.GetValidTwoFactorProviders(user.Id); - Assert.NotNull(factors); - Assert.True(factors.Count() == 2); - UnitTestHelper.IsSuccess(manager.SetEmail(user.Id, null)); - factors = manager.GetValidTwoFactorProviders(user.Id); - Assert.NotNull(factors); - Assert.True(factors.Count() == 1); - Assert.Equal("phone", factors[0]); - } - - [Fact] - public async Task PhoneFactorFailsAfterSecurityStampChangeTest() - { - var manager = TestUtil.CreateManager(); - var factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new IdentityUser("PhoneCodeTest"); - user.PhoneNumber = "4251234567"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - } - - [Fact] - public async Task WrongTokenProviderFailsTest() - { - var manager = TestUtil.CreateManager(); - var factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider()); - var user = new IdentityUser("PhoneCodeTest"); - user.PhoneNumber = "4251234567"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, "EmailCode", token)); - } - - [Fact] - public async Task WrongTokenFailsTest() - { - var manager = TestUtil.CreateManager(); - var factorId = "PhoneCode"; - manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); - var user = new IdentityUser("PhoneCodeTest"); - user.PhoneNumber = "4251234567"; - UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - var stamp = user.SecurityStamp; - Assert.NotNull(stamp); - var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - Assert.NotNull(token); - Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, "abc")); - } - - [Fact] - public async Task ResetTokenCallNoopForTokenValueZero() - { - var user = new IdentityUser() { UserName = "foo" }; - var store = new Mock>(); - store.Setup(x => x.ResetAccessFailedCountAsync(user)).Returns(() => - { - throw new Exception(); - }); - store.Setup(x => x.FindByIdAsync(It.IsAny())) - .Returns(() => Task.FromResult(user)); - store.Setup(x => x.GetAccessFailedCountAsync(It.IsAny())) - .Returns(() => Task.FromResult(0)); - var manager = new UserManager(store.Object); - UnitTestHelper.IsSuccess(await manager.ResetAccessFailedCountAsync(user.Id)); - } - - [Fact] - public void Create_preserves_culture() - { - var originalCulture = Thread.CurrentThread.CurrentCulture; - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - var expectedCulture = new CultureInfo("de-DE"); - Thread.CurrentThread.CurrentCulture = expectedCulture; - Thread.CurrentThread.CurrentUICulture = expectedCulture; - var manager = TestUtil.CreateManager(); - - try - { - var cultures = GetCurrentCultureAfter(() => manager.CreateAsync(new IdentityUser("whatever"))).Result; - Assert.Equal(expectedCulture, cultures.Item1); - Assert.Equal(expectedCulture, cultures.Item2); - } - finally - { - Thread.CurrentThread.CurrentCulture = originalCulture; - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } - - [Fact] - public void CreateSync_preserves_culture() - { - var originalCulture = Thread.CurrentThread.CurrentCulture; - var originalUICulture = Thread.CurrentThread.CurrentUICulture; - var expectedCulture = new CultureInfo("de-DE"); - Thread.CurrentThread.CurrentCulture = expectedCulture; - Thread.CurrentThread.CurrentUICulture = expectedCulture; - var manager = TestUtil.CreateManager(); - - try - { - var cultures = GetCurrentCultureAfter(() => manager.Create(new IdentityUser("whatever"))); - Assert.Equal(expectedCulture, cultures.Item1); - Assert.Equal(expectedCulture, cultures.Item2); - } - finally - { - Thread.CurrentThread.CurrentCulture = originalCulture; - Thread.CurrentThread.CurrentUICulture = originalUICulture; - } - } - - private static async Task> GetCurrentCultureAfter(Func action) - { - await action(); - return new Tuple(Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture); - } - - private static Tuple GetCurrentCultureAfter(Action action) - { - action(); - return new Tuple(Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture); - } - - private class NoOpTokenProvider : IUserTokenProvider - { - public Task GenerateAsync(string purpose, UserManager manager, - IdentityUser user) - { - throw new NotImplementedException(); - } - - public Task ValidateAsync(string purpose, string token, UserManager manager, - IdentityUser user) - { - throw new NotImplementedException(); - } - - public Task NotifyAsync(string token, UserManager manager, IdentityUser user) - { - throw new NotImplementedException(); - } - - public Task IsValidProviderForUserAsync(UserManager manager, IdentityUser user) - { - throw new NotImplementedException(); - } - } - - private class NoStampUserManager : UserManager - { - public NoStampUserManager() - : base(new UserStore(UnitTestHelper.CreateDefaultDb())) - { - UserValidator = new UserValidator(this) - { - AllowOnlyAlphanumericUserNames = true, - RequireUniqueEmail = false - }; - var dpp = new DpapiDataProtectionProvider(); - UserTokenProvider = new DataProtectorTokenProvider(dpp.Create("ASP.NET Identity")); - } - - public override bool SupportsUserSecurityStamp - { - get { return false; } - } - } - private class NoopUserStore : IUserStore { public Task CreateAsync(IdentityUser user) diff --git a/test/Identity.Test/packages.config b/test/Identity.Test/packages.config deleted file mode 100644 index da64c84..0000000 --- a/test/Identity.Test/packages.config +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/unittest.testsettings b/unittest.testsettings deleted file mode 100644 index 0987c2f..0000000 --- a/unittest.testsettings +++ /dev/null @@ -1,31 +0,0 @@ - - - - These are default test settings for a local test run. - - - - - - - - - - - - - - -
-
-
-
- - - - - - - - \ No newline at end of file From 70b578673058591a315592fce058c811caee1c7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Herceg?= Date: Wed, 24 Apr 2024 12:18:32 +0200 Subject: [PATCH 2/6] Removed unwanted changes --- Microsoft.AspNet.Identity.sln | 14 +++ Microsoft.AspNet.Identity.vssscc | 10 ++ ...icrosoft.AspNet.Identity.AspNetCore.csproj | 9 ++ .../35MSSharedLib1024.snk | Bin 0 -> 160 bytes .../Microsoft.AspNet.Identity.Core.csproj | 7 +- .../Properties/AssemblyInfo.cs | 8 +- .../35MSSharedLib1024.snk | Bin 0 -> 160 bytes ...oft.AspNet.Identity.EntityFramework.csproj | 7 +- .../Properties/AssemblyInfo.cs | 2 +- .../RoleStore.cs | 1 - .../UserStore.cs | 1 - ....AspNet.Identity.Owin.csproj.dtbcache.json | 1 + .../Microsoft.AspNet.Identity.Owin.csproj | 119 ++---------------- src/Microsoft.AspNet.Identity.Owin/app.config | 2 +- test/Identity.Test/35MSSharedLib1024.snk | Bin 0 -> 160 bytes test/Identity.Test/Identity.Test.csproj | 3 + 16 files changed, 66 insertions(+), 118 deletions(-) create mode 100644 Microsoft.AspNet.Identity.vssscc create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj create mode 100644 src/Microsoft.AspNet.Identity.Core/35MSSharedLib1024.snk create mode 100644 src/Microsoft.AspNet.Identity.EntityFramework/35MSSharedLib1024.snk create mode 100644 src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json create mode 100644 test/Identity.Test/35MSSharedLib1024.snk diff --git a/Microsoft.AspNet.Identity.sln b/Microsoft.AspNet.Identity.sln index b92237e..5a2df97 100644 --- a/Microsoft.AspNet.Identity.sln +++ b/Microsoft.AspNet.Identity.sln @@ -17,6 +17,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Identity.Test", "test\Identity.Test\Identity.Test.csproj", "{A7082BDD-985B-47B9-915B-7FA4CF541B5E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Owin", "src\Microsoft.AspNet.Identity.Owin\Microsoft.AspNet.Identity.Owin.csproj", "{943170EB-F4E7-4A6D-989E-2CF6C681DD89}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNet.Identity.AspNetCore", "src\Microsoft.AspNet.Identity.AspNetCore\Microsoft.AspNet.Identity.AspNetCore.csproj", "{5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -35,6 +39,14 @@ Global {A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Debug|Any CPU.Build.0 = Debug|Any CPU {A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Release|Any CPU.ActiveCfg = Release|Any CPU {A7082BDD-985B-47B9-915B-7FA4CF541B5E}.Release|Any CPU.Build.0 = Release|Any CPU + {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Debug|Any CPU.Build.0 = Debug|Any CPU + {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.ActiveCfg = Release|Any CPU + {943170EB-F4E7-4A6D-989E-2CF6C681DD89}.Release|Any CPU.Build.0 = Release|Any CPU + {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -43,6 +55,8 @@ Global {D2F24972-0F56-4C18-BD65-C26A320A0C68} = {0C1D4BD7-0771-4899-AF55-43D8791660A0} {D7298DAD-AB04-4502-9567-0461D0AD059E} = {0C1D4BD7-0771-4899-AF55-43D8791660A0} {A7082BDD-985B-47B9-915B-7FA4CF541B5E} = {FD5D1AFD-204F-4504-B8F3-74C2E1EEC848} + {943170EB-F4E7-4A6D-989E-2CF6C681DD89} = {0C1D4BD7-0771-4899-AF55-43D8791660A0} + {5DEFA76C-346F-4C97-A7D6-FAD6E19F6B7F} = {0C1D4BD7-0771-4899-AF55-43D8791660A0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {18A616DC-B136-4FD9-B3BC-DCE7D07D0693} diff --git a/Microsoft.AspNet.Identity.vssscc b/Microsoft.AspNet.Identity.vssscc new file mode 100644 index 0000000..6cb031b --- /dev/null +++ b/Microsoft.AspNet.Identity.vssscc @@ -0,0 +1,10 @@ +"" +{ +"FILE_VERSION" = "9237" +"ENLISTMENT_CHOICE" = "NEVER" +"PROJECT_FILE_RELATIVE_PATH" = "" +"NUMBER_OF_EXCLUDED_FILES" = "0" +"ORIGINAL_PROJECT_FILE_PATH" = "" +"NUMBER_OF_NESTED_PROJECTS" = "0" +"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROJECT" +} diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj b/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj new file mode 100644 index 0000000..fa71b7a --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/src/Microsoft.AspNet.Identity.Core/35MSSharedLib1024.snk b/src/Microsoft.AspNet.Identity.Core/35MSSharedLib1024.snk new file mode 100644 index 0000000000000000000000000000000000000000..695f1b38774e839e5b90059bfb7f32df1dff4223 GIT binary patch literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZ - netstandard2.0 + netstandard2.1;net45 Library Microsoft.AspNet.Identity false - - Microsoft.AspNet.Identity.Core Microsoft Microsoft.AspNet.Identity.Core Copyright © Microsoft 2012 2.0.0.0 2.1.0.0 + 35MSSharedLib1024.snk + true + true diff --git a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs index 708098e..9963720 100644 --- a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs @@ -21,9 +21,13 @@ [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: InternalsVisibleTo( - "Microsoft.AspNet.Identity.EntityFramework" + "Microsoft.AspNet.Identity.EntityFramework, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" )] [assembly: InternalsVisibleTo( - "Identity.Test" + "Microsoft.AspNet.Identity.Owin, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + )] +[assembly: + InternalsVisibleTo( + "Identity.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" )] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/35MSSharedLib1024.snk b/src/Microsoft.AspNet.Identity.EntityFramework/35MSSharedLib1024.snk new file mode 100644 index 0000000000000000000000000000000000000000..695f1b38774e839e5b90059bfb7f32df1dff4223 GIT binary patch literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZ - netstandard2.1 + netstandard2.1;net45 Library false - - Microsoft.AspNet.Identity.EntityFramework Microsoft Microsoft.AspNet.Identity.EntityFramework Copyright © Microsoft 2013 2.0.0.0 2.1.0.0 + 35MSSharedLib1024.snk + true + true diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs index d57e3f3..6fad7ee 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs @@ -21,5 +21,5 @@ [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: InternalsVisibleTo( - "Identity.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + "Identity.Test, , PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" )] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs index da68219..8ecbaee 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/RoleStore.cs @@ -3,7 +3,6 @@ using System; using System.Data.Entity; -using System.Data.Entity.Utilities; using System.Linq; using System.Threading.Tasks; diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs index 7f0ea17..2087cb8 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/UserStore.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Data.Entity; -using System.Data.Entity.Utilities; using System.Globalization; using System.Linq; using System.Linq.Expressions; diff --git a/src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json b/src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json new file mode 100644 index 0000000..068e320 --- /dev/null +++ b/src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json @@ -0,0 +1 @@ +{"RootPath":"D:\\Work\\AspNetIdentity\\src\\Microsoft.AspNet.Identity.Owin","ProjectFileName":"Microsoft.AspNet.Identity.Owin.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[],"References":[],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"D:\\Work\\AspNetIdentity\\src\\Microsoft.AspNet.Identity.Owin\\bin\\Debug\\Microsoft.AspNet.Identity.Owin.dll","OutputItemRelativePath":"Microsoft.AspNet.Identity.Owin.dll"},{"OutputItemFullPath":"D:\\Work\\AspNetIdentity\\src\\Microsoft.AspNet.Identity.Owin\\bin\\Debug\\Microsoft.AspNet.Identity.Owin.pdb","OutputItemRelativePath":"Microsoft.AspNet.Identity.Owin.pdb"}],"CopyToOutputEntries":[]} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj b/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj index 55d1ebd..3993e0d 100644 --- a/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj +++ b/src/Microsoft.AspNet.Identity.Owin/Microsoft.AspNet.Identity.Owin.csproj @@ -1,119 +1,26 @@ - - - + - Debug - AnyCPU - {943170EB-F4E7-4A6D-989E-2CF6C681DD89} + net45 Library bin\$(Configuration) - Properties - Microsoft.AspNet.Identity.Owin - Microsoft.AspNet.Identity.Owin - v4.8 - 512 - SAK - SAK - SAK - SAK ..\..\ true - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - Sdl6.1.ruleset - true - bin\Debug\Microsoft.AspNet.Identity.Owin.XML - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\Microsoft.AspNet.Identity.Owin.XML - - + false + 35MSSharedLib1024.snk true - - true - - 35MSSharedLib1024.snk - - - - ..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll - - - ..\..\packages\Microsoft.Owin.Security.3.0.1\lib\net45\Microsoft.Owin.Security.dll - - - ..\..\packages\Microsoft.Owin.Security.Cookies.3.0.1\lib\net45\Microsoft.Owin.Security.Cookies.dll - - - ..\..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll - - - False - ..\..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll - - - False - ..\..\packages\Owin.1.0\lib\net40\Owin.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - {d2f24972-0f56-4c18-bd65-c26a320a0c68} - Microsoft.AspNet.Identity.Core - + - - - + + + + + + + + - - - \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Owin/app.config b/src/Microsoft.AspNet.Identity.Owin/app.config index 9aabd76..fc2841c 100644 --- a/src/Microsoft.AspNet.Identity.Owin/app.config +++ b/src/Microsoft.AspNet.Identity.Owin/app.config @@ -12,4 +12,4 @@ - + diff --git a/test/Identity.Test/35MSSharedLib1024.snk b/test/Identity.Test/35MSSharedLib1024.snk new file mode 100644 index 0000000000000000000000000000000000000000..695f1b38774e839e5b90059bfb7f32df1dff4223 GIT binary patch literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZCopyright © Microsoft 2013 1.0.0.0 1.0.0.0 + 35MSSharedLib1024.snk + true + true From e834834c95aa8793b89fab3f235ee0c5694eba51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Herceg?= Date: Wed, 24 Apr 2024 12:23:23 +0200 Subject: [PATCH 3/6] Removed unwanted changes --- .gitignore | 2 +- .../Properties/AssemblyInfo.cs | 2 +- ...soft.AspNet.Identity.Owin.csproj.dtbcache.json | 1 - src/Microsoft.AspNet.Identity.Owin/app.config | 15 --------------- .../packages.config | 9 --------- 5 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json delete mode 100644 src/Microsoft.AspNet.Identity.Owin/app.config delete mode 100644 src/Microsoft.AspNet.Identity.Owin/packages.config diff --git a/.gitignore b/.gitignore index 639fa55..ad72bc4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ [Oo]bj/ [Bb]in/ packages/ -/.vs +.vs diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs index 6fad7ee..d57e3f3 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Identity.EntityFramework/Properties/AssemblyInfo.cs @@ -21,5 +21,5 @@ [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: InternalsVisibleTo( - "Identity.Test, , PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + "Identity.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" )] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json b/src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json deleted file mode 100644 index 068e320..0000000 --- a/src/Microsoft.AspNet.Identity.Owin/.vs/Microsoft.AspNet.Identity.Owin.csproj.dtbcache.json +++ /dev/null @@ -1 +0,0 @@ -{"RootPath":"D:\\Work\\AspNetIdentity\\src\\Microsoft.AspNet.Identity.Owin","ProjectFileName":"Microsoft.AspNet.Identity.Owin.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[],"References":[],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"D:\\Work\\AspNetIdentity\\src\\Microsoft.AspNet.Identity.Owin\\bin\\Debug\\Microsoft.AspNet.Identity.Owin.dll","OutputItemRelativePath":"Microsoft.AspNet.Identity.Owin.dll"},{"OutputItemFullPath":"D:\\Work\\AspNetIdentity\\src\\Microsoft.AspNet.Identity.Owin\\bin\\Debug\\Microsoft.AspNet.Identity.Owin.pdb","OutputItemRelativePath":"Microsoft.AspNet.Identity.Owin.pdb"}],"CopyToOutputEntries":[]} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Owin/app.config b/src/Microsoft.AspNet.Identity.Owin/app.config deleted file mode 100644 index fc2841c..0000000 --- a/src/Microsoft.AspNet.Identity.Owin/app.config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/src/Microsoft.AspNet.Identity.Owin/packages.config b/src/Microsoft.AspNet.Identity.Owin/packages.config deleted file mode 100644 index cc40c21..0000000 --- a/src/Microsoft.AspNet.Identity.Owin/packages.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file From 4a826a7fc251c5d8c71a63bbf6d61ac821c28071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Herceg?= Date: Wed, 24 Apr 2024 15:24:07 +0200 Subject: [PATCH 4/6] Fixed tests to support the new .NET --- .../35MSSharedLib1024.snk | Bin 0 -> 160 bytes .../DataProtectorTokenProvider.cs | 192 ++++++ .../AuthenticationManagerExtensions.cs | 57 ++ .../Extensions/OwinContextExtensions.cs | 62 ++ .../Extensions/SignInManagerExtensions.cs | 158 +++++ .../ExternalLoginInfo.cs | 33 + .../IIdentityFactoryProvider.cs | 30 + .../IdentityFactoryMiddleware.cs | 64 ++ .../IdentityFactoryOptions.cs | 25 + .../IdentityFactoryProvider.cs | 55 ++ ...icrosoft.AspNet.Identity.AspNetCore.csproj | 13 +- .../Properties/AssemblyInfo.cs | 6 + .../SecurityStampValidator.cs | 121 ++++ .../SignInManager.cs | 299 +++++++++ .../SignInStatus.cs | 32 + .../Properties/AssemblyInfo.cs | 10 +- test/Identity.Test/ApplicationUserTest.cs | 205 +++--- .../AuthenticationManagerExtensionsTest.cs | 610 +++++++++--------- test/Identity.Test/CustomGuidKeyTest.cs | 278 ++++---- test/Identity.Test/CustomIntKeyTest.cs | 122 ++-- test/Identity.Test/ExceptionHelper.cs | 5 + test/Identity.Test/GlobalHelpers.cs | 99 +++ test/Identity.Test/Identity.Test.csproj | 15 +- test/Identity.Test/LoginsTest.cs | 3 +- test/Identity.Test/RolesTest.cs | 18 +- test/Identity.Test/SecurityStampTest.cs | 376 ++++++----- test/Identity.Test/SignInManagerTest.cs | 51 +- test/Identity.Test/TestUtil.cs | 83 ++- test/Identity.Test/UserLockoutStoreTests.cs | 25 +- test/Identity.Test/xunit.runner.json | 4 + 30 files changed, 2254 insertions(+), 797 deletions(-) create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/35MSSharedLib1024.snk create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/DataProtectorTokenProvider.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/Extensions/AuthenticationManagerExtensions.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/Extensions/OwinContextExtensions.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/Extensions/SignInManagerExtensions.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/ExternalLoginInfo.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/IIdentityFactoryProvider.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryMiddleware.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryOptions.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryProvider.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/Properties/AssemblyInfo.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/SecurityStampValidator.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/SignInManager.cs create mode 100644 src/Microsoft.AspNet.Identity.AspNetCore/SignInStatus.cs create mode 100644 test/Identity.Test/GlobalHelpers.cs create mode 100644 test/Identity.Test/xunit.runner.json diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/35MSSharedLib1024.snk b/src/Microsoft.AspNet.Identity.AspNetCore/35MSSharedLib1024.snk new file mode 100644 index 0000000000000000000000000000000000000000..695f1b38774e839e5b90059bfb7f32df1dff4223 GIT binary patch literal 160 zcmV;R0AK$ABme*efB*oL000060ssI2Bme+XQ$aBR1ONa50098C{E+7Ye`kjtcRG*W zi8#m|)B?I?xgZ^2Sw5D;l4TxtPwG;3)3^j?qDHjEteSTF{rM+4WI`v zCD?tsZ^;k+S&r1&HRMb=j738S=;J$tCKNrc$@P|lZ + /// Token provider that uses an IDataProtector to generate encrypted tokens based off of the security stamp + /// + public class DataProtectorTokenProvider : DataProtectorTokenProvider + where TUser : class, IUser + { + /// + /// Constructor + /// + /// + public DataProtectorTokenProvider(IDataProtector protector) : base(protector) + { + } + } + + /// + /// Token provider that uses an IDataProtector to generate encrypted tokens based off of the security stamp + /// + public class DataProtectorTokenProvider : IUserTokenProvider + where TUser : class, IUser where TKey : IEquatable + { + /// + /// Constructor + /// + /// + public DataProtectorTokenProvider(IDataProtector protector) + { + if (protector == null) + { + throw new ArgumentNullException("protector"); + } + Protector = protector; + TokenLifespan = TimeSpan.FromDays(1); + } + + /// + /// IDataProtector for the token + /// + public IDataProtector Protector { get; private set; } + + /// + /// Lifespan after which the token is considered expired + /// + public TimeSpan TokenLifespan { get; set; } + + /// + /// Generate a protected string for a user + /// + /// + /// + /// + /// + public async Task GenerateAsync(string purpose, UserManager manager, TUser user) + { + if (user == null) + { + throw new ArgumentNullException("user"); + } + var ms = new MemoryStream(); + using (var writer = ms.CreateWriter()) + { + writer.Write(DateTimeOffset.UtcNow); + writer.Write(Convert.ToString(user.Id, CultureInfo.InvariantCulture)); + writer.Write(purpose ?? ""); + string stamp = null; + if (manager.SupportsUserSecurityStamp) + { + stamp = await manager.GetSecurityStampAsync(user.Id).WithCurrentCulture(); + } + writer.Write(stamp ?? ""); + } + var protectedBytes = Protector.Protect(ms.ToArray()); + return Convert.ToBase64String(protectedBytes); + } + + /// + /// Return false if the token is not valid + /// + /// + /// + /// + /// + /// + public async Task ValidateAsync(string purpose, string token, UserManager manager, TUser user) + { + try + { + var unprotectedData = Protector.Unprotect(Convert.FromBase64String(token)); + var ms = new MemoryStream(unprotectedData); + using (var reader = ms.CreateReader()) + { + var creationTime = reader.ReadDateTimeOffset(); + var expirationTime = creationTime + TokenLifespan; + if (expirationTime < DateTimeOffset.UtcNow) + { + return false; + } + + var userId = reader.ReadString(); + if (!String.Equals(userId, Convert.ToString(user.Id, CultureInfo.InvariantCulture))) + { + return false; + } + var purp = reader.ReadString(); + if (!String.Equals(purp, purpose)) + { + return false; + } + var stamp = reader.ReadString(); + if (reader.PeekChar() != -1) + { + return false; + } + + if (manager.SupportsUserSecurityStamp) + { + var expectedStamp = await manager.GetSecurityStampAsync(user.Id).WithCurrentCulture(); + return stamp == expectedStamp; + } + return stamp == ""; + } + } + // ReSharper disable once EmptyGeneralCatchClause + catch + { + // Do not leak exception + } + return false; + } + + /// + /// Returns true if the provider can be used to generate tokens for this user + /// + /// + /// + /// + public Task IsValidProviderForUserAsync(UserManager manager, TUser user) + { + return Task.FromResult(true); + } + + /// + /// This provider no-ops by default when asked to notify a user + /// + /// + /// + /// + /// + public Task NotifyAsync(string token, UserManager manager, TUser user) + { + return Task.FromResult(0); + } + } + + // Based on Levi's authentication sample + internal static class StreamExtensions + { + internal static readonly Encoding DefaultEncoding = new UTF8Encoding(false, true); + + public static BinaryReader CreateReader(this Stream stream) + { + return new BinaryReader(stream, DefaultEncoding, true); + } + + public static BinaryWriter CreateWriter(this Stream stream) + { + return new BinaryWriter(stream, DefaultEncoding, true); + } + + public static DateTimeOffset ReadDateTimeOffset(this BinaryReader reader) + { + return new DateTimeOffset(reader.ReadInt64(), TimeSpan.Zero); + } + + public static void Write(this BinaryWriter writer, DateTimeOffset value) + { + writer.Write(value.UtcTicks); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/AuthenticationManagerExtensions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/AuthenticationManagerExtensions.cs new file mode 100644 index 0000000..c2ea1f3 --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/AuthenticationManagerExtensions.cs @@ -0,0 +1,57 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Collections.Generic; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNet.Identity; +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNetCore +{ + /// + /// Extensions methods on IAuthenticationManager that add methods for using the default Application and External + /// authentication type constants + /// + internal static class AuthenticationManagerExtensions + { + /// + /// Returns true if there is a TwoFactorRememberBrowser cookie for a user + /// + /// + /// + /// + internal static async Task TwoFactorBrowserRememberedAsync(this HttpContext manager, + string userId) + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + var result = + await manager.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie).WithCurrentCulture(); + return (result?.Principal?.Identity is ClaimsIdentity claimsIdentity && claimsIdentity.GetUserId() == userId); + } + + /// + /// Creates a TwoFactorRememberBrowser cookie for a user + /// + /// + /// + /// + internal static ClaimsIdentity CreateTwoFactorRememberBrowserIdentity(this HttpContext manager, + string userId) + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + var rememberBrowserIdentity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); + rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.NameIdentifier, userId)); + return rememberBrowserIdentity; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/OwinContextExtensions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/OwinContextExtensions.cs new file mode 100644 index 0000000..af58e3f --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/OwinContextExtensions.cs @@ -0,0 +1,62 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Extension methods for OwinContext/> + /// + internal static class HttpContextExtensions + { + /// + /// Stores an object in the OwinContext using a key based on the AssemblyQualified type name + /// + /// + /// + /// + /// + internal static HttpContext Set(this HttpContext context, T value) + { + if (context == null) + { + throw new ArgumentNullException("context"); + } + + context.Items[typeof(T)] = value; + return context; + } + + /// + /// Retrieves an object from the OwinContext using a key based on the AssemblyQualified type name + /// + /// + /// + /// + internal static T Get(this HttpContext context) + { + if (context == null) + { + throw new ArgumentNullException("context"); + } + return (T)context.Items[typeof(T)]; + } + + /// + /// Get the user manager from the context + /// + /// + /// + /// + internal static TManager GetUserManager(this HttpContext context) + { + if (context == null) + { + throw new ArgumentNullException("context"); + } + return context.Get(); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/SignInManagerExtensions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/SignInManagerExtensions.cs new file mode 100644 index 0000000..8024afa --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/Extensions/SignInManagerExtensions.cs @@ -0,0 +1,158 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Security.Claims; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Extension methods for SignInManager/> + /// + public static class SignInManagerExtensions + { + /// + /// Called to generate the ClaimsIdentity for the user, override to add additional claims before SignIn + /// + /// + /// + /// + public static ClaimsIdentity CreateUserIdentity(this SignInManager manager, TUser user) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + return AsyncHelper.RunSync(() => manager.CreateUserIdentityAsync(user)); + } + + /// + /// Creates a user identity and then signs the identity using the AuthenticationManager + /// + /// + /// + /// + /// + /// + public static void SignIn(this SignInManager manager, TUser user, bool isPersistent, bool rememberBrowser) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + AsyncHelper.RunSync(() => manager.SignInAsync(user, isPersistent, rememberBrowser)); + } + + /// + /// Send a two factor code to a user + /// + /// + /// + /// + public static bool SendTwoFactorCode(this SignInManager manager, string provider) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + return AsyncHelper.RunSync(() => manager.SendTwoFactorCodeAsync(provider)); + } + + /// + /// Get the user id that has been verified already or null. + /// + /// + /// + public static TKey GetVerifiedUserId(this SignInManager manager) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + return AsyncHelper.RunSync(() => manager.GetVerifiedUserIdAsync()); + } + + /// + /// Has the user been verified (ie either via password or external login) + /// + /// + /// + public static bool HasBeenVerified(this SignInManager manager) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + return AsyncHelper.RunSync(() => manager.HasBeenVerifiedAsync()); + } + + /// + /// Two factor verification step + /// + /// + /// + /// + /// + /// + /// + public static SignInStatus TwoFactorSignIn(this SignInManager manager, string provider, string code, bool isPersistent, bool rememberBrowser) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + return AsyncHelper.RunSync(() => manager.TwoFactorSignInAsync(provider, code, isPersistent, rememberBrowser)); + } + + /// + /// Sign the user in using an associated external login + /// + /// + /// + /// + /// + public static SignInStatus ExternalSignIn(this SignInManager manager, ExternalLoginInfo loginInfo, bool isPersistent) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + return AsyncHelper.RunSync(() => manager.ExternalSignInAsync(loginInfo, isPersistent)); + } + + + /// + /// Sign in the user in using the user name and password + /// + /// + /// + /// + /// + /// + /// + public static SignInStatus PasswordSignIn(this SignInManager manager, string userName, string password, bool isPersistent, bool shouldLockout) + where TKey : IEquatable + where TUser : class, IUser + { + if (manager == null) + { + throw new ArgumentNullException("manager"); + } + return AsyncHelper.RunSync(() => manager.PasswordSignInAsync(userName, password, isPersistent, shouldLockout)); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/ExternalLoginInfo.cs b/src/Microsoft.AspNet.Identity.AspNetCore/ExternalLoginInfo.cs new file mode 100644 index 0000000..0a67358 --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/ExternalLoginInfo.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System.Security.Claims; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Used to return information needed to associate an external login + /// + public class ExternalLoginInfo + { + /// + /// Associated login data + /// + public UserLoginInfo Login { get; set; } + + /// + /// Suggested user name for a user + /// + public string DefaultUserName { get; set; } + + /// + /// Email claim from the external identity + /// + public string Email { get; set; } + + /// + /// The external identity + /// + public ClaimsIdentity ExternalIdentity { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IIdentityFactoryProvider.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IIdentityFactoryProvider.cs new file mode 100644 index 0000000..87db6ec --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/IIdentityFactoryProvider.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Interface used to create objects per request + /// + /// + public interface IIdentityFactoryProvider where T : IDisposable + { + /// + /// Called once per request to create an object + /// + /// + /// + /// + T Create(IdentityFactoryOptions options, HttpContext context); + + /// + /// Called at the end of the request to dispose the object created + /// + /// + /// + void Dispose(IdentityFactoryOptions options, T instance); + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryMiddleware.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryMiddleware.cs new file mode 100644 index 0000000..af6ecea --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryMiddleware.cs @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using static System.Net.Mime.MediaTypeNames; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// OwinMiddleware that initializes an object for use in the OwinContext via the Get/Set generic extensions method + /// + /// + /// + public class IdentityFactoryMiddleware : IMiddleware + where TResult : IDisposable + where TOptions : IdentityFactoryOptions + { + /// + /// Constructor + /// + /// Configuration options for the middleware + public IdentityFactoryMiddleware(TOptions options) + { + if (options == null) + { + throw new ArgumentNullException("options"); + } + if (options.Provider == null) + { + throw new ArgumentNullException("options.Provider"); + } + Options = options; + } + + /// + /// Configuration options + /// + public TOptions Options { get; private set; } + + /// + /// Create an object using the Options.Provider, storing it in the OwinContext and then disposes the object when finished + /// + /// + /// + public async Task InvokeAsync(HttpContext context, RequestDelegate next) + { + var instance = Options.Provider.Create(Options, context); + try + { + context.Set(instance); + if (next != null) + { + await next.Invoke(context); + } + } + finally + { + Options.Provider.Dispose(Options, instance); + } + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryOptions.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryOptions.cs new file mode 100644 index 0000000..480d589 --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryOptions.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNetCore.DataProtection; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Configuration options for a IdentityFactoryMiddleware + /// + /// + public class IdentityFactoryOptions where T : IDisposable + { + /// + /// Used to configure the data protection provider + /// + public IDataProtectionProvider DataProtectionProvider { get; set; } + + /// + /// Provider used to Create and Dispose objects + /// + public IIdentityFactoryProvider Provider { get; set; } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryProvider.cs b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryProvider.cs new file mode 100644 index 0000000..12fc5cc --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/IdentityFactoryProvider.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Used to configure how the IdentityFactoryMiddleware will create an instance of the specified type for each OwinContext + /// + /// + public class IdentityFactoryProvider : IIdentityFactoryProvider where T : class, IDisposable + { + /// + /// Constructor + /// + public IdentityFactoryProvider() + { + OnDispose = (options, instance) => { }; + OnCreate = (options, context) => null; + } + + /// + /// A delegate assigned to this property will be invoked when the related method is called + /// + public Func, HttpContext, T> OnCreate { get; set; } + + /// + /// A delegate assigned to this property will be invoked when the related method is called + /// + public Action, T> OnDispose { get; set; } + + /// + /// Calls the OnCreate Delegate + /// + /// + /// + /// + public virtual T Create(IdentityFactoryOptions options, HttpContext context) + { + return OnCreate(options, context); + } + + /// + /// Calls the OnDispose delegate + /// + /// + /// + public virtual void Dispose(IdentityFactoryOptions options, T instance) + { + OnDispose(options, instance); + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj b/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj index fa71b7a..9f0b24a 100644 --- a/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj +++ b/src/Microsoft.AspNet.Identity.AspNetCore/Microsoft.AspNet.Identity.AspNetCore.csproj @@ -1,9 +1,20 @@  - net8.0 + net6.0 enable enable + 35MSSharedLib1024.snk + true + true + + + + + + + + diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.AspNetCore/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..ea6dae6 --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/Properties/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Runtime.CompilerServices; + +[assembly: + InternalsVisibleTo( + "Identity.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + )] \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/SecurityStampValidator.cs b/src/Microsoft.AspNet.Identity.AspNetCore/SecurityStampValidator.cs new file mode 100644 index 0000000..b3f01bb --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/SecurityStampValidator.cs @@ -0,0 +1,121 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; + + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Static helper class used to configure a CookieAuthenticationProvider to validate a cookie against a user's security + /// stamp + /// + public static class SecurityStampValidator + { + /// + /// Can be used as the ValidateIdentity method for a CookieAuthenticationProvider which will check a user's security + /// stamp after validateInterval + /// Rejects the identity if the stamp changes, and otherwise will call regenerateIdentity to sign in a new + /// ClaimsIdentity + /// + /// + /// + /// + /// + /// + public static Func OnValidateIdentity( + TimeSpan validateInterval, Func> regenerateIdentity) + where TManager : UserManager + where TUser : class, IUser + { + return OnValidateIdentity(validateInterval, regenerateIdentity, id => id.GetUserId()); + } + + /// + /// Can be used as the ValidateIdentity method for a CookieAuthenticationProvider which will check a user's security + /// stamp after validateInterval + /// Rejects the identity if the stamp changes, and otherwise will call regenerateIdentity to sign in a new + /// ClaimsIdentity + /// + /// + /// + /// + /// + /// + /// + /// + public static Func OnValidateIdentity( + TimeSpan validateInterval, Func> regenerateIdentityCallback, + Func getUserIdCallback) + where TManager : UserManager + where TUser : class, IUser + where TKey : IEquatable + { + if (getUserIdCallback == null) + { + throw new ArgumentNullException("getUserIdCallback"); + } + return async context => + { + var currentUtc = DateTimeOffset.UtcNow; + //if (context.Options != null && context.Options.SystemClock != null) + //{ + // currentUtc = context.Options.SystemClock.UtcNow; + //} + var issuedUtc = context.Properties.IssuedUtc; + + // Only validate if enough time has elapsed + var validate = (issuedUtc == null); + if (issuedUtc != null) + { + var timeElapsed = currentUtc.Subtract(issuedUtc.Value); + validate = timeElapsed > validateInterval; + } + if (validate && context.Principal?.Identity is ClaimsIdentity claimsIdentity) + { + var manager = context.HttpContext.GetUserManager(); + var userId = getUserIdCallback(claimsIdentity); + if (manager != null && userId != null) + { + var user = await manager.FindByIdAsync(userId).WithCurrentCulture(); + var reject = true; + // Refresh the identity if the stamp matches, otherwise reject + if (user != null && manager.SupportsUserSecurityStamp) + { + var securityStamp = + claimsIdentity.FindFirstValue(Constants.DefaultSecurityStampClaimType); + if (securityStamp == await manager.GetSecurityStampAsync(userId).WithCurrentCulture()) + { + reject = false; + // Regenerate fresh claims if possible and resign in + if (regenerateIdentityCallback != null) + { + var identity = await regenerateIdentityCallback.Invoke(manager, user).WithCurrentCulture(); + if (identity != null) + { + // Fix for regression where this value is not updated + // Setting it to null so that it is refreshed by the cookie middleware + await context.HttpContext.SignInAsync(new ClaimsPrincipal(identity), context.Properties); + + // moved after SignIn so the test passes + context.Properties.IssuedUtc = null; + context.Properties.ExpiresUtc = null; + } + } + } + } + if (reject) + { + context.RejectPrincipal(); + await context.HttpContext.SignOutAsync(); + } + } + } + }; + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/SignInManager.cs b/src/Microsoft.AspNet.Identity.AspNetCore/SignInManager.cs new file mode 100644 index 0000000..341340c --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/SignInManager.cs @@ -0,0 +1,299 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +using System; +using System.Globalization; +using System.Security.Claims; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Manages Sign In operations for users + /// + /// + /// + public class SignInManager : IDisposable + where TUser : class, IUser + where TKey : IEquatable + { + /// + /// Constructor + /// + /// + /// + public SignInManager(UserManager userManager, HttpContext authenticationManager) + { + if (userManager == null) + { + throw new ArgumentNullException("userManager"); + } + if (authenticationManager == null) + { + throw new ArgumentNullException("authenticationManager"); + } + UserManager = userManager; + AuthenticationManager = authenticationManager; + } + + private string _authType; + /// + /// AuthenticationType that will be used by sign in, defaults to DefaultAuthenticationTypes.ApplicationCookie + /// + public string AuthenticationType + { + get { return _authType ?? DefaultAuthenticationTypes.ApplicationCookie; } + set { _authType = value; } + } + + /// + /// Used to operate on users + /// + public UserManager UserManager { get; set; } + + /// + /// Used to sign in identities + /// + public HttpContext AuthenticationManager { get; set; } + + /// + /// Called to generate the ClaimsIdentity for the user, override to add additional claims before SignIn + /// + /// + /// + public virtual Task CreateUserIdentityAsync(TUser user) + { + return UserManager.CreateIdentityAsync(user, AuthenticationType); + } + + /// + /// Convert a TKey userId to a string, by default this just calls ToString() + /// + /// + /// + public virtual string ConvertIdToString(TKey id) + { + return Convert.ToString(id, CultureInfo.InvariantCulture); + } + + /// + /// Convert a string id to the proper TKey using Convert.ChangeType + /// + /// + /// + public virtual TKey ConvertIdFromString(string id) + { + if (id == null) + { + return default(TKey); + } + return (TKey)Convert.ChangeType(id, typeof(TKey), CultureInfo.InvariantCulture); + } + + /// + /// Creates a user identity and then signs the identity using the AuthenticationManager + /// + /// + /// + /// + /// + public virtual async Task SignInAsync(TUser user, bool isPersistent, bool rememberBrowser) + { + var userIdentity = await CreateUserIdentityAsync(user).WithCurrentCulture(); + // Clear any partial cookies from external or two factor partial sign ins + await AuthenticationManager.SignOutAsync(DefaultAuthenticationTypes.ExternalCookie); + await AuthenticationManager.SignOutAsync(DefaultAuthenticationTypes.TwoFactorCookie); + if (rememberBrowser) + { + var rememberBrowserIdentity = AuthenticationManager.CreateTwoFactorRememberBrowserIdentity(ConvertIdToString(user.Id)); + await AuthenticationManager.SignInAsync(new ClaimsPrincipal(new[] { userIdentity, rememberBrowserIdentity }), new AuthenticationProperties { IsPersistent = isPersistent }); + } + else + { + await AuthenticationManager.SignInAsync(new ClaimsPrincipal(userIdentity), new AuthenticationProperties { IsPersistent = isPersistent }); + } + } + + /// + /// Send a two factor code to a user + /// + /// + /// + public virtual async Task SendTwoFactorCodeAsync(string provider) + { + var userId = await GetVerifiedUserIdAsync().WithCurrentCulture(); + if (userId == null) + { + return false; + } + + var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider).WithCurrentCulture(); + // See IdentityConfig.cs to plug in Email/SMS services to actually send the code + await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token).WithCurrentCulture(); + return true; + } + + /// + /// Get the user id that has been verified already or null. + /// + /// + public async Task GetVerifiedUserIdAsync() + { + var result = await AuthenticationManager.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorCookie).WithCurrentCulture(); + if (result?.Principal?.Identity is ClaimsIdentity claimsIdentity && !String.IsNullOrEmpty(claimsIdentity.GetUserId())) + { + return ConvertIdFromString(claimsIdentity.GetUserId()); + } + return default(TKey); + } + + /// + /// Has the user been verified (ie either via password or external login) + /// + /// + public async Task HasBeenVerifiedAsync() + { + return await GetVerifiedUserIdAsync().WithCurrentCulture() != null; + } + + /// + /// Two factor verification step + /// + /// + /// + /// + /// + /// + public virtual async Task TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberBrowser) + { + var userId = await GetVerifiedUserIdAsync().WithCurrentCulture(); + if (userId == null) + { + return SignInStatus.Failure; + } + var user = await UserManager.FindByIdAsync(userId).WithCurrentCulture(); + if (user == null) + { + return SignInStatus.Failure; + } + if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture()) + { + return SignInStatus.LockedOut; + } + if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, provider, code).WithCurrentCulture()) + { + // When token is verified correctly, clear the access failed count used for lockout + await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture(); + await SignInAsync(user, isPersistent, rememberBrowser).WithCurrentCulture(); + return SignInStatus.Success; + } + // If the token is incorrect, record the failure which also may cause the user to be locked out + await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture(); + return SignInStatus.Failure; + } + + /// + /// Sign the user in using an associated external login + /// + /// + /// + /// + public async Task ExternalSignInAsync(ExternalLoginInfo loginInfo, bool isPersistent) + { + var user = await UserManager.FindAsync(loginInfo.Login).WithCurrentCulture(); + if (user == null) + { + return SignInStatus.Failure; + } + if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture()) + { + return SignInStatus.LockedOut; + } + return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture(); + } + + private async Task IsTwoFactorEnabled(TUser user) + { + return await UserManager.GetTwoFactorEnabledAsync(user.Id).WithCurrentCulture() + && (await UserManager.GetValidTwoFactorProvidersAsync(user.Id).WithCurrentCulture()).Count > 0; + } + + private async Task SignInOrTwoFactor(TUser user, bool isPersistent) + { + var id = Convert.ToString(user.Id); + if (await IsTwoFactorEnabled(user) && !await AuthenticationManager.TwoFactorBrowserRememberedAsync(id).WithCurrentCulture()) + { + var identity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorCookie); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id)); + await AuthenticationManager.SignInAsync(new ClaimsPrincipal(identity)); + return SignInStatus.RequiresVerification; + } + await SignInAsync(user, isPersistent, false).WithCurrentCulture(); + return SignInStatus.Success; + } + + /// + /// Sign in the user in using the user name and password + /// + /// + /// + /// + /// + /// + public virtual async Task PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout) + { + if (UserManager == null) + { + return SignInStatus.Failure; + } + var user = await UserManager.FindByNameAsync(userName).WithCurrentCulture(); + if (user == null) + { + return SignInStatus.Failure; + } + if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture()) + { + return SignInStatus.LockedOut; + } + if (await UserManager.CheckPasswordAsync(user, password).WithCurrentCulture()) + { + if (!await IsTwoFactorEnabled(user)) + { + await UserManager.ResetAccessFailedCountAsync(user.Id).WithCurrentCulture(); + } + return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture(); + } + if (shouldLockout) + { + // If lockout is requested, increment access failed count which might lock out the user + await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture(); + if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture()) + { + return SignInStatus.LockedOut; + } + } + return SignInStatus.Failure; + } + + + /// + /// Dispose + /// + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// If disposing, calls dispose on the Context. Always nulls out the Context + /// + /// + protected virtual void Dispose(bool disposing) + { + } + } +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.AspNetCore/SignInStatus.cs b/src/Microsoft.AspNet.Identity.AspNetCore/SignInStatus.cs new file mode 100644 index 0000000..d78402a --- /dev/null +++ b/src/Microsoft.AspNet.Identity.AspNetCore/SignInStatus.cs @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +namespace Microsoft.AspNet.Identity.AspNetCore +{ + /// + /// Possible results from a sign in attempt + /// + public enum SignInStatus + { + /// + /// Sign in was successful + /// + Success, + + /// + /// User is locked out + /// + LockedOut, + + /// + /// Sign in requires addition verification (i.e. two factor) + /// + RequiresVerification, + + /// + /// Sign in failed + /// + Failure + } + +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs index 9963720..1f673ae 100644 --- a/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs +++ b/src/Microsoft.AspNet.Identity.Core/Properties/AssemblyInfo.cs @@ -21,12 +21,16 @@ [assembly: AssemblyMetadata("Serviceable", "True")] [assembly: InternalsVisibleTo( - "Microsoft.AspNet.Identity.EntityFramework, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" - )] + "Microsoft.AspNet.Identity.Owin, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + )] [assembly: InternalsVisibleTo( - "Microsoft.AspNet.Identity.Owin, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + "Microsoft.AspNet.Identity.AspNetCore, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" )] +[assembly: + InternalsVisibleTo( + "Microsoft.AspNet.Identity.EntityFramework, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" + )] [assembly: InternalsVisibleTo( "Identity.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9" diff --git a/test/Identity.Test/ApplicationUserTest.cs b/test/Identity.Test/ApplicationUserTest.cs index a11a599..04ec87a 100644 --- a/test/Identity.Test/ApplicationUserTest.cs +++ b/test/Identity.Test/ApplicationUserTest.cs @@ -7,40 +7,76 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -//using Microsoft.AspNet.Identity.Owin; -//using Microsoft.Owin; -//using Microsoft.Owin.Security.DataProtection; + +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin; +using Microsoft.Owin.Security.DataProtection; +#else +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.DataProtection; +#endif + using Xunit; namespace Identity.Test { public class ApplicationUserTest { - //private async Task CreateManager(OwinContext context) - //{ - // var options = new IdentityFactoryOptions - // { - // DataProtectionProvider = new DpapiDataProtectionProvider(), - // Provider = new IdentityFactoryProvider - // { - // OnCreate = (o, c) => ApplicationUserManager.Create(o, c) - // } - // }; - // var middleware = - // new IdentityFactoryMiddleware>( - // null, options); - // var dbMiddle = - // new IdentityFactoryMiddleware>( - // middleware, - // new IdentityFactoryOptions - // { - // Provider = new IdentityFactoryProvider - // { - // OnCreate = (o, c) => CreateDb() - // } - // }); - // await dbMiddle.Invoke(context); - //} +#if NETFRAMEWORK + private async Task CreateManager(OwinContext context) + { + var options = new IdentityFactoryOptions + { + DataProtectionProvider = new DpapiDataProtectionProvider(), + Provider = new IdentityFactoryProvider + { + OnCreate = (o, c) => ApplicationUserManager.Create(o, c) + } + }; + var middleware = + new IdentityFactoryMiddleware>( + null, options); + var dbMiddle = + new IdentityFactoryMiddleware>( + middleware, + new IdentityFactoryOptions + { + Provider = new IdentityFactoryProvider + { + OnCreate = (o, c) => CreateDb() + } + }); + await dbMiddle.Invoke(context); + } +#else + private async Task CreateManager(HttpContext context) + { + var options = new IdentityFactoryOptions + { + DataProtectionProvider = new EphemeralDataProtectionProvider(), + Provider = new IdentityFactoryProvider + { + OnCreate = (o, c) => ApplicationUserManager.Create(o, c) + } + }; + var middleware = + new IdentityFactoryMiddleware>( + options); + var dbMiddle = + new IdentityFactoryMiddleware>( + new IdentityFactoryOptions + { + Provider = new IdentityFactoryProvider + { + OnCreate = (o, c) => CreateDb() + } + }); + await dbMiddle.InvokeAsync(context, c => middleware.InvokeAsync(c, null)); + } +#endif + [Fact] public void EnsureDefaultSchemaWithApplicationUser() @@ -48,30 +84,30 @@ public void EnsureDefaultSchemaWithApplicationUser() IdentityDbContextTest.VerifyDefaultSchema(CreateDb()); } - //[Fact] - //public async Task ApplicationUserCreateTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager(); - // ApplicationUser[] users = - // { - // new ApplicationUser {UserName = "test", Email = "test@test.com"}, - // new ApplicationUser {UserName = "test1", Email = "test1@test.com"}, - // new ApplicationUser {UserName = "test2", Email = "test2@test.com"}, - // new ApplicationUser {UserName = "test3", Email = "test3@test.com"} - // }; - // foreach (ApplicationUser user in users) - // { - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // } - // foreach (ApplicationUser user in users) - // { - // var u = await manager.FindByIdAsync(user.Id); - // Assert.NotNull(u); - // Assert.Equal(u.UserName, user.UserName); - // } - //} + [Fact] + public async Task ApplicationUserCreateTest() + { + var context = GlobalHelpers.CreateContext(); + await CreateManager(context); + var manager = context.GetUserManager(); + ApplicationUser[] users = + { + new ApplicationUser {UserName = "test", Email = "test@test.com"}, + new ApplicationUser {UserName = "test1", Email = "test1@test.com"}, + new ApplicationUser {UserName = "test2", Email = "test2@test.com"}, + new ApplicationUser {UserName = "test3", Email = "test3@test.com"} + }; + foreach (ApplicationUser user in users) + { + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + } + foreach (ApplicationUser user in users) + { + var u = await manager.FindByIdAsync(user.Id); + Assert.NotNull(u); + Assert.Equal(u.UserName, user.UserName); + } + } private static ApplicationDbContext CreateDb() { @@ -167,36 +203,41 @@ public ApplicationUserManager(IUserStore store) { } - //public static ApplicationUserManager Create(IdentityFactoryOptions options, - // IOwinContext context) - //{ - // var manager = - // new ApplicationUserManager(new UserStore(context.Get())); - // manager.UserValidator = new UserValidator(manager) - // { - // AllowOnlyAlphanumericUserNames = false, - // RequireUniqueEmail = true - // }; - // manager.PasswordValidator = new MinimumLengthValidator(6); - // manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider - // { - // MessageFormat = "Your security code is: {0}" - // }); - // manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider - // { - // Subject = "SecurityCode", - // BodyFormat = "Your security code is {0}" - // }); - // manager.EmailService = new EmailService(); - // manager.SmsService = new SMSService(); - // var dataProtectionProvider = options.DataProtectionProvider; - // if (dataProtectionProvider != null) - // { - // manager.UserTokenProvider = - // new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); - // } - // return manager; - //} + public static ApplicationUserManager Create(IdentityFactoryOptions options, +#if NETFRAMEWORK + IOwinContext context +#else + HttpContext context +#endif + ) + { + var manager = + new ApplicationUserManager(new UserStore(context.Get())); + manager.UserValidator = new UserValidator(manager) + { + AllowOnlyAlphanumericUserNames = false, + RequireUniqueEmail = true + }; + manager.PasswordValidator = new MinimumLengthValidator(6); + manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider + { + MessageFormat = "Your security code is: {0}" + }); + manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider + { + Subject = "SecurityCode", + BodyFormat = "Your security code is {0}" + }); + manager.EmailService = new EmailService(); + manager.SmsService = new SMSService(); + var dataProtectionProvider = options.DataProtectionProvider; + if (dataProtectionProvider != null) + { + manager.UserTokenProvider = + new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); + } + return manager; + } } public class EmailService : IIdentityMessageService diff --git a/test/Identity.Test/AuthenticationManagerExtensionsTest.cs b/test/Identity.Test/AuthenticationManagerExtensionsTest.cs index 5d22c97..7c7cfa1 100644 --- a/test/Identity.Test/AuthenticationManagerExtensionsTest.cs +++ b/test/Identity.Test/AuthenticationManagerExtensionsTest.cs @@ -1,11 +1,12 @@ // Copyright (c) Microsoft Corporation, Inc. All rights reserved. // Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. +#if NETFRAMEWORK using System.Security.Claims; using System.Threading.Tasks; using Microsoft.AspNet.Identity; -//using Microsoft.AspNet.Identity.Owin; -//using Microsoft.Owin.Security; +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin.Security; using Moq; using Xunit; @@ -13,331 +14,324 @@ namespace Identity.Test { public class AuthenticationManagerExtensionsTest { - //[Fact] - //public void ExtensionsNullCheckTest() - //{ - // IAuthenticationManager manager = null; - // ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalAuthenticationTypes(), "manager"); - // ExceptionHelper.ThrowsArgumentNull( - // () => AsyncHelper.RunSync(() => manager.GetExternalIdentityAsync("whatever")), "manager"); - // ExceptionHelper.ThrowsArgumentNull(() => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync()), - // "manager"); - // ExceptionHelper.ThrowsArgumentNull( - // () => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync("key", "blah")), "manager"); - // ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo(), "manager"); - // ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo("key", "blah"), "manager"); - // ExceptionHelper.ThrowsArgumentNull(() => manager.CreateTwoFactorRememberBrowserIdentity("foo"), "manager"); - // ExceptionHelper.ThrowsArgumentNull( - // () => AsyncHelper.RunSync(() => manager.TwoFactorBrowserRememberedAsync("foo")), "manager"); - //} + [Fact] + public void ExtensionsNullCheckTest() + { + IAuthenticationManager manager = null; + ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalAuthenticationTypes(), "manager"); + ExceptionHelper.ThrowsArgumentNull( + () => AsyncHelper.RunSync(() => manager.GetExternalIdentityAsync("whatever")), "manager"); + ExceptionHelper.ThrowsArgumentNull(() => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync()), + "manager"); + ExceptionHelper.ThrowsArgumentNull( + () => AsyncHelper.RunSync(() => manager.GetExternalLoginInfoAsync("key", "blah")), "manager"); + ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo(), "manager"); + ExceptionHelper.ThrowsArgumentNull(() => manager.GetExternalLoginInfo("key", "blah"), "manager"); + ExceptionHelper.ThrowsArgumentNull(() => manager.CreateTwoFactorRememberBrowserIdentity("foo"), "manager"); + ExceptionHelper.ThrowsArgumentNull( + () => AsyncHelper.RunSync(() => manager.TwoFactorBrowserRememberedAsync("foo")), "manager"); + } - //[Fact] - //public async Task GetExternalLoginReturnsNullIfNoNameIdentifierTest() - //{ - // var manager = new Mock(); - // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), - // new AuthenticationProperties(), new AuthenticationDescription()))); - // Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); - //} + [Fact] + public async Task GetExternalLoginReturnsNullIfNoNameIdentifierTest() + { + var manager = new Mock(); + manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), + new AuthenticationProperties()))); + Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); + } + + [Fact] + public async Task GetExternalLoginDoesNotBlowUpWithNullName() + { + var manager = new Mock(); + var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ExternalCookie); + identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "foo")); + manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(identity, + new AuthenticationProperties()))); + var externalInfo = await manager.Object.GetExternalLoginInfoAsync(); + Assert.NotNull(externalInfo); + } - //[Fact] - //public async Task GetExternalLoginDoesNotBlowUpWithNullName() - //{ - // var manager = new Mock(); - // var identity = new ClaimsIdentity(DefaultAuthenticationTypes.ExternalCookie); - // identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, "foo")); - // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(identity, - // new AuthenticationProperties(), new AuthenticationDescription()))); - // var externalInfo = await manager.Object.GetExternalLoginInfoAsync(); - // Assert.NotNull(externalInfo); - //} + [Fact] + public async Task GetExternalLoginReturnsNullIfNoExternalIdTest() + { + var manager = new Mock(); + manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns(Task.FromResult(null)); + Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); + } - //[Fact] - //public async Task GetExternalLoginReturnsNullIfNoExternalIdTest() - //{ - // var manager = new Mock(); - // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns(Task.FromResult(null)); - // Assert.Null(await manager.Object.GetExternalLoginInfoAsync()); - //} + [Fact] + public async Task GetExternalLoginWithXsrfReturnsNullIfNoNameIdentifierTest() + { + var manager = new Mock(); + manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), + new AuthenticationProperties()))); + Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); + } - //[Fact] - //public async Task GetExternalLoginWithXsrfReturnsNullIfNoNameIdentifierTest() - //{ - // var manager = new Mock(); - // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), - // new AuthenticationProperties(), new AuthenticationDescription()))); - // Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); - //} + [Fact] + public async Task GetExternalLoginWithXsrfReturnsNullIfNoClaimsIdentityTest() + { + var manager = new Mock(); + manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(null, new AuthenticationProperties()))); + Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); + } - //[Fact] - //public async Task GetExternalLoginWithXsrfReturnsNullIfNoClaimsIdentityTest() - //{ - // var manager = new Mock(); - // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(null, new AuthenticationProperties(), - // new AuthenticationDescription()))); - // Assert.Null(await manager.Object.GetExternalLoginInfoAsync("xsrfKey", "foo")); - //} + [Fact] + public async Task GetExternalLoginTest() + { + var mockManager = new Mock(); + var props = new AuthenticationProperties(); + var loginInfo = new ExternalLoginInfo + { + Login = new UserLoginInfo("loginProvider", "key"), + DefaultUserName = "Hao Kung" + }; + var identity = CreateIdentity(loginInfo); + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns(Task.FromResult(GlobalHelpers.CreateAuthenticateResult(identity, props))); + var manager = mockManager.Object; + var externalInfo = await manager.GetExternalLoginInfoAsync(); + Assert.NotNull(externalInfo); + Assert.Equal(identity, externalInfo.ExternalIdentity); + Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + Assert.Equal("HaoKung", externalInfo.DefaultUserName); + } - //[Fact] - //public async Task GetExternalLoginTest() - //{ - // var mockManager = new Mock(); - // var props = new AuthenticationProperties(); - // var loginInfo = new ExternalLoginInfo - // { - // Login = new UserLoginInfo("loginProvider", "key"), - // DefaultUserName = "Hao Kung" - // }; - // var identity = CreateIdentity(loginInfo); - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription()))); - // var manager = mockManager.Object; - // var externalInfo = await manager.GetExternalLoginInfoAsync(); - // Assert.NotNull(externalInfo); - // Assert.Equal(identity, externalInfo.ExternalIdentity); - // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - // Assert.Equal("HaoKung", externalInfo.DefaultUserName); - //} + [Fact] + public void GetExternalLoginSyncTest() + { + var mockManager = new Mock(); + var props = new AuthenticationProperties(); + var loginInfo = new ExternalLoginInfo + { + Login = new UserLoginInfo("loginProvider", "key"), + DefaultUserName = "Hao Kung" + }; + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props))); + var manager = mockManager.Object; + var externalInfo = manager.GetExternalLoginInfo(); + Assert.NotNull(externalInfo); + Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + Assert.Equal("HaoKung", externalInfo.DefaultUserName); + } - //[Fact] - //public void GetExternalLoginSyncTest() - //{ - // var mockManager = new Mock(); - // var props = new AuthenticationProperties(); - // var loginInfo = new ExternalLoginInfo - // { - // Login = new UserLoginInfo("loginProvider", "key"), - // DefaultUserName = "Hao Kung" - // }; - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - // new AuthenticationDescription()))); - // var manager = mockManager.Object; - // var externalInfo = manager.GetExternalLoginInfo(); - // Assert.NotNull(externalInfo); - // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - // Assert.Equal("HaoKung", externalInfo.DefaultUserName); - //} + [Fact] + public async Task GetExternalLoginWithXsrfTest() + { + var mockManager = new Mock(); + var props = new AuthenticationProperties(); + props.GetPropertiesDictionary()["xsrfKey"] = "Hao"; + var loginInfo = new ExternalLoginInfo + { + Login = new UserLoginInfo("loginProvider", "key"), + DefaultUserName = "Hao Kung" + }; + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props))); + var manager = mockManager.Object; + var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "Hao"); + Assert.NotNull(externalInfo); + Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + Assert.Equal("HaoKung", externalInfo.DefaultUserName); + } - //[Fact] - //public async Task GetExternalLoginWithXsrfTest() - //{ - // var mockManager = new Mock(); - // var props = new AuthenticationProperties(); - // props.Dictionary["xsrfKey"] = "Hao"; - // var loginInfo = new ExternalLoginInfo - // { - // Login = new UserLoginInfo("loginProvider", "key"), - // DefaultUserName = "Hao Kung" - // }; - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - // new AuthenticationDescription()))); - // var manager = mockManager.Object; - // var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "Hao"); - // Assert.NotNull(externalInfo); - // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - // Assert.Equal("HaoKung", externalInfo.DefaultUserName); - //} + [Fact] + public void GetExternalLoginWithXsrfSyncTest() + { + var mockManager = new Mock(); + var props = new AuthenticationProperties(); + props.GetPropertiesDictionary()["xsrfKey"] = "Hao"; + var loginInfo = new ExternalLoginInfo + { + Login = new UserLoginInfo("loginProvider", "key"), + DefaultUserName = "Hao Kung" + }; + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props))); + var manager = mockManager.Object; + var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "Hao"); + Assert.NotNull(externalInfo); + Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); + Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); + Assert.Equal("HaoKung", externalInfo.DefaultUserName); + } - //[Fact] - //public void GetExternalLoginWithXsrfSyncTest() - //{ - // var mockManager = new Mock(); - // var props = new AuthenticationProperties(); - // props.Dictionary["xsrfKey"] = "Hao"; - // var loginInfo = new ExternalLoginInfo - // { - // Login = new UserLoginInfo("loginProvider", "key"), - // DefaultUserName = "Hao Kung" - // }; - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - // new AuthenticationDescription()))); - // var manager = mockManager.Object; - // var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "Hao"); - // Assert.NotNull(externalInfo); - // Assert.Equal(loginInfo.Login.LoginProvider, externalInfo.Login.LoginProvider); - // Assert.Equal(loginInfo.Login.ProviderKey, externalInfo.Login.ProviderKey); - // Assert.Equal("HaoKung", externalInfo.DefaultUserName); - //} + [Fact] + public async Task GetExternalLoginNullIfXsrfFailsTest() + { + var mockManager = new Mock(); + var props = new AuthenticationProperties(); + props.GetPropertiesDictionary()["xsrfKey"] = "Hao"; + var loginInfo = new ExternalLoginInfo + { + Login = new UserLoginInfo("loginProvider", "key"), + DefaultUserName = "Hao Kung" + }; + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props))); + var manager = mockManager.Object; + var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "NotHao"); + Assert.Null(externalInfo); + } - //[Fact] - //public async Task GetExternalLoginNullIfXsrfFailsTest() - //{ - // var mockManager = new Mock(); - // var props = new AuthenticationProperties(); - // props.Dictionary["xsrfKey"] = "Hao"; - // var loginInfo = new ExternalLoginInfo - // { - // Login = new UserLoginInfo("loginProvider", "key"), - // DefaultUserName = "Hao Kung" - // }; - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - // new AuthenticationDescription()))); - // var manager = mockManager.Object; - // var externalInfo = await manager.GetExternalLoginInfoAsync("xsrfKey", "NotHao"); - // Assert.Null(externalInfo); - //} + [Fact] + public void GetExternalLoginNullIfXsrfFailsSyncTest() + { + var mockManager = new Mock(); + var props = new AuthenticationProperties(); + props.GetPropertiesDictionary()["xsrfKey"] = "Hao"; + var loginInfo = new ExternalLoginInfo + { + Login = new UserLoginInfo("loginProvider", "key"), + DefaultUserName = "Hao Kung" + }; + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props))); + var manager = mockManager.Object; + var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "NotHao"); + Assert.Null(externalInfo); + } - //[Fact] - //public void GetExternalLoginNullIfXsrfFailsSyncTest() - //{ - // var mockManager = new Mock(); - // var props = new AuthenticationProperties(); - // props.Dictionary["xsrfKey"] = "Hao"; - // var loginInfo = new ExternalLoginInfo - // { - // Login = new UserLoginInfo("loginProvider", "key"), - // DefaultUserName = "Hao Kung" - // }; - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - // new AuthenticationDescription()))); - // var manager = mockManager.Object; - // var externalInfo = manager.GetExternalLoginInfo("xsrfKey", "NotHao"); - // Assert.Null(externalInfo); - //} + [Fact] + public async Task GetExternalIdentityReturnsNullIfNoNameIdentifierTest() + { + var manager = new Mock(); + manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), + new AuthenticationProperties()))); + Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); + } - //[Fact] - //public async Task GetExternalIdentityReturnsNullIfNoNameIdentifierTest() - //{ - // var manager = new Mock(); - // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateNoNameIdentifierIdentity("name", "authtype"), - // new AuthenticationProperties(), new AuthenticationDescription()))); - // Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); - //} + [Fact] + public async Task GetExternalIdentityReturnsNullIfNullNameTest() + { + var manager = new Mock(); + manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateNoClaimIdentity("authtype"), + new AuthenticationProperties()))); + Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); + } - //[Fact] - //public async Task GetExternalIdentityReturnsNullIfNullNameTest() - //{ - // var manager = new Mock(); - // manager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateNoClaimIdentity("authtype"), - // new AuthenticationProperties(), new AuthenticationDescription()))); - // Assert.Null(await manager.Object.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie)); - //} + [Fact] + public async Task GetExternalIdentityTest() + { + var mockManager = new Mock(); + var props = new AuthenticationProperties(); + var loginInfo = new ExternalLoginInfo + { + Login = new UserLoginInfo("loginProvider", "key"), + DefaultUserName = "Hao Kung" + }; + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(CreateIdentity(loginInfo), props))); + var manager = mockManager.Object; + var id = await manager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); + Assert.NotNull(id); + var idClaim = id.FindFirst(ClaimTypes.NameIdentifier); + Assert.NotNull(idClaim); + Assert.Equal(loginInfo.Login.LoginProvider, idClaim.Issuer); + Assert.Equal(loginInfo.Login.ProviderKey, idClaim.Value); + Assert.Equal(loginInfo.DefaultUserName, id.Name); + } - //[Fact] - //public async Task GetExternalIdentityTest() - //{ - // var mockManager = new Mock(); - // var props = new AuthenticationProperties(); - // var loginInfo = new ExternalLoginInfo - // { - // Login = new UserLoginInfo("loginProvider", "key"), - // DefaultUserName = "Hao Kung" - // }; - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(CreateIdentity(loginInfo), props, - // new AuthenticationDescription()))); - // var manager = mockManager.Object; - // var id = await manager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie); - // Assert.NotNull(id); - // var idClaim = id.FindFirst(ClaimTypes.NameIdentifier); - // Assert.NotNull(idClaim); - // Assert.Equal(loginInfo.Login.LoginProvider, idClaim.Issuer); - // Assert.Equal(loginInfo.Login.ProviderKey, idClaim.Value); - // Assert.Equal(loginInfo.DefaultUserName, id.Name); - //} + [Fact] + public void CreateRememberBrowserIdentityTest() + { + var mockManager = new Mock(); + var manager = mockManager.Object; + var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); + Assert.NotNull(identity); + Assert.Equal("userId", identity.GetUserId()); + Assert.Equal(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie, identity.AuthenticationType); + } - //[Fact] - //public void CreateRememberBrowserIdentityTest() - //{ - // var mockManager = new Mock(); - // var manager = mockManager.Object; - // var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); - // Assert.NotNull(identity); - // Assert.Equal("userId", identity.GetUserId()); - // Assert.Equal(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie, identity.AuthenticationType); - //} + [Fact] + public async Task BrowserRemeberedTest() + { + var mockManager = new Mock(); + var manager = mockManager.Object; + var props = new AuthenticationProperties(); + var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) + .Returns(Task.FromResult(GlobalHelpers.CreateAuthenticateResult(identity, props))); + Assert.True(await manager.TwoFactorBrowserRememberedAsync("userId")); + Assert.False(await manager.TwoFactorBrowserRememberedAsync("userNotId")); + } - //[Fact] - //public async Task BrowserRemeberedTest() - //{ - // var mockManager = new Mock(); - // var manager = mockManager.Object; - // var props = new AuthenticationProperties(); - // var identity = manager.CreateTwoFactorRememberBrowserIdentity("userId"); - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) - // .Returns(Task.FromResult(new AuthenticateResult(identity, props, new AuthenticationDescription()))); - // Assert.True(await manager.TwoFactorBrowserRememberedAsync("userId")); - // Assert.False(await manager.TwoFactorBrowserRememberedAsync("userNotId")); - //} + [Fact] + public async Task BrowserRemeberedFailWithNoIdentityTest() + { + var mockManager = new Mock(); + var manager = mockManager.Object; + var props = new AuthenticationProperties(); + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) + .Returns(Task.FromResult(GlobalHelpers.CreateAuthenticateResult(null, props))); + Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); + } - //[Fact] - //public async Task BrowserRemeberedFailWithNoIdentityTest() - //{ - // var mockManager = new Mock(); - // var manager = mockManager.Object; - // var props = new AuthenticationProperties(); - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) - // .Returns(Task.FromResult(new AuthenticateResult(null, props, new AuthenticationDescription()))); - // Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); - //} + [Fact] + public async Task BrowserRemeberedFailWithWrongIdentityTest() + { + var mockManager = new Mock(); + var manager = mockManager.Object; + var props = new AuthenticationProperties(); + mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) + .Returns( + Task.FromResult(GlobalHelpers.CreateAuthenticateResult(new ClaimsIdentity("whatever"), props))); + Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); + } - //[Fact] - //public async Task BrowserRemeberedFailWithWrongIdentityTest() - //{ - // var mockManager = new Mock(); - // var manager = mockManager.Object; - // var props = new AuthenticationProperties(); - // mockManager.Setup(a => a.AuthenticateAsync(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie)) - // .Returns( - // Task.FromResult(new AuthenticateResult(new ClaimsIdentity("whatever"), props, - // new AuthenticationDescription()))); - // Assert.False(await manager.TwoFactorBrowserRememberedAsync("userId")); - //} + public static ClaimsIdentity CreateNoNameIdentifierIdentity(string name, string authenticationType) + { + return new ClaimsIdentity( + new[] + { + new Claim(ClaimTypes.Name, name) + }, + authenticationType); + } - //public static ClaimsIdentity CreateNoNameIdentifierIdentity(string name, string authenticationType) - //{ - // return new ClaimsIdentity( - // new[] - // { - // new Claim(ClaimTypes.Name, name) - // }, - // authenticationType); - //} + public static ClaimsIdentity CreateNoClaimIdentity(string authenticationType) + { + return new ClaimsIdentity( + new Claim[] { }, + authenticationType); + } - //public static ClaimsIdentity CreateNoClaimIdentity(string authenticationType) - //{ - // return new ClaimsIdentity( - // new Claim[] {}, - // authenticationType); - //} - - //public static ClaimsIdentity CreateIdentity(ExternalLoginInfo info) - //{ - // return new ClaimsIdentity( - // new[] - // { - // new Claim(ClaimTypes.NameIdentifier, info.Login.ProviderKey, null, info.Login.LoginProvider), - // new Claim(ClaimTypes.Name, info.DefaultUserName) - // }, - // info.Login.LoginProvider); - //} + public static ClaimsIdentity CreateIdentity(ExternalLoginInfo info) + { + return new ClaimsIdentity( + new[] + { + new Claim(ClaimTypes.NameIdentifier, info.Login.ProviderKey, null, info.Login.LoginProvider), + new Claim(ClaimTypes.Name, info.DefaultUserName) + }, + info.Login.LoginProvider); + } } -} \ No newline at end of file +} +#endif diff --git a/test/Identity.Test/CustomGuidKeyTest.cs b/test/Identity.Test/CustomGuidKeyTest.cs index db42090..228bcff 100644 --- a/test/Identity.Test/CustomGuidKeyTest.cs +++ b/test/Identity.Test/CustomGuidKeyTest.cs @@ -8,11 +8,21 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -//using Microsoft.AspNet.Identity.Owin; -//using Microsoft.Owin; -//using Microsoft.Owin.Security; -//using Microsoft.Owin.Security.Cookies; -//using Microsoft.Owin.Security.DataProtection; + +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin; +using Microsoft.Owin.Security; +using Microsoft.Owin.Security.Cookies; +using Microsoft.Owin.Security.DataProtection; +#else +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; +#endif + using Xunit; namespace Identity.Test @@ -82,104 +92,134 @@ public async Task CustomGuidGetRolesForUserTest() } } - //[Fact] - //public async Task CustomGuidConfirmEmailTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new GuidUser("test"); - // Assert.False(user.EmailConfirmed); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); - // Assert.NotNull(token); - // UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); - // Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); - // UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); - // Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - //} + [Fact] + public async Task CustomGuidConfirmEmailTest() + { + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new GuidUser("test"); + Assert.False(user.EmailConfirmed); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); + Assert.True((bool)await manager.IsEmailConfirmedAsync(user.Id)); + UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); + Assert.False((bool)await manager.IsEmailConfirmedAsync(user.Id)); + } - //[Fact] - //public async Task CustomGuidEmailTokenFactorWithFormatTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var messageService = new TestMessageService(); - // manager.EmailService = messageService; - // var factorId = "EmailCode"; - // manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider - // { - // Subject = "Security Code", - // BodyFormat = "Your code is: {0}" - // }); - // var user = new GuidUser("EmailCodeTest"); - // user.Email = "foo@foo.com"; - // var password = "password"; - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); - // var stamp = user.SecurityStamp; - // Assert.NotNull(stamp); - // var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); - // Assert.NotNull(token); - // Assert.Null(messageService.Message); - // await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token); - // Assert.NotNull(messageService.Message); - // Assert.Equal("Security Code", messageService.Message.Subject); - // Assert.Equal("Your code is: " + token, messageService.Message.Body); - // Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); - //} + [Fact] + public async Task CustomGuidEmailTokenFactorWithFormatTest() + { + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var messageService = new TestMessageService(); + manager.EmailService = messageService; + var factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider + { + Subject = "Security Code", + BodyFormat = "Your code is: {0}" + }); + var user = new GuidUser("EmailCodeTest"); + user.Email = "foo@foo.com"; + var password = "password"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token); + Assert.NotNull(messageService.Message); + Assert.Equal("Security Code", messageService.Message.Subject); + Assert.Equal("Your code is: " + token, messageService.Message.Body); + Assert.True((bool)await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + } - //[Fact] - //public async Task OnValidateIdentityWithGuidTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new GuidUser {UserName = "test"}; - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var id = await SignIn(manager, user); - // var ticket = new AuthenticationTicket(id, new AuthenticationProperties {IssuedUtc = DateTimeOffset.UtcNow}); - // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - // await - // SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, - // SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); - // Assert.NotNull(context.Identity); - // Assert.Equal(user.Id.ToString(), id.GetUserId()); + [Fact] + public async Task OnValidateIdentityWithGuidTest() + { + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new GuidUser { UserName = "test" }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var id = await SignIn(manager, user); +#if NETFRAMEWORK + var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); +#else + var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, id.AuthenticationType); + var context = new CookieValidatePrincipalContext(owinContext, new AuthenticationScheme(id.AuthenticationType, null, typeof(CookieAuthenticationHandler)), new CookieAuthenticationOptions(), ticket); +#endif + await + SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, + SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); + var claimsIdentity = context.ExtractClaimsIdentity(); + Assert.NotNull(claimsIdentity); + Assert.Equal(user.Id.ToString(), id.GetUserId()); - // // change stamp and make sure it fails - // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - // await - // SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, - // SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); - // Assert.Null(context.Identity); - //} + // change stamp and make sure it fails + UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + await + SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, + SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); + claimsIdentity = context.ExtractClaimsIdentity(); + Assert.Null(claimsIdentity); + } - //private Task SignIn(UserManager manager, GuidUser user) - //{ - // return manager.ClaimsIdentityFactory.CreateAsync(manager, user, DefaultAuthenticationTypes.ApplicationCookie); - //} + private Task SignIn(UserManager manager, GuidUser user) + { + return manager.ClaimsIdentityFactory.CreateAsync(manager, user, DefaultAuthenticationTypes.ApplicationCookie); + } - //private async Task CreateManager(OwinContext context) - //{ - // var options = new IdentityFactoryOptions> - // { - // Provider = new TestProvider(), - // DataProtectionProvider = new DpapiDataProtectionProvider() - // }; - // var middleware = - // new IdentityFactoryMiddleware - // , IdentityFactoryOptions>>(null, options); - // var dbMiddle = new IdentityFactoryMiddleware>(middleware, - // new IdentityFactoryOptions - // { - // Provider = new IdentityFactoryProvider - // { - // OnCreate = (o, c) => GuidUserContext.Create(), - // } - // }); - // await dbMiddle.Invoke(context); - //} +#if NETFRAMEWORK + private async Task CreateManager(OwinContext context) + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(), + DataProtectionProvider = new DpapiDataProtectionProvider() + }; + var middleware = + new IdentityFactoryMiddleware + , IdentityFactoryOptions>>(null, options); + var dbMiddle = new IdentityFactoryMiddleware>(middleware, + new IdentityFactoryOptions + { + Provider = new IdentityFactoryProvider + { + OnCreate = (o, c) => GuidUserContext.Create(), + } + }); + await dbMiddle.Invoke(context); + } +#else + private async Task CreateManager(HttpContext context) + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(), + DataProtectionProvider = new EphemeralDataProtectionProvider() + }; + var middleware = + new IdentityFactoryMiddleware + , IdentityFactoryOptions>>(options); + var dbMiddle = new IdentityFactoryMiddleware>( + new IdentityFactoryOptions + { + Provider = new IdentityFactoryProvider + { + OnCreate = (o, c) => GuidUserContext.Create(), + } + }); + await dbMiddle.InvokeAsync(context, c => middleware.InvokeAsync(c, null)); + } +#endif public class GuidRole : IdentityRole { @@ -247,27 +287,27 @@ public GuidUserStore(DbContext context) } } - //private class TestProvider : IdentityFactoryProvider> - //{ - // public TestProvider() - // { - // OnCreate = ((options, context) => - // { - // var manager = new UserManager(new GuidUserStore(context.Get())); - // manager.UserValidator = new UserValidator(manager) - // { - // AllowOnlyAlphanumericUserNames = true, - // RequireUniqueEmail = false - // }; - // if (options.DataProtectionProvider != null) - // { - // manager.UserTokenProvider = - // new DataProtectorTokenProvider( - // options.DataProtectionProvider.Create("ASP.NET Identity")); - // } - // return manager; - // }); - // } - //} + private class TestProvider : IdentityFactoryProvider> + { + public TestProvider() + { + OnCreate = ((options, context) => + { + var manager = new UserManager(new GuidUserStore(context.Get())); + manager.UserValidator = new UserValidator(manager) + { + AllowOnlyAlphanumericUserNames = true, + RequireUniqueEmail = false + }; + if (options.DataProtectionProvider != null) + { + manager.UserTokenProvider = + new DataProtectorTokenProvider( + options.DataProtectionProvider.Create("ASP.NET Identity")); + } + return manager; + }); + } + } } } \ No newline at end of file diff --git a/test/Identity.Test/CustomIntKeyTest.cs b/test/Identity.Test/CustomIntKeyTest.cs index acbf272..6371492 100644 --- a/test/Identity.Test/CustomIntKeyTest.cs +++ b/test/Identity.Test/CustomIntKeyTest.cs @@ -6,9 +6,16 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -//using Microsoft.AspNet.Identity.Owin; -//using Microsoft.Owin; -//using Microsoft.Owin.Security.DataProtection; + +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin; +using Microsoft.Owin.Security.DataProtection; +#else +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.DataProtection; +#endif + using Xunit; namespace Identity.Test @@ -89,30 +96,41 @@ public async Task CustomIntGetRolesForUserTest() } } - //[Fact] - //public async Task IntKeyConfirmEmailTest() - //{ - // var manager = CreateManager(); - // var user = new CustomUser("testEmailConfirm"); - // Assert.False(user.EmailConfirmed); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); - // Assert.NotNull(token); - // UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); - // Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); - // UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); - // Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); - //} - - //private UserManager CreateManager() - //{ - // var options = new IdentityFactoryOptions> - // { - // Provider = new TestProvider(), - // DataProtectionProvider = new DpapiDataProtectionProvider() - // }; - // return options.Provider.Create(options, new OwinContext()); - //} + [Fact] + public async Task IntKeyConfirmEmailTest() + { + var manager = CreateManager(); + var user = new CustomUser("testEmailConfirm"); + Assert.False(user.EmailConfirmed); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); + Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); + UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); + Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); + } +#if NETFRAMEWORK + private UserManager CreateManager() + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(), + DataProtectionProvider = new DpapiDataProtectionProvider() + }; + return options.Provider.Create(options, new OwinContext()); + } +#else + private UserManager CreateManager() + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(), + DataProtectionProvider = new EphemeralDataProtectionProvider() + }; + return options.Provider.Create(options, GlobalHelpers.CreateContext()); + } +#endif public class CustomRole : IdentityRole { @@ -172,30 +190,30 @@ public CustomUserStore(DbContext context) } } - //private class TestProvider : IdentityFactoryProvider> - //{ - // public TestProvider() - // { - // OnCreate = ((options, context) => - // { - // Database.SetInitializer(new DropCreateDatabaseAlways()); - // var db = new CustomUserContext(); - // db.Database.Initialize(true); - // var manager = new UserManager(new CustomUserStore(db)); - // manager.UserValidator = new UserValidator(manager) - // { - // AllowOnlyAlphanumericUserNames = true, - // RequireUniqueEmail = false - // }; - // if (options.DataProtectionProvider != null) - // { - // manager.UserTokenProvider = - // new DataProtectorTokenProvider( - // options.DataProtectionProvider.Create("ASP.NET Identity")); - // } - // return manager; - // }); - // } - //} + private class TestProvider : IdentityFactoryProvider> + { + public TestProvider() + { + OnCreate = ((options, context) => + { + Database.SetInitializer(new DropCreateDatabaseAlways()); + var db = new CustomUserContext(); + db.Database.Initialize(true); + var manager = new UserManager(new CustomUserStore(db)); + manager.UserValidator = new UserValidator(manager) + { + AllowOnlyAlphanumericUserNames = true, + RequireUniqueEmail = false + }; + if (options.DataProtectionProvider != null) + { + manager.UserTokenProvider = + new DataProtectorTokenProvider( + options.DataProtectionProvider.Create("ASP.NET Identity")); + } + return manager; + }); + } + } } } \ No newline at end of file diff --git a/test/Identity.Test/ExceptionHelper.cs b/test/Identity.Test/ExceptionHelper.cs index 368badb..a9e3194 100644 --- a/test/Identity.Test/ExceptionHelper.cs +++ b/test/Identity.Test/ExceptionHelper.cs @@ -35,8 +35,13 @@ public static ArgumentException ThrowsArgumentException(Action del, string excep public static ArgumentException ThrowsArgumentNullOrEmpty(Action del, string paramName) { +#if NETFRAMEWORK return ThrowsArgumentException(del, "Value cannot be null or empty.\r\nParameter name: " + paramName, paramName); +#else + return ThrowsArgumentException(del, "Value cannot be null or empty. (Parameter '" + paramName + "')", + paramName); +#endif } public static ArgumentNullException ThrowsArgumentNull(Action del, string paramName) diff --git a/test/Identity.Test/GlobalHelpers.cs b/test/Identity.Test/GlobalHelpers.cs new file mode 100644 index 0000000..0a7e6dd --- /dev/null +++ b/test/Identity.Test/GlobalHelpers.cs @@ -0,0 +1,99 @@ +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; + +#if NETFRAMEWORK +using Microsoft.Owin; +using Microsoft.Owin.Security; +using Microsoft.Owin.Security.Cookies; +#else +using Microsoft.AspNet.Identity; +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.Extensions.DependencyInjection; +#endif + +namespace Identity.Test +{ + public static class GlobalHelpers + { +#if NETFRAMEWORK + public static OwinContext CreateContext() + { + return new OwinContext(); + } + + public static CookieValidateIdentityContext CreateCookieValidateIdentityContext(IOwinContext owinContext, AuthenticationTicket ticket, CookieAuthenticationOptions cookieAuthenticationOptions) + { + return new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + } + + public static AuthenticationTicket CreateAuthenticationTicket(ClaimsIdentity id, AuthenticationProperties authenticationProperties) + { + return new AuthenticationTicket(id, authenticationProperties); + } + + public static AuthenticateResult CreateAuthenticateResult(ClaimsIdentity identity, AuthenticationProperties properties) + { + return new AuthenticateResult(identity, properties, new AuthenticationDescription()); + } + + public static IDictionary GetPropertiesDictionary(this AuthenticationProperties props) + { + return props.Dictionary; + } + + public static ClaimsIdentity ExtractClaimsIdentity(this CookieValidateIdentityContext context) + { + return context.Identity; + } +#else + public static DefaultHttpContext CreateContext() + { + var services = new ServiceCollection(); + services.AddAuthentication(DefaultAuthenticationTypes.ExternalCookie) + .AddCookie(DefaultAuthenticationTypes.ExternalCookie) + .AddCookie(DefaultAuthenticationTypes.TwoFactorCookie); + services.AddLogging(); + + return new DefaultHttpContext() + { + RequestServices = services.BuildServiceProvider() + }; + } + + public static CookieValidatePrincipalContext CreateCookieValidateIdentityContext(DefaultHttpContext owinContext, AuthenticationTicket ticket, CookieAuthenticationOptions cookieAuthenticationOptions) + { + return new CookieValidatePrincipalContext(owinContext, new AuthenticationScheme(ticket.AuthenticationScheme, null, typeof(CookieAuthenticationHandler)), new CookieAuthenticationOptions(), ticket); + } + + public static AuthenticationTicket CreateAuthenticationTicket(ClaimsIdentity id, AuthenticationProperties authenticationProperties) + { + return new AuthenticationTicket(new ClaimsPrincipal(id), authenticationProperties, id.AuthenticationType); + } + + public static AuthenticateResult CreateAuthenticateResult(ClaimsIdentity identity, AuthenticationProperties properties) + { + return AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(identity), properties, identity.AuthenticationType)); + } + + public static IDictionary GetPropertiesDictionary(this AuthenticationProperties props) + { + return props.Parameters; + } + + public static ClaimsIdentity? ExtractClaimsIdentity(this CookieValidatePrincipalContext context) + { + return context.Principal?.Identity as ClaimsIdentity; + } + + public static IDataProtector Create(this IDataProtectionProvider provider, string purpose, params string[] subPurpose) + { + return provider.CreateProtector(purpose, subPurpose); + } +#endif + } +} \ No newline at end of file diff --git a/test/Identity.Test/Identity.Test.csproj b/test/Identity.Test/Identity.Test.csproj index c948b1f..ed6f030 100644 --- a/test/Identity.Test/Identity.Test.csproj +++ b/test/Identity.Test/Identity.Test.csproj @@ -1,8 +1,6 @@  - net8.0 - enable - enable + net6.0;net462 false true false @@ -20,6 +18,12 @@ + + + + + + @@ -30,4 +34,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + + PreserveNewest + + \ No newline at end of file diff --git a/test/Identity.Test/LoginsTest.cs b/test/Identity.Test/LoginsTest.cs index a2def95..c302618 100644 --- a/test/Identity.Test/LoginsTest.cs +++ b/test/Identity.Test/LoginsTest.cs @@ -50,7 +50,8 @@ public async Task AddDuplicateLoginFailsTest() //[Fact] - //public async Task RemoveUnknownLoginFailsTest() { + //public async Task RemoveUnknownLoginFailsTest() + //{ // var store = new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); // UnitTestHelper.IsFailure(await store.Users.RemoveLoginAsync("bogus", "whatever", "ignored")); //} diff --git a/test/Identity.Test/RolesTest.cs b/test/Identity.Test/RolesTest.cs index 9f7a85d..536fdd5 100644 --- a/test/Identity.Test/RolesTest.cs +++ b/test/Identity.Test/RolesTest.cs @@ -631,15 +631,15 @@ public void RemoveUserFromRolesSync() Assert.Equal(0, db.Set().Count()); } -// [Fact] -// public async Task UnknownUserThrowsTest() { -// var manager = new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); -// var r = new IdentityRole("r1"); -// UnitTestHelper.IsSuccess(await manager.Roles.CreateAsync(r)); -// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.RemoveUserFromRoleAsync("whatever", r.Name))); -// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.AddUserToRoleAsync("whatever", r.Name))); -// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.GetRolesForUserAsync("whatever"))); -// } + //[Fact] + //public async Task UnknownUserThrowsTest() { + // var manager = new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); + // var r = new IdentityRole("r1"); + // UnitTestHelper.IsSuccess(await manager.Roles.CreateAsync(r)); + // ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.RemoveUserFromRoleAsync("whatever", r.Name))); + // ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.AddUserToRoleAsync("whatever", r.Name))); + // ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.GetRolesForUserAsync("whatever"))); + //} [Fact] public async Task UnknownRoleThrowsTest() diff --git a/test/Identity.Test/SecurityStampTest.cs b/test/Identity.Test/SecurityStampTest.cs index ddfb9b1..3b6cae7 100644 --- a/test/Identity.Test/SecurityStampTest.cs +++ b/test/Identity.Test/SecurityStampTest.cs @@ -6,193 +6,217 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -//using Microsoft.AspNet.Identity.Owin; -//using Microsoft.Owin; -//using Microsoft.Owin.Security; -//using Microsoft.Owin.Security.Cookies; -//using Microsoft.Owin.Security.DataProtection; + +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin; +using Microsoft.Owin.Security; +using Microsoft.Owin.Security.Cookies; +using Microsoft.Owin.Security.DataProtection; +#else +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.Authentication; +using Microsoft.AspNetCore.Authentication.Cookies; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Http; +#endif + using Xunit; namespace Identity.Test { public class SecurityStampTest { - //[Fact] - //public async Task OnValidateIdentityNoBoomWithNullManagerTest() - //{ - // var owinContext = new OwinContext(); - // var id = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie); - // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - // .Invoke(context); - // Assert.NotNull(context.Identity); - //} - - //[Fact] - //public void OnValidateIdentityThrowsOnNullGetIdCallback() - //{ - // ExceptionHelper.ThrowsArgumentNull( - // () => AsyncHelper.RunSync(() => SecurityStampValidator.OnValidateIdentity, IdentityUser, string>(TimeSpan.Zero, SignIn, null) - // .Invoke(null)), "getUserIdCallback"); - //} - - //[Fact] - //public async Task OnValidateIdentityTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new IdentityUser("test"); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var id = await SignIn(manager, user); - // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - // .Invoke(context); - // Assert.NotNull(context.Identity); - // Assert.Equal(user.Id, id.GetUserId()); - - // // change stamp and make sure it fails - // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - // .Invoke(context); - // Assert.Null(context.Identity); - //} - - //[Fact] - //public async Task OnValidateRejectsUnknownUserIdentityTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new IdentityUser("test"); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var id = await SignIn(manager, user); - // UnitTestHelper.IsSuccess(await manager.DeleteAsync(user)); - // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - // .Invoke(context); - // Assert.Null(context.Identity); - //} - - //[Fact] - //public async Task OnValidateIdentityRejectsWithNoIssuedUtcTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new IdentityUser("test"); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var id = await SignIn(manager, user); - // var ticket = new AuthenticationTicket(id, new AuthenticationProperties()); - // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - // .Invoke(context); - // Assert.NotNull(context.Identity); - // Assert.Equal(user.Id, id.GetUserId()); - - // // change stamp does fail validation when no utc - // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) - // .Invoke(context); - // Assert.Null(context.Identity); - //} - - //[Fact] - //public async Task OnValidateIdentityDoesNotRejectRightAwayTest() - //{ - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new IdentityUser("test"); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var id = await SignIn(manager, user); - // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - - // // change stamp does not fail validation when not enough time elapsed - // UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>( - // TimeSpan.FromDays(1), SignIn).Invoke(context); - // Assert.NotNull(context.Identity); - // Assert.Equal(user.Id, id.GetUserId()); - //} - - //[Fact] - //public async Task OnValidateIdentityResetsContextPropertiesDatesTest() - //{ - // // Arrange - // var owinContext = new OwinContext(); - // await CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new IdentityUser(string.Format("{0}{1}", "test", new Random().Next())); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var id = await SignIn(manager, user); - // var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromHours(1)), IsPersistent = true }); - // var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); - - // await - // SecurityStampValidator.OnValidateIdentity, IdentityUser>( - // TimeSpan.Zero, SignIn).Invoke(context); - - // // Assert - // Assert.NotNull(context.Identity); - // Assert.NotNull(context.Properties); - // Assert.Null(context.Properties.IssuedUtc); - // Assert.Null(context.Properties.ExpiresUtc); - // Assert.True(context.Properties.IsPersistent); - //} + [Fact] + public async Task OnValidateIdentityNoBoomWithNullManagerTest() + { + var owinContext = GlobalHelpers.CreateContext(); + var id = new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie); + var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + .Invoke(context); + Assert.NotNull(context.ExtractClaimsIdentity()); + } + + [Fact] + public void OnValidateIdentityThrowsOnNullGetIdCallback() + { + ExceptionHelper.ThrowsArgumentNull( + () => AsyncHelper.RunSync(() => SecurityStampValidator.OnValidateIdentity, IdentityUser, string>(TimeSpan.Zero, SignIn, null) + .Invoke(null)), "getUserIdCallback"); + } + + [Fact] + public async Task OnValidateIdentityTest() + { + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var id = await SignIn(manager, user); + var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + .Invoke(context); + Assert.NotNull(context.ExtractClaimsIdentity()); + Assert.Equal(user.Id, id.GetUserId()); + + // change stamp and make sure it fails + UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + .Invoke(context); + Assert.Null(context.ExtractClaimsIdentity()); + } + + [Fact] + public async Task OnValidateRejectsUnknownUserIdentityTest() + { + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var id = await SignIn(manager, user); + UnitTestHelper.IsSuccess(await manager.DeleteAsync(user)); + var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + .Invoke(context); + Assert.Null(context.ExtractClaimsIdentity()); + } + + [Fact] + public async Task OnValidateIdentityRejectsWithNoIssuedUtcTest() + { + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var id = await SignIn(manager, user); + var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties()); + var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + .Invoke(context); + Assert.NotNull(context.ExtractClaimsIdentity()); + Assert.Equal(user.Id, id.GetUserId()); + + // change stamp does fail validation when no utc + UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>(TimeSpan.Zero, SignIn) + .Invoke(context); + Assert.Null(context.ExtractClaimsIdentity()); + } + + [Fact] + public async Task OnValidateIdentityDoesNotRejectRightAwayTest() + { + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var id = await SignIn(manager, user); + var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + + // change stamp does not fail validation when not enough time elapsed + UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>( + TimeSpan.FromDays(1), SignIn).Invoke(context); + Assert.NotNull(context.ExtractClaimsIdentity()); + Assert.Equal(user.Id, id.GetUserId()); + } + + [Fact] + public async Task OnValidateIdentityResetsContextPropertiesDatesTest() + { + // Arrange + var owinContext = GlobalHelpers.CreateContext(); + await CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new IdentityUser(string.Format("{0}{1}", "test", new Random().Next())); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var id = await SignIn(manager, user); + var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow, ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromHours(1)), IsPersistent = true }); + var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); + + await + SecurityStampValidator.OnValidateIdentity, IdentityUser>( + TimeSpan.Zero, SignIn).Invoke(context); + + // Assert + Assert.NotNull(context.ExtractClaimsIdentity()); + Assert.NotNull(context.Properties); + Assert.Null(context.Properties.IssuedUtc); + Assert.Null(context.Properties.ExpiresUtc); + Assert.True(context.Properties.IsPersistent); + } private Task SignIn(UserManager manager, IdentityUser user) { return manager.ClaimsIdentityFactory.CreateAsync(manager, user, DefaultAuthenticationTypes.ApplicationCookie); } +#if NETFRAMEWORK + private async Task CreateManager(OwinContext context) + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(), + DataProtectionProvider = new DpapiDataProtectionProvider() + }; + var middleware = + new IdentityFactoryMiddleware + , IdentityFactoryOptions>>(null, options); + await middleware.Invoke(context); + } +#else + private async Task CreateManager(HttpContext context) + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(), + DataProtectionProvider = new EphemeralDataProtectionProvider() + }; + var middleware = + new IdentityFactoryMiddleware + , IdentityFactoryOptions>>(options); + await middleware.InvokeAsync(context, null); + } +#endif - //private async Task CreateManager(OwinContext context) - //{ - // var options = new IdentityFactoryOptions> - // { - // Provider = new TestProvider(), - // DataProtectionProvider = new DpapiDataProtectionProvider() - // }; - // var middleware = - // new IdentityFactoryMiddleware - // , IdentityFactoryOptions>>(null, options); - // await middleware.Invoke(context); - //} - - //private class TestProvider : IdentityFactoryProvider> - //{ - // public TestProvider() - // { - // OnCreate = ((options, context) => - // { - // var manager = - // new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); - // manager.UserValidator = new UserValidator(manager) - // { - // AllowOnlyAlphanumericUserNames = true, - // RequireUniqueEmail = false - // }; - // if (options.DataProtectionProvider != null) - // { - // manager.UserTokenProvider = - // new DataProtectorTokenProvider( - // options.DataProtectionProvider.Create("ASP.NET Identity")); - // } - // return manager; - // }); - // OnDispose = (options, manager) => { }; - // } - //} + private class TestProvider : IdentityFactoryProvider> + { + public TestProvider() + { + OnCreate = ((options, context) => + { + var manager = + new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); + manager.UserValidator = new UserValidator(manager) + { + AllowOnlyAlphanumericUserNames = true, + RequireUniqueEmail = false + }; + if (options.DataProtectionProvider != null) + { + manager.UserTokenProvider = + new DataProtectorTokenProvider( + options.DataProtectionProvider.Create("ASP.NET Identity")); + } + return manager; + }); + OnDispose = (options, manager) => { }; + } + } } } \ No newline at end of file diff --git a/test/Identity.Test/SignInManagerTest.cs b/test/Identity.Test/SignInManagerTest.cs index 8b6adeb..dda1d46 100644 --- a/test/Identity.Test/SignInManagerTest.cs +++ b/test/Identity.Test/SignInManagerTest.cs @@ -5,9 +5,15 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; -//using Microsoft.AspNet.Identity.Owin; -//using Microsoft.Owin; -//using Microsoft.Owin.Security.DataProtection; + +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin; +using Microsoft.Owin.Security.DataProtection; +#else +using Microsoft.AspNet.Identity.AspNetCore; +#endif + using Xunit; using Xunit.Extensions; @@ -15,24 +21,29 @@ namespace Identity.Test { public class SignInManagerTest { - //[Theory] - //[InlineData(true, true)] - //[InlineData(true, false)] - //[InlineData(false, true)] - //[InlineData(false, false)] - //public async Task SignInAsyncCookiePersistenceTest(bool isPersistent, bool rememberBrowser) - //{ - // var owinContext = new OwinContext(); - // await TestUtil.CreateManager(owinContext); - // var manager = owinContext.GetUserManager>(); - // var user = new IdentityUser("SignInTest"); - // UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // var signInManager = new SignInManager(manager, owinContext.Authentication); + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public async Task SignInAsyncCookiePersistenceTest(bool isPersistent, bool rememberBrowser) + { + var owinContext = GlobalHelpers.CreateContext(); + await TestUtil.CreateManager(owinContext); + var manager = owinContext.GetUserManager>(); + var user = new IdentityUser("SignInTest"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); - // await signInManager.SignInAsync(user, isPersistent, rememberBrowser); +#if NETFRAMEWORK + var signInManager = new SignInManager(manager, owinContext.Authentication); + await signInManager.SignInAsync(user, isPersistent, rememberBrowser); + + Assert.Equal(isPersistent, owinContext.Authentication.AuthenticationResponseGrant.Properties.IsPersistent); +#else + var signInManager = new SignInManager(manager, owinContext); + await signInManager.SignInAsync(user, isPersistent, rememberBrowser); +#endif + } - // Assert.Equal(isPersistent, owinContext.Authentication.AuthenticationResponseGrant.Properties.IsPersistent); - //} - } } diff --git a/test/Identity.Test/TestUtil.cs b/test/Identity.Test/TestUtil.cs index 23253a3..d97c9b6 100644 --- a/test/Identity.Test/TestUtil.cs +++ b/test/Identity.Test/TestUtil.cs @@ -7,6 +7,16 @@ using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin; +using Microsoft.Owin.Security.DataProtection; +#else +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.DataProtection; +using Microsoft.AspNetCore.Http; +#endif + namespace Identity.Test { public static class TestUtil @@ -19,25 +29,76 @@ public static void SetupDatabase(string dataDirectory) where TDbCont public static UserManager CreateManager(DbContext db) { - var manager = - new UserManager(new UserStore(db)); - manager.UserValidator = new UserValidator(manager) + var options = new IdentityFactoryOptions> { - AllowOnlyAlphanumericUserNames = true, - RequireUniqueEmail = false + Provider = new TestProvider(db), +#if NETFRAMEWORK + DataProtectionProvider = new DpapiDataProtectionProvider() +#else + DataProtectionProvider = new EphemeralDataProtectionProvider() +#endif }; - manager.EmailService = new TestMessageService(); - manager.SmsService = new TestMessageService(); - //manager.UserTokenProvider = - // new DataProtectorTokenProvider( - // options.DataProtectionProvider.Create("ASP.NET Identity")); - return manager; + return options.Provider.Create(options, GlobalHelpers.CreateContext()); } public static UserManager CreateManager() { return CreateManager(UnitTestHelper.CreateDefaultDb()); } + +#if NETFRAMEWORK + public static async Task CreateManager(OwinContext context) + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(UnitTestHelper.CreateDefaultDb()), + DataProtectionProvider = new DpapiDataProtectionProvider() + }; + var middleware = + new IdentityFactoryMiddleware + , IdentityFactoryOptions>>(null, options); + await middleware.Invoke(context); + } +#else + public static async Task CreateManager(HttpContext context) + { + var options = new IdentityFactoryOptions> + { + Provider = new TestProvider(UnitTestHelper.CreateDefaultDb()), + DataProtectionProvider = new EphemeralDataProtectionProvider() + }; + var middleware = + new IdentityFactoryMiddleware + , IdentityFactoryOptions>>(options); + await middleware.InvokeAsync(context, null); + } +#endif + } + + public class TestProvider : IdentityFactoryProvider> + { + public TestProvider(DbContext db) + { + OnCreate = ((options, context) => + { + var manager = + new UserManager(new UserStore(db)); + manager.UserValidator = new UserValidator(manager) + { + AllowOnlyAlphanumericUserNames = true, + RequireUniqueEmail = false + }; + manager.EmailService = new TestMessageService(); + manager.SmsService = new TestMessageService(); + if (options.DataProtectionProvider != null) + { + manager.UserTokenProvider = + new DataProtectorTokenProvider( + options.DataProtectionProvider.Create("ASP.NET Identity")); + } + return manager; + }); + } } public class TestMessageService : IIdentityMessageService diff --git a/test/Identity.Test/UserLockoutStoreTests.cs b/test/Identity.Test/UserLockoutStoreTests.cs index e72aa06..2b65cd6 100644 --- a/test/Identity.Test/UserLockoutStoreTests.cs +++ b/test/Identity.Test/UserLockoutStoreTests.cs @@ -226,18 +226,19 @@ public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut() Assert.True(await mgr.IsLockedOutAsync(user.Id)); } - [Fact] - public async Task LockoutEndToNowPlus5ShouldNotBeLockedOut() - { - var mgr = TestUtil.CreateManager(); - mgr.UserLockoutEnabledByDefault = true; - var user = new IdentityUser("LockoutNowTest") { LockoutEndDateUtc = DateTime.Now.AddMinutes(5) }; - UnitTestHelper.IsSuccess(mgr.Create(user)); - Assert.True(mgr.GetLockoutEnabled(user.Id)); - Assert.True(user.LockoutEnabled); - // UTC is 8 hours earlier, so no lockout - Assert.False(await mgr.IsLockedOutAsync(user.Id)); - } + // this test assumes it is run in UTC-8 timezone + //[Fact] + //public async Task LockoutEndToNowPlus5ShouldNotBeLockedOut() + //{ + // var mgr = TestUtil.CreateManager(); + // mgr.UserLockoutEnabledByDefault = true; + // var user = new IdentityUser("LockoutNowTest") { LockoutEndDateUtc = DateTime.Now.AddMinutes(5) }; + // UnitTestHelper.IsSuccess(mgr.Create(user)); + // Assert.True(mgr.GetLockoutEnabled(user.Id)); + // Assert.True(user.LockoutEnabled); + // // UTC is 8 hours earlier, so no lockout + // Assert.False(await mgr.IsLockedOutAsync(user.Id)); + //} [Fact] public async Task UserLockedOutWithDateTimeNowPlus30() diff --git a/test/Identity.Test/xunit.runner.json b/test/Identity.Test/xunit.runner.json new file mode 100644 index 0000000..369786b --- /dev/null +++ b/test/Identity.Test/xunit.runner.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", + "parallelizeTestCollections": false +} \ No newline at end of file From ad8e2a61f38fc0953b3e8b6d4b7cbb1ccb1f445e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Herceg?= Date: Wed, 24 Apr 2024 15:41:01 +0200 Subject: [PATCH 5/6] Removed unnecessary differences in tests --- test/Identity.Test/CustomGuidKeyTest.cs | 9 +- test/Identity.Test/CustomIntKeyTest.cs | 15 +- test/Identity.Test/GlobalHelpers.cs | 11 + test/Identity.Test/LoginsTest.cs | 3 +- .../OwinContextExtensionsTest.cs | 30 + test/Identity.Test/RolesTest.cs | 18 +- test/Identity.Test/TestUtil.cs | 6 +- test/Identity.Test/UserManagerTest.cs | 1744 +++++++++++++++++ 8 files changed, 1800 insertions(+), 36 deletions(-) create mode 100644 test/Identity.Test/OwinContextExtensionsTest.cs diff --git a/test/Identity.Test/CustomGuidKeyTest.cs b/test/Identity.Test/CustomGuidKeyTest.cs index 228bcff..d35d9e1 100644 --- a/test/Identity.Test/CustomGuidKeyTest.cs +++ b/test/Identity.Test/CustomGuidKeyTest.cs @@ -149,13 +149,8 @@ public async Task OnValidateIdentityWithGuidTest() var user = new GuidUser { UserName = "test" }; UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); var id = await SignIn(manager, user); -#if NETFRAMEWORK - var ticket = new AuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); - var context = new CookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); -#else - var ticket = new AuthenticationTicket(new ClaimsPrincipal(id), new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }, id.AuthenticationType); - var context = new CookieValidatePrincipalContext(owinContext, new AuthenticationScheme(id.AuthenticationType, null, typeof(CookieAuthenticationHandler)), new CookieAuthenticationOptions(), ticket); -#endif + var ticket = GlobalHelpers.CreateAuthenticationTicket(id, new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow }); + var context = GlobalHelpers.CreateCookieValidateIdentityContext(owinContext, ticket, new CookieAuthenticationOptions()); await SecurityStampValidator.OnValidateIdentity, GuidUser, Guid>(TimeSpan.Zero, SignIn, claimId => new Guid(claimId.GetUserId())).Invoke(context); diff --git a/test/Identity.Test/CustomIntKeyTest.cs b/test/Identity.Test/CustomIntKeyTest.cs index 6371492..703f5ae 100644 --- a/test/Identity.Test/CustomIntKeyTest.cs +++ b/test/Identity.Test/CustomIntKeyTest.cs @@ -110,27 +110,16 @@ public async Task IntKeyConfirmEmailTest() UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); } -#if NETFRAMEWORK - private UserManager CreateManager() - { - var options = new IdentityFactoryOptions> - { - Provider = new TestProvider(), - DataProtectionProvider = new DpapiDataProtectionProvider() - }; - return options.Provider.Create(options, new OwinContext()); - } -#else + private UserManager CreateManager() { var options = new IdentityFactoryOptions> { Provider = new TestProvider(), - DataProtectionProvider = new EphemeralDataProtectionProvider() + DataProtectionProvider = GlobalHelpers.CreateDataProtectionProvider() }; return options.Provider.Create(options, GlobalHelpers.CreateContext()); } -#endif public class CustomRole : IdentityRole { diff --git a/test/Identity.Test/GlobalHelpers.cs b/test/Identity.Test/GlobalHelpers.cs index 0a7e6dd..06e8e12 100644 --- a/test/Identity.Test/GlobalHelpers.cs +++ b/test/Identity.Test/GlobalHelpers.cs @@ -6,6 +6,7 @@ using Microsoft.Owin; using Microsoft.Owin.Security; using Microsoft.Owin.Security.Cookies; +using Microsoft.Owin.Security.DataProtection; #else using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.AspNetCore; @@ -50,6 +51,11 @@ public static ClaimsIdentity ExtractClaimsIdentity(this CookieValidateIdentityCo { return context.Identity; } + + public static IDataProtectionProvider CreateDataProtectionProvider() + { + return new DpapiDataProtectionProvider(); + } #else public static DefaultHttpContext CreateContext() { @@ -94,6 +100,11 @@ public static IDataProtector Create(this IDataProtectionProvider provider, strin { return provider.CreateProtector(purpose, subPurpose); } + + public static IDataProtectionProvider CreateDataProtectionProvider() + { + return new EphemeralDataProtectionProvider(); + } #endif } } \ No newline at end of file diff --git a/test/Identity.Test/LoginsTest.cs b/test/Identity.Test/LoginsTest.cs index c302618..a2def95 100644 --- a/test/Identity.Test/LoginsTest.cs +++ b/test/Identity.Test/LoginsTest.cs @@ -50,8 +50,7 @@ public async Task AddDuplicateLoginFailsTest() //[Fact] - //public async Task RemoveUnknownLoginFailsTest() - //{ + //public async Task RemoveUnknownLoginFailsTest() { // var store = new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); // UnitTestHelper.IsFailure(await store.Users.RemoveLoginAsync("bogus", "whatever", "ignored")); //} diff --git a/test/Identity.Test/OwinContextExtensionsTest.cs b/test/Identity.Test/OwinContextExtensionsTest.cs new file mode 100644 index 0000000..7ef4c70 --- /dev/null +++ b/test/Identity.Test/OwinContextExtensionsTest.cs @@ -0,0 +1,30 @@ +// Copyright (c) Microsoft Corporation, Inc. All rights reserved. +// Licensed under the MIT License, Version 2.0. See License.txt in the project root for license information. + +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin; +#else +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.Http; +#endif +using Xunit; + +namespace Identity.Test +{ + public class OwinContextExtensionsTest + { + [Fact] + public void MiddlewareExtensionsNullCheckTest() + { +#if NETFRAMEWORK + IOwinContext context = null; +#else + HttpContext context = null; +#endif + ExceptionHelper.ThrowsArgumentNull(() => context.Get(), "context"); + ExceptionHelper.ThrowsArgumentNull(() => context.GetUserManager(), "context"); + ExceptionHelper.ThrowsArgumentNull(() => context.Set(null), "context"); + } + } +} \ No newline at end of file diff --git a/test/Identity.Test/RolesTest.cs b/test/Identity.Test/RolesTest.cs index 536fdd5..9f7a85d 100644 --- a/test/Identity.Test/RolesTest.cs +++ b/test/Identity.Test/RolesTest.cs @@ -631,15 +631,15 @@ public void RemoveUserFromRolesSync() Assert.Equal(0, db.Set().Count()); } - //[Fact] - //public async Task UnknownUserThrowsTest() { - // var manager = new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); - // var r = new IdentityRole("r1"); - // UnitTestHelper.IsSuccess(await manager.Roles.CreateAsync(r)); - // ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.RemoveUserFromRoleAsync("whatever", r.Name))); - // ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.AddUserToRoleAsync("whatever", r.Name))); - // ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.GetRolesForUserAsync("whatever"))); - //} +// [Fact] +// public async Task UnknownUserThrowsTest() { +// var manager = new UserManager(new UserStore(UnitTestHelper.CreateDefaultDb())); +// var r = new IdentityRole("r1"); +// UnitTestHelper.IsSuccess(await manager.Roles.CreateAsync(r)); +// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.RemoveUserFromRoleAsync("whatever", r.Name))); +// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.AddUserToRoleAsync("whatever", r.Name))); +// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => manager.Roles.GetRolesForUserAsync("whatever"))); +// } [Fact] public async Task UnknownRoleThrowsTest() diff --git a/test/Identity.Test/TestUtil.cs b/test/Identity.Test/TestUtil.cs index d97c9b6..548fa32 100644 --- a/test/Identity.Test/TestUtil.cs +++ b/test/Identity.Test/TestUtil.cs @@ -32,11 +32,7 @@ public static UserManager CreateManager(DbContext db) var options = new IdentityFactoryOptions> { Provider = new TestProvider(db), -#if NETFRAMEWORK - DataProtectionProvider = new DpapiDataProtectionProvider() -#else - DataProtectionProvider = new EphemeralDataProtectionProvider() -#endif + DataProtectionProvider = GlobalHelpers.CreateDataProtectionProvider() }; return options.Provider.Create(options, GlobalHelpers.CreateContext()); } diff --git a/test/Identity.Test/UserManagerTest.cs b/test/Identity.Test/UserManagerTest.cs index 5db39e5..0215860 100644 --- a/test/Identity.Test/UserManagerTest.cs +++ b/test/Identity.Test/UserManagerTest.cs @@ -10,6 +10,15 @@ using System.Threading.Tasks; using Microsoft.AspNet.Identity; using Microsoft.AspNet.Identity.EntityFramework; + +#if NETFRAMEWORK +using Microsoft.AspNet.Identity.Owin; +using Microsoft.Owin.Security.DataProtection; +#else +using Microsoft.AspNet.Identity.AspNetCore; +using Microsoft.AspNetCore.DataProtection; +#endif + using Xunit; using Moq; @@ -194,6 +203,97 @@ public void ManagerPublicNullCheckTest() ExceptionHelper.ThrowsArgumentNull(() => manager.RegisterTwoFactorProvider("bogus", null), "provider"); } + [Fact] + public void MethodsFailWithUnknownUserTest() + { + var db = UnitTestHelper.CreateDefaultDb(); + var manager = new UserManager(new UserStore(db)); + manager.UserTokenProvider = new NoOpTokenProvider(); + var error = "UserId not found."; + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.AddClaimAsync(null, new Claim("a", "b"))), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.AddLoginAsync(null, new UserLoginInfo("", ""))), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.AddPasswordAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.AddToRoleAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.AddToRolesAsync(null, "")), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.ChangePasswordAsync(null, null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetClaimsAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetLoginsAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetRolesAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.IsInRoleAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.RemoveClaimAsync(null, new Claim("a", "b"))), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.RemoveLoginAsync(null, new UserLoginInfo("", ""))), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.RemovePasswordAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.RemoveFromRoleAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.RemoveFromRolesAsync(null, "")), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.UpdateSecurityStampAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetSecurityStampAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.HasPasswordAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GeneratePasswordResetTokenAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.ResetPasswordAsync(null, null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.IsEmailConfirmedAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GenerateEmailConfirmationTokenAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.ConfirmEmailAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetEmailAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.SetEmailAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.IsPhoneNumberConfirmedAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.ChangePhoneNumberAsync(null, null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.VerifyChangePhoneNumberTokenAsync(null, null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetPhoneNumberAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.SetPhoneNumberAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetTwoFactorEnabledAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.SetTwoFactorEnabledAsync(null, true)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GenerateTwoFactorTokenAsync(null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.VerifyTwoFactorTokenAsync(null, null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.NotifyTwoFactorTokenAsync(null, null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.GetValidTwoFactorProvidersAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.VerifyUserTokenAsync(null, null, null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.AccessFailedAsync(null)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.SetLockoutEnabledAsync(null, false)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.SetLockoutEndDateAsync(null, DateTimeOffset.UtcNow)), error); + ExceptionHelper.ThrowsWithError( + () => AsyncHelper.RunSync(() => manager.IsLockedOutAsync(null)), error); + } + [Fact] public void MethodsThrowWhenDisposedTest() { @@ -370,6 +470,1650 @@ public async Task PasswordTooShortValidatorTest() "Passwords must be at least 6 characters."); } + [Fact] + public async Task CustomPasswordValidatorTest() + { + var manager = TestUtil.CreateManager(); + manager.PasswordValidator = new AlwaysBadValidator(); + UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser("Hao"), "password"), + AlwaysBadValidator.ErrorMessage); + } + + [Fact] + public async Task PasswordValidatorTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("passwordValidator"); + manager.PasswordValidator = new PasswordValidator { RequiredLength = 6, RequireNonLetterOrDigit = true }; + const string alphaError = "Passwords must have at least one non letter or digit character."; + const string lengthError = "Passwords must be at least 6 characters."; + UnitTestHelper.IsFailure(await manager.CreateAsync(user, "ab@de"), lengthError); + UnitTestHelper.IsFailure(await manager.CreateAsync(user, "abcdef"), alphaError); + UnitTestHelper.IsFailure(await manager.CreateAsync(user, "___"), lengthError); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "abcd@e!ld!kajfd")); + UnitTestHelper.IsFailure(await manager.CreateAsync(user, "abcde"), lengthError + " " + alphaError); + } + + [Fact] + public async Task CustomPasswordValidatorBlocksAddPasswordTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + manager.PasswordValidator = new AlwaysBadValidator(); + UnitTestHelper.IsFailure(await manager.AddPasswordAsync(user.Id, "password"), + AlwaysBadValidator.ErrorMessage); + } + + [Fact] + public async Task CustomUserNameValidatorTest() + { + var manager = TestUtil.CreateManager(); + manager.UserValidator = new AlwaysBadValidator(); + var result = await manager.CreateAsync(new IdentityUser("Hao")); + UnitTestHelper.IsFailure(result, AlwaysBadValidator.ErrorMessage); + } + + [Fact] + public async Task BadValidatorBlocksAllUpdatesTest() + { + var db = UnitTestHelper.CreateDefaultDb(); + var manager = new UserManager(new UserStore(db)); + var user = new IdentityUser("poorguy"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + const string error = AlwaysBadValidator.ErrorMessage; + manager.UserValidator = new AlwaysBadValidator(); + manager.PasswordValidator = new NoopValidator(); + UnitTestHelper.IsFailure(await manager.AddClaimAsync(user.Id, new Claim("a", "b")), error); + UnitTestHelper.IsFailure(await manager.AddLoginAsync(user.Id, new UserLoginInfo("", "")), error); + UnitTestHelper.IsFailure(await manager.AddPasswordAsync(user.Id, "a"), error); + UnitTestHelper.IsFailure(await manager.ChangePasswordAsync(user.Id, "a", "b"), error); + UnitTestHelper.IsFailure(await manager.RemoveClaimAsync(user.Id, new Claim("a", "b")), error); + UnitTestHelper.IsFailure(await manager.RemoveLoginAsync(user.Id, new UserLoginInfo("aa", "bb")), error); + UnitTestHelper.IsFailure(await manager.RemovePasswordAsync(user.Id), error); + UnitTestHelper.IsFailure(await manager.UpdateSecurityStampAsync(user.Id), error); + } + + [Fact] + public async Task CreateLocalUserWithOnlyWhitespaceUserNameFails() + { + var manager = new UserManager(new UserStore()); + var result = await manager.CreateAsync(new IdentityUser { UserName = " " }, "password"); + UnitTestHelper.IsFailure(result, "Name cannot be null or empty."); + } + + [Fact] + public async Task CreateLocalUserWithInvalidUserNameFails() + { + var manager = TestUtil.CreateManager(); + var result = await manager.CreateAsync(new IdentityUser { UserName = "a\0b" }, "password"); + UnitTestHelper.IsFailure(result, "User name a\0b is invalid, can only contain letters or digits."); + } + + [Fact] + public async Task CreateLocalUserWithInvalidPasswordThrows() + { + var manager = TestUtil.CreateManager(); + var result = await manager.CreateAsync(new IdentityUser("Hao"), "aa"); + UnitTestHelper.IsFailure(result, "Passwords must be at least 6 characters."); + } + + [Fact] + public async Task CreateExternalUserWithNullFails() + { + var manager = TestUtil.CreateManager(); + UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser { UserName = null }), + "Name cannot be null or empty."); + } + + [Fact] + public async Task AddPasswordWhenPasswordSetFails() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("HasPassword"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "password")); + UnitTestHelper.IsFailure(await manager.AddPasswordAsync(user.Id, "User already has a password.")); + } + + private async Task LazyLoadTestSetup(DbContext db, IdentityUser user) + { + var manager = new UserManager(new UserStore(db)); + var role = new RoleManager(new RoleStore(db)); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, new UserLoginInfo("provider", "key"))); + UnitTestHelper.IsSuccess(await role.CreateAsync(new IdentityRole("Admin"))); + UnitTestHelper.IsSuccess(await role.CreateAsync(new IdentityRole("Local"))); + UnitTestHelper.IsSuccess(await manager.AddToRoleAsync(user.Id, "Admin")); + UnitTestHelper.IsSuccess(await manager.AddToRoleAsync(user.Id, "Local")); + Claim[] userClaims = + { + new Claim("Whatever", "Value"), + new Claim("Whatever2", "Value2") + }; + foreach (var c in userClaims) + { + UnitTestHelper.IsSuccess(await manager.AddClaimAsync(user.Id, c)); + } + } + + [Fact] + public async Task LazyLoadDisabledFindByIdTest() + { + var db = UnitTestHelper.CreateDefaultDb(); + var user = new IdentityUser("Hao"); + user.Email = "hao@foo.com"; + await LazyLoadTestSetup(db, user); + + // Ensure lazy loading is not broken + db = new IdentityDbContext(); + db.Configuration.LazyLoadingEnabled = false; + db.Configuration.ProxyCreationEnabled = false; + var manager = new UserManager(new UserStore(db)); + var userById = await manager.FindByIdAsync(user.Id); + Assert.True(userById.Claims.Count == 2); + Assert.True(userById.Logins.Count == 1); + Assert.True(userById.Roles.Count == 2); + } + + [Fact] + public async Task LazyLoadDisabledFindByNameTest() + { + var db = UnitTestHelper.CreateDefaultDb(); + var user = new IdentityUser("Hao") { Email = "hao@foo.com" }; + await LazyLoadTestSetup(db, user); + + // Ensure lazy loading is not broken + db = new IdentityDbContext(); + db.Configuration.LazyLoadingEnabled = false; + db.Configuration.ProxyCreationEnabled = false; + var manager = new UserManager(new UserStore(db)); + var userByName = await manager.FindByNameAsync(user.UserName); + Assert.True(userByName.Claims.Count == 2); + Assert.True(userByName.Logins.Count == 1); + Assert.True(userByName.Roles.Count == 2); + } + + [Fact] + public async Task LazyLoadDisabledFindByLoginTest() + { + var db = UnitTestHelper.CreateDefaultDb(); + var user = new IdentityUser("Hao") { Email = "hao@foo.com" }; + await LazyLoadTestSetup(db, user); + + // Ensure lazy loading is not broken + db = new IdentityDbContext(); + db.Configuration.LazyLoadingEnabled = false; + db.Configuration.ProxyCreationEnabled = false; + var manager = new UserManager(new UserStore(db)); + var userByLogin = await manager.FindAsync(new UserLoginInfo("provider", "key")); + Assert.True(userByLogin.Claims.Count == 2); + Assert.True(userByLogin.Logins.Count == 1); + Assert.True(userByLogin.Roles.Count == 2); + } + + [Fact] + public async Task LazyLoadDisabledFindByEmailTest() + { + var db = UnitTestHelper.CreateDefaultDb(); + var user = new IdentityUser("Hao") { Email = "hao@foo.com" }; + await LazyLoadTestSetup(db, user); + + // Ensure lazy loading is not broken + db = new IdentityDbContext(); + db.Configuration.LazyLoadingEnabled = false; + db.Configuration.ProxyCreationEnabled = false; + var manager = new UserManager(new UserStore(db)); + var userByEmail = await manager.FindByEmailAsync(user.Email); + Assert.True(userByEmail.Claims.Count == 2); + Assert.True(userByEmail.Logins.Count == 1); + Assert.True(userByEmail.Roles.Count == 2); + } + + [Fact] + public async Task FindNullIdTest() + { + var manager = TestUtil.CreateManager(); + Assert.Null(await manager.FindByIdAsync(null)); + } + + [Fact] + public async Task CreateLocalUserTest() + { + var manager = TestUtil.CreateManager(); + const string password = "password"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("CreateLocalUserTest"), password)); + var user = await manager.FindByNameAsync("CreateLocalUserTest"); + Assert.NotNull(user); + Assert.NotNull(user.PasswordHash); + Assert.True(await manager.HasPasswordAsync(user.Id)); + var logins = await manager.GetLoginsAsync(user.Id); + Assert.NotNull(logins); + Assert.Equal(0, logins.Count()); + } + + [Fact] + public void CreateLocalUserTestSync() + { + var manager = TestUtil.CreateManager(); + const string password = "password"; + UnitTestHelper.IsSuccess(manager.Create(new IdentityUser("CreateLocalUserTest"), password)); + var user = manager.FindByName("CreateLocalUserTest"); + Assert.NotNull(user); + Assert.NotNull(user.PasswordHash); + Assert.True(manager.HasPassword(user.Id)); + var logins = manager.GetLogins(user.Id); + Assert.NotNull(logins); + Assert.Equal(0, logins.Count()); + } + + [Fact] + public async Task DeleteUserTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("Delete"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + UnitTestHelper.IsSuccess(await manager.DeleteAsync(user)); + Assert.Null(await manager.FindByIdAsync(user.Id)); + } + + [Fact] + public void DeleteUserSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("Delete"); + UnitTestHelper.IsSuccess(manager.Create(user)); + UnitTestHelper.IsSuccess(manager.Delete(user)); + Assert.Null(manager.FindById(user.Id)); + } + + [Fact] + public async Task CreateUserAddLoginTest() + { + var manager = TestUtil.CreateManager(); + const string userName = "CreateExternalUserTest"; + const string provider = "ZzAuth"; + const string providerKey = "HaoKey"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser(userName))); + var user = await manager.FindByNameAsync(userName); + var login = new UserLoginInfo(provider, providerKey); + UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); + var logins = await manager.GetLoginsAsync(user.Id); + Assert.NotNull(logins); + Assert.Equal(1, logins.Count()); + Assert.Equal(provider, logins.First().LoginProvider); + Assert.Equal(providerKey, logins.First().ProviderKey); + } + + [Fact] + public void CreateUserAddLoginSyncTest() + { + var manager = TestUtil.CreateManager(); + const string userName = "CreateExternalUserTest"; + const string provider = "ZzAuth"; + const string providerKey = "HaoKey"; + UnitTestHelper.IsSuccess(manager.Create(new IdentityUser(userName))); + var user = manager.FindByName(userName); + var login = new UserLoginInfo(provider, providerKey); + UnitTestHelper.IsSuccess(manager.AddLogin(user.Id, login)); + var logins = manager.GetLogins(user.Id); + Assert.NotNull(logins); + Assert.Equal(1, logins.Count()); + Assert.Equal(provider, logins.First().LoginProvider); + Assert.Equal(providerKey, logins.First().ProviderKey); + } + + [Fact] + public async Task CreateUserLoginAndAddPasswordTest() + { + var manager = TestUtil.CreateManager(); + var login = new UserLoginInfo("Provider", "key"); + var user = new IdentityUser("CreateUserLoginAddPasswordTest"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); + UnitTestHelper.IsSuccess(await manager.AddPasswordAsync(user.Id, "password")); + var logins = await manager.GetLoginsAsync(user.Id); + Assert.NotNull(logins); + Assert.Equal(1, logins.Count()); + Assert.Equal(user, await manager.FindAsync(login)); + Assert.Equal(user, await manager.FindAsync(user.UserName, "password")); + Assert.True(await manager.CheckPasswordAsync(user, "password")); + } + + [Fact] + public void CreateUserLoginAndAddPasswordSyncTest() + { + var manager = TestUtil.CreateManager(); + var login = new UserLoginInfo("Provider", "key"); + var user = new IdentityUser("CreateUserLoginAddPasswordTest"); + UnitTestHelper.IsSuccess(manager.Create(user)); + UnitTestHelper.IsSuccess(manager.AddLogin(user.Id, login)); + UnitTestHelper.IsSuccess(manager.AddPassword(user.Id, "password")); + var logins = manager.GetLogins(user.Id); + Assert.NotNull(logins); + Assert.Equal(1, logins.Count()); + Assert.Equal(user, manager.Find(login)); + Assert.Equal(user, manager.Find(user.UserName, "password")); + Assert.True(manager.CheckPassword(user, "password")); + } + + [Fact] + public async Task CreateUserAddRemoveLoginTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("CreateUserAddRemoveLoginTest"); + var login = new UserLoginInfo("Provider", "key"); + const string password = "password"; + var result = await manager.CreateAsync(user, password); + Assert.NotNull(user); + UnitTestHelper.IsSuccess(result); + UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); + Assert.Equal(user, await manager.FindAsync(login)); + var logins = await manager.GetLoginsAsync(user.Id); + Assert.NotNull(logins); + Assert.Equal(1, logins.Count()); + Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); + Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); + var stamp = await manager.GetSecurityStampAsync(user.Id); + UnitTestHelper.IsSuccess(await manager.RemoveLoginAsync(user.Id, login)); + Assert.Null(await manager.FindAsync(login)); + logins = await manager.GetLoginsAsync(user.Id); + Assert.NotNull(logins); + Assert.Equal(0, logins.Count()); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public void CreateUserAddRemoveLoginSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("CreateUserAddRemoveLoginTest"); + var login = new UserLoginInfo("Provider", "key"); + const string password = "password"; + var result = manager.Create(user, password); + Assert.NotNull(user); + UnitTestHelper.IsSuccess(result); + UnitTestHelper.IsSuccess(manager.AddLogin(user.Id, login)); + Assert.Equal(user, manager.Find(login)); + var logins = manager.GetLogins(user.Id); + Assert.NotNull(logins); + Assert.Equal(1, logins.Count()); + Assert.Equal(login.LoginProvider, logins.Last().LoginProvider); + Assert.Equal(login.ProviderKey, logins.Last().ProviderKey); + var stamp = manager.GetSecurityStamp(user.Id); + UnitTestHelper.IsSuccess(manager.RemoveLogin(user.Id, login)); + Assert.Null(manager.Find(login)); + logins = manager.GetLogins(user.Id); + Assert.NotNull(logins); + Assert.Equal(0, logins.Count()); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task RemovePasswordTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("RemovePasswordTest"); + const string password = "password"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = await manager.GetSecurityStampAsync(user.Id); + UnitTestHelper.IsSuccess(await manager.RemovePasswordAsync(user.Id)); + var u = await manager.FindByNameAsync(user.UserName); + Assert.NotNull(u); + Assert.Null(u.PasswordHash); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public void RemovePasswordSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("RemovePasswordTest"); + const string password = "password"; + UnitTestHelper.IsSuccess(manager.Create(user, password)); + var stamp = manager.GetSecurityStamp(user.Id); + UnitTestHelper.IsSuccess(manager.RemovePassword(user.Id)); + var u = manager.FindByName(user.UserName); + Assert.NotNull(u); + Assert.Null(u.PasswordHash); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ChangePasswordTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ChangePasswordTest"); + const string password = "password"; + const string newPassword = "newpassword"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + UnitTestHelper.IsSuccess(await manager.ChangePasswordAsync(user.Id, password, newPassword)); + Assert.Null(await manager.FindAsync(user.UserName, password)); + Assert.Equal(user, await manager.FindAsync(user.UserName, newPassword)); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public void ChangePasswordSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ChangePasswordTest"); + const string password = "password"; + const string newPassword = "newpassword"; + UnitTestHelper.IsSuccess(manager.Create(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + UnitTestHelper.IsSuccess(manager.ChangePassword(user.Id, password, newPassword)); + Assert.Null(manager.Find(user.UserName, password)); + Assert.Equal(user, manager.Find(user.UserName, newPassword)); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ResetPasswordTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ResetPasswordTest"); + const string password = "password"; + const string newPassword = "newpassword"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GeneratePasswordResetTokenAsync(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.ResetPasswordAsync(user.Id, token, newPassword)); + Assert.Null(await manager.FindAsync(user.UserName, password)); + Assert.Equal(user, await manager.FindAsync(user.UserName, newPassword)); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ResetPasswordWithNoStampTest() + { + var manager = new NoStampUserManager(); + var user = new IdentityUser("ResetPasswordTest"); + const string password = "password"; + const string newPassword = "newpassword"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var token = await manager.GeneratePasswordResetTokenAsync(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.ResetPasswordAsync(user.Id, token, newPassword)); + Assert.Null(await manager.FindAsync(user.UserName, password)); + Assert.Equal(user, await manager.FindAsync(user.UserName, newPassword)); + } + + [Fact] + public async Task GenerateUserTokenTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("UserTokenTest"); + var user2 = new IdentityUser("UserTokenTest2"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user2)); + var token = await manager.GenerateUserTokenAsync("test", user.Id); + Assert.True(await manager.VerifyUserTokenAsync(user.Id, "test", token)); + Assert.False(await manager.VerifyUserTokenAsync(user.Id, "test2", token)); + Assert.False(await manager.VerifyUserTokenAsync(user.Id, "test", token + "a")); + Assert.False(await manager.VerifyUserTokenAsync(user2.Id, "test", token)); + } + + [Fact] + public void GenerateUserTokenSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("UserTokenTest"); + var user2 = new IdentityUser("UserTokenTest2"); + UnitTestHelper.IsSuccess(manager.Create(user)); + UnitTestHelper.IsSuccess(manager.Create(user2)); + var token = manager.GenerateUserToken("test", user.Id); + Assert.True(manager.VerifyUserToken(user.Id, "test", token)); + Assert.False(manager.VerifyUserToken(user.Id, "test2", token)); + Assert.False(manager.VerifyUserToken(user.Id, "test", token + "a")); + Assert.False(manager.VerifyUserToken(user2.Id, "test", token)); + } + + [Fact] + public async Task GetTwoFactorEnabledTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("TwoFactorEnabledTest"); + UnitTestHelper.IsSuccess(manager.Create(user)); + Assert.False(await manager.GetTwoFactorEnabledAsync(user.Id)); + UnitTestHelper.IsSuccess(await manager.SetTwoFactorEnabledAsync(user.Id, true)); + Assert.True(await manager.GetTwoFactorEnabledAsync(user.Id)); + UnitTestHelper.IsSuccess(await manager.SetTwoFactorEnabledAsync(user.Id, false)); + Assert.False(await manager.GetTwoFactorEnabledAsync(user.Id)); + } + + [Fact] + public void GetTwoFactorEnabledSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("TwoFactorEnabledTest"); + UnitTestHelper.IsSuccess(manager.Create(user)); + Assert.False(manager.GetTwoFactorEnabled(user.Id)); + UnitTestHelper.IsSuccess(manager.SetTwoFactorEnabled(user.Id, true)); + Assert.True(manager.GetTwoFactorEnabled(user.Id)); + UnitTestHelper.IsSuccess(manager.SetTwoFactorEnabled(user.Id, false)); + Assert.False(manager.GetTwoFactorEnabled(user.Id)); + } + + [Fact] + public async Task ResetPasswordWithConfirmTokenFailsTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ResetPasswordTest"); + var password = "password"; + var newPassword = "newpassword"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, token, newPassword)); + Assert.Null(await manager.FindAsync(user.UserName, newPassword)); + Assert.Equal(user, await manager.FindAsync(user.UserName, password)); + Assert.Equal(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ResetPasswordWithExpiredTokenFailsTest() + { + var manager = TestUtil.CreateManager(); + var provider = GlobalHelpers.CreateDataProtectionProvider(); + //manager.PasswordResetTokens = new DataProtectorTokenProvider(provider.Create("ResetPassword")) { TokenLifespan = TimeSpan.FromTicks(0) }; + manager.UserTokenProvider = new DataProtectorTokenProvider(provider.Create("ResetPassword")) + { + TokenLifespan = TimeSpan.FromTicks(0) + }; + var user = new IdentityUser("ResetPasswordTest"); + var password = "password"; + var newPassword = "newpassword"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GeneratePasswordResetTokenAsync(user.Id); + Assert.NotNull(token); + Thread.Sleep(10); + UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, token, newPassword)); + Assert.Null(await manager.FindAsync(user.UserName, newPassword)); + Assert.Equal(user, await manager.FindAsync(user.UserName, password)); + Assert.Equal(stamp, user.SecurityStamp); + } + + [Fact] + public void ResetPasswordSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ResetPasswordTest"); + var password = "password"; + var newPassword = "newpassword"; + UnitTestHelper.IsSuccess(manager.Create(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = manager.GeneratePasswordResetToken(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(manager.ResetPassword(user.Id, token, newPassword)); + Assert.Null(manager.Find(user.UserName, password)); + Assert.Equal(user, manager.Find(user.UserName, newPassword)); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ResetPasswordFailsWithWrongTokenTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ResetPasswordTest"); + var password = "password"; + var newPassword = "newpassword"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, "bogus", newPassword), "Invalid token."); + Assert.Null(await manager.FindAsync(user.UserName, newPassword)); + Assert.Equal(user, await manager.FindAsync(user.UserName, password)); + Assert.Equal(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ResetPasswordFailsAfterPasswordChangeTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ResetPasswordTest"); + var password = "password"; + var newPassword = "newpassword"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = manager.GeneratePasswordResetToken(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.ChangePasswordAsync(user.Id, password, "bogus1")); + UnitTestHelper.IsFailure(await manager.ResetPasswordAsync(user.Id, token, newPassword), "Invalid token."); + Assert.Null(await manager.FindAsync(user.UserName, newPassword)); + Assert.Equal(user, await manager.FindAsync(user.UserName, "bogus1")); + } + + [Fact] + public async Task AddRemoveUserClaimTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ClaimsAddRemove"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; + foreach (Claim c in claims) + { + UnitTestHelper.IsSuccess(await manager.AddClaimAsync(user.Id, c)); + } + var userClaims = await manager.GetClaimsAsync(user.Id); + Assert.Equal(3, userClaims.Count); + UnitTestHelper.IsSuccess(await manager.RemoveClaimAsync(user.Id, claims[0])); + userClaims = await manager.GetClaimsAsync(user.Id); + Assert.Equal(2, userClaims.Count); + UnitTestHelper.IsSuccess(await manager.RemoveClaimAsync(user.Id, claims[1])); + userClaims = await manager.GetClaimsAsync(user.Id); + Assert.Equal(1, userClaims.Count); + UnitTestHelper.IsSuccess(await manager.RemoveClaimAsync(user.Id, claims[2])); + userClaims = await manager.GetClaimsAsync(user.Id); + Assert.Equal(0, userClaims.Count); + } + + [Fact] + public void AddRemoveUserClaimSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("ClaimsAddRemove"); + UnitTestHelper.IsSuccess(manager.Create(user)); + Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") }; + foreach (Claim c in claims) + { + UnitTestHelper.IsSuccess(manager.AddClaim(user.Id, c)); + } + var userClaims = manager.GetClaims(user.Id); + Assert.Equal(3, userClaims.Count); + UnitTestHelper.IsSuccess(manager.RemoveClaim(user.Id, claims[0])); + userClaims = manager.GetClaims(user.Id); + Assert.Equal(2, userClaims.Count); + UnitTestHelper.IsSuccess(manager.RemoveClaim(user.Id, claims[1])); + userClaims = manager.GetClaims(user.Id); + Assert.Equal(1, userClaims.Count); + UnitTestHelper.IsSuccess(manager.RemoveClaim(user.Id, claims[2])); + userClaims = manager.GetClaims(user.Id); + Assert.Equal(0, userClaims.Count); + } + + [Fact] + public async Task ChangePasswordFallsIfPasswordTooShortTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("user"); + var password = "password"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var result = await manager.ChangePasswordAsync(user.Id, password, "n"); + UnitTestHelper.IsFailure(result, "Passwords must be at least 6 characters."); + } + + [Fact] + public async Task ChangePasswordFallsIfPasswordWrongTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("user"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "password")); + var result = await manager.ChangePasswordAsync(user.Id, "bogus", "newpassword"); + UnitTestHelper.IsFailure(result, "Incorrect password."); + } + + [Fact] + public void ChangePasswordFallsIfPasswordWrongSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("user"); + UnitTestHelper.IsSuccess(manager.Create(user, "password")); + var result = manager.ChangePassword(user.Id, "bogus", "newpassword"); + UnitTestHelper.IsFailure(result, "Incorrect password."); + } + + [Fact] + public async Task CanRelaxUserNameAndPasswordValidationTest() + { + var manager = TestUtil.CreateManager(); + manager.UserValidator = new UserValidator(manager) { AllowOnlyAlphanumericUserNames = false }; + manager.PasswordValidator = new MinimumLengthValidator(1); + UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("Some spaces"), "pwd")); + } + + [Fact] + public async Task CanUseEmailAsUserNameTest() + { + var manager = TestUtil.CreateManager(); + UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("test_email@foo.com"))); + } + + [Fact] + public async Task AddDupeUserFailsTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("dupe"); + var user2 = new IdentityUser("dupe"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + UnitTestHelper.IsFailure(await manager.CreateAsync(user2), "Name dupe is already taken."); + } + + [Fact] + public async Task FindWithPasswordUnknownUserReturnsNullTest() + { + var manager = TestUtil.CreateManager(); + Assert.Null(await manager.FindAsync("bogus", "sdlkfsadf")); + Assert.Null(manager.Find("bogus", "sdlkfsadf")); + } + + [Fact] + public async Task UpdateSecurityStampTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("stampMe"); + Assert.Null(user.SecurityStamp); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public void UpdateSecurityStampSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("stampMe"); + Assert.Null(user.SecurityStamp); + UnitTestHelper.IsSuccess(manager.Create(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + UnitTestHelper.IsSuccess(manager.UpdateSecurityStamp(user.Id)); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + //[Fact] + //public async Task AddPasswordToUnknownUserFailsTest() { + // UnitTestHelper.IsFailure(await CreateManager().Users.UpdatePasswordAsync("bogus", "password"), "User bogus does not exist."); + //} + + //[Fact] + //public async Task CreateLocalUserNameTooLongThrowsTest() { + // var manager = CreateManager(); + // var userNameTooLong = new IdentityUser("baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + // var result = await manager.CreateAsync(userNameTooLong, "password"); + // Assert.False(result.Succeeded); + // Assert.True(result.Errors.First().Contains("maximum length")); // Should say something about max length in the error msg + //} + + ////[Fact] + ////public async Task CreateExternalUserNameTooLongThrowsTest() { + //// IdentityStoreContext noop = CreateManagerSync(); + //// string userNameTooLong = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + //// ExceptionHelper.ExpectException(() => AsyncHelper.RunSync(() => context.CreateWithLoginAsync(new IdentityUser(userNameTooLong), "whatever", "blah"))); + ////} + + [Fact] + public async Task AddDupeLoginFailsTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("DupeLogin"); + var login = new UserLoginInfo("provder", "key"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); + var result = await manager.AddLoginAsync(user.Id, login); + UnitTestHelper.IsFailure(result, "A user with that external login already exists."); + } + + [Fact] + public async Task AddLoginDoesNotChangeStampTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("stampTest"); + var login = new UserLoginInfo("provder", "key"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = await manager.GetSecurityStampAsync(user.Id); + UnitTestHelper.IsSuccess(await manager.AddLoginAsync(user.Id, login)); + Assert.Equal(stamp, await manager.GetSecurityStampAsync(user.Id)); + } + + [Fact] + public async Task MixManagerAndEfTest() + { + var db = UnitTestHelper.CreateDefaultDb(); + var manager = new UserManager(new UserStore(db)); + var user = new IdentityUser("MixEFManagerTest"); + var password = "password"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + user.SecurityStamp = "bogus"; + UnitTestHelper.IsSuccess(await manager.UpdateAsync(user)); + Assert.Equal("bogus", db.Users.Find(user.Id).SecurityStamp); + //var login = new UserLoginInfo("login", "key"); + //user.Logins.Add(new IdentityUserLogin() { User = user, LoginProvider = login.LoginProvider, ProviderKey = login.ProviderKey }); + //UnitTestHelper.IsSuccess(manager.Update(user)); + //Assert.Equal(login.LoginProvider, db.Users.Find(user.Id).Logins.First().LoginProvider); + //Assert.Equal(login.ProviderKey, db.Users.Find(user.Id).Logins.First().ProviderKey); + } + + [Fact] + public async Task CreateUserBasicStoreTest() + { + var manager = new UserManager(new NoopUserStore()); + UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("test"))); + } + + [Fact] + public async Task GetAllUsersTest() + { + var mgr = TestUtil.CreateManager(); + var users = new[] + { + new IdentityUser("user1"), + new IdentityUser("user2"), + new IdentityUser("user3") + }; + foreach (IdentityUser u in users) + { + UnitTestHelper.IsSuccess(await mgr.CreateAsync(u)); + } + IQueryable usersQ = mgr.Users; + Assert.Equal(3, usersQ.Count()); + Assert.NotNull(usersQ.Where(u => u.UserName == "user1").FirstOrDefault()); + Assert.NotNull(usersQ.Where(u => u.UserName == "user2").FirstOrDefault()); + Assert.NotNull(usersQ.Where(u => u.UserName == "user3").FirstOrDefault()); + Assert.Null(usersQ.Where(u => u.UserName == "bogus").FirstOrDefault()); + } + + [Fact] + public async Task ConfirmEmailFalseByDefaultTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); + } + + [Fact] + public async Task ConfirmEmailTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("test"); + Assert.False(user.EmailConfirmed); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.ConfirmEmailAsync(user.Id, token)); + Assert.True(await manager.IsEmailConfirmedAsync(user.Id)); + UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, null)); + Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); + } + + [Fact] + public void ConfirmEmailSyncTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("test"); + Assert.False(user.EmailConfirmed); + UnitTestHelper.IsSuccess(manager.Create(user)); + var token = manager.GenerateEmailConfirmationToken(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(manager.ConfirmEmail(user.Id, token)); + Assert.True(manager.IsEmailConfirmed(user.Id)); + UnitTestHelper.IsSuccess(manager.SetEmail(user.Id, null)); + Assert.False(manager.IsEmailConfirmed(user.Id)); + } + + [Fact] + public async Task ConfirmTokenFailsAfterPasswordChangeTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("test"); + Assert.False(user.EmailConfirmed); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, "password")); + var token = await manager.GenerateEmailConfirmationTokenAsync(user.Id); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.ChangePasswordAsync(user.Id, "password", "newpassword")); + UnitTestHelper.IsFailure(await manager.ConfirmEmailAsync(user.Id, token), "Invalid token."); + Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); + } + + [Fact] + public async Task FindByEmailTest() + { + var manager = TestUtil.CreateManager(); + const string userName = "EmailTest"; + const string email = "email@test.com"; + var user = new IdentityUser(userName) { Email = email }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var fetch = await manager.FindByEmailAsync(email); + Assert.Equal(user, fetch); + } + + [Fact] + public void FindByEmailSyncTest() + { + var manager = TestUtil.CreateManager(); + var userName = "EmailTest"; + var email = "email@test.com"; + var user = new IdentityUser(userName) { Email = email }; + UnitTestHelper.IsSuccess(manager.Create(user)); + var fetch = manager.FindByEmail(email); + Assert.Equal(user, fetch); + } + + [Fact] + public async Task SetEmailTest() + { + var manager = TestUtil.CreateManager(); + var userName = "EmailTest"; + var email = "email@test.com"; + var user = new IdentityUser(userName); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + Assert.Null(await manager.FindByEmailAsync(email)); + var stamp = await manager.GetSecurityStampAsync(user.Id); + UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, email)); + var fetch = await manager.FindByEmailAsync(email); + Assert.Equal(user, fetch); + Assert.Equal(email, await manager.GetEmailAsync(user.Id)); + Assert.False(await manager.IsEmailConfirmedAsync(user.Id)); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task CreateDupeEmailFailsTest() + { + var manager = TestUtil.CreateManager(); + manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; + var userName = "EmailTest"; + var email = "email@test.com"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser(userName) { Email = email })); + var user = new IdentityUser("two") { Email = email }; + UnitTestHelper.IsFailure(await manager.CreateAsync(user), "Email 'email@test.com' is already taken."); + } + + [Fact] + public async Task SetEmailToDupeFailsTest() + { + var manager = TestUtil.CreateManager(); + manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; + var email = "email@test.com"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(new IdentityUser("emailtest") { Email = email })); + var user = new IdentityUser("two") { Email = "something@else.com" }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + UnitTestHelper.IsFailure(await manager.SetEmailAsync(user.Id, email), + "Email 'email@test.com' is already taken."); + } + + [Fact] + public async Task RequireUniqueEmailBlocksBasicCreateTest() + { + var manager = TestUtil.CreateManager(); + manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; + UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser("emailtest"), "Email is too short.")); + } + + [Fact] + public async Task RequireUniqueEmailBlocksInvalidEmailTest() + { + var manager = TestUtil.CreateManager(); + manager.UserValidator = new UserValidator(manager) { RequireUniqueEmail = true }; + UnitTestHelper.IsFailure(await manager.CreateAsync(new IdentityUser("emailtest") { Email = "hi" }), + "Email 'hi' is invalid."); + } + + [Fact] + public async Task SetPhoneNumberTest() + { + var manager = TestUtil.CreateManager(); + var userName = "PhoneTest"; + var user = new IdentityUser(userName); + user.PhoneNumber = "123-456-7890"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = await manager.GetSecurityStampAsync(user.Id); + Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "123-456-7890"); + UnitTestHelper.IsSuccess(await manager.SetPhoneNumberAsync(user.Id, "111-111-1111")); + Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "111-111-1111"); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public void SetPhoneNumberSyncTest() + { + var manager = TestUtil.CreateManager(); + var userName = "PhoneTest"; + var user = new IdentityUser(userName); + user.PhoneNumber = "123-456-7890"; + UnitTestHelper.IsSuccess(manager.Create(user)); + var stamp = manager.GetSecurityStamp(user.Id); + Assert.Equal(manager.GetPhoneNumber(user.Id), "123-456-7890"); + UnitTestHelper.IsSuccess(manager.SetPhoneNumber(user.Id, "111-111-1111")); + Assert.Equal(manager.GetPhoneNumber(user.Id), "111-111-1111"); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ChangePhoneNumberTest() + { + var manager = TestUtil.CreateManager(); + var userName = "PhoneTest"; + var user = new IdentityUser(userName); + user.PhoneNumber = "123-456-7890"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + Assert.False(await manager.IsPhoneNumberConfirmedAsync(user.Id)); + var stamp = await manager.GetSecurityStampAsync(user.Id); + var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user.Id, "111-111-1111"); + UnitTestHelper.IsSuccess(await manager.ChangePhoneNumberAsync(user.Id, "111-111-1111", token1)); + Assert.True(await manager.IsPhoneNumberConfirmedAsync(user.Id)); + Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "111-111-1111"); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public void ChangePhoneNumberSyncTest() + { + var manager = TestUtil.CreateManager(); + var userName = "PhoneTest"; + var user = new IdentityUser(userName); + user.PhoneNumber = "123-456-7890"; + UnitTestHelper.IsSuccess(manager.Create(user)); + var stamp = manager.GetSecurityStamp(user.Id); + Assert.False(manager.IsPhoneNumberConfirmed(user.Id)); + var token1 = manager.GenerateChangePhoneNumberToken(user.Id, "111-111-1111"); + UnitTestHelper.IsSuccess(manager.ChangePhoneNumber(user.Id, "111-111-1111", token1)); + Assert.True(manager.IsPhoneNumberConfirmed(user.Id)); + Assert.Equal(manager.GetPhoneNumber(user.Id), "111-111-1111"); + Assert.NotEqual(stamp, user.SecurityStamp); + } + + [Fact] + public async Task ChangePhoneNumberFailsWithWrongTokenTest() + { + var manager = TestUtil.CreateManager(); + var userName = "PhoneTest"; + var user = new IdentityUser(userName); + user.PhoneNumber = "123-456-7890"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + Assert.False(await manager.IsPhoneNumberConfirmedAsync(user.Id)); + var stamp = await manager.GetSecurityStampAsync(user.Id); + UnitTestHelper.IsFailure(await manager.ChangePhoneNumberAsync(user.Id, "111-111-1111", "bogus"), + "Invalid token."); + Assert.False(await manager.IsPhoneNumberConfirmedAsync(user.Id)); + Assert.Equal(await manager.GetPhoneNumberAsync(user.Id), "123-456-7890"); + Assert.Equal(stamp, user.SecurityStamp); + } + + [Fact] + public async Task VerifyPhoneNumberTest() + { + var manager = TestUtil.CreateManager(); + var userName = "VerifyPhoneTest"; + var user = new IdentityUser(userName); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var num1 = "111-123-4567"; + var num2 = "111-111-1111"; + var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user.Id, num1); + var token2 = await manager.GenerateChangePhoneNumberTokenAsync(user.Id, num2); + Assert.NotEqual(token1, token2); + Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token1, num1)); + Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token2, num2)); + Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token2, num1)); + Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user.Id, token1, num2)); + } + + [Fact] + public void VerifyPhoneNumberSyncTest() + { + var manager = TestUtil.CreateManager(); + const string userName = "VerifyPhoneTest"; + var user = new IdentityUser(userName); + UnitTestHelper.IsSuccess(manager.Create(user)); + const string num1 = "111-123-4567"; + const string num2 = "111-111-1111"; + Assert.False(manager.IsPhoneNumberConfirmed(user.Id)); + var token1 = manager.GenerateChangePhoneNumberToken(user.Id, num1); + var token2 = manager.GenerateChangePhoneNumberToken(user.Id, num2); + Assert.NotEqual(token1, token2); + Assert.True(manager.VerifyChangePhoneNumberToken(user.Id, token1, num1)); + Assert.True(manager.VerifyChangePhoneNumberToken(user.Id, token2, num2)); + Assert.False(manager.VerifyChangePhoneNumberToken(user.Id, token2, num1)); + Assert.False(manager.VerifyChangePhoneNumberToken(user.Id, token1, num2)); + } + + [Fact] + public async Task EmailTokenFactorTest() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.EmailService = messageService; + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); + var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; + const string password = "password"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal(String.Empty, messageService.Message.Subject); + Assert.Equal(token, messageService.Message.Body); + Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + } + + [Fact] + public async Task EmailTokenFactorWithFormatTest() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.EmailService = messageService; + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider + { + Subject = "Security Code", + BodyFormat = "Your code is: {0}" + }); + var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; + const string password = "password"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal("Security Code", messageService.Message.Subject); + Assert.Equal("Your code is: " + token, messageService.Message.Body); + Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + } + + [Fact] + public void EmailTokenFactorWithFormatSyncTest() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.EmailService = messageService; + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider + { + Subject = "Security Code", + BodyFormat = "Your code is: {0}" + }); + var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; + const string password = "password"; + UnitTestHelper.IsSuccess(manager.Create(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = manager.GenerateTwoFactorToken(user.Id, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + UnitTestHelper.IsSuccess(manager.NotifyTwoFactorToken(user.Id, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal("Security Code", messageService.Message.Subject); + Assert.Equal("Your code is: " + token, messageService.Message.Body); + Assert.True(manager.VerifyTwoFactorToken(user.Id, factorId, token)); + } + + [Fact] + public async Task EmailFactorFailsAfterSecurityStampChangeTest() + { + var manager = TestUtil.CreateManager(); + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); + var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + } + + [Fact] + public void EmailTokenFactorSyncTest() + { + var manager = TestUtil.CreateManager(); + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); + var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; + const string password = "password"; + UnitTestHelper.IsSuccess(manager.Create(user, password)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = manager.GenerateTwoFactorToken(user.Id, factorId); + Assert.NotNull(token); + Assert.True(manager.VerifyTwoFactorToken(user.Id, factorId, token)); + } + + [Fact] + public void EmailFactorFailsAfterSecurityStampChangeSyncTest() + { + var manager = TestUtil.CreateManager(); + const string factorId = "EmailCode"; + manager.RegisterTwoFactorProvider(factorId, new EmailTokenProvider()); + var user = new IdentityUser("EmailCodeTest") { Email = "foo@foo.com" }; + UnitTestHelper.IsSuccess(manager.Create(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = manager.GenerateTwoFactorToken(user.Id, factorId); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(manager.UpdateSecurityStamp(user.Id)); + Assert.False(manager.VerifyTwoFactorToken(user.Id, factorId, token)); + } + + [Fact] + public async Task UserTwoFactorProviderTest() + { + var manager = TestUtil.CreateManager(); + const string factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); + var user = new IdentityUser("PhoneCodeTest"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + UnitTestHelper.IsSuccess(await manager.SetTwoFactorEnabledAsync(user.Id, true)); + Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user.Id)); + Assert.True(await manager.GetTwoFactorEnabledAsync(user.Id)); + } + + [Fact] + public async Task SendSms() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.SmsService = messageService; + var user = new IdentityUser("SmsTest") { PhoneNumber = "4251234567" }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + await manager.SendSmsAsync(user.Id, "Hi"); + Assert.NotNull(messageService.Message); + Assert.Equal("Hi", messageService.Message.Body); + } + + [Fact] + public async Task SendEmail() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.EmailService = messageService; + var user = new IdentityUser("EmailTest") { Email = "foo@foo.com" }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + await manager.SendEmailAsync(user.Id, "Hi", "Body"); + Assert.NotNull(messageService.Message); + Assert.Equal("Hi", messageService.Message.Subject); + Assert.Equal("Body", messageService.Message.Body); + } + + [Fact] + public void SendSmsSync() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.SmsService = messageService; + var user = new IdentityUser("SmsTest") { PhoneNumber = "4251234567" }; + UnitTestHelper.IsSuccess(manager.Create(user)); + manager.SendSms(user.Id, "Hi"); + Assert.NotNull(messageService.Message); + Assert.Equal("Hi", messageService.Message.Body); + } + + [Fact] + public void SendEmailSync() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.EmailService = messageService; + var user = new IdentityUser("EmailTest") { Email = "foo@foo.com" }; + UnitTestHelper.IsSuccess(manager.Create(user)); + manager.SendEmail(user.Id, "Hi", "Body"); + Assert.NotNull(messageService.Message); + Assert.Equal("Hi", messageService.Message.Subject); + Assert.Equal("Body", messageService.Message.Body); + } + + + [Fact] + public async Task PhoneTokenFactorTest() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.SmsService = messageService; + const string factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); + var user = new IdentityUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal(token, messageService.Message.Body); + Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + } + + [Fact] + public void PhoneTokenFactorSyncTest() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.SmsService = messageService; + const string factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); + var user = new IdentityUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; + UnitTestHelper.IsSuccess(manager.Create(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = manager.GenerateTwoFactorToken(user.Id, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + UnitTestHelper.IsSuccess(manager.NotifyTwoFactorToken(user.Id, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal(token, messageService.Message.Body); + Assert.True(manager.VerifyTwoFactorToken(user.Id, factorId, token)); + } + + [Fact] + public async Task PhoneTokenFactorFormatTest() + { + var manager = TestUtil.CreateManager(); + var messageService = new TestMessageService(); + manager.SmsService = messageService; + const string factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider + { + MessageFormat = "Your code is: {0}" + }); + var user = new IdentityUser("PhoneCodeTest") { PhoneNumber = "4251234567" }; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + Assert.Null(messageService.Message); + UnitTestHelper.IsSuccess(await manager.NotifyTwoFactorTokenAsync(user.Id, factorId, token)); + Assert.NotNull(messageService.Message); + Assert.Equal("Your code is: " + token, messageService.Message.Body); + Assert.True(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + } + + [Fact] + public async Task NoFactorProviderTest() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("PhoneCodeTest"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + const string error = "No IUserTwoFactorProvider for 'bogus' is registered."; + ExceptionHelper.ThrowsWithError( + () => manager.GenerateTwoFactorToken(user.Id, "bogus"), error); + ExceptionHelper.ThrowsWithError( + () => manager.VerifyTwoFactorToken(user.Id, "bogus", "bogus"), error); + } + + [Fact] + public async Task GetValidTwoFactorTestEmptyWithNoProviders() + { + var manager = TestUtil.CreateManager(); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); + Assert.NotNull(factors); + Assert.True(!factors.Any()); + } + + [Fact] + public async Task GetValidTwoFactorTest() + { + var manager = TestUtil.CreateManager(); + manager.RegisterTwoFactorProvider("phone", new PhoneNumberTokenProvider()); + manager.RegisterTwoFactorProvider("email", new EmailTokenProvider()); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); + Assert.NotNull(factors); + UnitTestHelper.IsSuccess(await manager.SetPhoneNumberAsync(user.Id, "111-111-1111")); + factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); + Assert.False(factors.Any()); + // Need to confirm + user.PhoneNumberConfirmed = true; + UnitTestHelper.IsSuccess(manager.Update(user)); + factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); + Assert.True(factors.Count() == 1); + Assert.Equal("phone", factors[0]); + Assert.NotNull(factors); + Assert.True(factors.Count() == 1); + Assert.Equal("phone", factors[0]); + UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, "test@test.com")); + factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); + Assert.NotNull(factors); + Assert.True(factors.Count() == 1); + // Need to confirm + user.EmailConfirmed = true; + UnitTestHelper.IsSuccess(await manager.UpdateAsync(user)); + factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); + Assert.NotNull(factors); + Assert.True(factors.Count() == 2); + UnitTestHelper.IsSuccess(await manager.SetEmailAsync(user.Id, "somethingelse")); + factors = await manager.GetValidTwoFactorProvidersAsync(user.Id); + Assert.NotNull(factors); + Assert.True(factors.Count() == 1); + Assert.Equal("phone", factors[0]); + } + + [Fact] + public void GetValidTwoFactorSyncTest() + { + var manager = TestUtil.CreateManager(); + manager.RegisterTwoFactorProvider("phone", new PhoneNumberTokenProvider()); + manager.RegisterTwoFactorProvider("email", new EmailTokenProvider()); + var user = new IdentityUser("test"); + UnitTestHelper.IsSuccess(manager.Create(user)); + var factors = manager.GetValidTwoFactorProviders(user.Id); + Assert.NotNull(factors); + Assert.False(factors.Any()); + UnitTestHelper.IsSuccess(manager.SetPhoneNumber(user.Id, "111-111-1111")); + factors = manager.GetValidTwoFactorProviders(user.Id); + Assert.NotNull(factors); + Assert.False(factors.Any()); + // Need to confirm + user.PhoneNumberConfirmed = true; + UnitTestHelper.IsSuccess(manager.Update(user)); + factors = manager.GetValidTwoFactorProviders(user.Id); + Assert.True(factors.Count() == 1); + Assert.Equal("phone", factors[0]); + UnitTestHelper.IsSuccess(manager.SetEmail(user.Id, "test@test.com")); + factors = manager.GetValidTwoFactorProviders(user.Id); + Assert.NotNull(factors); + Assert.True(factors.Count() == 1); + // Need to confirm + user.EmailConfirmed = true; + UnitTestHelper.IsSuccess(manager.Update(user)); + factors = manager.GetValidTwoFactorProviders(user.Id); + Assert.NotNull(factors); + Assert.True(factors.Count() == 2); + UnitTestHelper.IsSuccess(manager.SetEmail(user.Id, null)); + factors = manager.GetValidTwoFactorProviders(user.Id); + Assert.NotNull(factors); + Assert.True(factors.Count() == 1); + Assert.Equal("phone", factors[0]); + } + + [Fact] + public async Task PhoneFactorFailsAfterSecurityStampChangeTest() + { + var manager = TestUtil.CreateManager(); + var factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); + var user = new IdentityUser("PhoneCodeTest"); + user.PhoneNumber = "4251234567"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + UnitTestHelper.IsSuccess(await manager.UpdateSecurityStampAsync(user.Id)); + Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, token)); + } + + [Fact] + public async Task WrongTokenProviderFailsTest() + { + var manager = TestUtil.CreateManager(); + var factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); + manager.RegisterTwoFactorProvider("EmailCode", new EmailTokenProvider()); + var user = new IdentityUser("PhoneCodeTest"); + user.PhoneNumber = "4251234567"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, "EmailCode", token)); + } + + [Fact] + public async Task WrongTokenFailsTest() + { + var manager = TestUtil.CreateManager(); + var factorId = "PhoneCode"; + manager.RegisterTwoFactorProvider(factorId, new PhoneNumberTokenProvider()); + var user = new IdentityUser("PhoneCodeTest"); + user.PhoneNumber = "4251234567"; + UnitTestHelper.IsSuccess(await manager.CreateAsync(user)); + var stamp = user.SecurityStamp; + Assert.NotNull(stamp); + var token = await manager.GenerateTwoFactorTokenAsync(user.Id, factorId); + Assert.NotNull(token); + Assert.False(await manager.VerifyTwoFactorTokenAsync(user.Id, factorId, "abc")); + } + + [Fact] + public async Task ResetTokenCallNoopForTokenValueZero() + { + var user = new IdentityUser() { UserName = "foo" }; + var store = new Mock>(); + store.Setup(x => x.ResetAccessFailedCountAsync(user)).Returns(() => + { + throw new Exception(); + }); + store.Setup(x => x.FindByIdAsync(It.IsAny())) + .Returns(() => Task.FromResult(user)); + store.Setup(x => x.GetAccessFailedCountAsync(It.IsAny())) + .Returns(() => Task.FromResult(0)); + var manager = new UserManager(store.Object); + UnitTestHelper.IsSuccess(await manager.ResetAccessFailedCountAsync(user.Id)); + } + + [Fact] + public void Create_preserves_culture() + { + var originalCulture = Thread.CurrentThread.CurrentCulture; + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + var expectedCulture = new CultureInfo("de-DE"); + Thread.CurrentThread.CurrentCulture = expectedCulture; + Thread.CurrentThread.CurrentUICulture = expectedCulture; + var manager = TestUtil.CreateManager(); + + try + { + var cultures = GetCurrentCultureAfter(() => manager.CreateAsync(new IdentityUser("whatever"))).Result; + Assert.Equal(expectedCulture, cultures.Item1); + Assert.Equal(expectedCulture, cultures.Item2); + } + finally + { + Thread.CurrentThread.CurrentCulture = originalCulture; + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } + + [Fact] + public void CreateSync_preserves_culture() + { + var originalCulture = Thread.CurrentThread.CurrentCulture; + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + var expectedCulture = new CultureInfo("de-DE"); + Thread.CurrentThread.CurrentCulture = expectedCulture; + Thread.CurrentThread.CurrentUICulture = expectedCulture; + var manager = TestUtil.CreateManager(); + + try + { + var cultures = GetCurrentCultureAfter(() => manager.Create(new IdentityUser("whatever"))); + Assert.Equal(expectedCulture, cultures.Item1); + Assert.Equal(expectedCulture, cultures.Item2); + } + finally + { + Thread.CurrentThread.CurrentCulture = originalCulture; + Thread.CurrentThread.CurrentUICulture = originalUICulture; + } + } + + private static async Task> GetCurrentCultureAfter(Func action) + { + await action(); + return new Tuple(Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture); + } + + private static Tuple GetCurrentCultureAfter(Action action) + { + action(); + return new Tuple(Thread.CurrentThread.CurrentCulture, Thread.CurrentThread.CurrentUICulture); + } + + private class NoOpTokenProvider : IUserTokenProvider + { + public Task GenerateAsync(string purpose, UserManager manager, + IdentityUser user) + { + throw new NotImplementedException(); + } + + public Task ValidateAsync(string purpose, string token, UserManager manager, + IdentityUser user) + { + throw new NotImplementedException(); + } + + public Task NotifyAsync(string token, UserManager manager, IdentityUser user) + { + throw new NotImplementedException(); + } + + public Task IsValidProviderForUserAsync(UserManager manager, IdentityUser user) + { + throw new NotImplementedException(); + } + } + + private class NoStampUserManager : UserManager + { + public NoStampUserManager() + : base(new UserStore(UnitTestHelper.CreateDefaultDb())) + { + UserValidator = new UserValidator(this) + { + AllowOnlyAlphanumericUserNames = true, + RequireUniqueEmail = false + }; + var dpp = GlobalHelpers.CreateDataProtectionProvider(); + UserTokenProvider = new DataProtectorTokenProvider(dpp.Create("ASP.NET Identity")); + } + + public override bool SupportsUserSecurityStamp + { + get { return false; } + } + } + private class NoopUserStore : IUserStore { public Task CreateAsync(IdentityUser user) From 5e1b31fb6f9308b42fc8056a2a4390191e300e3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Ja=C5=A1ka?= Date: Tue, 15 Oct 2024 08:12:46 +0200 Subject: [PATCH 6/6] EntityFramework updated to 6.5.1 --- .../Microsoft.AspNet.Identity.EntityFramework.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj b/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj index 900c224..f8659da 100644 --- a/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj +++ b/src/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework.csproj @@ -32,6 +32,6 @@ - + \ No newline at end of file