Initial DI changes from app building
Incorporate feedback and make identity DI friendly everywhere Also start using the new OptionsSetup
This commit is contained in:
parent
8e5ac31889
commit
31f76b8d58
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Microsoft.AspNet.Identity.Entity;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity
|
||||||
|
{
|
||||||
|
public static class IdentityBuilderExtensions
|
||||||
|
{
|
||||||
|
public static IdentityBuilder<TUser, TRole> AddEntity<TUser, TRole>(this IdentityBuilder<TUser, TRole> builder)
|
||||||
|
where TUser : EntityUser
|
||||||
|
where TRole : EntityRole
|
||||||
|
{
|
||||||
|
builder.Services.AddScoped<IUserStore<TUser>, UserStore<TUser>>();
|
||||||
|
builder.Services.AddScoped<UserManager<TUser>, UserManager<TUser>>();
|
||||||
|
builder.Services.AddScoped<IRoleStore<TRole>, RoleStore<TRole>>();
|
||||||
|
builder.Services.AddScoped<RoleManager<TRole>, RoleManager<TRole>>();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ using System;
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
using Microsoft.AspNet.DependencyInjection.Fallback;
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
using Microsoft.Data.Entity;
|
using Microsoft.Data.Entity;
|
||||||
|
using Microsoft.Data.SqlServer;
|
||||||
using Microsoft.Data.InMemory;
|
using Microsoft.Data.InMemory;
|
||||||
using Microsoft.Data.Entity.Metadata;
|
using Microsoft.Data.Entity.Metadata;
|
||||||
|
|
||||||
|
|
@ -33,7 +34,7 @@ namespace Microsoft.AspNet.Identity.Entity
|
||||||
|
|
||||||
public class IdentityContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : DbContext
|
public class IdentityContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : DbContext
|
||||||
where TUser : EntityUser<TKey, TUserLogin, TUserRole, TUserClaim>
|
where TUser : EntityUser<TKey, TUserLogin, TUserRole, TUserClaim>
|
||||||
where TRole : EntityRole<TKey, TUserRole> /*, TUserRole*/
|
where TRole : EntityRole<TKey, TUserRole>
|
||||||
where TUserLogin : IdentityUserLogin<TKey>
|
where TUserLogin : IdentityUserLogin<TKey>
|
||||||
where TUserRole : IdentityUserRole<TKey>
|
where TUserRole : IdentityUserRole<TKey>
|
||||||
where TUserClaim : IdentityUserClaim<TKey>
|
where TUserClaim : IdentityUserClaim<TKey>
|
||||||
|
|
@ -51,7 +52,7 @@ namespace Microsoft.AspNet.Identity.Entity
|
||||||
protected override void OnConfiguring(EntityConfigurationBuilder builder)
|
protected override void OnConfiguring(EntityConfigurationBuilder builder)
|
||||||
{
|
{
|
||||||
//#if NET45
|
//#if NET45
|
||||||
// builder.SqlServerConnectionString(@"Server=(localdb)\v11.0;Database=IdentityDb;Trusted_Connection=True;");
|
// builder.SqlServerConnectionString(@"Server=(localdb)\v11.0;Database=IdentityDb3;Trusted_Connection=True;");
|
||||||
//#else
|
//#else
|
||||||
builder.UseInMemoryStore();
|
builder.UseInMemoryStore();
|
||||||
//#endif
|
//#endif
|
||||||
|
|
|
||||||
|
|
@ -20,20 +20,14 @@
|
||||||
<Content Include="Project.json" />
|
<Content Include="Project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<<<<<<< HEAD
|
|
||||||
<Compile Include="IdentityContext.cs" />
|
|
||||||
<Compile Include="IdentityRole.cs" />
|
|
||||||
<Compile Include="IdentityUser.cs" />
|
|
||||||
<Compile Include="IdentityUserClaim.cs" />
|
|
||||||
<Compile Include="IdentityUserLogin.cs" />
|
|
||||||
<Compile Include="IdentityUserRole.cs" />
|
|
||||||
=======
|
|
||||||
<Compile Include="EntityRole.cs" />
|
<Compile Include="EntityRole.cs" />
|
||||||
<Compile Include="EntityUser.cs" />
|
<Compile Include="EntityUser.cs" />
|
||||||
<Compile Include="IdentityContext.cs" />
|
<Compile Include="IdentityContext.cs" />
|
||||||
>>>>>>> POCO
|
|
||||||
<Compile Include="RoleStore.cs" />
|
<Compile Include="RoleStore.cs" />
|
||||||
<Compile Include="UserStore.cs" />
|
<Compile Include="UserStore.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -24,6 +24,11 @@ using Microsoft.Data.Entity;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity.Entity
|
namespace Microsoft.AspNet.Identity.Entity
|
||||||
{
|
{
|
||||||
|
public class RoleStore<TRole> : RoleStore<TRole, string> where TRole : EntityRole
|
||||||
|
{
|
||||||
|
public RoleStore(DbContext context) : base(context) { }
|
||||||
|
}
|
||||||
|
|
||||||
public class RoleStore<TRole, TKey> :
|
public class RoleStore<TRole, TKey> :
|
||||||
IQueryableRoleStore<TRole>
|
IQueryableRoleStore<TRole>
|
||||||
where TRole : EntityRole
|
where TRole : EntityRole
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,9 @@
|
||||||
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.DependencyInjection": "0.1-alpha-*",
|
"Microsoft.AspNet.DependencyInjection": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Identity": "0.1-alpha-*",
|
"Microsoft.AspNet.Identity": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Logging": "0.1-alpha-*",
|
|
||||||
"Microsoft.Data.Entity": "0.1-alpha-*",
|
"Microsoft.Data.Entity": "0.1-alpha-*",
|
||||||
"Microsoft.Data.Relational": "0.1-alpha-*",
|
"Microsoft.Data.Relational": "0.1-alpha-*",
|
||||||
|
"Microsoft.Data.SqlServer": "0.1-alpha-*",
|
||||||
"Microsoft.Data.InMemory": "0.1-alpha-*",
|
"Microsoft.Data.InMemory": "0.1-alpha-*",
|
||||||
"System.Security.Claims" : "0.1-alpha-*"
|
"System.Security.Claims" : "0.1-alpha-*"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Microsoft.AspNet.Identity.InMemory;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity
|
||||||
|
{
|
||||||
|
public static class IdentityBuilderExtensions
|
||||||
|
{
|
||||||
|
public static IdentityBuilder<TUser, TRole> AddInMemory<TUser, TRole>(this IdentityBuilder<TUser, TRole> builder)
|
||||||
|
where TUser : IdentityUser
|
||||||
|
where TRole : IdentityRole
|
||||||
|
{
|
||||||
|
builder.Services.AddScoped<IUserStore<TUser>, InMemoryUserStore<TUser>>();
|
||||||
|
builder.Services.AddScoped<UserManager<TUser>, UserManager<TUser>>();
|
||||||
|
builder.Services.AddScoped<IRoleStore<TRole>, InMemoryRoleStore<TRole>>();
|
||||||
|
builder.Services.AddScoped<RoleManager<TRole>, RoleManager<TRole>>();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -23,5 +23,8 @@
|
||||||
<Compile Include="InMemoryRoleStore.cs" />
|
<Compile Include="InMemoryRoleStore.cs" />
|
||||||
<Compile Include="InMemoryUserStore.cs" />
|
<Compile Include="InMemoryUserStore.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -2,10 +2,7 @@
|
||||||
"version": "0.1-alpha-*",
|
"version": "0.1-alpha-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Identity": "0.1-alpha-*",
|
"Microsoft.AspNet.Identity": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Abstractions" : "0.1-alpha-*",
|
|
||||||
"Microsoft.AspNet.ConfigurationModel" : "0.1-alpha-*",
|
|
||||||
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.RequestContainer" : "0.1-alpha-*",
|
|
||||||
"System.Security.Claims": "0.1-alpha-*"
|
"System.Security.Claims": "0.1-alpha-*"
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,6 @@ namespace Microsoft.AspNet.Identity.Security
|
||||||
{
|
{
|
||||||
public static class DefaultAuthenticationTypes
|
public static class DefaultAuthenticationTypes
|
||||||
{
|
{
|
||||||
public const string ApplicationCookie = "Microsoft.Aspnet.Identity.Security.Application";
|
public static readonly string ApplicationCookie = typeof(DefaultAuthenticationTypes).Namespace+".Application";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -20,8 +20,13 @@
|
||||||
<Content Include="Project.json" />
|
<Content Include="Project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="DefaultAuthenticationTypes.cs" />
|
||||||
|
<Compile Include="IdentityExtensions.cs" />
|
||||||
<Compile Include="SignInManager.cs" />
|
<Compile Include="SignInManager.cs" />
|
||||||
<Compile Include="SignInStatus.cs" />
|
<Compile Include="SignInStatus.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc.
|
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
|
@ -17,13 +17,37 @@
|
||||||
|
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
using Microsoft.AspNet.Abstractions.Security;
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using System;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity.Security
|
namespace Microsoft.AspNet.Identity.Security
|
||||||
{
|
{
|
||||||
public class SignInManager<TUser> where TUser : class
|
public class SignInManager<TUser> : SignInManager<UserManager<TUser>, TUser> where TUser : class
|
||||||
{
|
{
|
||||||
|
public SignInManager(UserManager<TUser> userManager, IContextAccessor<HttpContext> contextAccessor)
|
||||||
|
: base(userManager, contextAccessor) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class SignInManager<TManager, TUser> where TManager : UserManager<TUser> where TUser : class
|
||||||
|
{
|
||||||
|
public SignInManager(TManager userManager, IContextAccessor<HttpContext> contextAccessor)
|
||||||
|
{
|
||||||
|
if (userManager == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("userManager");
|
||||||
|
}
|
||||||
|
if (contextAccessor == null || contextAccessor.Value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("contextAccessor");
|
||||||
|
}
|
||||||
|
UserManager = userManager;
|
||||||
|
Context = contextAccessor.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: this should go into some kind of Options/setup
|
||||||
private string _authType;
|
private string _authType;
|
||||||
public string AuthenticationType
|
public string AuthenticationType
|
||||||
{
|
{
|
||||||
|
|
@ -31,25 +55,16 @@ namespace Microsoft.AspNet.Identity.Security
|
||||||
set { _authType = value; }
|
set { _authType = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public UserManager<TUser> UserManager { get; set; }
|
public TManager UserManager { get; private set; }
|
||||||
public HttpContext Context { get; set; }
|
public HttpContext Context { get; private set; }
|
||||||
|
|
||||||
public virtual async Task<ClaimsIdentity> CreateUserIdentityAsync(TUser user)
|
public virtual async Task<ClaimsIdentity> CreateUserIdentityAsync(TUser user)
|
||||||
{
|
{
|
||||||
if (UserManager == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return await UserManager.CreateIdentityAsync(user, AuthenticationType);
|
return await UserManager.CreateIdentityAsync(user, AuthenticationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual async Task SignInAsync(TUser user, bool isPersistent, bool rememberBrowser)
|
public virtual async Task SignInAsync(TUser user, bool isPersistent, bool rememberBrowser)
|
||||||
{
|
{
|
||||||
if (Context == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: all the two factor logic/external/rememberBrowser
|
// TODO: all the two factor logic/external/rememberBrowser
|
||||||
var userIdentity = await CreateUserIdentityAsync(user);
|
var userIdentity = await CreateUserIdentityAsync(user);
|
||||||
Context.Response.SignIn(userIdentity, new AuthenticationProperties { IsPersistent = isPersistent });
|
Context.Response.SignIn(userIdentity, new AuthenticationProperties { IsPersistent = isPersistent });
|
||||||
|
|
@ -57,10 +72,6 @@ namespace Microsoft.AspNet.Identity.Security
|
||||||
|
|
||||||
public virtual void SignOut()
|
public virtual void SignOut()
|
||||||
{
|
{
|
||||||
if (Context == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Context.Response.SignOut(AuthenticationType);
|
Context.Response.SignOut(AuthenticationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,10 +162,6 @@ namespace Microsoft.AspNet.Identity.Security
|
||||||
|
|
||||||
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
|
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
|
||||||
{
|
{
|
||||||
if (UserManager == null)
|
|
||||||
{
|
|
||||||
return SignInStatus.Failure;
|
|
||||||
}
|
|
||||||
var user = await UserManager.FindByNameAsync(userName);
|
var user = await UserManager.FindByNameAsync(userName);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNet.ConfigurationModel;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity
|
||||||
|
{
|
||||||
|
public class ClaimTypeOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ClaimType used for the security stamp by default
|
||||||
|
/// </summary>
|
||||||
|
public static readonly string DefaultSecurityStampClaimType = "AspNet.Identity.SecurityStamp";
|
||||||
|
|
||||||
|
public ClaimTypeOptions()
|
||||||
|
{
|
||||||
|
Role = ClaimTypes.Role;
|
||||||
|
SecurityStamp = DefaultSecurityStampClaimType;
|
||||||
|
UserId = ClaimTypes.NameIdentifier;
|
||||||
|
UserName = ClaimTypes.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClaimTypeOptions(IConfiguration config) : this()
|
||||||
|
{
|
||||||
|
IdentityOptions.Read(this, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Claim type used for role claims
|
||||||
|
/// </summary>
|
||||||
|
public string Role { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Claim type used for the user name
|
||||||
|
/// </summary>
|
||||||
|
public string UserName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Claim type used for the user id
|
||||||
|
/// </summary>
|
||||||
|
public string UserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Claim type used for the user security stamp
|
||||||
|
/// </summary>
|
||||||
|
public string SecurityStamp { get; set; }
|
||||||
|
|
||||||
|
public virtual void Copy(ClaimTypeOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Role = options.Role;
|
||||||
|
SecurityStamp = options.SecurityStamp;
|
||||||
|
UserId = options.UserId;
|
||||||
|
UserName = options.UserName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -19,6 +19,7 @@ using System;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity
|
namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
|
|
@ -29,42 +30,6 @@ namespace Microsoft.AspNet.Identity
|
||||||
public class ClaimsIdentityFactory<TUser> : IClaimsIdentityFactory<TUser>
|
public class ClaimsIdentityFactory<TUser> : IClaimsIdentityFactory<TUser>
|
||||||
where TUser : class
|
where TUser : class
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// ClaimType used for the security stamp by default
|
|
||||||
/// </summary>
|
|
||||||
public const string DefaultSecurityStampClaimType = "AspNet.Identity.SecurityStamp";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
public ClaimsIdentityFactory()
|
|
||||||
{
|
|
||||||
RoleClaimType = ClaimsIdentity.DefaultRoleClaimType;
|
|
||||||
UserIdClaimType = ClaimTypes.NameIdentifier;
|
|
||||||
UserNameClaimType = ClaimsIdentity.DefaultNameClaimType;
|
|
||||||
SecurityStampClaimType = DefaultSecurityStampClaimType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Claim type used for role claims
|
|
||||||
/// </summary>
|
|
||||||
public string RoleClaimType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Claim type used for the user name
|
|
||||||
/// </summary>
|
|
||||||
public string UserNameClaimType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Claim type used for the user id
|
|
||||||
/// </summary>
|
|
||||||
public string UserIdClaimType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Claim type used for the user security stamp
|
|
||||||
/// </summary>
|
|
||||||
public string SecurityStampClaimType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// CreateAsync a ClaimsIdentity from a user
|
/// CreateAsync a ClaimsIdentity from a user
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -86,19 +51,19 @@ namespace Microsoft.AspNet.Identity
|
||||||
}
|
}
|
||||||
var userId = await manager.GetUserIdAsync(user, cancellationToken);
|
var userId = await manager.GetUserIdAsync(user, cancellationToken);
|
||||||
var userName = await manager.GetUserNameAsync(user, cancellationToken);
|
var userName = await manager.GetUserNameAsync(user, cancellationToken);
|
||||||
var id = new ClaimsIdentity(authenticationType, UserNameClaimType, RoleClaimType);
|
var id = new ClaimsIdentity(authenticationType, manager.Options.ClaimType.UserName, manager.Options.ClaimType.Role);
|
||||||
id.AddClaim(new Claim(UserIdClaimType, userId));
|
id.AddClaim(new Claim(manager.Options.ClaimType.UserId, userId));
|
||||||
id.AddClaim(new Claim(UserNameClaimType, userName, ClaimValueTypes.String));
|
id.AddClaim(new Claim(manager.Options.ClaimType.UserName, userName, ClaimValueTypes.String));
|
||||||
if (manager.SupportsUserSecurityStamp)
|
if (manager.SupportsUserSecurityStamp)
|
||||||
{
|
{
|
||||||
id.AddClaim(new Claim(SecurityStampClaimType, await manager.GetSecurityStampAsync(user, cancellationToken)));
|
id.AddClaim(new Claim(manager.Options.ClaimType.SecurityStamp, await manager.GetSecurityStampAsync(user, cancellationToken)));
|
||||||
}
|
}
|
||||||
if (manager.SupportsUserRole)
|
if (manager.SupportsUserRole)
|
||||||
{
|
{
|
||||||
var roles = await manager.GetRolesAsync(user, cancellationToken);
|
var roles = await manager.GetRolesAsync(user, cancellationToken);
|
||||||
foreach (var roleName in roles)
|
foreach (var roleName in roles)
|
||||||
{
|
{
|
||||||
id.AddClaim(new Claim(RoleClaimType, roleName, ClaimValueTypes.String));
|
id.AddClaim(new Claim(manager.Options.ClaimType.Role, roleName, ClaimValueTypes.String));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (manager.SupportsUserClaim)
|
if (manager.SupportsUserClaim)
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to validate passwords
|
/// Used to validate passwords
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IPasswordValidator
|
public interface IPasswordValidator<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validate the item
|
/// Validate the item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<IdentityResult> ValidateAsync(string password, CancellationToken cancellationToken = default(CancellationToken));
|
Task<IdentityResult> ValidateAsync(string password, UserManager<TUser> manager, CancellationToken cancellationToken = default(CancellationToken));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,55 +22,82 @@ namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
public class IdentityBuilder<TUser, TRole> where TUser : class where TRole : class
|
public class IdentityBuilder<TUser, TRole> where TUser : class where TRole : class
|
||||||
{
|
{
|
||||||
private ServiceCollection Services { get; set; }
|
public ServiceCollection Services { get; private set; }
|
||||||
|
|
||||||
public IdentityBuilder(ServiceCollection services)
|
public IdentityBuilder(ServiceCollection services)
|
||||||
{
|
{
|
||||||
Services = services;
|
Services = services;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> Use<T>(Func<T> func)
|
// Rename to Add
|
||||||
|
|
||||||
|
public IdentityBuilder<TUser, TRole> AddInstance<T>(Func<T> func)
|
||||||
{
|
{
|
||||||
Services.AddInstance<T>(func());
|
Services.AddInstance(func());
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UseIdentity()
|
public IdentityBuilder<TUser, TRole> AddUserStore(Func<IUserStore<TUser>> func)
|
||||||
{
|
{
|
||||||
Services.Add(IdentityServices.GetDefaultUserServices<TUser>());
|
return AddInstance(func);
|
||||||
Services.Add(IdentityServices.GetDefaultRoleServices<TRole>());
|
}
|
||||||
|
|
||||||
|
public IdentityBuilder<TUser, TRole> AddRoleStore(Func<IRoleStore<TRole>> func)
|
||||||
|
{
|
||||||
|
return AddInstance(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityBuilder<TUser, TRole> AddPasswordValidator(Func<IPasswordValidator<TUser>> func)
|
||||||
|
{
|
||||||
|
return AddInstance(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityBuilder<TUser, TRole> AddUserValidator(Func<IUserValidator<TUser>> func)
|
||||||
|
{
|
||||||
|
return AddInstance(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OptionsSetup<TOptions> : IOptionsSetup<TOptions>
|
||||||
|
{
|
||||||
|
public Action<TOptions> SetupAction { get; private set; }
|
||||||
|
|
||||||
|
public OptionsSetup(Action<TOptions> setupAction)
|
||||||
|
{
|
||||||
|
if (setupAction == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("setupAction");
|
||||||
|
}
|
||||||
|
SetupAction = setupAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Setup(TOptions options)
|
||||||
|
{
|
||||||
|
SetupAction(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Order { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityBuilder<TUser, TRole> SetupOptions(Action<IdentityOptions> action, int order)
|
||||||
|
{
|
||||||
|
Services.AddSetup(new OptionsSetup<IdentityOptions>(action) {Order = order});
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UseUserStore(Func<IUserStore<TUser>> func)
|
public IdentityBuilder<TUser, TRole> SetupOptions(Action<IdentityOptions> action)
|
||||||
{
|
{
|
||||||
return Use(func);
|
return SetupOptions(action, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UseRoleStore(Func<IRoleStore<TRole>> func)
|
public IdentityBuilder<TUser, TRole> AddUserManager<TManager>() where TManager : UserManager<TUser>
|
||||||
{
|
{
|
||||||
return Use(func);
|
Services.AddScoped<TManager>();
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UsePasswordValidator(Func<IPasswordValidator> func)
|
|
||||||
{
|
|
||||||
return Use(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UseUserValidator(Func<IUserValidator<TUser>> func)
|
|
||||||
{
|
|
||||||
return Use(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UseUserManager<TManager>() where TManager : UserManager<TUser>
|
|
||||||
{
|
|
||||||
Services.AddScoped<TManager, TManager>();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UseRoleManager<TManager>() where TManager : RoleManager<TRole>
|
public IdentityBuilder<TUser, TRole> AddRoleManager<TManager>() where TManager : RoleManager<TRole>
|
||||||
{
|
{
|
||||||
Services.AddScoped<TManager, TManager>();
|
Services.AddScoped<TManager>();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,10 +106,5 @@ namespace Microsoft.AspNet.Identity
|
||||||
// return Use(func);
|
// return Use(func);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
public IdentityBuilder<TUser, TRole> UseLockoutPolicy(Func<LockoutPolicy> func)
|
|
||||||
{
|
|
||||||
return Use(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
using System.Reflection;
|
||||||
|
using Microsoft.AspNet.ConfigurationModel;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Configuration for lockout
|
||||||
|
/// </summary>
|
||||||
|
public class IdentityOptions
|
||||||
|
{
|
||||||
|
|
||||||
|
public IdentityOptions()
|
||||||
|
{
|
||||||
|
// TODO: Split into sub options
|
||||||
|
ClaimType = new ClaimTypeOptions();
|
||||||
|
User = new UserOptions();
|
||||||
|
Password = new PasswordOptions();
|
||||||
|
Lockout = new LockoutOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityOptions(IConfiguration config)
|
||||||
|
{
|
||||||
|
ClaimType = new ClaimTypeOptions(config.GetSubKey("identity:claimtype"));
|
||||||
|
User = new UserOptions(config.GetSubKey("identity:user"));
|
||||||
|
Password = new PasswordOptions(config.GetSubKey("identity:password"));
|
||||||
|
//Lockout = new LockoutOptions(config.GetSubKey("identity:lockout"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Read(object obj, IConfiguration config)
|
||||||
|
{
|
||||||
|
var type = obj.GetType();
|
||||||
|
var props = type.GetTypeInfo().DeclaredProperties;
|
||||||
|
foreach (var prop in props)
|
||||||
|
{
|
||||||
|
// TODO: handle non string types?
|
||||||
|
if (!prop.CanWrite)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var configValue = config.Get(prop.Name);
|
||||||
|
if (configValue == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (prop.PropertyType == typeof(string))
|
||||||
|
{
|
||||||
|
prop.SetValue(obj, configValue);
|
||||||
|
}
|
||||||
|
else if (prop.PropertyType == typeof(int))
|
||||||
|
{
|
||||||
|
// todo: TryParse/ errors?
|
||||||
|
prop.SetValue(obj, int.Parse(configValue));
|
||||||
|
}
|
||||||
|
else if (prop.PropertyType == typeof(bool))
|
||||||
|
{
|
||||||
|
// todo: TryParse/ errors?
|
||||||
|
prop.SetValue(obj, bool.Parse(configValue));
|
||||||
|
}
|
||||||
|
//else if (prop.PropertyType == typeof(TimeSpan))
|
||||||
|
//{
|
||||||
|
// // todo: TryParse/ errors?
|
||||||
|
// prop.SetValue(obj, TimeSpan.Parse(configValue));
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ClaimTypeOptions ClaimType { get; set; }
|
||||||
|
|
||||||
|
public UserOptions User { get; set; }
|
||||||
|
|
||||||
|
public PasswordOptions Password { get; set; }
|
||||||
|
|
||||||
|
public LockoutOptions Lockout { get; set; }
|
||||||
|
|
||||||
|
// TODO: maybe make this internal as its only for tests
|
||||||
|
public void Copy(IdentityOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
User.Copy(options.User);
|
||||||
|
Password.Copy(options.Password);
|
||||||
|
Lockout.Copy(options.Lockout);
|
||||||
|
ClaimType.Copy(options.ClaimType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,6 +28,7 @@ namespace Microsoft.AspNet.DependencyInjection
|
||||||
{
|
{
|
||||||
services.Add(IdentityServices.GetDefaultUserServices<TUser>());
|
services.Add(IdentityServices.GetDefaultUserServices<TUser>());
|
||||||
services.Add(IdentityServices.GetDefaultRoleServices<TRole>());
|
services.Add(IdentityServices.GetDefaultRoleServices<TRole>());
|
||||||
|
services.AddSingleton<IOptionsAccessor<IdentityOptions>, OptionsAccessor<IdentityOptions>>();
|
||||||
actionBuilder(new IdentityBuilder<TUser, TRole>(services));
|
actionBuilder(new IdentityBuilder<TUser, TRole>(services));
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
@ -35,10 +36,7 @@ namespace Microsoft.AspNet.DependencyInjection
|
||||||
public static ServiceCollection AddIdentity<TUser>(this ServiceCollection services, Action<IdentityBuilder<TUser, IdentityRole>> actionBuilder)
|
public static ServiceCollection AddIdentity<TUser>(this ServiceCollection services, Action<IdentityBuilder<TUser, IdentityRole>> actionBuilder)
|
||||||
where TUser : class
|
where TUser : class
|
||||||
{
|
{
|
||||||
services.Add(IdentityServices.GetDefaultUserServices<TUser>());
|
return services.AddIdentity<TUser, IdentityRole>(actionBuilder);
|
||||||
services.Add(IdentityServices.GetDefaultRoleServices<IdentityRole>());
|
|
||||||
actionBuilder(new IdentityBuilder<TUser, IdentityRole>(services));
|
|
||||||
return services;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -38,26 +38,12 @@ namespace Microsoft.AspNet.Identity
|
||||||
var describe = new ServiceDescriber(configuration);
|
var describe = new ServiceDescriber(configuration);
|
||||||
|
|
||||||
// TODO: review defaults for validators should get picked up from config?
|
// TODO: review defaults for validators should get picked up from config?
|
||||||
yield return describe.Instance<IUserValidator<TUser>>(new UserValidator<TUser>());
|
yield return describe.Transient<IUserValidator<TUser>, UserValidator<TUser>>();
|
||||||
yield return describe.Instance<IPasswordValidator>(new PasswordValidator()
|
yield return describe.Transient<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
|
||||||
{
|
yield return describe.Transient<IPasswordHasher, PasswordHasher>();
|
||||||
RequiredLength = 6,
|
yield return describe.Transient<IClaimsIdentityFactory<TUser>, ClaimsIdentityFactory<TUser>>();
|
||||||
RequireDigit = true,
|
|
||||||
RequireLowercase = true,
|
|
||||||
RequireNonLetterOrDigit = true,
|
|
||||||
RequireUppercase = true
|
|
||||||
});
|
|
||||||
yield return describe.Instance<IPasswordHasher>(new PasswordHasher());
|
|
||||||
yield return describe.Instance<IClaimsIdentityFactory<TUser>>(new ClaimsIdentityFactory<TUser>());
|
|
||||||
yield return describe.Instance<LockoutPolicy>(new LockoutPolicy
|
|
||||||
{
|
|
||||||
UserLockoutEnabledByDefault = false,
|
|
||||||
DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5),
|
|
||||||
MaxFailedAccessAttemptsBeforeLockout = 5
|
|
||||||
});
|
|
||||||
|
|
||||||
// TODO: rationalize email/sms/usertoken services
|
// TODO: rationalize email/sms/usertoken services
|
||||||
// TODO: configure lockout from config?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<IServiceDescriptor> GetDefaultRoleServices<TRole>() where TRole : class
|
public static IEnumerable<IServiceDescriptor> GetDefaultRoleServices<TRole>() where TRole : class
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity
|
||||||
|
{
|
||||||
|
public class LockoutOptions
|
||||||
|
{
|
||||||
|
public LockoutOptions()
|
||||||
|
{
|
||||||
|
DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
|
||||||
|
EnabledByDefault = false;
|
||||||
|
MaxFailedAccessAttempts = 5;
|
||||||
|
}
|
||||||
|
public void Copy(LockoutOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultLockoutTimeSpan = options.DefaultLockoutTimeSpan;
|
||||||
|
EnabledByDefault = options.EnabledByDefault;
|
||||||
|
MaxFailedAccessAttempts = options.MaxFailedAccessAttempts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If true, will enable user lockout when users are created
|
||||||
|
/// </summary>
|
||||||
|
public bool EnabledByDefault { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of access attempts allowed for a user before lockout (if enabled)
|
||||||
|
/// </summary>
|
||||||
|
public int MaxFailedAccessAttempts { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Default amount of time an user is locked out for after MaxFailedAccessAttempsBeforeLockout is reached
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan DefaultLockoutTimeSpan { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,8 +24,18 @@
|
||||||
<Compile Include="ClaimsIdentityFactory.cs" />
|
<Compile Include="ClaimsIdentityFactory.cs" />
|
||||||
<Compile Include="Crypto.cs" />
|
<Compile Include="Crypto.cs" />
|
||||||
<Compile Include="IClaimsIdentityFactory.cs" />
|
<Compile Include="IClaimsIdentityFactory.cs" />
|
||||||
|
<Compile Include="IdentityBuilder.cs" />
|
||||||
<Compile Include="IdentityMessage.cs" />
|
<Compile Include="IdentityMessage.cs" />
|
||||||
|
<Compile Include="IdentityOptions.cs" />
|
||||||
<Compile Include="IdentityResult.cs" />
|
<Compile Include="IdentityResult.cs" />
|
||||||
|
<Compile Include="IdentityRole.cs" />
|
||||||
|
<Compile Include="IdentityServiceCollectionExtensions.cs" />
|
||||||
|
<Compile Include="IdentityServices.cs" />
|
||||||
|
<Compile Include="IdentitySetup.cs" />
|
||||||
|
<Compile Include="IdentityUser.cs" />
|
||||||
|
<Compile Include="IdentityUserClaim.cs" />
|
||||||
|
<Compile Include="IdentityUserLogin.cs" />
|
||||||
|
<Compile Include="IdentityUserRole.cs" />
|
||||||
<Compile Include="IIdentityMessageService.cs" />
|
<Compile Include="IIdentityMessageService.cs" />
|
||||||
<Compile Include="IPasswordHasher.cs" />
|
<Compile Include="IPasswordHasher.cs" />
|
||||||
<Compile Include="IPasswordValidator.cs" />
|
<Compile Include="IPasswordValidator.cs" />
|
||||||
|
|
@ -56,5 +66,8 @@
|
||||||
<Compile Include="UserManager.cs" />
|
<Compile Include="UserManager.cs" />
|
||||||
<Compile Include="UserValidator.cs" />
|
<Compile Include="UserValidator.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
using Microsoft.AspNet.ConfigurationModel;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity
|
||||||
|
{
|
||||||
|
public class PasswordOptions
|
||||||
|
{
|
||||||
|
public PasswordOptions()
|
||||||
|
{
|
||||||
|
RequireDigit = true;
|
||||||
|
RequireLowercase = true;
|
||||||
|
RequireNonLetterOrDigit = true;
|
||||||
|
RequireUppercase = true;
|
||||||
|
RequiredLength = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PasswordOptions(IConfiguration config) : this()
|
||||||
|
{
|
||||||
|
IdentityOptions.Read(this, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Minimum required length
|
||||||
|
/// </summary>
|
||||||
|
public int RequiredLength { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Require a non letter or digit character
|
||||||
|
/// </summary>
|
||||||
|
public bool RequireNonLetterOrDigit { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Require a lower case letter ('a' - 'z')
|
||||||
|
/// </summary>
|
||||||
|
public bool RequireLowercase { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Require an upper case letter ('A' - 'Z')
|
||||||
|
/// </summary>
|
||||||
|
public bool RequireUppercase { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Require a digit ('0' - '9')
|
||||||
|
/// </summary>
|
||||||
|
public bool RequireDigit { get; set; }
|
||||||
|
|
||||||
|
public virtual void Copy(PasswordOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
RequireDigit = options.RequireDigit;
|
||||||
|
RequireLowercase = options.RequireLowercase;
|
||||||
|
RequireNonLetterOrDigit = options.RequireNonLetterOrDigit;
|
||||||
|
RequireUppercase = options.RequireUppercase;
|
||||||
|
RequiredLength = options.RequiredLength;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -27,63 +27,44 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to validate some basic password policy like length and number of non alphanumerics
|
/// Used to validate some basic password policy like length and number of non alphanumerics
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PasswordValidator : IPasswordValidator
|
public class PasswordValidator<TUser> : IPasswordValidator<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Minimum required length
|
/// Ensures that the password is of the required length and meets the configured requirements
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int RequiredLength { get; set; }
|
/// <param name="password"></param>
|
||||||
|
/// <param name="manager"></param>
|
||||||
/// <summary>
|
|
||||||
/// Require a non letter or digit character
|
|
||||||
/// </summary>
|
|
||||||
public bool RequireNonLetterOrDigit { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Require a lower case letter ('a' - 'z')
|
|
||||||
/// </summary>
|
|
||||||
public bool RequireLowercase { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Require an upper case letter ('A' - 'Z')
|
|
||||||
/// </summary>
|
|
||||||
public bool RequireUppercase { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Require a digit ('0' - '9')
|
|
||||||
/// </summary>
|
|
||||||
public bool RequireDigit { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ensures that the string is of the required length and meets the configured requirements
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="item"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public virtual Task<IdentityResult> ValidateAsync(string item, CancellationToken cancellationToken = default(CancellationToken))
|
public virtual Task<IdentityResult> ValidateAsync(string password, UserManager<TUser> manager, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
if (item == null)
|
if (password == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("item");
|
throw new ArgumentNullException("password");
|
||||||
|
}
|
||||||
|
if (manager == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("manager");
|
||||||
}
|
}
|
||||||
var errors = new List<string>();
|
var errors = new List<string>();
|
||||||
if (string.IsNullOrWhiteSpace(item) || item.Length < RequiredLength)
|
var options = manager.Options.Password;
|
||||||
|
if (string.IsNullOrWhiteSpace(password) || password.Length < options.RequiredLength)
|
||||||
{
|
{
|
||||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PasswordTooShort, RequiredLength));
|
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PasswordTooShort, options.RequiredLength));
|
||||||
}
|
}
|
||||||
if (RequireNonLetterOrDigit && item.All(IsLetterOrDigit))
|
if (options.RequireNonLetterOrDigit && password.All(IsLetterOrDigit))
|
||||||
{
|
{
|
||||||
errors.Add(Resources.PasswordRequireNonLetterOrDigit);
|
errors.Add(Resources.PasswordRequireNonLetterOrDigit);
|
||||||
}
|
}
|
||||||
if (RequireDigit && !item.Any(IsDigit))
|
if (options.RequireDigit && !password.Any(IsDigit))
|
||||||
{
|
{
|
||||||
errors.Add(Resources.PasswordRequireDigit);
|
errors.Add(Resources.PasswordRequireDigit);
|
||||||
}
|
}
|
||||||
if (RequireLowercase && !item.Any(IsLower))
|
if (options.RequireLowercase && !password.Any(IsLower))
|
||||||
{
|
{
|
||||||
errors.Add(Resources.PasswordRequireLower);
|
errors.Add(Resources.PasswordRequireLower);
|
||||||
}
|
}
|
||||||
if (RequireUppercase && !item.Any(IsUpper))
|
if (options.RequireUppercase && !password.Any(IsUpper))
|
||||||
{
|
{
|
||||||
errors.Add(Resources.PasswordRequireUpper);
|
errors.Add(Resources.PasswordRequireUpper);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,24 +32,23 @@ namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
public RoleManager(IServiceProvider services)
|
|
||||||
{
|
|
||||||
Initialize(services);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor
|
/// Constructor
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="services"></param>
|
||||||
/// <param name="store">The IRoleStore is responsible for commiting changes via the UpdateAsync/CreateAsync methods</param>
|
/// <param name="store">The IRoleStore is responsible for commiting changes via the UpdateAsync/CreateAsync methods</param>
|
||||||
public RoleManager(IRoleStore<TRole> store)
|
public RoleManager(IServiceProvider services, IRoleStore<TRole> store)
|
||||||
{
|
{
|
||||||
if (store == null)
|
if (store == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("store");
|
throw new ArgumentNullException("store");
|
||||||
}
|
}
|
||||||
var services = new ServiceCollection { IdentityServices.GetDefaultRoleServices<TRole>() };
|
if (services == null)
|
||||||
services.AddInstance<IRoleStore<TRole>>(store);
|
{
|
||||||
Initialize(services.BuildServiceProvider());
|
throw new ArgumentNullException("services");
|
||||||
|
}
|
||||||
|
RoleValidator = services.GetService<IRoleValidator<TRole>>() ?? new RoleValidator<TRole>();
|
||||||
|
Store = store;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -90,21 +89,6 @@ namespace Microsoft.AspNet.Identity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Initialize(IServiceProvider services)
|
|
||||||
{
|
|
||||||
if (services == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("services");
|
|
||||||
}
|
|
||||||
Store = services.GetService<IRoleStore<TRole>>();
|
|
||||||
if (Store == null)
|
|
||||||
{
|
|
||||||
// TODO: what is the right way to enforce required services
|
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
|
||||||
RoleValidator = services.GetService<IRoleValidator<TRole>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dispose this object
|
/// Dispose this object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -41,52 +41,34 @@ namespace Microsoft.AspNet.Identity
|
||||||
private TimeSpan _defaultLockout = TimeSpan.Zero;
|
private TimeSpan _defaultLockout = TimeSpan.Zero;
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private IPasswordHasher _passwordHasher;
|
private IPasswordHasher _passwordHasher;
|
||||||
private LockoutPolicy _lockoutPolicy;
|
private IdentityOptions _options;
|
||||||
|
|
||||||
// Needed for mock unit tests
|
|
||||||
public UserManager() { }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor which takes a service provider
|
/// Constructor which takes a service provider and user store
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serviceProvider"></param>
|
/// <param name="serviceProvider"></param>
|
||||||
public UserManager(IServiceProvider serviceProvider)
|
/// <param name="store"></param>
|
||||||
{
|
/// <param name="optionsAccessor"></param>
|
||||||
Initialize(serviceProvider);
|
public UserManager(IServiceProvider serviceProvider, IUserStore<TUser> store, IOptionsAccessor<IdentityOptions> optionsAccessor)
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="store">The IUserStore is responsible for commiting changes via the UpdateAsync/CreateAsync methods</param>
|
|
||||||
public UserManager(IUserStore<TUser> store)
|
|
||||||
{
|
|
||||||
if (store == null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException("store");
|
|
||||||
}
|
|
||||||
var services = new ServiceCollection { IdentityServices.GetDefaultUserServices<TUser>() };
|
|
||||||
services.AddInstance<IUserStore<TUser>>(store);
|
|
||||||
Initialize(services.BuildServiceProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize(IServiceProvider serviceProvider)
|
|
||||||
{
|
{
|
||||||
if (serviceProvider == null)
|
if (serviceProvider == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException("serviceProvider");
|
throw new ArgumentNullException("serviceProvider");
|
||||||
}
|
}
|
||||||
PasswordHasher = serviceProvider.GetService<IPasswordHasher>();
|
if (store == null)
|
||||||
UserValidator = serviceProvider.GetService<IUserValidator<TUser>>();
|
|
||||||
PasswordValidator = serviceProvider.GetService<IPasswordValidator>();
|
|
||||||
ClaimsIdentityFactory = serviceProvider.GetService<IClaimsIdentityFactory<TUser>>();
|
|
||||||
LockoutPolicy = serviceProvider.GetService<LockoutPolicy>();
|
|
||||||
Store = serviceProvider.GetService<IUserStore<TUser>>();
|
|
||||||
if (Store == null)
|
|
||||||
{
|
{
|
||||||
// TODO: what is the right way to enforce required services
|
throw new ArgumentNullException("store");
|
||||||
throw new InvalidOperationException();
|
|
||||||
}
|
}
|
||||||
|
if (optionsAccessor == null || optionsAccessor.Options == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("optionsAccessor");
|
||||||
|
}
|
||||||
|
Store = store;
|
||||||
|
Options = optionsAccessor.Options;
|
||||||
|
PasswordHasher = serviceProvider.GetService<IPasswordHasher>() ?? new PasswordHasher();
|
||||||
|
UserValidator = serviceProvider.GetService<IUserValidator<TUser>>() ?? new UserValidator<TUser>();
|
||||||
|
PasswordValidator = serviceProvider.GetService<IPasswordValidator<TUser>>() ?? new PasswordValidator<TUser>();
|
||||||
|
ClaimsIdentityFactory = serviceProvider.GetService<IClaimsIdentityFactory<TUser>>() ?? new ClaimsIdentityFactory<TUser>();
|
||||||
// TODO: Email/Sms/Token services
|
// TODO: Email/Sms/Token services
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +106,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to validate passwords before persisting changes
|
/// Used to validate passwords before persisting changes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IPasswordValidator PasswordValidator { get; set; }
|
public IPasswordValidator<TUser> PasswordValidator { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used to create claims identities from users
|
/// Used to create claims identities from users
|
||||||
|
|
@ -162,30 +144,23 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IUserTokenProvider<TUser> UserTokenProvider { get; set; }
|
public IUserTokenProvider<TUser> UserTokenProvider { get; set; }
|
||||||
|
|
||||||
public LockoutPolicy LockoutPolicy { get; set; }
|
public IdentityOptions Options
|
||||||
|
|
||||||
private bool UserLockoutEnabledByDefault
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return LockoutPolicy != null && LockoutPolicy.UserLockoutEnabledByDefault;
|
ThrowIfDisposed();
|
||||||
|
return _options;
|
||||||
}
|
}
|
||||||
}
|
set
|
||||||
|
|
||||||
private int MaxFailedAccessAttemptsBeforeLockout
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
return LockoutPolicy != null ? LockoutPolicy.MaxFailedAccessAttemptsBeforeLockout : 0;
|
ThrowIfDisposed();
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("value");
|
||||||
|
}
|
||||||
|
_options = value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private TimeSpan DefaultAccountLockoutTimeSpan
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return LockoutPolicy != null ? LockoutPolicy.DefaultAccountLockoutTimeSpan : TimeSpan.FromMinutes(5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -380,7 +355,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (UserLockoutEnabledByDefault && SupportsUserLockout)
|
if (Options.Lockout.EnabledByDefault && SupportsUserLockout)
|
||||||
{
|
{
|
||||||
await GetUserLockoutStore().SetLockoutEnabledAsync(user, true, cancellationToken);
|
await GetUserLockoutStore().SetLockoutEnabledAsync(user, true, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
@ -673,7 +648,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
if (PasswordValidator != null)
|
if (PasswordValidator != null)
|
||||||
{
|
{
|
||||||
var result = await PasswordValidator.ValidateAsync(newPassword, cancellationToken);
|
var result = await PasswordValidator.ValidateAsync(newPassword, this, cancellationToken);
|
||||||
if (!result.Succeeded)
|
if (!result.Succeeded)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -1757,12 +1732,12 @@ namespace Microsoft.AspNet.Identity
|
||||||
}
|
}
|
||||||
// If this puts the user over the threshold for lockout, lock them out and reset the access failed count
|
// If this puts the user over the threshold for lockout, lock them out and reset the access failed count
|
||||||
var count = await store.IncrementAccessFailedCountAsync(user, cancellationToken);
|
var count = await store.IncrementAccessFailedCountAsync(user, cancellationToken);
|
||||||
if (count < MaxFailedAccessAttemptsBeforeLockout)
|
if (count < Options.Lockout.MaxFailedAccessAttempts)
|
||||||
{
|
{
|
||||||
return await UpdateAsync(user, cancellationToken);
|
return await UpdateAsync(user, cancellationToken);
|
||||||
}
|
}
|
||||||
await
|
await
|
||||||
store.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow.Add(DefaultAccountLockoutTimeSpan), cancellationToken);
|
store.SetLockoutEndDateAsync(user, DateTimeOffset.UtcNow.Add(Options.Lockout.DefaultLockoutTimeSpan), cancellationToken);
|
||||||
await store.ResetAccessFailedCountAsync(user, cancellationToken);
|
await store.ResetAccessFailedCountAsync(user, cancellationToken);
|
||||||
return await UpdateAsync(user, cancellationToken);
|
return await UpdateAsync(user, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
using Microsoft.AspNet.ConfigurationModel;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity
|
||||||
|
{
|
||||||
|
public class UserOptions
|
||||||
|
{
|
||||||
|
public UserOptions()
|
||||||
|
{
|
||||||
|
AllowOnlyAlphanumericNames = true;
|
||||||
|
//User.RequireUniqueEmail = true; // TODO: app decision?
|
||||||
|
}
|
||||||
|
|
||||||
|
public UserOptions(IConfiguration config) : this()
|
||||||
|
{
|
||||||
|
IdentityOptions.Read(this, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Only allow [A-Za-z0-9@_] in UserNames
|
||||||
|
/// </summary>
|
||||||
|
public bool AllowOnlyAlphanumericNames { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If set, enforces that emails are non empty, valid, and unique
|
||||||
|
/// </summary>
|
||||||
|
public bool RequireUniqueEmail { get; set; }
|
||||||
|
|
||||||
|
public virtual void Copy(UserOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AllowOnlyAlphanumericNames = options.AllowOnlyAlphanumericNames;
|
||||||
|
RequireUniqueEmail = options.RequireUniqueEmail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -33,24 +33,6 @@ namespace Microsoft.AspNet.Identity
|
||||||
/// <typeparam name="TUser"></typeparam>
|
/// <typeparam name="TUser"></typeparam>
|
||||||
public class UserValidator<TUser> : IUserValidator<TUser> where TUser : class
|
public class UserValidator<TUser> : IUserValidator<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Constructor
|
|
||||||
/// </summary>
|
|
||||||
public UserValidator()
|
|
||||||
{
|
|
||||||
AllowOnlyAlphanumericUserNames = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Only allow [A-Za-z0-9@_] in UserNames
|
|
||||||
/// </summary>
|
|
||||||
public bool AllowOnlyAlphanumericUserNames { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If set, enforces that emails are non empty, valid, and unique
|
|
||||||
/// </summary>
|
|
||||||
public bool RequireUniqueEmail { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Validates a user before saving
|
/// Validates a user before saving
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -70,7 +52,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
}
|
}
|
||||||
var errors = new List<string>();
|
var errors = new List<string>();
|
||||||
await ValidateUserName(manager, user, errors);
|
await ValidateUserName(manager, user, errors);
|
||||||
if (RequireUniqueEmail)
|
if (manager.Options.User.RequireUniqueEmail)
|
||||||
{
|
{
|
||||||
await ValidateEmail(manager, user, errors);
|
await ValidateEmail(manager, user, errors);
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +108,7 @@ namespace Microsoft.AspNet.Identity
|
||||||
{
|
{
|
||||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "UserName"));
|
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "UserName"));
|
||||||
}
|
}
|
||||||
else if (AllowOnlyAlphanumericUserNames && !userName.All(IsAlphaNumeric))
|
else if (manager.Options.User.AllowOnlyAlphanumericNames && !userName.All(IsAlphaNumeric))
|
||||||
{
|
{
|
||||||
// If any characters are not letters or digits, its an illegal user name
|
// If any characters are not letters or digits, its an illegal user name
|
||||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.InvalidUserName, userName));
|
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.InvalidUserName, userName));
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
||||||
"System.Security.Claims" : "0.1-alpha-*",
|
|
||||||
"Microsoft.AspNet.HttpFeature" : "0.1-alpha-*",
|
"Microsoft.AspNet.HttpFeature" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Security.DataProtection" : "0.1-alpha-*"
|
"Microsoft.AspNet.Security.DataProtection" : "0.1-alpha-*",
|
||||||
|
"System.Security.Claims" : "0.1-alpha-*"
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"net45": {},
|
"net45": {},
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
"System.Linq.Expressions": "4.0.0.0",
|
"System.Linq.Expressions": "4.0.0.0",
|
||||||
"System.Linq.Queryable": "4.0.0.0",
|
"System.Linq.Queryable": "4.0.0.0",
|
||||||
"System.Reflection": "4.0.10.0",
|
"System.Reflection": "4.0.10.0",
|
||||||
|
"System.Reflection.Extensions": "4.0.0.0",
|
||||||
"System.Resources.ResourceManager": "4.0.0.0",
|
"System.Resources.ResourceManager": "4.0.0.0",
|
||||||
"System.Runtime": "4.0.20.0",
|
"System.Runtime": "4.0.20.0",
|
||||||
"System.Runtime.Extensions": "4.0.10.0",
|
"System.Runtime.Extensions": "4.0.10.0",
|
||||||
|
|
|
||||||
|
|
@ -26,5 +26,8 @@
|
||||||
<Compile Include="TestIdentityFactory.cs" />
|
<Compile Include="TestIdentityFactory.cs" />
|
||||||
<Compile Include="UserStoreTest.cs" />
|
<Compile Include="UserStoreTest.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -17,12 +17,64 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
|
using Microsoft.AspNet.Identity.Test;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using Microsoft.Data.InMemory;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity.Entity.Test
|
namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
{
|
{
|
||||||
public class RoleStoreTest
|
public class RoleStoreTest
|
||||||
{
|
{
|
||||||
|
class ApplicationRoleManager : RoleManager<EntityRole>
|
||||||
|
{
|
||||||
|
public ApplicationRoleManager(IServiceProvider services, IRoleStore<EntityRole> store) : base(services, store) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task CanCreateUsingAddRoleManager()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
#if NET45
|
||||||
|
// services.AddEntityFramework(s => s.AddSqlServer());
|
||||||
|
//#else
|
||||||
|
services.AddEntityFramework(s => s.AddInMemoryStore());
|
||||||
|
#endif
|
||||||
|
// TODO: this should construct a new instance of InMemoryStore
|
||||||
|
var store = new RoleStore<EntityRole>(new IdentityContext());
|
||||||
|
services.AddIdentity<EntityUser, EntityRole>(s =>
|
||||||
|
{
|
||||||
|
s.AddRoleStore(() => store);
|
||||||
|
s.AddRoleManager<ApplicationRoleManager>();
|
||||||
|
});
|
||||||
|
|
||||||
|
var provider = services.BuildServiceProvider();
|
||||||
|
var manager = provider.GetService<ApplicationRoleManager>();
|
||||||
|
Assert.NotNull(manager);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityRole("arole")));
|
||||||
|
}
|
||||||
|
[Fact]
|
||||||
|
public async Task CanCreateRoleWithSingletonManager()
|
||||||
|
{
|
||||||
|
var services = new ServiceCollection();
|
||||||
|
#if NET45
|
||||||
|
// services.AddEntityFramework(s => s.AddSqlServer());
|
||||||
|
//#else
|
||||||
|
services.AddEntityFramework(s => s.AddInMemoryStore());
|
||||||
|
#endif
|
||||||
|
services.AddTransient<DbContext, IdentityContext>();
|
||||||
|
services.AddTransient<IRoleStore<EntityRole>, RoleStore<EntityRole>>();
|
||||||
|
//todo: services.AddSingleton<RoleManager<EntityRole>, RoleManager<EntityRole>>();
|
||||||
|
// TODO: How to configure SqlServer?
|
||||||
|
services.AddSingleton<ApplicationRoleManager, ApplicationRoleManager>();
|
||||||
|
var provider = services.BuildServiceProvider();
|
||||||
|
var manager = provider.GetService<ApplicationRoleManager>();
|
||||||
|
Assert.NotNull(manager);
|
||||||
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityRole("someRole")));
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task RoleStoreMethodsThrowWhenDisposedTest()
|
public async Task RoleStoreMethodsThrowWhenDisposedTest()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
using Microsoft.AspNet.Abstractions;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
|
using Microsoft.AspNet.Identity.Entity;
|
||||||
|
using Microsoft.AspNet.Identity.Test;
|
||||||
|
using Microsoft.AspNet.PipelineCore;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Data.Entity;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
|
{
|
||||||
|
public class StartupTest
|
||||||
|
{
|
||||||
|
public class ApplicationUser : EntityUser { }
|
||||||
|
public class ApplicationUserManager : UserManager<ApplicationUser>
|
||||||
|
{
|
||||||
|
public ApplicationUserManager(IServiceProvider services, IUserStore<ApplicationUser> store, IOptionsAccessor<IdentityOptions> options) : base(services, store, options) { }
|
||||||
|
}
|
||||||
|
public class ApplicationRoleManager : RoleManager<EntityRole>
|
||||||
|
{
|
||||||
|
public ApplicationRoleManager(IServiceProvider services, IRoleStore<EntityRole> store) : base(services, store) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class PasswordsNegativeLengthSetup : IOptionsSetup<IdentityOptions>
|
||||||
|
{
|
||||||
|
public int Order { get { return 0; } }
|
||||||
|
public void Setup(IdentityOptions options)
|
||||||
|
{
|
||||||
|
options.Password.RequiredLength = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanCustomizeIdentityOptions()
|
||||||
|
{
|
||||||
|
IBuilder builder = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
builder.UseServices(services => {
|
||||||
|
services.AddIdentity<IdentityUser>(identityServices => { });
|
||||||
|
services.AddSetup<PasswordsNegativeLengthSetup>();
|
||||||
|
});
|
||||||
|
|
||||||
|
var setup = builder.ApplicationServices.GetService<IOptionsSetup<IdentityOptions>>();
|
||||||
|
Assert.IsType(typeof(PasswordsNegativeLengthSetup), setup);
|
||||||
|
var optionsGetter = builder.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>();
|
||||||
|
Assert.NotNull(optionsGetter);
|
||||||
|
setup.Setup(optionsGetter.Options);
|
||||||
|
|
||||||
|
var myOptions = optionsGetter.Options;
|
||||||
|
Assert.True(myOptions.Password.RequireLowercase);
|
||||||
|
Assert.True(myOptions.Password.RequireDigit);
|
||||||
|
Assert.True(myOptions.Password.RequireNonLetterOrDigit);
|
||||||
|
Assert.True(myOptions.Password.RequireUppercase);
|
||||||
|
Assert.Equal(-1, myOptions.Password.RequiredLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanSetupIdentityOptions()
|
||||||
|
{
|
||||||
|
IBuilder app = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
app.UseServices(services => services.AddIdentity<IdentityUser>(identityServices => identityServices.SetupOptions(options => options.User.RequireUniqueEmail = true)));
|
||||||
|
|
||||||
|
var optionsGetter = app.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>();
|
||||||
|
Assert.NotNull(optionsGetter);
|
||||||
|
|
||||||
|
var myOptions = optionsGetter.Options;
|
||||||
|
Assert.True(myOptions.User.RequireUniqueEmail);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task EnsureStartupUsageWorks()
|
||||||
|
{
|
||||||
|
IBuilder builder = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
|
||||||
|
//builder.UseServices(services => services.AddIdentity<ApplicationUser>(s =>
|
||||||
|
// s.AddEntity<ApplicationDbContext>()
|
||||||
|
//{
|
||||||
|
|
||||||
|
builder.UseServices(services =>
|
||||||
|
{
|
||||||
|
services.AddEntityFramework();
|
||||||
|
services.AddTransient<DbContext, IdentityContext>();
|
||||||
|
services.AddIdentity<ApplicationUser, EntityRole>(s =>
|
||||||
|
{
|
||||||
|
s.AddEntity();
|
||||||
|
s.AddUserManager<ApplicationUserManager>();
|
||||||
|
s.AddRoleManager<ApplicationRoleManager>();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var userStore = builder.ApplicationServices.GetService<IUserStore<ApplicationUser>>();
|
||||||
|
var roleStore = builder.ApplicationServices.GetService<IRoleStore<EntityRole>>();
|
||||||
|
var userManager = builder.ApplicationServices.GetService<ApplicationUserManager>();
|
||||||
|
//TODO: var userManager = builder.ApplicationServices.GetService<UserManager<IdentityUser>();
|
||||||
|
var roleManager = builder.ApplicationServices.GetService<ApplicationRoleManager>();
|
||||||
|
|
||||||
|
Assert.NotNull(userStore);
|
||||||
|
Assert.NotNull(userManager);
|
||||||
|
Assert.NotNull(roleStore);
|
||||||
|
Assert.NotNull(roleManager);
|
||||||
|
|
||||||
|
//await CreateAdminUser(builder.ApplicationServices);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task CreateAdminUser(IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
const string userName = "admin";
|
||||||
|
const string roleName = "Admins";
|
||||||
|
const string password = "1qaz@WSX";
|
||||||
|
var userManager = serviceProvider.GetService<ApplicationUserManager>();
|
||||||
|
var roleManager = serviceProvider.GetService<ApplicationRoleManager>();
|
||||||
|
|
||||||
|
var user = new ApplicationUser { UserName = userName };
|
||||||
|
IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password));
|
||||||
|
IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(new EntityRole { Name = roleName }));
|
||||||
|
IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(user, roleName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,74 +36,63 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public static DbContext CreateContext()
|
public static DbContext CreateContext()
|
||||||
{
|
{
|
||||||
var serviceProvider = new ServiceCollection()
|
var serviceProvider = new ServiceCollection()
|
||||||
.AddEntityFramework(s => s.AddInMemoryStore())
|
//#if NET45
|
||||||
.BuildServiceProvider();
|
// .AddEntityFramework(s => s.AddSqlServer())
|
||||||
|
//#else
|
||||||
|
.AddEntityFramework(s => s.AddInMemoryStore())
|
||||||
|
//#endif
|
||||||
|
.BuildServiceProvider();
|
||||||
|
|
||||||
var db = new IdentityContext(serviceProvider);
|
var db = new IdentityContext(serviceProvider);
|
||||||
// var sql = db.Configuration.DataStore as SqlServerDataStore;
|
|
||||||
// if (sql != null)
|
|
||||||
// {
|
|
||||||
//#if NET45
|
|
||||||
// var builder = new DbConnectionStringBuilder {ConnectionString = sql.ConnectionString};
|
|
||||||
// var targetDatabase = builder["Database"].ToString();
|
|
||||||
|
|
||||||
// // Connect to master, check if database exists, and create if not
|
// TODO: Recreate DB, doesn't support String ID or Identity context yet
|
||||||
// builder.Add("Database", "master");
|
//if (!db.Database.Exists())
|
||||||
// using (var masterConnection = new SqlConnection(builder.ConnectionString))
|
//{
|
||||||
// {
|
// db.Database.Create();
|
||||||
// masterConnection.Open();
|
|
||||||
|
|
||||||
// var masterCommand = masterConnection.CreateCommand();
|
|
||||||
// masterCommand.CommandText = "SELECT COUNT(*) FROM sys.databases WHERE [name]=N'" + targetDatabase +
|
|
||||||
// "'";
|
|
||||||
// if ((int?) masterCommand.ExecuteScalar() < 1)
|
|
||||||
// {
|
|
||||||
// masterCommand.CommandText = "CREATE DATABASE [" + targetDatabase + "]";
|
|
||||||
// masterCommand.ExecuteNonQuery();
|
|
||||||
|
|
||||||
// using (var conn = new SqlConnection(sql.ConnectionString))
|
|
||||||
// {
|
|
||||||
// conn.Open();
|
|
||||||
// var command = conn.CreateCommand();
|
|
||||||
// command.CommandText = @"
|
|
||||||
//CREATE TABLE [dbo].[AspNetUsers] (
|
|
||||||
//[Id] NVARCHAR (128) NOT NULL,
|
|
||||||
//[Email] NVARCHAR (256) NULL,
|
|
||||||
//[EmailConfirmed] BIT NOT NULL,
|
|
||||||
//[PasswordHash] NVARCHAR (MAX) NULL,
|
|
||||||
//[SecurityStamp] NVARCHAR (MAX) NULL,
|
|
||||||
//[PhoneNumber] NVARCHAR (MAX) NULL,
|
|
||||||
//[PhoneNumberConfirmed] BIT NOT NULL,
|
|
||||||
//[TwoFactorEnabled] BIT NOT NULL,
|
|
||||||
//[LockoutEndDateUtc] DATETIME NULL,
|
|
||||||
//[LockoutEnabled] BIT NOT NULL,
|
|
||||||
//[AccessFailedCount] INT NOT NULL,
|
|
||||||
//[UserName] NVARCHAR (256) NOT NULL
|
|
||||||
//) ";
|
|
||||||
// //CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
|
|
||||||
// command.ExecuteNonQuery();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//#else
|
|
||||||
// throw new NotSupportedException("SQL Server is not yet supported when running against K10.");
|
|
||||||
//#endif
|
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
// TODO: CreateAsync DB?
|
// TODO: CreateAsync DB?
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TestSetup : IOptionsSetup<IdentityOptions>
|
||||||
|
{
|
||||||
|
private readonly IdentityOptions _options;
|
||||||
|
|
||||||
|
public TestSetup(IdentityOptions options)
|
||||||
|
{
|
||||||
|
_options = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Order { get { return 0; } }
|
||||||
|
public void Setup(IdentityOptions options)
|
||||||
|
{
|
||||||
|
options.Copy(_options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static UserManager<EntityUser> CreateManager(DbContext context)
|
public static UserManager<EntityUser> CreateManager(DbContext context)
|
||||||
{
|
{
|
||||||
var manager = new UserManager<EntityUser>(new UserStore(context))
|
var services = new ServiceCollection();
|
||||||
|
services.AddTransient<IUserValidator<EntityUser>, UserValidator<EntityUser>>();
|
||||||
|
services.AddTransient<IPasswordValidator<IdentityUser>, PasswordValidator<IdentityUser>>();
|
||||||
|
services.AddInstance<IUserStore<EntityUser>>(new UserStore<EntityUser>(context));
|
||||||
|
services.AddSingleton<UserManager<EntityUser>, UserManager<EntityUser>>();
|
||||||
|
var options = new IdentityOptions
|
||||||
{
|
{
|
||||||
UserValidator = new UserValidator<EntityUser>(),
|
Password = new PasswordOptions
|
||||||
PasswordValidator = new PasswordValidator()
|
{
|
||||||
|
RequireDigit = false,
|
||||||
|
RequireLowercase = false,
|
||||||
|
RequireNonLetterOrDigit = false,
|
||||||
|
RequireUppercase = false
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return manager;
|
var optionsAccessor = new OptionsAccessor<IdentityOptions>(new[] { new TestSetup(options) });
|
||||||
|
//services.AddInstance<IOptionsAccessor<IdentityOptions>>(new OptionsAccessor<IdentityOptions>(new[] { new TestSetup(options) }));
|
||||||
|
//return services.BuildServiceProvider().GetService<UserManager<EntityUser>>();
|
||||||
|
return new UserManager<EntityUser>(services.BuildServiceProvider(), new UserStore<EntityUser>(context), optionsAccessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserManager<EntityUser> CreateManager()
|
public static UserManager<EntityUser> CreateManager()
|
||||||
|
|
@ -113,7 +102,11 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
|
|
||||||
public static RoleManager<EntityRole> CreateRoleManager(DbContext context)
|
public static RoleManager<EntityRole> CreateRoleManager(DbContext context)
|
||||||
{
|
{
|
||||||
return new RoleManager<EntityRole>(new RoleStore<EntityRole, string>(context));
|
var services = new ServiceCollection();
|
||||||
|
services.AddTransient<IRoleValidator<EntityRole>, RoleValidator<EntityRole>>();
|
||||||
|
services.AddInstance<IRoleStore<EntityRole>>(new RoleStore<EntityRole, string>(context));
|
||||||
|
// return services.BuildServiceProvider().GetService<RoleManager<EntityRole>>();
|
||||||
|
return new RoleManager<EntityRole>(services.BuildServiceProvider(), new RoleStore<EntityRole, string>(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RoleManager<EntityRole> CreateRoleManager()
|
public static RoleManager<EntityRole> CreateRoleManager()
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,12 @@
|
||||||
|
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
using Microsoft.AspNet.DependencyInjection.Fallback;
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
|
using Microsoft.AspNet.Identity.Test;
|
||||||
using Microsoft.AspNet.Testing;
|
using Microsoft.AspNet.Testing;
|
||||||
using Microsoft.Data.Entity;
|
using Microsoft.Data.Entity;
|
||||||
using Microsoft.Data.Entity.Metadata;
|
using Microsoft.Data.Entity.Metadata;
|
||||||
using Microsoft.Data.Entity.Storage;
|
|
||||||
using Microsoft.Data.InMemory;
|
using Microsoft.Data.InMemory;
|
||||||
|
using Microsoft.Data.SqlServer;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
|
@ -35,37 +36,49 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
{
|
{
|
||||||
class ApplicationUserManager : UserManager<EntityUser>
|
class ApplicationUserManager : UserManager<EntityUser>
|
||||||
{
|
{
|
||||||
public ApplicationUserManager(IServiceProvider services) : base(services) { }
|
public ApplicationUserManager(IServiceProvider services, IUserStore<EntityUser> store, IOptionsAccessor<IdentityOptions> options) : base(services, store, options) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Fact] Disabled - see issue #48
|
[Fact]
|
||||||
public async Task CanUseAddedManagerInstance()
|
public async Task CanUseAddedManagerInstance()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
var store = new UserStore(new IdentityContext());
|
#if NET45
|
||||||
services.AddInstance<UserManager<EntityUser>>(new UserManager<EntityUser>(store));
|
// services.AddEntityFramework(s => s.AddSqlServer());
|
||||||
|
//#else
|
||||||
|
services.AddEntityFramework(s => s.AddInMemoryStore());
|
||||||
|
#endif
|
||||||
|
services.AddSingleton<IOptionsAccessor<IdentityOptions>, OptionsAccessor<IdentityOptions>>();
|
||||||
|
services.AddInstance<DbContext>(new IdentityContext());
|
||||||
|
services.AddTransient<IUserStore<EntityUser>, UserStore>();
|
||||||
|
services.AddSingleton<ApplicationUserManager, ApplicationUserManager>();
|
||||||
var provider = services.BuildServiceProvider();
|
var provider = services.BuildServiceProvider();
|
||||||
var manager = provider.GetService<UserManager<EntityUser>>();
|
var manager = provider.GetService<ApplicationUserManager>();
|
||||||
Assert.NotNull(manager);
|
Assert.NotNull(manager);
|
||||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityUser("hello")));
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityUser("hello")));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task CanUseSingletonManagerInstance()
|
public async Task CanCreateUsingAddUserManager()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
|
#if NET45
|
||||||
|
// services.AddEntityFramework(s => s.AddSqlServer());
|
||||||
|
//#else
|
||||||
|
services.AddEntityFramework(s => s.AddInMemoryStore());
|
||||||
|
#endif
|
||||||
|
// TODO: this needs to construct a new instance of InMemoryStore
|
||||||
var store = new UserStore(new IdentityContext());
|
var store = new UserStore(new IdentityContext());
|
||||||
services.AddIdentity<EntityUser, EntityRole>(s =>
|
services.AddIdentity<EntityUser, EntityRole>(s =>
|
||||||
{
|
{
|
||||||
s.UseUserStore(() => store);
|
s.AddUserStore(() => store);
|
||||||
s.UseUserManager<ApplicationUserManager>();
|
s.AddUserManager<ApplicationUserManager>();
|
||||||
});
|
});
|
||||||
//services.AddSingleton<ApplicationUserManager, ApplicationUserManager>();
|
|
||||||
|
|
||||||
var provider = services.BuildServiceProvider();
|
var provider = services.BuildServiceProvider();
|
||||||
var manager = provider.GetService<ApplicationUserManager>();
|
var manager = provider.GetService<ApplicationUserManager>();
|
||||||
Assert.NotNull(manager);
|
Assert.NotNull(manager);
|
||||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityUser("hello")));
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityUser("hello2")));
|
||||||
}
|
}
|
||||||
|
|
||||||
//[Fact]
|
//[Fact]
|
||||||
|
|
@ -308,7 +321,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
{
|
{
|
||||||
var manager = TestIdentityFactory.CreateManager();
|
var manager = TestIdentityFactory.CreateManager();
|
||||||
var user = new EntityUser("UpdateBlocked") { Email = email };
|
var user = new EntityUser("UpdateBlocked") { Email = email };
|
||||||
manager.UserValidator = new UserValidator<EntityUser> { RequireUniqueEmail = true };
|
manager.Options.User.RequireUniqueEmail = true;
|
||||||
IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email cannot be null or empty.");
|
IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email cannot be null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -320,7 +333,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
{
|
{
|
||||||
var manager = TestIdentityFactory.CreateManager();
|
var manager = TestIdentityFactory.CreateManager();
|
||||||
var user = new EntityUser("UpdateBlocked") { Email = email };
|
var user = new EntityUser("UpdateBlocked") { Email = email };
|
||||||
manager.UserValidator = new UserValidator<EntityUser> { RequireUniqueEmail = true };
|
manager.Options.User.RequireUniqueEmail = true;
|
||||||
IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email '" + email + "' is invalid.");
|
IdentityResultAssert.IsFailure(await manager.CreateAsync(user), "Email '" + email + "' is invalid.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -523,7 +536,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task AddDupeEmailFallsWhenUniqueEmailRequired()
|
public async Task AddDupeEmailFallsWhenUniqueEmailRequired()
|
||||||
{
|
{
|
||||||
var manager = TestIdentityFactory.CreateManager();
|
var manager = TestIdentityFactory.CreateManager();
|
||||||
manager.UserValidator = new UserValidator<EntityUser> { RequireUniqueEmail = true };
|
manager.Options.User.RequireUniqueEmail = true;
|
||||||
var user = new EntityUser("dupe") { Email = "yup@yup.com" };
|
var user = new EntityUser("dupe") { Email = "yup@yup.com" };
|
||||||
var user2 = new EntityUser("dupeEmail") { Email = "yup@yup.com" };
|
var user2 = new EntityUser("dupeEmail") { Email = "yup@yup.com" };
|
||||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
|
|
@ -618,10 +631,10 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
var claims = identity.Claims.ToList();
|
var claims = identity.Claims.ToList();
|
||||||
Assert.NotNull(claims);
|
Assert.NotNull(claims);
|
||||||
Assert.True(
|
Assert.True(
|
||||||
claims.Any(c => c.Type == claimsFactory.UserNameClaimType && c.Value == user.UserName));
|
claims.Any(c => c.Type == manager.Options.ClaimType.UserName && c.Value == user.UserName));
|
||||||
Assert.True(claims.Any(c => c.Type == claimsFactory.UserIdClaimType && c.Value == user.Id));
|
Assert.True(claims.Any(c => c.Type == manager.Options.ClaimType.UserId && c.Value == user.Id.ToString()));
|
||||||
Assert.True(claims.Any(c => c.Type == claimsFactory.RoleClaimType && c.Value == "Admin"));
|
Assert.True(claims.Any(c => c.Type == manager.Options.ClaimType.Role && c.Value == "Admin"));
|
||||||
Assert.True(claims.Any(c => c.Type == claimsFactory.RoleClaimType && c.Value == "Local"));
|
Assert.True(claims.Any(c => c.Type == manager.Options.ClaimType.Role && c.Value == "Local"));
|
||||||
foreach (var cl in userClaims)
|
foreach (var cl in userClaims)
|
||||||
{
|
{
|
||||||
Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
|
Assert.True(claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
|
||||||
|
|
@ -790,11 +803,9 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task SingleFailureLockout()
|
public async Task SingleFailureLockout()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||||
{
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1),
|
mgr.Options.Lockout.MaxFailedAccessAttempts = 0;
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
};
|
|
||||||
var user = new EntityUser("fastLockout");
|
var user = new EntityUser("fastLockout");
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -810,12 +821,9 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task TwoFailureLockout()
|
public async Task TwoFailureLockout()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||||
{
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1),
|
mgr.Options.Lockout.MaxFailedAccessAttempts = 2;
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
MaxFailedAccessAttemptsBeforeLockout = 2
|
|
||||||
};
|
|
||||||
var user = new EntityUser("twoFailureLockout");
|
var user = new EntityUser("twoFailureLockout");
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -835,12 +843,9 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task ResetAccessCountPreventsLockout()
|
public async Task ResetAccessCountPreventsLockout()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||||
{
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1),
|
mgr.Options.Lockout.MaxFailedAccessAttempts = 2;
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
MaxFailedAccessAttemptsBeforeLockout = 2
|
|
||||||
};
|
|
||||||
var user = new EntityUser("resetLockout");
|
var user = new EntityUser("resetLockout");
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -864,11 +869,8 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task CanEnableLockoutManuallyAndLockout()
|
public async Task CanEnableLockoutManuallyAndLockout()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||||
{
|
mgr.Options.Lockout.MaxFailedAccessAttempts = 2;
|
||||||
DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1),
|
|
||||||
MaxFailedAccessAttemptsBeforeLockout = 2
|
|
||||||
};
|
|
||||||
var user = new EntityUser("manualLockout");
|
var user = new EntityUser("manualLockout");
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.False(await mgr.GetLockoutEnabledAsync(user));
|
Assert.False(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -891,10 +893,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task UserNotLockedOutWithNullDateTimeAndIsSetToNullDate()
|
public async Task UserNotLockedOutWithNullDateTimeAndIsSetToNullDate()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
{
|
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
};
|
|
||||||
var user = new EntityUser("LockoutTest");
|
var user = new EntityUser("LockoutTest");
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -922,10 +921,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut()
|
public async Task LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
{
|
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
};
|
|
||||||
var user = new EntityUser("LockoutUtcNowTest") { LockoutEnd = DateTime.UtcNow.AddSeconds(-1) };
|
var user = new EntityUser("LockoutUtcNowTest") { LockoutEnd = DateTime.UtcNow.AddSeconds(-1) };
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -937,10 +933,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut()
|
public async Task LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
{
|
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
};
|
|
||||||
var user = new EntityUser("LockoutUtcNowTest");
|
var user = new EntityUser("LockoutUtcNowTest");
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -953,10 +946,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut()
|
public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
{
|
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
};
|
|
||||||
var user = new EntityUser("LockoutUtcNowTest") { LockoutEnd = DateTime.UtcNow.AddMinutes(5) };
|
var user = new EntityUser("LockoutUtcNowTest") { LockoutEnd = DateTime.UtcNow.AddMinutes(5) };
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -968,10 +958,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
public async Task UserLockedOutWithDateTimeLocalKindNowPlus30()
|
public async Task UserLockedOutWithDateTimeLocalKindNowPlus30()
|
||||||
{
|
{
|
||||||
var mgr = TestIdentityFactory.CreateManager();
|
var mgr = TestIdentityFactory.CreateManager();
|
||||||
mgr.LockoutPolicy = new LockoutPolicy
|
mgr.Options.Lockout.EnabledByDefault = true;
|
||||||
{
|
|
||||||
UserLockoutEnabledByDefault = true,
|
|
||||||
};
|
|
||||||
var user = new EntityUser("LockoutTest");
|
var user = new EntityUser("LockoutTest");
|
||||||
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await mgr.CreateAsync(user));
|
||||||
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
Assert.True(await mgr.GetLockoutEnabledAsync(user));
|
||||||
|
|
@ -995,11 +982,11 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AlwaysBadValidator : IUserValidator<EntityUser>, IRoleValidator<EntityRole>,
|
private class AlwaysBadValidator : IUserValidator<EntityUser>, IRoleValidator<EntityRole>,
|
||||||
IPasswordValidator
|
IPasswordValidator<EntityUser>
|
||||||
{
|
{
|
||||||
public const string ErrorMessage = "I'm Bad.";
|
public const string ErrorMessage = "I'm Bad.";
|
||||||
|
|
||||||
public Task<IdentityResult> ValidateAsync(string password, CancellationToken token)
|
public Task<IdentityResult> ValidateAsync(string password, UserManager<EntityUser> manager,CancellationToken token)
|
||||||
{
|
{
|
||||||
return Task.FromResult(IdentityResult.Failed(ErrorMessage));
|
return Task.FromResult(IdentityResult.Failed(ErrorMessage));
|
||||||
}
|
}
|
||||||
|
|
@ -1326,7 +1313,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
||||||
{
|
{
|
||||||
var manager = TestIdentityFactory.CreateManager();
|
var manager = TestIdentityFactory.CreateManager();
|
||||||
const string userName = "PhoneTest";
|
const string userName = "PhoneTest";
|
||||||
var user = new EntityUser(userName) {PhoneNumber = "123-456-7890"};
|
var user = new EntityUser(userName) { PhoneNumber = "123-456-7890" };
|
||||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||||
var stamp = await manager.GetSecurityStampAsync(user);
|
var stamp = await manager.GetSecurityStampAsync(user);
|
||||||
Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890");
|
Assert.Equal(await manager.GetPhoneNumberAsync(user), "123-456-7890");
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"version": "0.1-alpha-*",
|
"version": "0.1-alpha-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.Bcl.Immutable": "1.1.18-beta-*",
|
"Microsoft.AspNet.Abstractions": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.DependencyInjection": "0.1-alpha-*",
|
|
||||||
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.DependencyInjection": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Identity": "",
|
"Microsoft.AspNet.Identity": "",
|
||||||
"Microsoft.AspNet.Identity.Entity": "",
|
"Microsoft.AspNet.Identity.Entity": "",
|
||||||
"Microsoft.AspNet.PipelineCore": "0.1-alpha-*",
|
"Microsoft.AspNet.PipelineCore": "0.1-alpha-*",
|
||||||
|
|
@ -11,9 +11,12 @@
|
||||||
"Microsoft.AspNet.RequestContainer": "0.1-alpha-*",
|
"Microsoft.AspNet.RequestContainer": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*",
|
"Microsoft.AspNet.Security.DataProtection": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Testing": "0.1-alpha-*",
|
"Microsoft.AspNet.Testing": "0.1-alpha-*",
|
||||||
|
"Microsoft.Bcl.Immutable": "1.1.18-beta-*",
|
||||||
"Microsoft.Data.Entity": "0.1-alpha-*",
|
"Microsoft.Data.Entity": "0.1-alpha-*",
|
||||||
"Microsoft.Data.InMemory": "0.1-alpha-*",
|
"Microsoft.Data.InMemory": "0.1-alpha-*",
|
||||||
|
"Microsoft.Data.Migrations": "0.1-alpha-*",
|
||||||
"Microsoft.Data.Relational": "0.1-alpha-*",
|
"Microsoft.Data.Relational": "0.1-alpha-*",
|
||||||
|
"Microsoft.Data.SqlServer": "0.1-alpha-*",
|
||||||
"Remotion.Linq": "1.15.13.0",
|
"Remotion.Linq": "1.15.13.0",
|
||||||
"System.Security.Claims": "0.1-alpha-*",
|
"System.Security.Claims": "0.1-alpha-*",
|
||||||
"Xunit.KRunner": "0.1-alpha-*",
|
"Xunit.KRunner": "0.1-alpha-*",
|
||||||
|
|
@ -22,9 +25,11 @@
|
||||||
"xunit.core": "2.0.0-aspnet-*",
|
"xunit.core": "2.0.0-aspnet-*",
|
||||||
"xunit.execution": "2.0.0-aspnet-*"
|
"xunit.execution": "2.0.0-aspnet-*"
|
||||||
},
|
},
|
||||||
|
"code": "**\\*.cs;..\\Shared\\*.cs",
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"net45": {
|
"net45": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"Moq" : "4.2.1312.1622",
|
||||||
"System.Runtime": "",
|
"System.Runtime": "",
|
||||||
"System.Collections": "",
|
"System.Collections": "",
|
||||||
"System.Data": ""
|
"System.Data": ""
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -23,6 +23,10 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="IdentityResultAssert.cs" />
|
<Compile Include="IdentityResultAssert.cs" />
|
||||||
<Compile Include="InMemoryStoreTest.cs" />
|
<Compile Include="InMemoryStoreTest.cs" />
|
||||||
|
<Compile Include="StartupTest.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
using Microsoft.AspNet.DependencyInjection;
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
using Microsoft.AspNet.DependencyInjection.Fallback;
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
|
using Microsoft.AspNet.Identity.Test;
|
||||||
using Microsoft.AspNet.PipelineCore;
|
using Microsoft.AspNet.PipelineCore;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -27,23 +28,78 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
||||||
{
|
{
|
||||||
public class StartupTest
|
public class StartupTest
|
||||||
{
|
{
|
||||||
|
public class ApplicationUser : IdentityUser { }
|
||||||
|
|
||||||
|
public class ApplicationUserManager : UserManager<ApplicationUser>
|
||||||
|
{
|
||||||
|
public ApplicationUserManager(IServiceProvider services, IUserStore<ApplicationUser> store, IOptionsAccessor<IdentityOptions> options) : base(services, store, options) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PasswordsNegativeLengthSetup : IOptionsSetup<IdentityOptions>
|
||||||
|
{
|
||||||
|
public int Order { get { return 0; } }
|
||||||
|
public void Setup(IdentityOptions options)
|
||||||
|
{
|
||||||
|
options.Password.RequiredLength = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanCustomizeIdentityOptions()
|
||||||
|
{
|
||||||
|
IBuilder builder = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
builder.UseServices(services => {
|
||||||
|
services.AddIdentity<IdentityUser>(identityServices => { });
|
||||||
|
services.AddSetup<PasswordsNegativeLengthSetup>();
|
||||||
|
});
|
||||||
|
|
||||||
|
var setup = builder.ApplicationServices.GetService<IOptionsSetup<IdentityOptions>>();
|
||||||
|
Assert.IsType(typeof(PasswordsNegativeLengthSetup), setup);
|
||||||
|
var optionsGetter = builder.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>();
|
||||||
|
Assert.NotNull(optionsGetter);
|
||||||
|
setup.Setup(optionsGetter.Options);
|
||||||
|
|
||||||
|
var myOptions = optionsGetter.Options;
|
||||||
|
Assert.True(myOptions.Password.RequireLowercase);
|
||||||
|
Assert.True(myOptions.Password.RequireDigit);
|
||||||
|
Assert.True(myOptions.Password.RequireNonLetterOrDigit);
|
||||||
|
Assert.True(myOptions.Password.RequireUppercase);
|
||||||
|
Assert.Equal(-1, myOptions.Password.RequiredLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CanSetupIdentityOptions()
|
||||||
|
{
|
||||||
|
IBuilder app = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
app.UseServices(services => services.AddIdentity<IdentityUser>(identityServices => identityServices.SetupOptions(options => options.User.RequireUniqueEmail = true)));
|
||||||
|
|
||||||
|
var optionsGetter = app.ApplicationServices.GetService<IOptionsAccessor<IdentityOptions>>();
|
||||||
|
Assert.NotNull(optionsGetter);
|
||||||
|
|
||||||
|
var myOptions = optionsGetter.Options;
|
||||||
|
Assert.True(myOptions.User.RequireUniqueEmail);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task EnsureStartupUsageWorks()
|
public async Task EnsureStartupUsageWorks()
|
||||||
{
|
{
|
||||||
IBuilder builder = new Builder(new ServiceCollection().BuildServiceProvider());
|
IBuilder builder = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
|
||||||
|
//builder.UseServices(services => services.AddIdentity<ApplicationUser>(s =>
|
||||||
|
// s.AddEntity<ApplicationDbContext>()
|
||||||
|
//{
|
||||||
|
|
||||||
builder.UseServices(services => services.AddIdentity<ApplicationUser>(s =>
|
builder.UseServices(services => services.AddIdentity<ApplicationUser>(s =>
|
||||||
{
|
{
|
||||||
s.UseUserStore(() => new InMemoryUserStore<ApplicationUser>());
|
s.AddInMemory();
|
||||||
s.UseUserManager<ApplicationUserManager>();
|
s.AddUserManager<ApplicationUserManager>();
|
||||||
s.UseRoleStore(() => new InMemoryRoleStore<IdentityRole>());
|
s.AddRoleManager<ApplicationRoleManager>();
|
||||||
s.UseRoleManager<ApplicationRoleManager>();
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
var userStore = builder.ApplicationServices.GetService<IUserStore<ApplicationUser>>();
|
var userStore = builder.ApplicationServices.GetService<IUserStore<ApplicationUser>>();
|
||||||
var roleStore = builder.ApplicationServices.GetService<IRoleStore<IdentityRole>>();
|
var roleStore = builder.ApplicationServices.GetService<IRoleStore<IdentityRole>>();
|
||||||
var userManager = builder.ApplicationServices.GetService<ApplicationUserManager>();
|
var userManager = builder.ApplicationServices.GetService<ApplicationUserManager>();
|
||||||
|
//TODO: var userManager = builder.ApplicationServices.GetService<UserManager<IdentityUser>();
|
||||||
var roleManager = builder.ApplicationServices.GetService<ApplicationRoleManager>();
|
var roleManager = builder.ApplicationServices.GetService<ApplicationRoleManager>();
|
||||||
|
|
||||||
Assert.NotNull(userStore);
|
Assert.NotNull(userStore);
|
||||||
|
|
@ -67,21 +123,5 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
||||||
IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(new IdentityRole { Name = roleName }));
|
IdentityResultAssert.IsSuccess(await roleManager.CreateAsync(new IdentityRole { Name = roleName }));
|
||||||
IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(user, roleName));
|
IdentityResultAssert.IsSuccess(await userManager.AddToRoleAsync(user, roleName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class ApplicationUserManager : UserManager<ApplicationUser>
|
|
||||||
{
|
|
||||||
public ApplicationUserManager(IServiceProvider services) : base(services) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ApplicationRoleManager : RoleManager<IdentityRole>
|
|
||||||
{
|
|
||||||
public ApplicationRoleManager(IServiceProvider services) : base(services) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ApplicationUser : IdentityUser
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"version": "0.1-alpha-*",
|
"version": "0.1-alpha-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Abstractions" : "0.1-alpha-*",
|
"Microsoft.AspNet.Abstractions" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.ConfigurationModel" : "0.1-alpha-*",
|
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Identity" : "0.1-alpha-*",
|
"Microsoft.AspNet.Identity" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Identity.InMemory" : "0.1-alpha-*",
|
"Microsoft.AspNet.Identity.InMemory" : "0.1-alpha-*",
|
||||||
|
|
@ -15,9 +15,11 @@
|
||||||
"xunit.core": "2.0.0-aspnet-*",
|
"xunit.core": "2.0.0-aspnet-*",
|
||||||
"xunit.execution": "2.0.0-aspnet-*"
|
"xunit.execution": "2.0.0-aspnet-*"
|
||||||
},
|
},
|
||||||
|
"code": "**\\*.cs;..\\Shared\\*.cs",
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"net45": {
|
"net45": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"Moq" : "4.2.1312.1622",
|
||||||
"System.Runtime": "",
|
"System.Runtime": "",
|
||||||
"System.Collections": ""
|
"System.Collections": ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,12 @@
|
||||||
<Content Include="Project.json" />
|
<Content Include="Project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="IdentityExtensionsTest.cs" />
|
||||||
<Compile Include="SignInManagerTest.cs" />
|
<Compile Include="SignInManagerTest.cs" />
|
||||||
<Compile Include="TestUser.cs" />
|
<Compile Include="TestUser.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -15,9 +15,18 @@
|
||||||
// See the Apache 2 License for the specific language governing
|
// See the Apache 2 License for the specific language governing
|
||||||
// permissions and limitations under the License.
|
// permissions and limitations under the License.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.AspNet.Abstractions;
|
using Microsoft.AspNet.Abstractions;
|
||||||
using Microsoft.AspNet.Abstractions.Security;
|
using Microsoft.AspNet.Abstractions.Security;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
|
using Microsoft.AspNet.Identity.InMemory;
|
||||||
|
using Microsoft.AspNet.Identity.Test;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.Logging;
|
||||||
|
using Microsoft.AspNet.PipelineCore;
|
||||||
|
using Microsoft.AspNet.FeatureModel;
|
||||||
|
using Microsoft.AspNet.Security.Cookies;
|
||||||
using Moq;
|
using Moq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -27,16 +36,117 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
{
|
{
|
||||||
public class SignInManagerTest
|
public class SignInManagerTest
|
||||||
{
|
{
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
|
[Theory]
|
||||||
|
[InlineData(true)]
|
||||||
|
[InlineData(false)]
|
||||||
|
public async Task VerifyAccountControllerSignIn(bool isPersistent)
|
||||||
|
{
|
||||||
|
IBuilder app = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
app.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||||
|
{
|
||||||
|
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
|
||||||
|
});
|
||||||
|
|
||||||
|
var context = new Mock<HttpContext>();
|
||||||
|
var response = new Mock<HttpResponse>();
|
||||||
|
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||||
|
response.Setup(r => r.SignIn(It.IsAny<ClaimsIdentity>(), It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent))).Verifiable();
|
||||||
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
app.UseServices(services =>
|
||||||
|
{
|
||||||
|
services.AddInstance(contextAccessor.Object);
|
||||||
|
services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
|
||||||
|
services.AddIdentity<ApplicationUser, IdentityRole>(s =>
|
||||||
|
{
|
||||||
|
s.AddInMemory();
|
||||||
|
s.AddUserManager<ApplicationUserManager>();
|
||||||
|
s.AddRoleManager<ApplicationRoleManager>();
|
||||||
|
});
|
||||||
|
services.AddTransient<ApplicationSignInManager>();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var user = new ApplicationUser
|
||||||
|
{
|
||||||
|
UserName = "Yolo"
|
||||||
|
};
|
||||||
|
const string password = "Yol0Sw@g!";
|
||||||
|
var userManager = app.ApplicationServices.GetService<ApplicationUserManager>();
|
||||||
|
var signInManager = app.ApplicationServices.GetService<ApplicationSignInManager>();
|
||||||
|
|
||||||
|
IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password));
|
||||||
|
var result = await signInManager.PasswordSignInAsync(user.UserName, password, isPersistent, false);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(SignInStatus.Success, result);
|
||||||
|
context.VerifyAll();
|
||||||
|
response.VerifyAll();
|
||||||
|
contextAccessor.VerifyAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
//[Theory]
|
||||||
|
//[InlineData(true)]
|
||||||
|
//[InlineData(false)]
|
||||||
|
//public async Task VerifyAccountControllerSignInFunctional(bool isPersistent)
|
||||||
|
//{
|
||||||
|
// IBuilder app = new Builder(new ServiceCollection().BuildServiceProvider());
|
||||||
|
// app.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||||
|
// {
|
||||||
|
// AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie
|
||||||
|
// });
|
||||||
|
|
||||||
|
// TODO: how to functionally test context?
|
||||||
|
// var context = new DefaultHttpContext(new FeatureCollection());
|
||||||
|
// var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
// contextAccessor.Setup(a => a.Value).Returns(context);
|
||||||
|
// app.UseServices(services =>
|
||||||
|
// {
|
||||||
|
// services.AddInstance(contextAccessor.Object);
|
||||||
|
// services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
|
||||||
|
// services.AddIdentity<ApplicationUser, IdentityRole>(s =>
|
||||||
|
// {
|
||||||
|
// s.AddUserStore(() => new InMemoryUserStore<ApplicationUser>());
|
||||||
|
// s.AddUserManager<ApplicationUserManager>();
|
||||||
|
// s.AddRoleStore(() => new InMemoryRoleStore<IdentityRole>());
|
||||||
|
// s.AddRoleManager<ApplicationRoleManager>();
|
||||||
|
// });
|
||||||
|
// services.AddTransient<ApplicationSignInManager>();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // Act
|
||||||
|
// var user = new ApplicationUser
|
||||||
|
// {
|
||||||
|
// UserName = "Yolo"
|
||||||
|
// };
|
||||||
|
// const string password = "Yol0Sw@g!";
|
||||||
|
// var userManager = app.ApplicationServices.GetService<ApplicationUserManager>();
|
||||||
|
// var signInManager = app.ApplicationServices.GetService<ApplicationSignInManager>();
|
||||||
|
|
||||||
|
// IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password));
|
||||||
|
// var result = await signInManager.PasswordSignInAsync(user.UserName, password, isPersistent, false);
|
||||||
|
|
||||||
|
// // Assert
|
||||||
|
// Assert.Equal(SignInStatus.Success, result);
|
||||||
|
// contextAccessor.VerifyAll();
|
||||||
|
//}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ConstructorNullChecks()
|
||||||
|
{
|
||||||
|
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<IdentityUser>(null, null));
|
||||||
|
var userManager = MockHelpers.MockUserManager<IdentityUser>().Object;
|
||||||
|
Assert.Throws<ArgumentNullException>("contextAccessor", () => new SignInManager<IdentityUser>(userManager, null));
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: Mock fails in K (this works fine in net45)
|
//TODO: Mock fails in K (this works fine in net45)
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task EnsureClaimsIdentityFactoryCreateIdentityCalled()
|
public async Task EnsureClaimsIdentityFactoryCreateIdentityCalled()
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var store = new Mock<IUserStore<TestUser>>();
|
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
var userManager = new UserManager<TestUser>(store.Object);
|
var userManager = MockHelpers.TestUserManager<TestUser>();
|
||||||
var identityFactory = new Mock<IClaimsIdentityFactory<TestUser>>();
|
var identityFactory = new Mock<IClaimsIdentityFactory<TestUser>>();
|
||||||
const string authType = "Test";
|
const string authType = "Test";
|
||||||
var testIdentity = new ClaimsIdentity(authType);
|
var testIdentity = new ClaimsIdentity(authType);
|
||||||
|
|
@ -46,13 +156,21 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
var response = new Mock<HttpResponse>();
|
var response = new Mock<HttpResponse>();
|
||||||
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||||
response.Setup(r => r.SignIn(testIdentity, It.IsAny<AuthenticationProperties>())).Verifiable();
|
response.Setup(r => r.SignIn(testIdentity, It.IsAny<AuthenticationProperties>())).Verifiable();
|
||||||
var helper = new SignInManager<TestUser> { UserManager = userManager, AuthenticationType = authType, Context = context.Object };
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
var helper = new SignInManager<TestUser>(userManager, contextAccessor.Object)
|
||||||
|
{
|
||||||
|
AuthenticationType = authType
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
await helper.SignInAsync(user, false, false);
|
await helper.SignInAsync(user, false, false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
identityFactory.VerifyAll();
|
identityFactory.VerifyAll();
|
||||||
|
context.VerifyAll();
|
||||||
|
contextAccessor.VerifyAll();
|
||||||
|
response.VerifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -60,10 +178,13 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
var manager = new Mock<UserManager<TestUser>>();
|
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||||
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
||||||
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
||||||
var helper = new SignInManager<TestUser> { UserManager = manager.Object };
|
var context = new Mock<HttpContext>();
|
||||||
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
||||||
|
|
@ -73,12 +194,14 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
manager.VerifyAll();
|
manager.VerifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task CanPasswordSignIn()
|
[InlineData(true)]
|
||||||
|
[InlineData(false)]
|
||||||
|
public async Task CanPasswordSignIn(bool isPersistent)
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
var manager = new Mock<UserManager<TestUser>>();
|
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||||
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
||||||
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
||||||
manager.Setup(m => m.CheckPasswordAsync(user, "password", CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
manager.Setup(m => m.CheckPasswordAsync(user, "password", CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
||||||
|
|
@ -86,28 +209,39 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
var context = new Mock<HttpContext>();
|
var context = new Mock<HttpContext>();
|
||||||
var response = new Mock<HttpResponse>();
|
var response = new Mock<HttpResponse>();
|
||||||
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||||
response.Setup(r => r.SignIn(It.IsAny<ClaimsIdentity>(), It.IsAny<AuthenticationProperties>())).Verifiable();
|
response.Setup(r => r.SignIn(It.IsAny<ClaimsIdentity>(), It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent))).Verifiable();
|
||||||
var helper = new SignInManager<TestUser> { UserManager = manager.Object, Context = context.Object };
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
|
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal(SignInStatus.Success, result);
|
Assert.Equal(SignInStatus.Success, result);
|
||||||
manager.VerifyAll();
|
manager.VerifyAll();
|
||||||
|
context.VerifyAll();
|
||||||
|
response.VerifyAll();
|
||||||
|
contextAccessor.VerifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
[InlineData(DefaultAuthenticationTypes.ApplicationCookie)]
|
[InlineData("Microsoft.AspNet.Identity.Security.Application")]
|
||||||
[InlineData("Foo")]
|
[InlineData("Foo")]
|
||||||
public void SignOutCallsContextResponseSignOut(string authenticationType)
|
public void SignOutCallsContextResponseSignOut(string authenticationType)
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
|
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||||
var context = new Mock<HttpContext>();
|
var context = new Mock<HttpContext>();
|
||||||
var response = new Mock<HttpResponse>();
|
var response = new Mock<HttpResponse>();
|
||||||
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||||
response.Setup(r => r.SignOut(authenticationType)).Verifiable();
|
response.Setup(r => r.SignOut(authenticationType)).Verifiable();
|
||||||
var helper = new SignInManager<TestUser> { Context = context.Object, AuthenticationType = authenticationType };
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object)
|
||||||
|
{
|
||||||
|
AuthenticationType = authenticationType
|
||||||
|
};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
helper.SignOut();
|
helper.SignOut();
|
||||||
|
|
@ -122,12 +256,14 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
var manager = new Mock<UserManager<TestUser>>();
|
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||||
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
||||||
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
||||||
manager.Setup(m => m.CheckPasswordAsync(user, "bogus", CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
manager.Setup(m => m.CheckPasswordAsync(user, "bogus", CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
||||||
var helper = new SignInManager<TestUser> { UserManager = manager.Object };
|
var context = new Mock<HttpContext>();
|
||||||
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object);
|
||||||
// Act
|
// Act
|
||||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
||||||
|
|
||||||
|
|
@ -141,9 +277,12 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
public async Task PasswordSignInFailsWithUnknownUser()
|
public async Task PasswordSignInFailsWithUnknownUser()
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var manager = new Mock<UserManager<TestUser>>();
|
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||||
manager.Setup(m => m.FindByNameAsync("bogus", CancellationToken.None)).ReturnsAsync(null).Verifiable();
|
manager.Setup(m => m.FindByNameAsync("bogus", CancellationToken.None)).ReturnsAsync(null).Verifiable();
|
||||||
var helper = new SignInManager<TestUser> { UserManager = manager.Object };
|
var context = new Mock<HttpContext>();
|
||||||
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
|
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
|
||||||
|
|
@ -153,60 +292,12 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
manager.VerifyAll();
|
manager.VerifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task PasswordSignInFailsWithNoUserManager()
|
|
||||||
{
|
|
||||||
// Setup
|
|
||||||
var helper = new SignInManager<TestUser>();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(SignInStatus.Failure, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SignInWithNoContextDoesNotBlowUp()
|
|
||||||
{
|
|
||||||
// Setup
|
|
||||||
var helper = new SignInManager<TestUser>();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
await helper.SignInAsync(null, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void SignOutWithNoContextDoesNotBlowUp()
|
|
||||||
{
|
|
||||||
// Setup
|
|
||||||
var helper = new SignInManager<TestUser>();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
helper.SignOut();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task CreateUserIdentityReturnsNullNoUserManager()
|
|
||||||
{
|
|
||||||
// Setup
|
|
||||||
var user = new TestUser();
|
|
||||||
var helper = new SignInManager<TestUser>();
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var result = await helper.CreateUserIdentityAsync(user);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Null(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PasswordSignInFailsWithWrongPasswordCanAccessFailedAndLockout()
|
public async Task PasswordSignInFailsWithWrongPasswordCanAccessFailedAndLockout()
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
var manager = new Mock<UserManager<TestUser>>();
|
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||||
var lockedout = false;
|
var lockedout = false;
|
||||||
manager.Setup(m => m.AccessFailedAsync(user, CancellationToken.None)).Returns(() =>
|
manager.Setup(m => m.AccessFailedAsync(user, CancellationToken.None)).Returns(() =>
|
||||||
{
|
{
|
||||||
|
|
@ -216,7 +307,10 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).Returns(() => Task.FromResult(lockedout));
|
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).Returns(() => Task.FromResult(lockedout));
|
||||||
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
manager.Setup(m => m.FindByNameAsync(user.UserName, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
||||||
manager.Setup(m => m.CheckPasswordAsync(user, "bogus", CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
manager.Setup(m => m.CheckPasswordAsync(user, "bogus", CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
||||||
var helper = new SignInManager<TestUser> { UserManager = manager.Object };
|
var context = new Mock<HttpContext>();
|
||||||
|
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||||
|
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||||
|
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);
|
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);
|
||||||
|
|
@ -226,5 +320,30 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
||||||
manager.VerifyAll();
|
manager.VerifyAll();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
public class ApplicationSignInManager : SignInManager<ApplicationUser>
|
||||||
|
{
|
||||||
|
public ApplicationSignInManager(ApplicationUserManager manager, IContextAccessor<HttpContext> contextAccessor)
|
||||||
|
: base(manager, contextAccessor)
|
||||||
|
{
|
||||||
|
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NullLoggerFactory : ILoggerFactory
|
||||||
|
{
|
||||||
|
public ILogger Create(string name)
|
||||||
|
{
|
||||||
|
return new NullLogger();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NullLogger : ILogger
|
||||||
|
{
|
||||||
|
public bool WriteCore(TraceType eventType, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,10 +2,18 @@
|
||||||
"version": "0.1-alpha-*",
|
"version": "0.1-alpha-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Abstractions" : "0.1-alpha-*",
|
"Microsoft.AspNet.Abstractions" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.ConfigurationModel" : "0.1-alpha-*",
|
"Microsoft.AspNet.ConfigurationModel": "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Identity" : "",
|
"Microsoft.AspNet.Identity" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Identity.Security" : "",
|
"Microsoft.AspNet.Identity.InMemory" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.Identity.Security" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.Logging" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.HttpFeature" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.FeatureModel" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.PipelineCore" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.RequestContainer" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.Security" : "0.1-alpha-*",
|
||||||
|
"Microsoft.AspNet.Security.Cookies" : "0.1-alpha-*",
|
||||||
"Microsoft.AspNet.Testing" : "0.1-alpha-*",
|
"Microsoft.AspNet.Testing" : "0.1-alpha-*",
|
||||||
"System.Security.Claims" : "0.1-alpha-*",
|
"System.Security.Claims" : "0.1-alpha-*",
|
||||||
"Xunit.KRunner": "0.1-alpha-*",
|
"Xunit.KRunner": "0.1-alpha-*",
|
||||||
|
|
@ -14,6 +22,7 @@
|
||||||
"xunit.core": "2.0.0-aspnet-*",
|
"xunit.core": "2.0.0-aspnet-*",
|
||||||
"xunit.execution": "2.0.0-aspnet-*"
|
"xunit.execution": "2.0.0-aspnet-*"
|
||||||
},
|
},
|
||||||
|
"code": "**\\*.cs;..\\Shared\\*.cs",
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"net45": {
|
"net45": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -31,7 +33,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task CreateIdentityNullChecks()
|
public async Task CreateIdentityNullChecks()
|
||||||
{
|
{
|
||||||
var factory = new ClaimsIdentityFactory<TestUser>();
|
var factory = new ClaimsIdentityFactory<TestUser>();
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.MockUserManager<TestUser>().Object;
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("manager",
|
await Assert.ThrowsAsync<ArgumentNullException>("manager",
|
||||||
async () => await factory.CreateAsync(null, null, "whatever"));
|
async () => await factory.CreateAsync(null, null, "whatever"));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
|
|
@ -50,7 +52,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task EnsureClaimsIdentityHasExpectedClaims(bool supportRoles, bool supportClaims)
|
public async Task EnsureClaimsIdentityHasExpectedClaims(bool supportRoles, bool supportClaims)
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var userManager = new Mock<UserManager<TestUser>>();
|
var userManager = MockHelpers.MockUserManager<TestUser>();
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
userManager.Setup(m => m.SupportsUserRole).Returns(supportRoles);
|
userManager.Setup(m => m.SupportsUserRole).Returns(supportRoles);
|
||||||
userManager.Setup(m => m.SupportsUserClaim).Returns(supportClaims);
|
userManager.Setup(m => m.SupportsUserClaim).Returns(supportClaims);
|
||||||
|
|
@ -60,6 +62,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
userManager.Setup(m => m.GetRolesAsync(user, CancellationToken.None)).ReturnsAsync(roleClaims);
|
userManager.Setup(m => m.GetRolesAsync(user, CancellationToken.None)).ReturnsAsync(roleClaims);
|
||||||
var userClaims = new[] { new Claim("Whatever", "Value"), new Claim("Whatever2", "Value2") };
|
var userClaims = new[] { new Claim("Whatever", "Value"), new Claim("Whatever2", "Value2") };
|
||||||
userManager.Setup(m => m.GetClaimsAsync(user, CancellationToken.None)).ReturnsAsync(userClaims);
|
userManager.Setup(m => m.GetClaimsAsync(user, CancellationToken.None)).ReturnsAsync(userClaims);
|
||||||
|
userManager.Object.Options = new IdentityOptions();
|
||||||
|
|
||||||
const string authType = "Microsoft.AspNet.Identity";
|
const string authType = "Microsoft.AspNet.Identity";
|
||||||
var factory = new ClaimsIdentityFactory<TestUser>();
|
var factory = new ClaimsIdentityFactory<TestUser>();
|
||||||
|
|
@ -68,15 +71,16 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
var identity = await factory.CreateAsync(userManager.Object, user, authType);
|
var identity = await factory.CreateAsync(userManager.Object, user, authType);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
var manager = userManager.Object;
|
||||||
Assert.NotNull(identity);
|
Assert.NotNull(identity);
|
||||||
Assert.Equal(authType, identity.AuthenticationType);
|
Assert.Equal(authType, identity.AuthenticationType);
|
||||||
var claims = identity.Claims.ToList();
|
var claims = identity.Claims.ToList();
|
||||||
Assert.NotNull(claims);
|
Assert.NotNull(claims);
|
||||||
Assert.True(
|
Assert.True(
|
||||||
claims.Any(c => c.Type == factory.UserNameClaimType && c.Value == user.UserName));
|
claims.Any(c => c.Type == manager.Options.ClaimType.UserName && c.Value == user.UserName));
|
||||||
Assert.True(claims.Any(c => c.Type == factory.UserIdClaimType && c.Value == user.Id));
|
Assert.True(claims.Any(c => c.Type == manager.Options.ClaimType.UserId && c.Value == user.Id));
|
||||||
Assert.Equal(supportRoles, claims.Any(c => c.Type == factory.RoleClaimType && c.Value == "Admin"));
|
Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimType.Role && c.Value == "Admin"));
|
||||||
Assert.Equal(supportRoles, claims.Any(c => c.Type == factory.RoleClaimType && c.Value == "Local"));
|
Assert.Equal(supportRoles, claims.Any(c => c.Type == manager.Options.ClaimType.Role && c.Value == "Local"));
|
||||||
foreach (var cl in userClaims)
|
foreach (var cl in userClaims)
|
||||||
{
|
{
|
||||||
Assert.Equal(supportClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
|
Assert.Equal(supportClaims, claims.Any(c => c.Type == cl.Type && c.Value == cl.Value));
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
var validator = new UserValidator<IdentityUser>();
|
var validator = new UserValidator<IdentityUser>();
|
||||||
services.AddIdentity<IdentityUser>(b => b.UseUserValidator(() => validator));
|
services.AddIdentity<IdentityUser>(b => b.AddUserValidator(() => validator));
|
||||||
Assert.Equal(validator, services.BuildServiceProvider().GetService<IUserValidator<IdentityUser>>());
|
Assert.Equal(validator, services.BuildServiceProvider().GetService<IUserValidator<IdentityUser>>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,69 +37,47 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public void CanSpecifyPasswordValidatorInstance()
|
public void CanSpecifyPasswordValidatorInstance()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
var validator = new PasswordValidator();
|
var validator = new PasswordValidator<IdentityUser>();
|
||||||
services.AddIdentity<IdentityUser>(b => b.UsePasswordValidator(() => validator));
|
services.AddIdentity<IdentityUser>(b => b.AddPasswordValidator(() => validator));
|
||||||
Assert.Equal(validator, services.BuildServiceProvider().GetService<IPasswordValidator>());
|
Assert.Equal(validator, services.BuildServiceProvider().GetService<IPasswordValidator<IdentityUser>>());
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public void CanSpecifyLockoutPolicyInstance()
|
|
||||||
{
|
|
||||||
var services = new ServiceCollection();
|
|
||||||
var policy = new LockoutPolicy();
|
|
||||||
services.AddIdentity<IdentityUser>(b => b.UseLockoutPolicy(() => policy));
|
|
||||||
Assert.Equal(policy, services.BuildServiceProvider().GetService<LockoutPolicy>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void CanSpecifyPasswordHasherInstance()
|
public void CanSpecifyPasswordHasherInstance()
|
||||||
{
|
{
|
||||||
CanOverride<IPasswordHasher, PasswordHasher>();
|
CanOverride<IPasswordHasher>(new PasswordHasher());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void CanSpecifyClaimsIdentityFactoryInstance()
|
public void CanSpecifyClaimsIdentityFactoryInstance()
|
||||||
{
|
{
|
||||||
CanOverride<IClaimsIdentityFactory<IdentityUser>, ClaimsIdentityFactory<IdentityUser>>();
|
CanOverride<IClaimsIdentityFactory<IdentityUser>>(new ClaimsIdentityFactory<IdentityUser>());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void EnsureDefaultServices()
|
public void EnsureDefaultServices()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
var builder = new IdentityBuilder<IdentityUser, IdentityRole>(services);
|
services.AddIdentity<IdentityUser>(identity => { });
|
||||||
builder.UseIdentity();
|
|
||||||
|
|
||||||
var provider = services.BuildServiceProvider();
|
var provider = services.BuildServiceProvider();
|
||||||
var userValidator = provider.GetService<IUserValidator<IdentityUser>>() as UserValidator<IdentityUser>;
|
var userValidator = provider.GetService<IUserValidator<IdentityUser>>() as UserValidator<IdentityUser>;
|
||||||
Assert.NotNull(userValidator);
|
Assert.NotNull(userValidator);
|
||||||
Assert.True(userValidator.AllowOnlyAlphanumericUserNames);
|
|
||||||
Assert.False(userValidator.RequireUniqueEmail);
|
|
||||||
|
|
||||||
var pwdValidator = provider.GetService<IPasswordValidator>() as PasswordValidator;
|
var pwdValidator = provider.GetService<IPasswordValidator<IdentityUser>>() as PasswordValidator<IdentityUser>;
|
||||||
Assert.NotNull(userValidator);
|
Assert.NotNull(pwdValidator);
|
||||||
Assert.True(pwdValidator.RequireDigit);
|
|
||||||
Assert.True(pwdValidator.RequireLowercase);
|
|
||||||
Assert.True(pwdValidator.RequireNonLetterOrDigit);
|
|
||||||
Assert.True(pwdValidator.RequireUppercase);
|
|
||||||
Assert.Equal(6, pwdValidator.RequiredLength);
|
|
||||||
|
|
||||||
var hasher = provider.GetService<IPasswordHasher>() as PasswordHasher;
|
var hasher = provider.GetService<IPasswordHasher>() as PasswordHasher;
|
||||||
Assert.NotNull(hasher);
|
Assert.NotNull(hasher);
|
||||||
|
|
||||||
var claimsFactory = provider.GetService<IClaimsIdentityFactory<IdentityUser>>() as ClaimsIdentityFactory<IdentityUser>;
|
var claimsFactory = provider.GetService<IClaimsIdentityFactory<IdentityUser>>() as ClaimsIdentityFactory<IdentityUser>;
|
||||||
Assert.NotNull(claimsFactory);
|
Assert.NotNull(claimsFactory);
|
||||||
Assert.Equal(ClaimTypes.Role, claimsFactory.RoleClaimType);
|
|
||||||
Assert.Equal(ClaimsIdentityFactory<IdentityUser>.DefaultSecurityStampClaimType, claimsFactory.SecurityStampClaimType);
|
|
||||||
Assert.Equal(ClaimTypes.Name, claimsFactory.UserNameClaimType);
|
|
||||||
Assert.Equal(ClaimTypes.NameIdentifier, claimsFactory.UserIdClaimType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CanOverride<TService, TImplementation>() where TImplementation : TService,new()
|
private static void CanOverride<TService>(TService instance)
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection();
|
var services = new ServiceCollection();
|
||||||
var instance = new TImplementation();
|
services.AddIdentity<IdentityUser>(b => b.AddInstance<TService>(() => instance));
|
||||||
services.AddIdentity<IdentityUser>(b => b.Use<TService>(() => instance));
|
|
||||||
Assert.Equal(instance, services.BuildServiceProvider().GetService<TService>());
|
Assert.Equal(instance, services.BuildServiceProvider().GetService<TService>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using Microsoft.AspNet.ConfigurationModel;
|
||||||
|
using Microsoft.AspNet.ConfigurationModel.Sources;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity.Test
|
||||||
|
{
|
||||||
|
public class IdentityOptionsTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void VerifyDefaultOptions()
|
||||||
|
{
|
||||||
|
var options = new IdentityOptions();
|
||||||
|
Assert.False(options.Lockout.EnabledByDefault);
|
||||||
|
Assert.Equal(TimeSpan.FromMinutes(5), options.Lockout.DefaultLockoutTimeSpan);
|
||||||
|
Assert.Equal(5, options.Lockout.MaxFailedAccessAttempts);
|
||||||
|
|
||||||
|
Assert.True(options.Password.RequireDigit);
|
||||||
|
Assert.True(options.Password.RequireLowercase);
|
||||||
|
Assert.True(options.Password.RequireNonLetterOrDigit);
|
||||||
|
Assert.True(options.Password.RequireUppercase);
|
||||||
|
Assert.Equal(6, options.Password.RequiredLength);
|
||||||
|
|
||||||
|
Assert.True(options.User.AllowOnlyAlphanumericNames);
|
||||||
|
Assert.False(options.User.RequireUniqueEmail);
|
||||||
|
|
||||||
|
Assert.Equal(ClaimTypes.Role, options.ClaimType.Role);
|
||||||
|
Assert.Equal(ClaimTypes.Name, options.ClaimType.UserName);
|
||||||
|
Assert.Equal(ClaimTypes.NameIdentifier, options.ClaimType.UserId);
|
||||||
|
Assert.Equal(ClaimTypeOptions.DefaultSecurityStampClaimType, options.ClaimType.SecurityStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void CopyNullIsNoop()
|
||||||
|
{
|
||||||
|
var options = new IdentityOptions();
|
||||||
|
options.Copy(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void IdentityOptionsFromConfig()
|
||||||
|
{
|
||||||
|
const string roleClaimType = "rolez";
|
||||||
|
const string usernameClaimType = "namez";
|
||||||
|
const string useridClaimType = "idz";
|
||||||
|
const string securityStampClaimType = "stampz";
|
||||||
|
|
||||||
|
var dic = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"identity:claimtype:role", roleClaimType},
|
||||||
|
{"identity:claimtype:username", usernameClaimType},
|
||||||
|
{"identity:claimtype:userid", useridClaimType},
|
||||||
|
{"identity:claimtype:securitystamp", securityStampClaimType},
|
||||||
|
{"identity:user:requireUniqueEmail", "true"},
|
||||||
|
{"identity:password:RequiredLength", "10"},
|
||||||
|
{"identity:password:RequireNonLetterOrDigit", "false"},
|
||||||
|
{"identity:password:RequireUpperCase", "false"},
|
||||||
|
{"identity:password:RequireDigit", "false"},
|
||||||
|
{"identity:password:RequireLowerCase", "false"}
|
||||||
|
};
|
||||||
|
var config = new ConfigurationModel.Configuration { new MemoryConfigurationSource(dic) };
|
||||||
|
Assert.Equal(roleClaimType, config.Get("identity:claimtype:role"));
|
||||||
|
var options = new IdentityOptions(config);
|
||||||
|
Assert.Equal(roleClaimType, options.ClaimType.Role);
|
||||||
|
Assert.Equal(useridClaimType, options.ClaimType.UserId);
|
||||||
|
Assert.Equal(usernameClaimType, options.ClaimType.UserName);
|
||||||
|
Assert.Equal(securityStampClaimType, options.ClaimType.SecurityStamp);
|
||||||
|
Assert.True(options.User.RequireUniqueEmail);
|
||||||
|
Assert.True(options.User.AllowOnlyAlphanumericNames);
|
||||||
|
Assert.True(options.User.AllowOnlyAlphanumericNames);
|
||||||
|
Assert.False(options.Password.RequireDigit);
|
||||||
|
Assert.False(options.Password.RequireLowercase);
|
||||||
|
Assert.False(options.Password.RequireNonLetterOrDigit);
|
||||||
|
Assert.False(options.Password.RequireUppercase);
|
||||||
|
Assert.Equal(10, options.Password.RequiredLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void ClaimTypeOptionsFromConfig()
|
||||||
|
{
|
||||||
|
const string roleClaimType = "rolez";
|
||||||
|
const string usernameClaimType = "namez";
|
||||||
|
const string useridClaimType = "idz";
|
||||||
|
const string securityStampClaimType = "stampz";
|
||||||
|
|
||||||
|
var dic = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"role", roleClaimType},
|
||||||
|
{"username", usernameClaimType},
|
||||||
|
{"userid", useridClaimType},
|
||||||
|
{"securitystamp", securityStampClaimType}
|
||||||
|
};
|
||||||
|
var config = new ConfigurationModel.Configuration {new MemoryConfigurationSource(dic)};
|
||||||
|
Assert.Equal(roleClaimType, config.Get("role"));
|
||||||
|
var options = new ClaimTypeOptions(config);
|
||||||
|
Assert.Equal(roleClaimType, options.Role);
|
||||||
|
Assert.Equal(useridClaimType, options.UserId);
|
||||||
|
Assert.Equal(usernameClaimType, options.UserName);
|
||||||
|
Assert.Equal(securityStampClaimType, options.SecurityStamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PasswordOptionsFromConfig()
|
||||||
|
{
|
||||||
|
var dic = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{"RequiredLength", "10"},
|
||||||
|
{"RequireNonLetterOrDigit", "false"},
|
||||||
|
{"RequireUpperCase", "false"},
|
||||||
|
{"RequireDigit", "false"},
|
||||||
|
{"RequireLowerCase", "false"}
|
||||||
|
};
|
||||||
|
var config = new ConfigurationModel.Configuration { new MemoryConfigurationSource(dic) };
|
||||||
|
var options = new PasswordOptions(config);
|
||||||
|
Assert.False(options.RequireDigit);
|
||||||
|
Assert.False(options.RequireLowercase);
|
||||||
|
Assert.False(options.RequireNonLetterOrDigit);
|
||||||
|
Assert.False(options.RequireUppercase);
|
||||||
|
Assert.Equal(10, options.RequiredLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ClaimsIdentityFactoryTest.cs" />
|
<Compile Include="ClaimsIdentityFactoryTest.cs" />
|
||||||
|
<Compile Include="IdentityBuilderTest.cs" />
|
||||||
<Compile Include="IdentityResultAssert.cs" />
|
<Compile Include="IdentityResultAssert.cs" />
|
||||||
<Compile Include="IdentityResultTest.cs" />
|
<Compile Include="IdentityResultTest.cs" />
|
||||||
<Compile Include="NoopRoleStore.cs" />
|
<Compile Include="NoopRoleStore.cs" />
|
||||||
|
|
@ -30,10 +31,12 @@
|
||||||
<Compile Include="RoleManagerTest.cs" />
|
<Compile Include="RoleManagerTest.cs" />
|
||||||
<Compile Include="RoleValidatorTest.cs" />
|
<Compile Include="RoleValidatorTest.cs" />
|
||||||
<Compile Include="TestRole.cs" />
|
<Compile Include="TestRole.cs" />
|
||||||
<Compile Include="TestServices.cs" />
|
|
||||||
<Compile Include="TestUser.cs" />
|
<Compile Include="TestUser.cs" />
|
||||||
<Compile Include="UserManagerTest.cs" />
|
<Compile Include="UserManagerTest.cs" />
|
||||||
<Compile Include="UserValidatorTest.cs" />
|
<Compile Include="UserValidatorTest.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\ProjectK\Microsoft.Web.ProjectK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -39,11 +39,12 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task ValidateThrowsWithNullTest()
|
public async Task ValidateThrowsWithNullTest()
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var validator = new PasswordValidator();
|
var validator = new PasswordValidator<IdentityUser>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
// Assert
|
// Assert
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>(() => validator.ValidateAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("password", () => validator.ValidateAsync(null, null));
|
||||||
|
await Assert.ThrowsAsync<ArgumentNullException>("manager", () => validator.ValidateAsync("foo", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -54,8 +55,13 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task FailsIfTooShortTests(string input)
|
public async Task FailsIfTooShortTests(string input)
|
||||||
{
|
{
|
||||||
const string error = "Passwords must be at least 6 characters.";
|
const string error = "Passwords must be at least 6 characters.";
|
||||||
var valid = new PasswordValidator {RequiredLength = 6};
|
var manager = MockHelpers.TestUserManager<IdentityUser>();
|
||||||
IdentityResultAssert.IsFailure(await valid.ValidateAsync(input), error);
|
var valid = new PasswordValidator<IdentityUser>();
|
||||||
|
manager.Options.Password.RequireUppercase = false;
|
||||||
|
manager.Options.Password.RequireNonLetterOrDigit = false;
|
||||||
|
manager.Options.Password.RequireLowercase = false;
|
||||||
|
manager.Options.Password.RequireDigit = false;
|
||||||
|
IdentityResultAssert.IsFailure(await valid.ValidateAsync(input, manager), error);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -63,8 +69,13 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[InlineData("aaaaaaaaaaa")]
|
[InlineData("aaaaaaaaaaa")]
|
||||||
public async Task SuccessIfLongEnoughTests(string input)
|
public async Task SuccessIfLongEnoughTests(string input)
|
||||||
{
|
{
|
||||||
var valid = new PasswordValidator {RequiredLength = 6};
|
var manager = MockHelpers.TestUserManager<IdentityUser>();
|
||||||
IdentityResultAssert.IsSuccess(await valid.ValidateAsync(input));
|
var valid = new PasswordValidator<IdentityUser>();
|
||||||
|
manager.Options.Password.RequireUppercase = false;
|
||||||
|
manager.Options.Password.RequireNonLetterOrDigit = false;
|
||||||
|
manager.Options.Password.RequireLowercase = false;
|
||||||
|
manager.Options.Password.RequireDigit = false;
|
||||||
|
IdentityResultAssert.IsSuccess(await valid.ValidateAsync(input, manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -72,8 +83,14 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[InlineData("aaaaaaaaaaa")]
|
[InlineData("aaaaaaaaaaa")]
|
||||||
public async Task FailsWithoutRequiredNonAlphanumericTests(string input)
|
public async Task FailsWithoutRequiredNonAlphanumericTests(string input)
|
||||||
{
|
{
|
||||||
var valid = new PasswordValidator {RequireNonLetterOrDigit = true};
|
var manager = MockHelpers.TestUserManager<IdentityUser>();
|
||||||
IdentityResultAssert.IsFailure(await valid.ValidateAsync(input),
|
var valid = new PasswordValidator<IdentityUser>();
|
||||||
|
manager.Options.Password.RequireUppercase = false;
|
||||||
|
manager.Options.Password.RequireNonLetterOrDigit = true;
|
||||||
|
manager.Options.Password.RequireLowercase = false;
|
||||||
|
manager.Options.Password.RequireDigit = false;
|
||||||
|
manager.Options.Password.RequiredLength = 0;
|
||||||
|
IdentityResultAssert.IsFailure(await valid.ValidateAsync(input, manager),
|
||||||
"Passwords must have at least one non letter or digit character.");
|
"Passwords must have at least one non letter or digit character.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,8 +100,14 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[InlineData("!!!!!!")]
|
[InlineData("!!!!!!")]
|
||||||
public async Task SucceedsWithRequiredNonAlphanumericTests(string input)
|
public async Task SucceedsWithRequiredNonAlphanumericTests(string input)
|
||||||
{
|
{
|
||||||
var valid = new PasswordValidator {RequireNonLetterOrDigit = true};
|
var manager = MockHelpers.TestUserManager<IdentityUser>();
|
||||||
IdentityResultAssert.IsSuccess(await valid.ValidateAsync(input));
|
var valid = new PasswordValidator<IdentityUser>();
|
||||||
|
manager.Options.Password.RequireUppercase = false;
|
||||||
|
manager.Options.Password.RequireNonLetterOrDigit = true;
|
||||||
|
manager.Options.Password.RequireLowercase = false;
|
||||||
|
manager.Options.Password.RequireDigit = false;
|
||||||
|
manager.Options.Password.RequiredLength = 0;
|
||||||
|
IdentityResultAssert.IsSuccess(await valid.ValidateAsync(input, manager));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Theory]
|
[Theory]
|
||||||
|
|
@ -101,14 +124,8 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
const string lowerError = "Passwords must have at least one lowercase ('a'-'z').";
|
const string lowerError = "Passwords must have at least one lowercase ('a'-'z').";
|
||||||
const string digitError = "Passwords must have at least one digit ('0'-'9').";
|
const string digitError = "Passwords must have at least one digit ('0'-'9').";
|
||||||
const string lengthError = "Passwords must be at least 6 characters.";
|
const string lengthError = "Passwords must be at least 6 characters.";
|
||||||
var valid = new PasswordValidator
|
var manager = MockHelpers.TestUserManager<IdentityUser>();
|
||||||
{
|
var valid = new PasswordValidator<IdentityUser>();
|
||||||
RequireNonLetterOrDigit = true,
|
|
||||||
RequireDigit = true,
|
|
||||||
RequireLowercase = true,
|
|
||||||
RequireUppercase = true,
|
|
||||||
RequiredLength = 6
|
|
||||||
};
|
|
||||||
var errors = new List<string>();
|
var errors = new List<string>();
|
||||||
if ((errorMask & Errors.Length) != Errors.None)
|
if ((errorMask & Errors.Length) != Errors.None)
|
||||||
{
|
{
|
||||||
|
|
@ -132,11 +149,11 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
}
|
}
|
||||||
if (errors.Count == 0)
|
if (errors.Count == 0)
|
||||||
{
|
{
|
||||||
IdentityResultAssert.IsSuccess(await valid.ValidateAsync(input));
|
IdentityResultAssert.IsSuccess(await valid.ValidateAsync(input, manager));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IdentityResultAssert.IsFailure(await valid.ValidateAsync(input), string.Join(" ", errors));
|
IdentityResultAssert.IsFailure(await valid.ValidateAsync(input, manager), string.Join(" ", errors));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,22 +19,18 @@ using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity.Test
|
namespace Microsoft.AspNet.Identity.Test
|
||||||
{
|
{
|
||||||
public class RoleManagerTest
|
public class RoleManagerTest
|
||||||
{
|
{
|
||||||
[Fact]
|
|
||||||
public void ConstructorThrowsWithNullStore()
|
|
||||||
{
|
|
||||||
Assert.Throws<ArgumentNullException>("store", () => new RoleManager<TestRole>((IRoleStore<TestRole>)null));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void RolesQueryableFailWhenStoreNotImplemented()
|
public void RolesQueryableFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new RoleManager<TestRole>(new NoopRoleStore());
|
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
|
||||||
Assert.False(manager.SupportsQueryableRoles);
|
Assert.False(manager.SupportsQueryableRoles);
|
||||||
Assert.Throws<NotSupportedException>(() => manager.Roles.Count());
|
Assert.Throws<NotSupportedException>(() => manager.Roles.Count());
|
||||||
}
|
}
|
||||||
|
|
@ -42,7 +38,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public void DisposeAfterDisposeDoesNotThrow()
|
public void DisposeAfterDisposeDoesNotThrow()
|
||||||
{
|
{
|
||||||
var manager = new RoleManager<TestRole>(new NoopRoleStore());
|
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
|
||||||
manager.Dispose();
|
manager.Dispose();
|
||||||
manager.Dispose();
|
manager.Dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -50,10 +46,12 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task RoleManagerPublicNullChecks()
|
public async Task RoleManagerPublicNullChecks()
|
||||||
{
|
{
|
||||||
|
var provider = new ServiceCollection().BuildServiceProvider();
|
||||||
Assert.Throws<ArgumentNullException>("store",
|
Assert.Throws<ArgumentNullException>("store",
|
||||||
() => new RoleManager<TestRole>((IRoleStore<TestRole>)null));
|
() => new RoleManager<TestRole>(provider, null));
|
||||||
var manager = new RoleManager<TestRole>(new NotImplementedStore());
|
Assert.Throws<ArgumentNullException>("services",
|
||||||
Assert.Throws<ArgumentNullException>("services", () => manager.Initialize(null));
|
() => new RoleManager<TestRole>(null, new NotImplementedStore()));
|
||||||
|
var manager = new RoleManager<TestRole>(provider, new NotImplementedStore());
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.CreateAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.CreateAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.UpdateAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.UpdateAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.DeleteAsync(null));
|
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await manager.DeleteAsync(null));
|
||||||
|
|
@ -64,7 +62,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task RoleStoreMethodsThrowWhenDisposed()
|
public async Task RoleStoreMethodsThrowWhenDisposed()
|
||||||
{
|
{
|
||||||
var manager = new RoleManager<TestRole>(new NoopRoleStore());
|
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
|
||||||
manager.Dispose();
|
manager.Dispose();
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByIdAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByIdAsync(null));
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByNameAsync(null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.FindByNameAsync(null));
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity.Test
|
namespace Microsoft.AspNet.Identity.Test
|
||||||
|
|
@ -27,7 +29,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task ValidateThrowsWithNull()
|
public async Task ValidateThrowsWithNull()
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var manager = new RoleManager<TestRole>(new NoopRoleStore());
|
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
|
||||||
var validator = new RoleValidator<TestRole>();
|
var validator = new RoleValidator<TestRole>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -42,7 +44,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task ValidateFailsWithTooShortRoleName(string input)
|
public async Task ValidateFailsWithTooShortRoleName(string input)
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var manager = new RoleManager<TestRole>(new NoopRoleStore());
|
var manager = new RoleManager<TestRole>(new ServiceCollection().BuildServiceProvider(), new NoopRoleStore());
|
||||||
var validator = new RoleValidator<TestRole>();
|
var validator = new RoleValidator<TestRole>();
|
||||||
var user = new TestRole {Name = input};
|
var user = new TestRole {Name = input};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,23 +34,22 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
{
|
{
|
||||||
public IUserStore<TestUser> StorePublic { get { return Store; } }
|
public IUserStore<TestUser> StorePublic { get { return Store; } }
|
||||||
|
|
||||||
public TestManager(IServiceProvider provider) : base(provider) { }
|
public TestManager(IServiceProvider provider, IUserStore<TestUser> store, IOptionsAccessor<IdentityOptions> options) : base(provider, store, options) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void EnsureDefaultServicesDefaultsWithStoreWorks()
|
public void EnsureDefaultServicesDefaultsWithStoreWorks()
|
||||||
{
|
{
|
||||||
var services = new ServiceCollection {IdentityServices.GetDefaultUserServices<TestUser>()};
|
var services = new ServiceCollection {IdentityServices.GetDefaultUserServices<TestUser>()};
|
||||||
services.AddInstance<IUserStore<TestUser>>(new NoopUserStore());
|
services.AddInstance<IOptionsAccessor<IdentityOptions>>(new OptionsAccessor<IdentityOptions>(null));
|
||||||
var manager = new TestManager(services.BuildServiceProvider());
|
services.AddTransient<IUserStore<TestUser>, NoopUserStore>();
|
||||||
|
services.AddTransient<TestManager>();
|
||||||
|
var manager = services.BuildServiceProvider().GetService<TestManager>();
|
||||||
Assert.NotNull(manager.PasswordHasher);
|
Assert.NotNull(manager.PasswordHasher);
|
||||||
Assert.NotNull(manager.PasswordValidator);
|
Assert.NotNull(manager.PasswordValidator);
|
||||||
Assert.NotNull(manager.UserValidator);
|
Assert.NotNull(manager.UserValidator);
|
||||||
Assert.NotNull(manager.StorePublic);
|
Assert.NotNull(manager.StorePublic);
|
||||||
Assert.NotNull(manager.LockoutPolicy);
|
Assert.NotNull(manager.Options);
|
||||||
Assert.Equal(TimeSpan.FromMinutes(5), manager.LockoutPolicy.DefaultAccountLockoutTimeSpan);
|
|
||||||
Assert.Equal(5, manager.LockoutPolicy.MaxFailedAccessAttemptsBeforeLockout);
|
|
||||||
Assert.False(manager.LockoutPolicy.UserLockoutEnabledByDefault);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if NET45
|
#if NET45
|
||||||
|
|
@ -61,11 +60,9 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
// Setup
|
// Setup
|
||||||
var store = new Mock<IUserStore<TestUser>>();
|
var store = new Mock<IUserStore<TestUser>>();
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
|
var options = new OptionsAccessor<IdentityOptions>(null);
|
||||||
store.Setup(s => s.CreateAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
store.Setup(s => s.CreateAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
||||||
var validator = new Mock<UserValidator<TestUser>>();
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
var userManager = new UserManager<TestUser>(store.Object);
|
|
||||||
validator.Setup(v => v.ValidateAsync(userManager, user, CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
|
|
||||||
userManager.UserValidator = validator.Object;
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.CreateAsync(user);
|
var result = await userManager.CreateAsync(user);
|
||||||
|
|
@ -81,8 +78,9 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
// Setup
|
// Setup
|
||||||
var store = new Mock<IUserStore<TestUser>>();
|
var store = new Mock<IUserStore<TestUser>>();
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
|
var options = new OptionsAccessor<IdentityOptions>(null);
|
||||||
store.Setup(s => s.DeleteAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
store.Setup(s => s.DeleteAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
||||||
var userManager = new UserManager<TestUser>(store.Object);
|
var userManager = new UserManager<TestUser>(new ServiceCollection().BuildServiceProvider(), store.Object, options);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.DeleteAsync(user);
|
var result = await userManager.DeleteAsync(user);
|
||||||
|
|
@ -99,10 +97,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
var store = new Mock<IUserStore<TestUser>>();
|
var store = new Mock<IUserStore<TestUser>>();
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
||||||
var validator = new Mock<UserValidator<TestUser>>();
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
var userManager = new UserManager<TestUser>(store.Object);
|
|
||||||
validator.Setup(v => v.ValidateAsync(userManager, user, CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
|
|
||||||
userManager.UserValidator = validator.Object;
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.UpdateAsync(user);
|
var result = await userManager.UpdateAsync(user);
|
||||||
|
|
@ -119,10 +114,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
var store = new Mock<IUserStore<TestUser>>();
|
var store = new Mock<IUserStore<TestUser>>();
|
||||||
var user = new TestUser();
|
var user = new TestUser();
|
||||||
store.Setup(s => s.SetUserNameAsync(user, It.IsAny<string>(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
store.Setup(s => s.SetUserNameAsync(user, It.IsAny<string>(), CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
||||||
var validator = new Mock<UserValidator<TestUser>>();
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
var userManager = new UserManager<TestUser>(store.Object);
|
|
||||||
validator.Setup(v => v.ValidateAsync(userManager, user, CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
|
|
||||||
userManager.UserValidator = validator.Object;
|
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.SetUserNameAsync(user, "foo");
|
var result = await userManager.SetUserNameAsync(user, "foo");
|
||||||
|
|
@ -139,7 +131,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
var store = new Mock<IUserStore<TestUser>>();
|
var store = new Mock<IUserStore<TestUser>>();
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
store.Setup(s => s.FindByIdAsync(user.Id, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable();
|
store.Setup(s => s.FindByIdAsync(user.Id, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable();
|
||||||
var userManager = new UserManager<TestUser>(store.Object);
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.FindByIdAsync(user.Id);
|
var result = await userManager.FindByIdAsync(user.Id);
|
||||||
|
|
@ -156,7 +148,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
var store = new Mock<IUserStore<TestUser>>();
|
var store = new Mock<IUserStore<TestUser>>();
|
||||||
var user = new TestUser {UserName="Foo"};
|
var user = new TestUser {UserName="Foo"};
|
||||||
store.Setup(s => s.FindByNameAsync(user.UserName, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable();
|
store.Setup(s => s.FindByNameAsync(user.UserName, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable();
|
||||||
var userManager = new UserManager<TestUser>(store.Object);
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.FindByNameAsync(user.UserName);
|
var result = await userManager.FindByNameAsync(user.UserName);
|
||||||
|
|
@ -184,7 +176,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
store.Setup(s => s.UpdateAsync(user, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
|
||||||
store.Setup(s => s.GetRolesAsync(user, CancellationToken.None)).ReturnsAsync(new List<string>()).Verifiable();
|
store.Setup(s => s.GetRolesAsync(user, CancellationToken.None)).ReturnsAsync(new List<string>()).Verifiable();
|
||||||
var userManager = new UserManager<TestUser>(store.Object) {UserValidator = null};
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.AddToRolesAsync(user, roles);
|
var result = await userManager.AddToRolesAsync(user, roles);
|
||||||
|
|
@ -200,12 +192,12 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
// Setup
|
// Setup
|
||||||
var store = new Mock<IUserRoleStore<TestUser>>();
|
var store = new Mock<IUserRoleStore<TestUser>>();
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
var roles = new string[] { "A", "B", "C" };
|
var roles = new[] { "A", "B", "C" };
|
||||||
store.Setup(s => s.AddToRoleAsync(user, "A", CancellationToken.None))
|
store.Setup(s => s.AddToRoleAsync(user, "A", CancellationToken.None))
|
||||||
.Returns(Task.FromResult(0))
|
.Returns(Task.FromResult(0))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
store.Setup(s => s.GetRolesAsync(user, CancellationToken.None)).ReturnsAsync(new List<string> { "B" }).Verifiable();
|
store.Setup(s => s.GetRolesAsync(user, CancellationToken.None)).ReturnsAsync(new List<string> { "B" }).Verifiable();
|
||||||
var userManager = new UserManager<TestUser>(store.Object) { UserValidator = null };
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.AddToRolesAsync(user, roles);
|
var result = await userManager.AddToRolesAsync(user, roles);
|
||||||
|
|
@ -221,7 +213,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
// Setup
|
// Setup
|
||||||
var store = new Mock<IUserRoleStore<TestUser>>();
|
var store = new Mock<IUserRoleStore<TestUser>>();
|
||||||
var user = new TestUser { UserName = "Foo" };
|
var user = new TestUser { UserName = "Foo" };
|
||||||
var roles = new string[] { "A", "B", "C" };
|
var roles = new[] { "A", "B", "C" };
|
||||||
store.Setup(s => s.RemoveFromRoleAsync(user, "A", CancellationToken.None))
|
store.Setup(s => s.RemoveFromRoleAsync(user, "A", CancellationToken.None))
|
||||||
.Returns(Task.FromResult(0))
|
.Returns(Task.FromResult(0))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
|
|
@ -241,7 +233,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
store.Setup(s => s.IsInRoleAsync(user, "C", CancellationToken.None))
|
store.Setup(s => s.IsInRoleAsync(user, "C", CancellationToken.None))
|
||||||
.Returns(Task.FromResult(true))
|
.Returns(Task.FromResult(true))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
var userManager = new UserManager<TestUser>(store.Object) { UserValidator = null };
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.RemoveFromRolesAsync(user, roles);
|
var result = await userManager.RemoveFromRolesAsync(user, roles);
|
||||||
|
|
@ -267,7 +259,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
store.Setup(s => s.IsInRoleAsync(user, "B", CancellationToken.None))
|
store.Setup(s => s.IsInRoleAsync(user, "B", CancellationToken.None))
|
||||||
.Returns(Task.FromResult(false))
|
.Returns(Task.FromResult(false))
|
||||||
.Verifiable();
|
.Verifiable();
|
||||||
var userManager = new UserManager<TestUser>(store.Object) { UserValidator = null };
|
var userManager = MockHelpers.TestUserManager<TestUser>(store.Object);
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var result = await userManager.RemoveFromRolesAsync(user, roles);
|
var result = await userManager.RemoveFromRolesAsync(user, roles);
|
||||||
|
|
@ -282,21 +274,21 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task CheckPasswordWithNullUserReturnsFalse()
|
public async Task CheckPasswordWithNullUserReturnsFalse()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new EmptyStore());
|
var manager = MockHelpers.TestUserManager(new EmptyStore());
|
||||||
Assert.False(await manager.CheckPasswordAsync(null, "whatevs"));
|
Assert.False(await manager.CheckPasswordAsync(null, "whatevs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task FindWithUnknownUserAndPasswordReturnsNull()
|
public async Task FindWithUnknownUserAndPasswordReturnsNull()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new EmptyStore());
|
var manager = MockHelpers.TestUserManager(new EmptyStore());
|
||||||
Assert.Null(await manager.FindByUserNamePasswordAsync("bogus", "whatevs"));
|
Assert.Null(await manager.FindByUserNamePasswordAsync("bogus", "whatevs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void UsersQueryableFailWhenStoreNotImplemented()
|
public void UsersQueryableFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsQueryableUsers);
|
Assert.False(manager.SupportsQueryableUsers);
|
||||||
Assert.Throws<NotSupportedException>(() => manager.Users.Count());
|
Assert.Throws<NotSupportedException>(() => manager.Users.Count());
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +296,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task UsersEmailMethodsFailWhenStoreNotImplemented()
|
public async Task UsersEmailMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserEmail);
|
Assert.False(manager.SupportsUserEmail);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(() => manager.FindByEmailAsync(null));
|
await Assert.ThrowsAsync<NotSupportedException>(() => manager.FindByEmailAsync(null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(() => manager.SetEmailAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(() => manager.SetEmailAsync(null, null));
|
||||||
|
|
@ -316,7 +308,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task UsersPhoneNumberMethodsFailWhenStoreNotImplemented()
|
public async Task UsersPhoneNumberMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserPhoneNumber);
|
Assert.False(manager.SupportsUserPhoneNumber);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetPhoneNumberAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetPhoneNumberAsync(null, null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetPhoneNumberAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetPhoneNumberAsync(null, null));
|
||||||
|
|
@ -326,7 +318,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task TokenMethodsThrowWithNoTokenProvider()
|
public async Task TokenMethodsThrowWithNoTokenProvider()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(
|
await Assert.ThrowsAsync<NotSupportedException>(
|
||||||
async () => await manager.GenerateUserTokenAsync(null, null));
|
async () => await manager.GenerateUserTokenAsync(null, null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(
|
await Assert.ThrowsAsync<NotSupportedException>(
|
||||||
|
|
@ -336,7 +328,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PasswordMethodsFailWhenStoreNotImplemented()
|
public async Task PasswordMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserPassword);
|
Assert.False(manager.SupportsUserPassword);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(() => manager.CreateAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(() => manager.CreateAsync(null, null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(() => manager.ChangePasswordAsync(null, null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(() => manager.ChangePasswordAsync(null, null, null));
|
||||||
|
|
@ -349,7 +341,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task SecurityStampMethodsFailWhenStoreNotImplemented()
|
public async Task SecurityStampMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserSecurityStamp);
|
Assert.False(manager.SupportsUserSecurityStamp);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(() => manager.UpdateSecurityStampAsync(null));
|
await Assert.ThrowsAsync<NotSupportedException>(() => manager.UpdateSecurityStampAsync(null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(() => manager.GetSecurityStampAsync(null));
|
await Assert.ThrowsAsync<NotSupportedException>(() => manager.GetSecurityStampAsync(null));
|
||||||
|
|
@ -366,7 +358,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task LoginMethodsFailWhenStoreNotImplemented()
|
public async Task LoginMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserLogin);
|
Assert.False(manager.SupportsUserLogin);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddLoginAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddLoginAsync(null, null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveLoginAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveLoginAsync(null, null));
|
||||||
|
|
@ -377,7 +369,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ClaimMethodsFailWhenStoreNotImplemented()
|
public async Task ClaimMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserClaim);
|
Assert.False(manager.SupportsUserClaim);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddClaimAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddClaimAsync(null, null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveClaimAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.RemoveClaimAsync(null, null));
|
||||||
|
|
@ -387,7 +379,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task TwoFactorStoreMethodsFailWhenStoreNotImplemented()
|
public async Task TwoFactorStoreMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserTwoFactor);
|
Assert.False(manager.SupportsUserTwoFactor);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetTwoFactorEnabledAsync(null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetTwoFactorEnabledAsync(null));
|
||||||
await
|
await
|
||||||
|
|
@ -397,7 +389,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task LockoutStoreMethodsFailWhenStoreNotImplemented()
|
public async Task LockoutStoreMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserLockout);
|
Assert.False(manager.SupportsUserLockout);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetLockoutEnabledAsync(null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.GetLockoutEnabledAsync(null));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetLockoutEnabledAsync(null, true));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.SetLockoutEnabledAsync(null, true));
|
||||||
|
|
@ -410,7 +402,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task RoleMethodsFailWhenStoreNotImplemented()
|
public async Task RoleMethodsFailWhenStoreNotImplemented()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
Assert.False(manager.SupportsUserRole);
|
Assert.False(manager.SupportsUserRole);
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddToRoleAsync(null, "bogus"));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddToRoleAsync(null, "bogus"));
|
||||||
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddToRolesAsync(null, null));
|
await Assert.ThrowsAsync<NotSupportedException>(async () => await manager.AddToRolesAsync(null, null));
|
||||||
|
|
@ -423,7 +415,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public void DisposeAfterDisposeDoesNotThrow()
|
public void DisposeAfterDisposeDoesNotThrow()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
manager.Dispose();
|
manager.Dispose();
|
||||||
manager.Dispose();
|
manager.Dispose();
|
||||||
}
|
}
|
||||||
|
|
@ -432,23 +424,26 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task PasswordValidatorBlocksCreate()
|
public async Task PasswordValidatorBlocksCreate()
|
||||||
{
|
{
|
||||||
// TODO: Can switch to Mock eventually
|
// TODO: Can switch to Mock eventually
|
||||||
var manager = new UserManager<TestUser>(new EmptyStore())
|
var manager = MockHelpers.TestUserManager(new EmptyStore());
|
||||||
{
|
manager.PasswordValidator = new BadPasswordValidator<TestUser>();
|
||||||
PasswordValidator = new BadPasswordValidtor()
|
|
||||||
};
|
|
||||||
IdentityResultAssert.IsFailure(await manager.CreateAsync(new TestUser(), "password"),
|
IdentityResultAssert.IsFailure(await manager.CreateAsync(new TestUser(), "password"),
|
||||||
BadPasswordValidtor.ErrorMessage);
|
BadPasswordValidator<TestUser>.ErrorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ManagerPublicNullChecks()
|
public async Task ManagerPublicNullChecks()
|
||||||
{
|
{
|
||||||
|
var provider = new ServiceCollection().BuildServiceProvider();
|
||||||
Assert.Throws<ArgumentNullException>("serviceProvider",
|
Assert.Throws<ArgumentNullException>("serviceProvider",
|
||||||
() => new UserManager<TestUser>((IServiceProvider)null));
|
() => new UserManager<TestUser>(null, null, null));
|
||||||
var manager = new UserManager<TestUser>(new NotImplementedStore());
|
Assert.Throws<ArgumentNullException>("store",
|
||||||
Assert.Throws<ArgumentNullException>(() => manager.ClaimsIdentityFactory = null);
|
() => new UserManager<TestUser>(provider, null, null));
|
||||||
Assert.Throws<ArgumentNullException>(() => manager.PasswordHasher = null);
|
Assert.Throws<ArgumentNullException>("optionsAccessor",
|
||||||
Assert.Throws<ArgumentNullException>("serviceProvider", () => manager.Initialize(null));
|
() => new UserManager<TestUser>(provider, new NotImplementedStore(), null));
|
||||||
|
var manager = new UserManager<TestUser>(provider, new NotImplementedStore(), new OptionsAccessor<IdentityOptions>(null));
|
||||||
|
Assert.Throws<ArgumentNullException>("value", () => manager.ClaimsIdentityFactory = null);
|
||||||
|
Assert.Throws<ArgumentNullException>("value", () => manager.PasswordHasher = null);
|
||||||
|
Assert.Throws<ArgumentNullException>("value", () => manager.Options = null);
|
||||||
await
|
await
|
||||||
Assert.ThrowsAsync<ArgumentNullException>("user",
|
Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
async () => await manager.CreateIdentityAsync(null, "whatever"));
|
async () => await manager.CreateIdentityAsync(null, "whatever"));
|
||||||
|
|
@ -476,10 +471,8 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task MethodsFailWithUnknownUserTest()
|
public async Task MethodsFailWithUnknownUserTest()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new EmptyStore())
|
var manager = MockHelpers.TestUserManager(new EmptyStore());
|
||||||
{
|
manager.UserTokenProvider = new NoOpTokenProvider();
|
||||||
UserTokenProvider = new NoOpTokenProvider()
|
|
||||||
};
|
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
async () => await manager.GetUserNameAsync(null));
|
async () => await manager.GetUserNameAsync(null));
|
||||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||||
|
|
@ -583,7 +576,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task MethodsThrowWhenDisposedTest()
|
public async Task MethodsThrowWhenDisposedTest()
|
||||||
{
|
{
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
manager.Dispose();
|
manager.Dispose();
|
||||||
Assert.Throws<ObjectDisposedException>(() => manager.ClaimsIdentityFactory);
|
Assert.Throws<ObjectDisposedException>(() => manager.ClaimsIdentityFactory);
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddClaimAsync(null, null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.AddClaimAsync(null, null));
|
||||||
|
|
@ -620,11 +613,11 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ConfirmEmailAsync(null, null));
|
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ConfirmEmailAsync(null, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BadPasswordValidtor : IPasswordValidator
|
private class BadPasswordValidator<TUser> : IPasswordValidator<TUser> where TUser : class
|
||||||
{
|
{
|
||||||
public const string ErrorMessage = "I'm Bad.";
|
public const string ErrorMessage = "I'm Bad.";
|
||||||
|
|
||||||
public Task<IdentityResult> ValidateAsync(string password, CancellationToken cancellationToken = default(CancellationToken))
|
public Task<IdentityResult> ValidateAsync(string password, UserManager<TUser> manager, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
{
|
{
|
||||||
return Task.FromResult(IdentityResult.Failed(ErrorMessage));
|
return Task.FromResult(IdentityResult.Failed(ErrorMessage));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Identity.Test
|
namespace Microsoft.AspNet.Identity.Test
|
||||||
|
|
@ -27,7 +29,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task ValidateThrowsWithNull()
|
public async Task ValidateThrowsWithNull()
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
var validator = new UserValidator<TestUser>();
|
var validator = new UserValidator<TestUser>();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -42,7 +44,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task ValidateFailsWithTooShortUserNames(string input)
|
public async Task ValidateFailsWithTooShortUserNames(string input)
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
var validator = new UserValidator<TestUser>();
|
var validator = new UserValidator<TestUser>();
|
||||||
var user = new TestUser {UserName = input};
|
var user = new TestUser {UserName = input};
|
||||||
|
|
||||||
|
|
@ -62,7 +64,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task DefaultAlphaNumericOnlyUserNameValidation(string userName, bool expectSuccess)
|
public async Task DefaultAlphaNumericOnlyUserNameValidation(string userName, bool expectSuccess)
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
var validator = new UserValidator<TestUser>();
|
var validator = new UserValidator<TestUser>();
|
||||||
var user = new TestUser {UserName = userName};
|
var user = new TestUser {UserName = userName};
|
||||||
|
|
||||||
|
|
@ -89,8 +91,9 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
public async Task CanAllowNonAlphaNumericUserName(string userName, bool expectSuccess)
|
public async Task CanAllowNonAlphaNumericUserName(string userName, bool expectSuccess)
|
||||||
{
|
{
|
||||||
// Setup
|
// Setup
|
||||||
var manager = new UserManager<TestUser>(new NoopUserStore());
|
var manager = MockHelpers.TestUserManager(new NoopUserStore());
|
||||||
var validator = new UserValidator<TestUser> {AllowOnlyAlphanumericUserNames = false};
|
manager.Options.User.AllowOnlyAlphanumericNames = false;
|
||||||
|
var validator = new UserValidator<TestUser>();
|
||||||
var user = new TestUser {UserName = userName};
|
var user = new TestUser {UserName = userName};
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
"xunit.core": "2.0.0-aspnet-*",
|
"xunit.core": "2.0.0-aspnet-*",
|
||||||
"xunit.execution": "2.0.0-aspnet-*"
|
"xunit.execution": "2.0.0-aspnet-*"
|
||||||
},
|
},
|
||||||
|
"code": "**\\*.cs;..\\Shared\\*.cs",
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"net45": {
|
"net45": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity.Test
|
||||||
|
{
|
||||||
|
public class ApplicationUserManager : UserManager<ApplicationUser>
|
||||||
|
{
|
||||||
|
public ApplicationUserManager(IServiceProvider services, IUserStore<ApplicationUser> store, IOptionsAccessor<IdentityOptions> options) : base(services, store, options) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ApplicationRoleManager : RoleManager<IdentityRole>
|
||||||
|
{
|
||||||
|
public ApplicationRoleManager(IServiceProvider services, IRoleStore<IdentityRole> store) : base(services, store) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ApplicationUser : IdentityUser
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.DependencyInjection;
|
||||||
|
using Microsoft.AspNet.DependencyInjection.Fallback;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity.Test
|
||||||
|
{
|
||||||
|
public static class MockHelpers
|
||||||
|
{
|
||||||
|
public static Mock<UserManager<TUser>> MockUserManager<TUser>() where TUser : class
|
||||||
|
{
|
||||||
|
var store = new Mock<IUserStore<TUser>>();
|
||||||
|
var options = new OptionsAccessor<IdentityOptions>(null);
|
||||||
|
return new Mock<UserManager<TUser>>(new ServiceCollection().BuildServiceProvider(), store.Object, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserManager<TUser> TestUserManager<TUser>() where TUser : class
|
||||||
|
{
|
||||||
|
return TestUserManager(new Mock<IUserStore<TUser>>().Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserManager<TUser> TestUserManager<TUser>(IUserStore<TUser> store) where TUser : class
|
||||||
|
{
|
||||||
|
var options = new OptionsAccessor<IdentityOptions>(null);
|
||||||
|
var validator = new Mock<UserValidator<TUser>>();
|
||||||
|
var userManager = new UserManager<TUser>(new ServiceCollection().BuildServiceProvider(), store, options);
|
||||||
|
validator.Setup(v => v.ValidateAsync(userManager, It.IsAny<TUser>(), CancellationToken.None)).Returns(Task.FromResult(IdentityResult.Success)).Verifiable();
|
||||||
|
userManager.UserValidator = validator.Object;
|
||||||
|
return userManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Identity.Test
|
||||||
|
{
|
||||||
|
public class TestMessageService : IIdentityMessageService
|
||||||
|
{
|
||||||
|
public IdentityMessage Message { get; set; }
|
||||||
|
|
||||||
|
public Task SendAsync(IdentityMessage message, CancellationToken cancellationToken = default(CancellationToken))
|
||||||
|
{
|
||||||
|
Message = message;
|
||||||
|
return Task.FromResult(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Identity.Test
|
||||||
Id = Guid.NewGuid().ToString();
|
Id = Guid.NewGuid().ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Id { get; set; }
|
public string Id { get; private set; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue