Merge pull request #23 from d-barker/master
Updated library to netcoreapp3.1 and netstandard2.1 (all unit tests passing)
This commit is contained in:
@@ -1,27 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
<PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wp8+wpa81;</PackageTargetFallback>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<UserSecretsId>aspnet-MongoIdentitySample.Mvc-95B15D82-54F6-4001-B4B0-6ADF4B1BB00E</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCore.Identity.MongoDbCore" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.6.1" />
|
||||
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.13.0-beta1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Cookies" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.0" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -31,4 +29,14 @@
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\AspNetCore.Identity.MongoDbCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -53,10 +53,10 @@ namespace MongoIdentitySample.Mvc
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env) //, ILoggerFactory loggerFactory)
|
||||
{
|
||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
loggerFactory.AddDebug();
|
||||
//loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
//loggerFactory.AddDebug();
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
@@ -68,17 +68,23 @@ namespace MongoIdentitySample.Mvc
|
||||
app.UseExceptionHandler("/Home/Error");
|
||||
}
|
||||
|
||||
app.UseRouting();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseIdentity();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
// Add external authentication middleware below. To configure them please see https://go.microsoft.com/fwlink/?LinkID=532715
|
||||
|
||||
app.UseMvc(routes =>
|
||||
//app.UseMvc(routes =>
|
||||
//{
|
||||
// routes.MapRoute(
|
||||
// name: "default",
|
||||
// template: "{controller=Home}/{action=Index}/{id?}");
|
||||
//});
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netcoreapp2.0;netstandard2.0</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp3.1;netstandard2.1</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DocumentationFile>bin\Release\netstandard2.0\AspNetCore.Identity.MongoDbCore.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\Release\netstandard2.1\AspNetCore.Identity.MongoDbCore.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>bin\Debug\netstandard2.0\AspNetCore.Identity.MongoDbCore.xml</DocumentationFile>
|
||||
<DocumentationFile>bin\Debug\netstandard2.1\AspNetCore.Identity.MongoDbCore.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.2.0" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.7.0" />
|
||||
<PackageReference Include="MongoDbGenericRepository" Version="1.4.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="3.1.1" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.10.1" />
|
||||
<PackageReference Include="MongoDbGenericRepository" Version="1.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -211,10 +211,13 @@ namespace AspNetCore.Identity.MongoDbCore
|
||||
var updateRes = await collection.ReplaceOneAsync(x => x.Id.Equals(user.Id)
|
||||
&& x.ConcurrencyStamp.Equals(oldStamp),
|
||||
user);
|
||||
|
||||
|
||||
if (updateRes.ModifiedCount == 0)
|
||||
{
|
||||
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
|
||||
}
|
||||
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
|
||||
+21
-15
@@ -1,30 +1,36 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspNetCore.Identity.MongoDbCore" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.7.0" />
|
||||
<PackageReference Include="MongoDbGenericRepository" Version="1.4.0" />
|
||||
<PackageReference Include="Moq" Version="4.8.1" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.1.1" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.10.1" />
|
||||
<PackageReference Include="MongoDbGenericRepository" Version="1.4.1" />
|
||||
<PackageReference Include="Moq" Version="4.13.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\AspNetCore.Identity.MongoDbCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
+1
-1
@@ -300,7 +300,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
|
||||
private class MySignInManager : SignInManager<TestUser>
|
||||
{
|
||||
public MySignInManager(UserManager<TestUser> manager, IHttpContextAccessor context, IUserClaimsPrincipalFactory<TestUser> claimsFactory) : base(manager, context, claimsFactory, null, null, null) { }
|
||||
public MySignInManager(UserManager<TestUser> manager, IHttpContextAccessor context, IUserClaimsPrincipalFactory<TestUser> claimsFactory) : base(manager, context, claimsFactory, null, null, null, null) { }
|
||||
}
|
||||
|
||||
private class MyUserManager : UserManager<TestUser>
|
||||
|
||||
+212
-96
@@ -2,6 +2,7 @@
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
@@ -9,9 +10,11 @@ using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
using AspNetCore.Identity.MongoDbCore.IntegrationTests;
|
||||
|
||||
namespace Microsoft.AspNetCore.Identity.Test
|
||||
{
|
||||
@@ -71,150 +74,263 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
[InlineData(false)]
|
||||
public async Task OnValidatePrincipalTestSuccess(bool isPersistent)
|
||||
{
|
||||
var user = new TestUser("test");
|
||||
var userManager = MockHelpers.MockUserManager<TestUser>();
|
||||
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
|
||||
var identityOptions = new Mock<IOptions<IdentityOptions>>();
|
||||
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var user = new TestUser { UserName = "test" };
|
||||
|
||||
var manager = SetupUserManager(user);
|
||||
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
var roleManager = MockHelpers.MockRoleManager<TestRole>();
|
||||
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
|
||||
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
|
||||
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
|
||||
|
||||
var loggerFactory = new MockLoggerFactory();
|
||||
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
|
||||
|
||||
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1), IsPersistent = isPersistent };
|
||||
|
||||
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
var principal = new ClaimsPrincipal(id);
|
||||
|
||||
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1), IsPersistent = isPersistent };
|
||||
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
|
||||
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
|
||||
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
|
||||
signInManager.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
|
||||
helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
|
||||
helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
|
||||
|
||||
var logFactory = new MockLoggerFactory();
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton<ILoggerFactory>(loggerFactory);
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
services.AddSingleton(helper.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
|
||||
|
||||
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
var ticket = new AuthenticationTicket(principal,
|
||||
properties,
|
||||
IdentityConstants.ApplicationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
Assert.NotNull(cookieContext.Properties);
|
||||
Assert.NotNull(cookieContext.Options);
|
||||
Assert.NotNull(cookieContext.Principal);
|
||||
await
|
||||
SecurityStampValidator.ValidatePrincipalAsync(context);
|
||||
Assert.NotNull(context.Principal);
|
||||
signInManager.VerifyAll();
|
||||
SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
|
||||
Assert.NotNull(cookieContext.Principal);
|
||||
helper.VerifyAll();
|
||||
}
|
||||
|
||||
private static Mock<UserManager<TestUser>> SetupUserManager(TestUser user)
|
||||
{
|
||||
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||
manager.Setup(m => m.FindByNameAsync(user.UserName)).ReturnsAsync(user);
|
||||
manager.Setup(m => m.FindByIdAsync(user.Id)).ReturnsAsync(user);
|
||||
manager.Setup(m => m.GetUserIdAsync(user)).ReturnsAsync(user.Id.ToString());
|
||||
manager.Setup(m => m.GetUserNameAsync(user)).ReturnsAsync(user.UserName);
|
||||
return manager;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnValidateIdentityRejectsWhenValidateSecurityStampFails()
|
||||
{
|
||||
var user = new TestUser("test");
|
||||
var userManager = MockHelpers.MockUserManager<TestUser>();
|
||||
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
|
||||
var identityOptions = new Mock<IOptions<IdentityOptions>>();
|
||||
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var user = new TestUser { UserName = "test" };
|
||||
|
||||
var manager = SetupUserManager(user);
|
||||
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
|
||||
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
|
||||
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
|
||||
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
var roleManager = MockHelpers.MockRoleManager<TestRole>();
|
||||
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
|
||||
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
|
||||
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
|
||||
var logStore = new StringBuilder();
|
||||
var loggerFactory = new MockLoggerFactory();
|
||||
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
|
||||
|
||||
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) };
|
||||
|
||||
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
var principal = new ClaimsPrincipal(id);
|
||||
//because the request fails the create user principal is never called and therefore not verifiable
|
||||
//helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
|
||||
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
|
||||
helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
|
||||
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(helper.Object);
|
||||
services.AddSingleton<ILoggerFactory>(loggerFactory);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
|
||||
|
||||
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
|
||||
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) },
|
||||
IdentityConstants.ApplicationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
await SecurityStampValidator.ValidatePrincipalAsync(context);
|
||||
Assert.Null(context.Principal);
|
||||
signInManager.VerifyAll();
|
||||
|
||||
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
|
||||
Assert.NotNull(cookieContext.Properties);
|
||||
Assert.NotNull(cookieContext.Options);
|
||||
Assert.NotNull(cookieContext.Principal);
|
||||
|
||||
await SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
|
||||
|
||||
Assert.Null(cookieContext.Principal);
|
||||
|
||||
helper.VerifyAll();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnValidateIdentityRejectsWhenNoIssuedUtc()
|
||||
{
|
||||
var user = new TestUser("test");
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var userManager = MockHelpers.MockUserManager<TestUser>();
|
||||
var identityOptions = new Mock<IOptions<IdentityOptions>>();
|
||||
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
|
||||
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
|
||||
var user = new TestUser { UserName = "test" };
|
||||
|
||||
var manager = SetupUserManager(user);
|
||||
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
|
||||
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
|
||||
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
|
||||
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
var roleManager = MockHelpers.MockRoleManager<TestRole>();
|
||||
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
|
||||
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
|
||||
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
|
||||
var logStore = new StringBuilder();
|
||||
var loggerFactory = new MockLoggerFactory();
|
||||
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
|
||||
|
||||
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) };
|
||||
|
||||
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
var principal = new ClaimsPrincipal(id);
|
||||
//because the request fails the create user principal is never called and therefore not verifiable
|
||||
//helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
|
||||
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
|
||||
helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
|
||||
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(helper.Object);
|
||||
services.AddSingleton<ILoggerFactory>(loggerFactory);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
|
||||
|
||||
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
// testing the ticket UTC setting, in this case lack of setting
|
||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
|
||||
new AuthenticationProperties(),
|
||||
IdentityConstants.ApplicationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
await SecurityStampValidator.ValidatePrincipalAsync(context);
|
||||
Assert.Null(context.Principal);
|
||||
signInManager.VerifyAll();
|
||||
|
||||
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
|
||||
Assert.NotNull(cookieContext.Properties);
|
||||
Assert.NotNull(cookieContext.Options);
|
||||
Assert.NotNull(cookieContext.Principal);
|
||||
|
||||
await SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
|
||||
|
||||
Assert.Null(cookieContext.Principal);
|
||||
|
||||
helper.VerifyAll();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OnValidateIdentityDoesNotRejectsWhenNotExpired()
|
||||
{
|
||||
var user = new TestUser("test");
|
||||
var httpContext = new Mock<HttpContext>();
|
||||
var userManager = MockHelpers.MockUserManager<TestUser>();
|
||||
var identityOptions = new Mock<IOptions<IdentityOptions>>();
|
||||
identityOptions.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
var claimsManager = new Mock<IUserClaimsPrincipalFactory<TestUser>>();
|
||||
var options = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.FromDays(1) });
|
||||
var user = new TestUser { UserName = "test" };
|
||||
|
||||
var manager = SetupUserManager(user);
|
||||
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(true).Verifiable();
|
||||
|
||||
var context = new Mock<HttpContext>();
|
||||
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(httpContext.Object);
|
||||
var signInManager = new Mock<SignInManager<TestUser>>(userManager.Object,
|
||||
contextAccessor.Object, claimsManager.Object, identityOptions.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
|
||||
signInManager.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).Throws(new Exception("Shouldn't be called"));
|
||||
signInManager.Setup(s => s.SignInAsync(user, false, null)).Throws(new Exception("Shouldn't be called"));
|
||||
var services = new ServiceCollection();
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(signInManager.Object);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(options.Object, signInManager.Object, new SystemClock()));
|
||||
httpContext.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
var roleManager = MockHelpers.MockRoleManager<TestRole>();
|
||||
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(new IdentityOptions());
|
||||
|
||||
var securityStampOptions = new Mock<IOptions<SecurityStampValidatorOptions>>();
|
||||
securityStampOptions.Setup(a => a.Value).Returns(new SecurityStampValidatorOptions { ValidationInterval = TimeSpan.Zero });
|
||||
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
|
||||
var logStore = new StringBuilder();
|
||||
var loggerFactory = new MockLoggerFactory();
|
||||
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
|
||||
|
||||
var helper = new Mock<SignInManager<TestUser>>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
var properties = new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow.AddSeconds(-1) };
|
||||
|
||||
var id = new ClaimsIdentity(IdentityConstants.ApplicationScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
var principal = new ClaimsPrincipal(id);
|
||||
//because the request fails the create user principal is never called and therefore not verifiable
|
||||
//helper.Setup(s => s.CreateUserPrincipalAsync(user)).ReturnsAsync(principal).Verifiable();
|
||||
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(user).Verifiable();
|
||||
//helper.Setup(s => s.ValidateSecurityStampAsync(It.IsAny<ClaimsPrincipal>())).ReturnsAsync(default(TestUser)).Verifiable();
|
||||
helper.Setup(s => s.SignInAsync(user, false, null)).Throws(new Exception("Shouldn't be called"));
|
||||
|
||||
var services = new ServiceCollection();
|
||||
|
||||
services.AddSingleton(options.Object);
|
||||
services.AddSingleton(helper.Object);
|
||||
services.AddSingleton<ILoggerFactory>(loggerFactory);
|
||||
services.AddSingleton<ISecurityStampValidator>(new SecurityStampValidator<TestUser>(securityStampOptions.Object, helper.Object, new SystemClock(), loggerFactory));
|
||||
|
||||
context.Setup(c => c.RequestServices).Returns(services.BuildServiceProvider());
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
|
||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(id),
|
||||
new AuthenticationProperties { IssuedUtc = DateTimeOffset.UtcNow },
|
||||
IdentityConstants.ApplicationScheme);
|
||||
var context = new CookieValidatePrincipalContext(httpContext.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
Assert.NotNull(context.Properties);
|
||||
Assert.NotNull(context.Options);
|
||||
Assert.NotNull(context.Principal);
|
||||
await SecurityStampValidator.ValidatePrincipalAsync(context);
|
||||
Assert.NotNull(context.Principal);
|
||||
|
||||
var cookieContext = new CookieValidatePrincipalContext(context.Object, new AuthenticationSchemeBuilder(IdentityConstants.ApplicationScheme) { HandlerType = typeof(NoopHandler) }.Build(), new CookieAuthenticationOptions(), ticket);
|
||||
Assert.NotNull(cookieContext.Properties);
|
||||
Assert.NotNull(cookieContext.Options);
|
||||
Assert.NotNull(cookieContext.Principal);
|
||||
await SecurityStampValidator.ValidatePrincipalAsync(cookieContext);
|
||||
Assert.NotNull(cookieContext.Principal);
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
-53
@@ -7,6 +7,7 @@ using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AspNetCore.Identity.MongoDbCore.IntegrationTests;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@@ -68,13 +69,13 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
[Fact]
|
||||
public void ConstructorNullChecks()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<TestUser>(null, null, null, null, null, null));
|
||||
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<TestUser>(null, null, null, null, null, null, null));
|
||||
var userManager = MockHelpers.MockUserManager<TestUser>().Object;
|
||||
Assert.Throws<ArgumentNullException>("contextAccessor", () => new SignInManager<TestUser>(userManager, null, null, null, null, null));
|
||||
Assert.Throws<ArgumentNullException>("contextAccessor", () => new SignInManager<TestUser>(userManager, null, null, null, null, null, null));
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
var context = new Mock<HttpContext>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context.Object);
|
||||
Assert.Throws<ArgumentNullException>("claimsFactory", () => new SignInManager<TestUser>(userManager, contextAccessor.Object, null, null, null, null));
|
||||
Assert.Throws<ArgumentNullException>("claimsFactory", () => new SignInManager<TestUser>(userManager, contextAccessor.Object, null, null, null, null, null));
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
@@ -122,9 +123,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(identityOptions);
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
|
||||
var logStore = new StringBuilder();
|
||||
var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger.Object, new Mock<IAuthenticationSchemeProvider>().Object);
|
||||
var loggerFactory = new MockLoggerFactory();
|
||||
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
|
||||
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
||||
@@ -132,7 +133,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
// Assert
|
||||
Assert.False(result.Succeeded);
|
||||
Assert.True(result.IsLockedOut);
|
||||
Assert.Contains($"User {user.Id} is currently locked out.", logStore.ToString());
|
||||
Assert.Contains($"User {user.Id} is currently locked out.", loggerFactory.LogStore.ToString());
|
||||
manager.Verify();
|
||||
}
|
||||
|
||||
@@ -153,9 +154,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(identityOptions);
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager.Object, roleManager.Object, options.Object);
|
||||
var logStore = new StringBuilder();
|
||||
var logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger.Object, new Mock<IAuthenticationSchemeProvider>().Object);
|
||||
var loggerFactory = new MockLoggerFactory();
|
||||
var logger = loggerFactory.CreateLogger<SignInManager<TestUser>>();
|
||||
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object, claimsFactory, options.Object, logger, new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
|
||||
// Act
|
||||
var result = await helper.CheckPasswordSignInAsync(user, "bogus", false);
|
||||
@@ -163,7 +164,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
// Assert
|
||||
Assert.False(result.Succeeded);
|
||||
Assert.True(result.IsLockedOut);
|
||||
Assert.Contains($"User {user.Id} is currently locked out.", logStore.ToString());
|
||||
Assert.Contains($"User {user.Id} is currently locked out.", loggerFactory.LogStore.ToString());
|
||||
manager.Verify();
|
||||
}
|
||||
|
||||
@@ -177,7 +178,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
return manager;
|
||||
}
|
||||
|
||||
private static SignInManager<TestUser> SetupSignInManager(UserManager<TestUser> manager, HttpContext context, StringBuilder logStore = null, IdentityOptions identityOptions = null)
|
||||
private static SignInManager<TestUser> SetupSignInManager(UserManager<TestUser> manager, HttpContext context, MockLoggerFactory factory, IdentityOptions identityOptions = null)
|
||||
{
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context);
|
||||
@@ -186,8 +187,20 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(identityOptions);
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager, roleManager.Object, options.Object);
|
||||
var sm = new SignInManager<TestUser>(manager, contextAccessor.Object, claimsFactory, options.Object, null, new Mock<IAuthenticationSchemeProvider>().Object);
|
||||
sm.Logger = MockHelpers.MockILogger<SignInManager<TestUser>>(logStore ?? new StringBuilder()).Object;
|
||||
var sm = new SignInManager<TestUser>(manager, contextAccessor.Object, claimsFactory, options.Object,factory.CreateLogger<SignInManager<TestUser>>(), new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
return sm;
|
||||
}
|
||||
|
||||
private static Mock<SignInManager<TestUser>> MockSignInManager(UserManager<TestUser> manager, HttpContext context, MockLoggerFactory factory, IdentityOptions identityOptions = null)
|
||||
{
|
||||
var contextAccessor = new Mock<IHttpContextAccessor>();
|
||||
contextAccessor.Setup(a => a.HttpContext).Returns(context);
|
||||
var roleManager = MockHelpers.MockRoleManager<TestRole>();
|
||||
identityOptions = identityOptions ?? new IdentityOptions();
|
||||
var options = new Mock<IOptions<IdentityOptions>>();
|
||||
options.Setup(a => a.Value).Returns(identityOptions);
|
||||
var claimsFactory = new UserClaimsPrincipalFactory<TestUser, TestRole>(manager, roleManager.Object, options.Object);
|
||||
var sm = new Mock<SignInManager<TestUser>>(manager, contextAccessor.Object, claimsFactory, options.Object, factory.CreateLogger<SignInManager<TestUser>>(), new Mock<IAuthenticationSchemeProvider>().Object, new Mock<IUserConfirmation<TestUser>>().Object);
|
||||
return sm;
|
||||
}
|
||||
|
||||
@@ -206,7 +219,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
SetupSignIn(context, auth, user.Id, isPersistent);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
|
||||
@@ -230,8 +245,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
SetupSignIn(context, auth, user.Id, false);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
|
||||
|
||||
@@ -256,8 +271,8 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
SetupSignIn(context, auth);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
|
||||
|
||||
@@ -288,7 +303,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password")).ReturnsAsync(true).Verifiable();
|
||||
manager.Setup(m => m.GetValidTwoFactorProvidersAsync(user)).ReturnsAsync(new string[1] { "Fake" }).Verifiable();
|
||||
var context = new DefaultHttpContext();
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
|
||||
var auth = MockAuth(context);
|
||||
auth.Setup(a => a.SignInAsync(context, IdentityConstants.TwoFactorUserIdScheme,
|
||||
It.Is<ClaimsPrincipal>(id => id.FindFirstValue(ClaimTypes.Name) == user.Id),
|
||||
@@ -326,7 +344,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
}
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
|
||||
if (bypass)
|
||||
{
|
||||
@@ -473,7 +493,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
|
||||
SetupSignIn(context, auth, user.Id, isPersistent, loginProvider);
|
||||
|
||||
// Act
|
||||
@@ -493,6 +516,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
var context = new DefaultHttpContext();
|
||||
var services = new ServiceCollection();
|
||||
var auth = MockAuth(context);
|
||||
var loginProvider = "loginprovider";
|
||||
var id = new ClaimsIdentity();
|
||||
@@ -503,25 +527,26 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
// REVIEW: auth changes we lost the ability to mock is persistent
|
||||
//var properties = new AuthenticationProperties { IsPersistent = isPersistent };
|
||||
var authResult = AuthenticateResult.NoResult();
|
||||
auth.Setup(a => a.AuthenticateAsync(context, IdentityConstants.ApplicationScheme))
|
||||
.Returns(Task.FromResult(authResult)).Verifiable();
|
||||
|
||||
auth.Setup(a => a.AuthenticateAsync(context, IdentityConstants.ApplicationScheme)).Returns(Task.FromResult(authResult)).Verifiable();
|
||||
|
||||
var manager = SetupUserManager(user);
|
||||
var signInManager = new Mock<SignInManager<TestUser>>(manager.Object,
|
||||
new HttpContextAccessor { HttpContext = context },
|
||||
new Mock<IUserClaimsPrincipalFactory<TestUser>>().Object,
|
||||
null, null, new Mock<IAuthenticationSchemeProvider>().Object)
|
||||
{ CallBase = true };
|
||||
//signInManager.Setup(s => s.SignInAsync(user, It.Is<AuthenticationProperties>(p => p.IsPersistent == isPersistent),
|
||||
//externalLogin? loginProvider : null)).Returns(Task.FromResult(0)).Verifiable();
|
||||
signInManager.Setup(s => s.SignInAsync(user, It.IsAny<AuthenticationProperties>(), null)).Returns(Task.FromResult(0)).Verifiable();
|
||||
signInManager.Object.Context = context;
|
||||
|
||||
// Act
|
||||
await signInManager.Object.RefreshSignInAsync(user);
|
||||
using (MockLoggerFactory loggerFactory = new MockLoggerFactory())
|
||||
{
|
||||
var signInManager = MockSignInManager(manager.Object, context, loggerFactory, null);
|
||||
|
||||
// Assert
|
||||
auth.Verify();
|
||||
signInManager.Verify();
|
||||
signInManager.CallBase = true; // need this magic!
|
||||
|
||||
signInManager.Setup(s => s.SignInWithClaimsAsync(user, It.IsAny<AuthenticationProperties>(), It.IsAny<List<Claim>>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
|
||||
// Act
|
||||
await signInManager.Object.RefreshSignInAsync(user);
|
||||
|
||||
// Assert
|
||||
auth.Verify();
|
||||
signInManager.Verify();
|
||||
}
|
||||
}
|
||||
|
||||
//[Theory]
|
||||
@@ -606,7 +631,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var manager = SetupUserManager(user);
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
|
||||
auth.Setup(a => a.SignInAsync(
|
||||
context,
|
||||
IdentityConstants.TwoFactorRememberMeScheme,
|
||||
@@ -644,9 +672,12 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
SetupSignIn(context, auth);
|
||||
var id = new ClaimsIdentity(IdentityConstants.TwoFactorRememberMeScheme);
|
||||
id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
|
||||
auth.Setup(a => a.AuthenticateAsync(context, IdentityConstants.TwoFactorRememberMeScheme))
|
||||
|
||||
auth.Setup(a => a.AuthenticateAsync(It.IsAny<HttpContext>(), IdentityConstants.TwoFactorRememberMeScheme))
|
||||
.ReturnsAsync(AuthenticateResult.Success(new AuthenticationTicket(new ClaimsPrincipal(id), null, IdentityConstants.TwoFactorRememberMeScheme))).Verifiable();
|
||||
var helper = SetupSignInManager(manager.Object, context);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
|
||||
@@ -664,6 +695,15 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
return auth;
|
||||
}
|
||||
|
||||
private Mock<IAuthenticationService> MockAuth(ServiceCollection services)
|
||||
{
|
||||
var auth = new Mock<IAuthenticationService>();
|
||||
|
||||
services.AddSingleton(auth.Object);
|
||||
|
||||
return auth;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SignOutCallsContextResponseSignOut()
|
||||
{
|
||||
@@ -671,10 +711,11 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var manager = MockHelpers.TestUserManager<TestUser>();
|
||||
var context = new DefaultHttpContext();
|
||||
var auth = MockAuth(context);
|
||||
var loggerFactory = new MockLoggerFactory();
|
||||
auth.Setup(a => a.SignOutAsync(context, IdentityConstants.ApplicationScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, IdentityConstants.TwoFactorUserIdScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
auth.Setup(a => a.SignOutAsync(context, IdentityConstants.ExternalScheme, It.IsAny<AuthenticationProperties>())).Returns(Task.FromResult(0)).Verifiable();
|
||||
var helper = SetupSignInManager(manager, context, null, manager.Options);
|
||||
var helper = SetupSignInManager(manager, context, loggerFactory, manager.Options);
|
||||
|
||||
// Act
|
||||
await helper.SignOutAsync();
|
||||
@@ -693,8 +734,10 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).ReturnsAsync(false).Verifiable();
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var logStore = new StringBuilder();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object, logStore);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
||||
var checkResult = await helper.CheckPasswordSignInAsync(user, "bogus", false);
|
||||
@@ -702,7 +745,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
// Assert
|
||||
Assert.False(result.Succeeded);
|
||||
Assert.False(checkResult.Succeeded);
|
||||
Assert.Contains($"User {user.Id} failed to provide the correct password.", logStore.ToString());
|
||||
Assert.Contains($"User {user.Id} failed to provide the correct password.", loggerFactory.LogStore.ToString());
|
||||
manager.Verify();
|
||||
context.Verify();
|
||||
}
|
||||
@@ -714,7 +757,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||
manager.Setup(m => m.FindByNameAsync("bogus")).ReturnsAsync(default(TestUser)).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
|
||||
@@ -741,7 +786,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).Returns(() => Task.FromResult(lockedout));
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);
|
||||
@@ -768,7 +815,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
manager.Setup(m => m.IsLockedOutAsync(user)).Returns(() => Task.FromResult(lockedout));
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "bogus")).ReturnsAsync(false).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context.Object, loggerFactory);
|
||||
|
||||
// Act
|
||||
var result = await helper.CheckPasswordSignInAsync(user, "bogus", true);
|
||||
@@ -802,8 +851,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var identityOptions = new IdentityOptions();
|
||||
identityOptions.SignIn.RequireConfirmedEmail = true;
|
||||
var logStore = new StringBuilder();
|
||||
var helper = SetupSignInManager(manager.Object, context, logStore, identityOptions);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory, identityOptions);
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user, "password", false, false);
|
||||
|
||||
@@ -811,7 +861,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
|
||||
Assert.Equal(confirmed, result.Succeeded);
|
||||
Assert.NotEqual(confirmed, result.IsNotAllowed);
|
||||
Assert.Equal(confirmed, !logStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed email."));
|
||||
Assert.Equal(confirmed, !loggerFactory.LogStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed email."));
|
||||
|
||||
manager.Verify();
|
||||
auth.Verify();
|
||||
@@ -846,8 +896,9 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
|
||||
var identityOptions = new IdentityOptions();
|
||||
identityOptions.SignIn.RequireConfirmedPhoneNumber = true;
|
||||
var logStore = new StringBuilder();
|
||||
var helper = SetupSignInManager(manager.Object, context, logStore, identityOptions);
|
||||
|
||||
MockLoggerFactory loggerFactory = new MockLoggerFactory();
|
||||
var helper = SetupSignInManager(manager.Object, context, loggerFactory, identityOptions);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user, "password", false, false);
|
||||
@@ -855,7 +906,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
// Assert
|
||||
Assert.Equal(confirmed, result.Succeeded);
|
||||
Assert.NotEqual(confirmed, result.IsNotAllowed);
|
||||
Assert.Equal(confirmed, !logStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed phone number."));
|
||||
Assert.Equal(confirmed, !loggerFactory.LogStore.ToString().Contains($"User {user.Id} cannot sign in without a confirmed phone number."));
|
||||
manager.Verify();
|
||||
auth.Verify();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Identity.Test;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace AspNetCore.Identity.MongoDbCore.IntegrationTests
|
||||
{
|
||||
public class MockLoggerFactory : ILoggerFactory
|
||||
{
|
||||
public StringBuilder LogStore;
|
||||
|
||||
public List<ILogger> Loggers = new List<ILogger>();
|
||||
|
||||
public MockLoggerFactory()
|
||||
{
|
||||
LogStore = new StringBuilder();
|
||||
}
|
||||
|
||||
public void AddProvider(ILoggerProvider provider)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ILogger CreateLogger(string categoryName)
|
||||
{
|
||||
var logger = new MockLogger(categoryName, LogStore);
|
||||
|
||||
Loggers.Add(logger);
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
public ILogger<T> CreateLogger<T>() where T : class
|
||||
{
|
||||
//var logger = MockHelpers.MockILogger<T>(LogStore).Object;
|
||||
var logger = new MockLogger<T>(LogStore);
|
||||
|
||||
Loggers.Add(logger);
|
||||
|
||||
return logger;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class MockLogger : MockLogger<object>
|
||||
{
|
||||
public String Name { get; protected set; }
|
||||
public MockLogger(string name, StringBuilder store) : base(store)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public class MockLogger<T> : ILogger<T>
|
||||
{
|
||||
public StringBuilder LogMessages;
|
||||
|
||||
public MockLogger(StringBuilder store)
|
||||
{
|
||||
LogMessages = store;
|
||||
}
|
||||
|
||||
public IDisposable BeginScope<TState>(TState state)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsEnabled(LogLevel logLevel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
|
||||
{
|
||||
if (formatter != null)
|
||||
{
|
||||
LogMessages.Append(formatter(state, exception));
|
||||
}
|
||||
else
|
||||
{
|
||||
LogMessages.Append(state.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+5
-3
@@ -289,7 +289,7 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
var manager = CreateManager();
|
||||
var username = "Create" + Guid.NewGuid().ToString();
|
||||
var user = CreateTestUser(username, useNamePrefixAsUserName: true);
|
||||
var stamp = await manager.GetSecurityStampAsync(user);
|
||||
Assert.Null(user.SecurityStamp);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
Assert.NotNull(await manager.GetSecurityStampAsync(user));
|
||||
}
|
||||
@@ -947,10 +947,12 @@ namespace Microsoft.AspNetCore.Identity.Test
|
||||
}
|
||||
var manager = CreateManager();
|
||||
var user = CreateTestUser();
|
||||
Assert.Null(await manager.GetSecurityStampAsync(user));
|
||||
var originalStamp = user.SecurityStamp;
|
||||
//Update to library, can no longer test for null; throws an exceptoin
|
||||
Assert.Null(user.SecurityStamp);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
var stamp = await manager.GetSecurityStampAsync(user);
|
||||
Assert.NotNull(stamp);
|
||||
Assert.NotEqual(originalStamp, stamp);
|
||||
IdentityResultAssert.IsSuccess(await manager.UpdateSecurityStampAsync(user));
|
||||
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user