Move SignIn Manger to core
Also cleans up CTP1 interface/tests
This commit is contained in:
parent
55e1b4312d
commit
9053ec56a4
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Identity.Entity;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
// Move to DI namespace?
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
public static class EntityIdentityBuilderExtensions
|
||||
{
|
||||
public static IdentityBuilder<TUser, TRole> AddEntityFrameworkInMemory<TUser, TRole, TDbContext>(this IdentityBuilder<TUser, TRole> builder)
|
||||
where TUser : EntityUser
|
||||
where TRole : EntityRole
|
||||
where TDbContext : DbContext
|
||||
{
|
||||
builder.Services.AddScoped<TDbContext>();
|
||||
builder.Services.AddScoped<IUserStore<TUser>, InMemoryUserStore<TUser, TDbContext>>();
|
||||
builder.Services.AddScoped<IRoleStore<TRole>, EntityRoleStore<TRole, TDbContext>>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
// todo: add overloads
|
||||
public static IdentityBuilder<TUser, IdentityRole> AddEntityFramework<TUser, TContext>(this IdentityBuilder<TUser, IdentityRole> builder)
|
||||
where TUser : User where TContext : DbContext
|
||||
{
|
||||
builder.Services.AddScoped<IUserStore<TUser>, UserStore<TUser, TContext>>();
|
||||
builder.Services.AddScoped<TContext>();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,19 +10,28 @@ using Microsoft.Data.Entity;
|
|||
|
||||
namespace Microsoft.AspNet.Identity.Entity
|
||||
{
|
||||
public class EntityRoleStore<TRole> : EntityRoleStore<TRole, string> where TRole : EntityRole
|
||||
public class EntityRoleStore<TRole> : EntityRoleStore<TRole, IdentityContext>
|
||||
where TRole : EntityRole
|
||||
{
|
||||
public EntityRoleStore(DbContext context) : base(context) { }
|
||||
public EntityRoleStore(IdentityContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class EntityRoleStore<TRole, TKey> :
|
||||
public class EntityRoleStore<TRole, TContext> : EntityRoleStore<TRole, string, TContext>
|
||||
where TRole : EntityRole
|
||||
where TContext : DbContext
|
||||
{
|
||||
public EntityRoleStore(TContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class EntityRoleStore<TRole, TKey, TContext> :
|
||||
IQueryableRoleStore<TRole>
|
||||
where TRole : EntityRole
|
||||
where TKey : IEquatable<TKey>
|
||||
where TContext : DbContext
|
||||
{
|
||||
private bool _disposed;
|
||||
|
||||
public EntityRoleStore(DbContext context)
|
||||
public EntityRoleStore(TContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Identity.Entity;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Framework.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>, InMemoryUserStore<TUser>>();
|
||||
builder.Services.AddScoped<IRoleStore<TRole>, EntityRoleStore<TRole>>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IdentityBuilder<TUser, IdentityRole> AddEntity<TUser>(this IdentityBuilder<TUser, IdentityRole> builder)
|
||||
where TUser : User
|
||||
{
|
||||
builder.Services.AddScoped<IUserStore<TUser>, UserStore<TUser>>();
|
||||
builder.Services.AddScoped<UserManager<TUser>>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
// todo: remove
|
||||
public static IdentityBuilder<TUser, IdentityRole> AddEntity<TUser, TContext>(this IdentityBuilder<TUser, IdentityRole> builder)
|
||||
where TUser : User where TContext : DbContext
|
||||
{
|
||||
builder.Services.AddScoped<IUserStore<TUser>, UserStore<TUser, TContext>>();
|
||||
builder.Services.AddScoped<UserManager<TUser>>();
|
||||
builder.Services.AddScoped<TContext>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
// todo: add overloads
|
||||
public static IdentityBuilder<TUser, IdentityRole> AddEntityFramework<TUser, TContext>(this IdentityBuilder<TUser, IdentityRole> builder)
|
||||
where TUser : User where TContext : DbContext
|
||||
{
|
||||
builder.Services.AddScoped<IUserStore<TUser>, UserStore<TUser, TContext>>();
|
||||
builder.Services.AddScoped<UserManager<TUser>>();
|
||||
builder.Services.AddScoped<TContext>();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,14 @@ namespace Microsoft.AspNet.Identity.Entity
|
|||
public IdentityContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
|
||||
}
|
||||
|
||||
public class IdentityContext<TUser> :
|
||||
IdentityContext<TUser, EntityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
|
||||
where TUser : EntityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
|
||||
{
|
||||
public IdentityContext() { }
|
||||
public IdentityContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
|
||||
}
|
||||
|
||||
public class IdentityContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : DbContext
|
||||
where TUser : EntityUser<TKey, TUserLogin, TUserRole, TUserClaim>
|
||||
where TRole : EntityRole<TKey, TUserRole>
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Identity.Entity;
|
||||
using Microsoft.Data.Entity;
|
||||
|
||||
namespace Microsoft.Framework.DependencyInjection
|
||||
{
|
||||
public static class IdentityEntityServiceCollectionExtensions
|
||||
{
|
||||
public static IdentityBuilder<TUser, IdentityRole> AddIdentityEntityFramework<TContext, TUser>(this ServiceCollection services)
|
||||
where TUser : User where TContext : DbContext
|
||||
{
|
||||
var builder = services.AddIdentity<TUser, IdentityRole>();
|
||||
services.AddScoped<TContext>();
|
||||
services.AddScoped<IUserStore<TUser>, UserStore<TUser, TContext>>();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,7 @@ namespace Microsoft.AspNet.Identity.Entity
|
|||
{
|
||||
public IdentitySqlContext() { }
|
||||
public IdentitySqlContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
|
||||
public IdentitySqlContext(IServiceProvider serviceProvider, string nameOrConnectionString) : base(serviceProvider, nameOrConnectionString) { }
|
||||
public IdentitySqlContext(DbContextOptions options) : base(options) { }
|
||||
public IdentitySqlContext(IServiceProvider serviceProvider, DbContextOptions options) : base(serviceProvider, options) { }
|
||||
}
|
||||
|
|
@ -23,16 +24,23 @@ namespace Microsoft.AspNet.Identity.Entity
|
|||
public DbSet<IdentityUserClaim> UserClaims { get; set; }
|
||||
//public DbSet<TRole> Roles { get; set; }
|
||||
|
||||
private readonly string _nameOrConnectionString;
|
||||
|
||||
public IdentitySqlContext() { }
|
||||
public IdentitySqlContext(IServiceProvider serviceProvider, string nameOrConnectionString) : base(serviceProvider)
|
||||
{
|
||||
_nameOrConnectionString = nameOrConnectionString;
|
||||
}
|
||||
public IdentitySqlContext(IServiceProvider serviceProvider) : base(serviceProvider) { }
|
||||
public IdentitySqlContext(DbContextOptions options) : base(options) { }
|
||||
public IdentitySqlContext(IServiceProvider serviceProvider, DbContextOptions options) : base(serviceProvider, options) { }
|
||||
|
||||
|
||||
protected override void OnConfiguring(DbContextOptions builder)
|
||||
{
|
||||
// TODO: pull connection string from config
|
||||
builder.UseSqlServer(@"Server=(localdb)\v11.0;Database=SimpleIdentity-5-28;Trusted_Connection=True;");
|
||||
if (!string.IsNullOrEmpty(_nameOrConnectionString))
|
||||
{
|
||||
builder.UseSqlServer(_nameOrConnectionString);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
|
|
|
|||
|
|
@ -13,18 +13,25 @@ using Microsoft.Data.Entity;
|
|||
|
||||
namespace Microsoft.AspNet.Identity.Entity
|
||||
{
|
||||
public class InMemoryInMemoryUserStore :
|
||||
InMemoryUserStore<EntityUser>
|
||||
public class InMemoryUserStore : InMemoryUserStore<EntityUser, IdentityContext>
|
||||
{
|
||||
public InMemoryInMemoryUserStore(DbContext context) : base(context) { }
|
||||
public InMemoryUserStore(IdentityContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class InMemoryUserStore<TUser> : InMemoryUserStore<TUser, EntityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> where TUser:EntityUser
|
||||
public class InMemoryUserStore<TUser> : InMemoryUserStore<TUser, IdentityContext>
|
||||
where TUser : EntityUser
|
||||
{
|
||||
public InMemoryUserStore(DbContext context) : base(context) { }
|
||||
public InMemoryUserStore(IdentityContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class InMemoryUserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> :
|
||||
public class InMemoryUserStore<TUser, TContext> : InMemoryUserStore<TUser, EntityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim, TContext>
|
||||
where TUser:EntityUser
|
||||
where TContext : DbContext
|
||||
{
|
||||
public InMemoryUserStore(TContext context) : base(context) { }
|
||||
}
|
||||
|
||||
public class InMemoryUserStore<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim, TContext> :
|
||||
IUserLoginStore<TUser>,
|
||||
IUserClaimStore<TUser>,
|
||||
IUserRoleStore<TUser>,
|
||||
|
|
@ -41,10 +48,11 @@ namespace Microsoft.AspNet.Identity.Entity
|
|||
where TUserLogin : IdentityUserLogin<TKey>, new()
|
||||
where TUserRole : IdentityUserRole<TKey>, new()
|
||||
where TUserClaim : IdentityUserClaim<TKey>, new()
|
||||
where TContext : DbContext
|
||||
{
|
||||
private bool _disposed;
|
||||
|
||||
public InMemoryUserStore(DbContext context)
|
||||
public InMemoryUserStore(TContext context)
|
||||
{
|
||||
if (context == null)
|
||||
{
|
||||
|
|
@ -54,7 +62,7 @@ namespace Microsoft.AspNet.Identity.Entity
|
|||
AutoSaveChanges = true;
|
||||
}
|
||||
|
||||
public DbContext Context { get; private set; }
|
||||
public TContext Context { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If true will call SaveChanges after CreateAsync/UpdateAsync/DeleteAsync
|
||||
|
|
|
|||
|
|
@ -23,9 +23,8 @@
|
|||
<Compile Include="EntityRole.cs" />
|
||||
<Compile Include="EntityRoleStore.cs" />
|
||||
<Compile Include="EntityUser.cs" />
|
||||
<Compile Include="IdentityBuilderExtensions.cs" />
|
||||
<Compile Include="EntityIdentityBuilderExtensions.cs" />
|
||||
<Compile Include="IdentityContext.cs" />
|
||||
<Compile Include="IdentityEntityServiceCollectionExtensions.cs" />
|
||||
<Compile Include="IdentitySqlContext.cs" />
|
||||
<Compile Include="InMemoryUserStore.cs" />
|
||||
<Compile Include="RoleStore.cs" />
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ namespace Microsoft.AspNet.Identity.Entity
|
|||
public User()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString();
|
||||
// TODO: remove when bug is fixed
|
||||
UserName = "";
|
||||
PasswordHash = "";
|
||||
}
|
||||
|
||||
public User(string userName) : this()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Security;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Security
|
||||
{
|
||||
public class HttpAuthenticationManager : IAuthenticationManager
|
||||
{
|
||||
public static readonly string TwoFactorUserIdAuthenticationType = "Microsoft.AspNet.Identity.TwoFactor.UserId";
|
||||
public static readonly string TwoFactorRememberedAuthenticationType = "Microsoft.AspNet.Identity.TwoFactor.Remembered";
|
||||
|
||||
public HttpAuthenticationManager(IContextAccessor<HttpContext> contextAccessor)
|
||||
{
|
||||
Context = contextAccessor.Value;
|
||||
}
|
||||
|
||||
public HttpContext Context { get; private set; }
|
||||
|
||||
public void ForgetClient()
|
||||
{
|
||||
Context.Response.SignOut(TwoFactorRememberedAuthenticationType);
|
||||
}
|
||||
|
||||
public async Task<bool> IsClientRememeberedAsync(string userId)
|
||||
{
|
||||
var result =
|
||||
await Context.AuthenticateAsync(TwoFactorRememberedAuthenticationType);
|
||||
return (result != null && result.Identity != null && result.Identity.Name == userId);
|
||||
}
|
||||
|
||||
public void RememberClient(string userId)
|
||||
{
|
||||
var rememberBrowserIdentity = new ClaimsIdentity(TwoFactorRememberedAuthenticationType);
|
||||
rememberBrowserIdentity.AddClaim(new Claim(ClaimTypes.Name, userId));
|
||||
Context.Response.SignIn(rememberBrowserIdentity);
|
||||
}
|
||||
|
||||
public async Task<string> RetrieveUserId()
|
||||
{
|
||||
var result = await Context.AuthenticateAsync(TwoFactorUserIdAuthenticationType);
|
||||
if (result != null && result.Identity != null)
|
||||
{
|
||||
return result.Identity.Name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SignIn(ClaimsIdentity identity, bool isPersistent)
|
||||
{
|
||||
Context.Response.SignIn(identity, new AuthenticationProperties { IsPersistent = isPersistent });
|
||||
}
|
||||
public void SignOut(string authenticationType)
|
||||
{
|
||||
Context.Response.SignOut(authenticationType);
|
||||
}
|
||||
|
||||
public Task StoreUserId(string userId)
|
||||
{
|
||||
var userIdentity = new ClaimsIdentity(TwoFactorUserIdAuthenticationType);
|
||||
userIdentity.AddClaim(new Claim(ClaimTypes.Name, userId));
|
||||
Context.Response.SignIn(userIdentity);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8,18 +8,11 @@ namespace Microsoft.AspNet.Identity
|
|||
{
|
||||
public static class IdentityBuilderExtensions
|
||||
{
|
||||
// TODO: remove
|
||||
public static IdentityBuilder<TUser, IdentityRole> AddSecurity<TUser>(this IdentityBuilder<TUser, IdentityRole> builder)
|
||||
where TUser : class
|
||||
{
|
||||
builder.Services.AddScoped<SignInManager<TUser>>();
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IdentityBuilder<TUser, IdentityRole> AddHttpSignIn<TUser>(this IdentityBuilder<TUser, IdentityRole> builder)
|
||||
where TUser : class
|
||||
{
|
||||
builder.Services.AddScoped<SignInManager<TUser>>();
|
||||
// todo: review should this be scoped?
|
||||
builder.Services.AddTransient<IAuthenticationManager, HttpAuthenticationManager>();
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,9 @@
|
|||
<Content Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DefaultAuthenticationTypes.cs" />
|
||||
<Compile Include="HttpAuthenticationManager.cs" />
|
||||
<Compile Include="IdentityBuilderExtensions.cs" />
|
||||
<Compile Include="IdentityExtensions.cs" />
|
||||
<Compile Include="SecurityServiceCollectionExtensions.cs" />
|
||||
<Compile Include="SignInManager.cs" />
|
||||
<Compile Include="SignInStatus.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Identity.Security;
|
||||
|
||||
namespace Microsoft.Framework.DependencyInjection
|
||||
{
|
||||
public static class SecurityServiceCollectionExtensions
|
||||
{
|
||||
// todo: remove?
|
||||
public static ServiceCollection AddSecurity<TUser>(this ServiceCollection services)
|
||||
where TUser : class
|
||||
{
|
||||
services.AddTransient<SignInManager<TUser>>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,178 +0,0 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Security;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Security
|
||||
{
|
||||
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;
|
||||
public string AuthenticationType
|
||||
{
|
||||
get { return _authType ?? DefaultAuthenticationTypes.ApplicationCookie; }
|
||||
set { _authType = value; }
|
||||
}
|
||||
|
||||
public TManager UserManager { get; private set; }
|
||||
public HttpContext Context { get; private set; }
|
||||
|
||||
public virtual async Task<ClaimsIdentity> CreateUserIdentityAsync(TUser user)
|
||||
{
|
||||
return await UserManager.CreateIdentityAsync(user, AuthenticationType);
|
||||
}
|
||||
|
||||
public virtual async Task SignInAsync(TUser user, bool isPersistent, bool rememberBrowser)
|
||||
{
|
||||
// TODO: all the two factor logic/external/rememberBrowser
|
||||
var userIdentity = await CreateUserIdentityAsync(user);
|
||||
Context.Response.SignIn(userIdentity, new AuthenticationProperties { IsPersistent = isPersistent });
|
||||
}
|
||||
|
||||
public virtual void SignOut()
|
||||
{
|
||||
Context.Response.SignOut(AuthenticationType);
|
||||
}
|
||||
|
||||
//public virtual async Task<bool> SendTwoFactorCode(string provider)
|
||||
//{
|
||||
// var userId = await GetVerifiedUserId();
|
||||
// if (userId == null)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// var token = await UserManager.GenerateTwoFactorTokenAsync(userId, provider);
|
||||
// // See IdentityConfig.cs to plug in Email/SMS services to actually send the code
|
||||
// await UserManager.NotifyTwoFactorTokenAsync(userId, provider, token);
|
||||
// return true;
|
||||
//}
|
||||
|
||||
//public Task<TKey> GetVerifiedUserId()
|
||||
//{
|
||||
// //var result = await AuthenticationManager.Authenticate(DefaultAuthenticationTypes.TwoFactorCookie);
|
||||
// //if (result != null && result.Identity != null && !String.IsNullOrEmpty(result.Identity.GetUserIdAsync()))
|
||||
// //{
|
||||
// // return result.Identity.GetUserIdAsync();
|
||||
// //}
|
||||
// return Task.FromResult(default(TKey));
|
||||
//}
|
||||
|
||||
//public async Task<bool> HasBeenVerified()
|
||||
//{
|
||||
// return await GetVerifiedUserId() != null;
|
||||
//}
|
||||
|
||||
//public virtual async Task<SignInStatus> TwoFactorSignIn(string provider, string code, bool isPersistent, bool rememberBrowser)
|
||||
//{
|
||||
// var userId = await GetVerifiedUserId();
|
||||
// if (userId == null)
|
||||
// {
|
||||
// return SignInStatus.Failure;
|
||||
// }
|
||||
// var user = await UserManager.FindByIdAsync(userId);
|
||||
// if (user == null)
|
||||
// {
|
||||
// return SignInStatus.Failure;
|
||||
// }
|
||||
// if (await UserManager.IsLockedOutAsync(user.Id))
|
||||
// {
|
||||
// return SignInStatus.LockedOut;
|
||||
// }
|
||||
// if (await UserManager.VerifyTwoFactorTokenAsync(user.Id, provider, code))
|
||||
// {
|
||||
// // When token is verified correctly, clear the access failed count used for lockout
|
||||
// await UserManager.ResetAccessFailedCountAsync(user.Id);
|
||||
// await SignIn(user, isPersistent, rememberBrowser);
|
||||
// return SignInStatus.Success;
|
||||
// }
|
||||
// // If the token is incorrect, record the failure which also may cause the user to be locked out
|
||||
// await UserManager.AccessFailedAsync(user.Id);
|
||||
// return SignInStatus.Failure;
|
||||
//}
|
||||
|
||||
//public async Task<SignInStatus> ExternalSignIn(ExternalLoginInfo loginInfo, bool isPersistent)
|
||||
//{
|
||||
// var user = await UserManager.FindByLoginAsync(loginInfo.Login);
|
||||
// if (user == null)
|
||||
// {
|
||||
// return SignInStatus.Failure;
|
||||
// }
|
||||
// if (await UserManager.IsLockedOutAsync(user.Id))
|
||||
// {
|
||||
// return SignInStatus.LockedOut;
|
||||
// }
|
||||
// return await SignInOrTwoFactor(user, isPersistent);
|
||||
//}
|
||||
|
||||
//private async Task<SignInStatus> SignInOrTwoFactor(TUser user, bool isPersistent)
|
||||
//{
|
||||
// if (await UserManager.GetTwoFactorEnabledAsync(user.Id))
|
||||
// //&& !await AuthenticationManager.TwoFactorBrowserRemembered(user.Id))
|
||||
// {
|
||||
// //var identity = new ClaimsIdentity(DefaultAuthenticationTypes.TwoFactorCookie);
|
||||
// //identity.AddClaimAsync(new Claim(ClaimTypes.NameIdentifier, user.Id));
|
||||
// //AuthenticationManager.SignIn(identity);
|
||||
// return SignInStatus.RequiresTwoFactorAuthentication;
|
||||
// }
|
||||
// await SignIn(user, isPersistent, false);
|
||||
// return SignInStatus.Success;
|
||||
//}
|
||||
|
||||
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
|
||||
{
|
||||
var user = await UserManager.FindByNameAsync(userName);
|
||||
if (user == null)
|
||||
{
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
if (UserManager.SupportsUserLockout && await UserManager.IsLockedOutAsync(user))
|
||||
{
|
||||
return SignInStatus.LockedOut;
|
||||
}
|
||||
if (await UserManager.CheckPasswordAsync(user, password))
|
||||
{
|
||||
await SignInAsync(user, isPersistent, false);
|
||||
return SignInStatus.Success;
|
||||
//TODO: return await SignInOrTwoFactor(user, isPersistent);
|
||||
}
|
||||
if (UserManager.SupportsUserLockout && shouldLockout)
|
||||
{
|
||||
// If lockout is requested, increment access failed count which might lock out the user
|
||||
await UserManager.AccessFailedAsync(user);
|
||||
if (await UserManager.IsLockedOutAsync(user))
|
||||
{
|
||||
return SignInStatus.LockedOut;
|
||||
}
|
||||
}
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -42,17 +42,5 @@ namespace Microsoft.AspNet.Identity
|
|||
/// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Security
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
public static class DefaultAuthenticationTypes
|
||||
{
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
public interface IAuthenticationManager
|
||||
{
|
||||
void SignIn(ClaimsIdentity identity, bool isPersistent);
|
||||
void SignOut(string authenticationType);
|
||||
|
||||
// remember browser for two factor
|
||||
void ForgetClient();
|
||||
void RememberClient(string userId);
|
||||
Task<bool> IsClientRememeberedAsync(string userId);
|
||||
|
||||
// half cookie
|
||||
Task StoreUserId(string userId);
|
||||
Task<string> RetrieveUserId();
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ namespace Microsoft.AspNet.Identity
|
|||
|
||||
public IdentityOptions()
|
||||
{
|
||||
// TODO: Split into sub options
|
||||
ClaimType = new ClaimTypeOptions();
|
||||
User = new UserOptions();
|
||||
Password = new PasswordOptions();
|
||||
|
|
@ -28,18 +27,5 @@ namespace Microsoft.AspNet.Identity
|
|||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@ namespace Microsoft.Framework.DependencyInjection
|
|||
services.Add(IdentityServices.GetDefaultUserServices<TUser>());
|
||||
services.Add(IdentityServices.GetDefaultRoleServices<TRole>());
|
||||
services.AddScoped<UserManager<TUser>>();
|
||||
services.AddScoped<SignInManager<TUser>>();
|
||||
services.AddScoped<RoleManager<TRole>>();
|
||||
return new IdentityBuilder<TUser, TRole>(services);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
<Compile Include="ClaimsIdentityFactory.cs" />
|
||||
<Compile Include="ClaimTypeOptions.cs" />
|
||||
<Compile Include="Crypto.cs" />
|
||||
<Compile Include="DefaultAuthenticationTypes.cs" />
|
||||
<Compile Include="IAuthenticationManager.cs" />
|
||||
<Compile Include="IClaimsIdentityFactory.cs" />
|
||||
<Compile Include="IdentityBuilder.cs" />
|
||||
<Compile Include="IdentityMessage.cs" />
|
||||
|
|
@ -64,6 +66,8 @@
|
|||
<Compile Include="Rfc6238AuthenticationService.cs" />
|
||||
<Compile Include="RoleManager.cs" />
|
||||
<Compile Include="RoleValidator.cs" />
|
||||
<Compile Include="SignInManager.cs" />
|
||||
<Compile Include="SignInStatus.cs" />
|
||||
<Compile Include="UserLoginInfo.cs" />
|
||||
<Compile Include="UserManager.cs" />
|
||||
<Compile Include="UserOptions.cs" />
|
||||
|
|
|
|||
|
|
@ -40,18 +40,5 @@ namespace Microsoft.AspNet.Identity
|
|||
/// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface that manages SignIn operations for a user
|
||||
/// </summary>
|
||||
/// <typeparam name="TUser"></typeparam>
|
||||
public class SignInManager<TUser> where TUser : class
|
||||
{
|
||||
public SignInManager(UserManager<TUser> userManager, IAuthenticationManager authenticationManager)
|
||||
{
|
||||
if (userManager == null)
|
||||
{
|
||||
throw new ArgumentNullException("userManager");
|
||||
}
|
||||
if (authenticationManager == null)
|
||||
{
|
||||
throw new ArgumentNullException("authenticationManager");
|
||||
}
|
||||
UserManager = userManager;
|
||||
AuthenticationManager = authenticationManager;
|
||||
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie;
|
||||
}
|
||||
|
||||
// TODO: this should go into some kind of Options/setup
|
||||
public string AuthenticationType { get; set; }
|
||||
|
||||
public UserManager<TUser> UserManager { get; private set; }
|
||||
public IAuthenticationManager AuthenticationManager { get; private set; }
|
||||
|
||||
// Should this be a func?
|
||||
public virtual async Task<ClaimsIdentity> CreateUserIdentityAsync(TUser user)
|
||||
{
|
||||
return await UserManager.CreateIdentityAsync(user, AuthenticationType);
|
||||
}
|
||||
|
||||
public virtual async Task SignInAsync(TUser user, bool isPersistent)
|
||||
{
|
||||
var userIdentity = await CreateUserIdentityAsync(user);
|
||||
AuthenticationManager.SignIn(userIdentity, isPersistent);
|
||||
}
|
||||
|
||||
// TODO: Should this be async?
|
||||
public void SignOut()
|
||||
{
|
||||
AuthenticationManager.SignOut(AuthenticationType);
|
||||
}
|
||||
|
||||
public virtual async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
|
||||
{
|
||||
var user = await UserManager.FindByNameAsync(userName);
|
||||
if (user == null)
|
||||
{
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
if (UserManager.SupportsUserLockout && await UserManager.IsLockedOutAsync(user))
|
||||
{
|
||||
return SignInStatus.LockedOut;
|
||||
}
|
||||
if (await UserManager.CheckPasswordAsync(user, password))
|
||||
{
|
||||
return await SignInOrTwoFactor(user, isPersistent);
|
||||
}
|
||||
if (UserManager.SupportsUserLockout && shouldLockout)
|
||||
{
|
||||
// If lockout is requested, increment access failed count which might lock out the user
|
||||
await UserManager.AccessFailedAsync(user);
|
||||
if (await UserManager.IsLockedOutAsync(user))
|
||||
{
|
||||
return SignInStatus.LockedOut;
|
||||
}
|
||||
}
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
|
||||
public virtual async Task<bool> SendTwoFactorCode(string provider)
|
||||
{
|
||||
var userId = await AuthenticationManager.RetrieveUserId();
|
||||
if (userId == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var user = await UserManager.FindByIdAsync(userId);
|
||||
if (user == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var token = await UserManager.GenerateTwoFactorTokenAsync(user, provider);
|
||||
// See IdentityConfig.cs to plug in Email/SMS services to actually send the code
|
||||
await UserManager.NotifyTwoFactorTokenAsync(user, provider, token);
|
||||
return true;
|
||||
}
|
||||
|
||||
//public async Task<bool> HasBeenVerified()
|
||||
//{
|
||||
// return await GetVerifiedUserId() != null;
|
||||
//}
|
||||
|
||||
public virtual async Task RememberTwoFactorClient(TUser user)
|
||||
{
|
||||
var userId = await UserManager.GetUserIdAsync(user);
|
||||
AuthenticationManager.RememberClient(userId);
|
||||
}
|
||||
|
||||
public virtual Task ForgetTwoFactorClientAsync()
|
||||
{
|
||||
AuthenticationManager.ForgetClient();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public virtual async Task<SignInStatus> TwoFactorSignInAsync(string provider, string code, bool isPersistent)
|
||||
{
|
||||
var userId = await AuthenticationManager.RetrieveUserId();
|
||||
if (userId == null)
|
||||
{
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
var user = await UserManager.FindByIdAsync(userId);
|
||||
if (user == null)
|
||||
{
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
if (await UserManager.IsLockedOutAsync(user))
|
||||
{
|
||||
return SignInStatus.LockedOut;
|
||||
}
|
||||
if (await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
|
||||
{
|
||||
// When token is verified correctly, clear the access failed count used for lockout
|
||||
await UserManager.ResetAccessFailedCountAsync(user);
|
||||
await SignInAsync(user, isPersistent);
|
||||
return SignInStatus.Success;
|
||||
}
|
||||
// If the token is incorrect, record the failure which also may cause the user to be locked out
|
||||
await UserManager.AccessFailedAsync(user);
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
|
||||
public async Task<SignInStatus> ExternalLoginSignInAsync(UserLoginInfo loginInfo, bool isPersistent)
|
||||
{
|
||||
var user = await UserManager.FindByLoginAsync(loginInfo);
|
||||
if (user == null)
|
||||
{
|
||||
return SignInStatus.Failure;
|
||||
}
|
||||
if (await UserManager.IsLockedOutAsync(user))
|
||||
{
|
||||
return SignInStatus.LockedOut;
|
||||
}
|
||||
return await SignInOrTwoFactor(user, isPersistent);
|
||||
}
|
||||
|
||||
private async Task<SignInStatus> SignInOrTwoFactor(TUser user, bool isPersistent)
|
||||
{
|
||||
if (await UserManager.GetTwoFactorEnabledAsync(user))
|
||||
{
|
||||
var userId = await UserManager.GetUserIdAsync(user);
|
||||
if (!await AuthenticationManager.IsClientRememeberedAsync(userId))
|
||||
{
|
||||
// Store the userId for use after two factor check
|
||||
await AuthenticationManager.StoreUserId(userId);
|
||||
return SignInStatus.RequiresVerification;
|
||||
}
|
||||
}
|
||||
await SignInAsync(user, isPersistent);
|
||||
return SignInStatus.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Security
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
public enum SignInStatus
|
||||
{
|
||||
Success,
|
||||
LockedOut,
|
||||
RequiresTwoFactorAuthentication,
|
||||
RequiresVerification,
|
||||
Failure
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -727,7 +727,7 @@ namespace Microsoft.AspNet.Identity
|
|||
/// <param name="newPassword"></param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> ResetPassword(TUser user, string token, string newPassword, CancellationToken cancellationToken = default(CancellationToken))
|
||||
public virtual async Task<IdentityResult> ResetPasswordAsync(TUser user, string token, string newPassword, CancellationToken cancellationToken = default(CancellationToken))
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
|
|
|
|||
|
|
@ -22,15 +22,5 @@ namespace Microsoft.AspNet.Identity
|
|||
/// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,10 +19,6 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
{
|
||||
public class InMemoryUserStoreTest
|
||||
{
|
||||
class ApplicationUserManager : UserManager<EntityUser>
|
||||
{
|
||||
public ApplicationUserManager(IServiceProvider services, IUserStore<EntityUser> store, IOptionsAccessor<IdentityOptions> options) : base(services, store, options) { }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanUseAddedManagerInstance()
|
||||
|
|
@ -30,11 +26,11 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
var services = new ServiceCollection();
|
||||
services.AddEntityFramework().AddInMemoryStore();
|
||||
services.AddSingleton<IOptionsAccessor<IdentityOptions>, OptionsAccessor<IdentityOptions>>();
|
||||
services.AddInstance<DbContext>(new IdentityContext());
|
||||
services.AddTransient<IUserStore<EntityUser>, InMemoryInMemoryUserStore>();
|
||||
services.AddSingleton<ApplicationUserManager, ApplicationUserManager>();
|
||||
services.AddInstance<IdentityContext>(new IdentityContext());
|
||||
services.AddTransient<IUserStore<EntityUser>, InMemoryUserStore>();
|
||||
services.AddSingleton<UserManager<EntityUser>>();
|
||||
var provider = services.BuildServiceProvider();
|
||||
var manager = provider.GetService<ApplicationUserManager>();
|
||||
var manager = provider.GetService<UserManager<EntityUser>>();
|
||||
Assert.NotNull(manager);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityUser("hello")));
|
||||
}
|
||||
|
|
@ -46,41 +42,23 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
services.AddEntityFramework().AddInMemoryStore();
|
||||
|
||||
// TODO: this needs to construct a new instance of InMemoryStore
|
||||
var store = new InMemoryInMemoryUserStore(new IdentityContext());
|
||||
var store = new InMemoryUserStore(new IdentityContext());
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddIdentity<EntityUser, EntityRole>(s =>
|
||||
{
|
||||
s.AddUserStore(() => store);
|
||||
s.AddUserManager<ApplicationUserManager>();
|
||||
});
|
||||
|
||||
var provider = services.BuildServiceProvider();
|
||||
var manager = provider.GetService<ApplicationUserManager>();
|
||||
var manager = provider.GetService<UserManager<EntityUser>>();
|
||||
Assert.NotNull(manager);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityUser("hello2")));
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task CanUseSingletonGenericManagerInstance()
|
||||
//{
|
||||
// var services = new ServiceCollection();
|
||||
// var store = new EntityUserStore(new IdentityContext());
|
||||
// services.AddIdentity<EntityUser>(s =>
|
||||
// {
|
||||
// s.UseStore(() => store);
|
||||
// s.UseManager<UserManager<EntityUser>>();
|
||||
// });
|
||||
|
||||
// var provider = services.BuildServiceProvider();
|
||||
// var manager = provider.GetService<UserManager<EntityUser>>();
|
||||
// Assert.NotNull(manager);
|
||||
// IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityUser("hello")));
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task EntityUserStoreMethodsThrowWhenDisposedTest()
|
||||
{
|
||||
var store = new InMemoryInMemoryUserStore(new IdentityContext());
|
||||
var store = new InMemoryUserStore(new IdentityContext());
|
||||
store.Dispose();
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.AddClaimAsync(null, null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.AddLoginAsync(null, null));
|
||||
|
|
@ -112,8 +90,8 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
[Fact]
|
||||
public async Task EntityUserStorePublicNullCheckTest()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>("context", () => new InMemoryInMemoryUserStore(null));
|
||||
var store = new InMemoryInMemoryUserStore(new IdentityContext());
|
||||
Assert.Throws<ArgumentNullException>("context", () => new InMemoryUserStore(null));
|
||||
var store = new InMemoryUserStore(new IdentityContext());
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.GetUserIdAsync(null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.GetUserNameAsync(null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user", async () => await store.SetUserNameAsync(null, null));
|
||||
|
|
@ -675,7 +653,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
Assert.NotNull(stamp);
|
||||
var token = await manager.GeneratePasswordResetTokenAsync(user);
|
||||
Assert.NotNull(token);
|
||||
IdentityResultAssert.IsSuccess(await manager.ResetPassword(user, token, newPassword));
|
||||
IdentityResultAssert.IsSuccess(await manager.ResetPasswordAsync(user, token, newPassword));
|
||||
Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, newPassword));
|
||||
Assert.NotEqual(stamp, user.SecurityStamp);
|
||||
|
|
@ -695,7 +673,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
var token = await manager.GeneratePasswordResetTokenAsync(user);
|
||||
Assert.NotNull(token);
|
||||
manager.PasswordValidator = new AlwaysBadValidator();
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPassword(user, token, newPassword),
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, token, newPassword),
|
||||
AlwaysBadValidator.ErrorMessage);
|
||||
Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
|
|
@ -713,7 +691,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password));
|
||||
var stamp = user.SecurityStamp;
|
||||
Assert.NotNull(stamp);
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPassword(user, "bogus", newPassword), "Invalid token.");
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, "bogus", newPassword), "Invalid token.");
|
||||
Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(stamp, user.SecurityStamp);
|
||||
|
|
|
|||
|
|
@ -28,4 +28,4 @@
|
|||
<Compile Include="TestIdentityFactory.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -14,11 +14,6 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
{
|
||||
public class RoleStoreTest
|
||||
{
|
||||
class ApplicationRoleManager : RoleManager<EntityRole>
|
||||
{
|
||||
public ApplicationRoleManager(IServiceProvider services, IRoleStore<EntityRole> store) : base(services, store) { }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanCreateUsingAddRoleManager()
|
||||
{
|
||||
|
|
@ -29,11 +24,10 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
services.AddIdentity<EntityUser, EntityRole>(s =>
|
||||
{
|
||||
s.AddRoleStore(() => store);
|
||||
s.AddRoleManager<ApplicationRoleManager>();
|
||||
});
|
||||
|
||||
var provider = services.BuildServiceProvider();
|
||||
var manager = provider.GetService<ApplicationRoleManager>();
|
||||
var manager = provider.GetService<RoleManager<EntityRole>>();
|
||||
Assert.NotNull(manager);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityRole("arole")));
|
||||
}
|
||||
|
|
@ -42,13 +36,11 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddEntityFramework().AddInMemoryStore();
|
||||
services.AddTransient<DbContext, IdentityContext>();
|
||||
services.AddTransient<IdentityContext>();
|
||||
services.AddTransient<IRoleStore<EntityRole>, EntityRoleStore<EntityRole>>();
|
||||
//todo: services.AddSingleton<RoleManager<EntityRole>, RoleManager<EntityRole>>();
|
||||
// TODO: How to configure SqlServer?
|
||||
services.AddSingleton<ApplicationRoleManager, ApplicationRoleManager>();
|
||||
services.AddSingleton<RoleManager<EntityRole>>();
|
||||
var provider = services.BuildServiceProvider();
|
||||
var manager = provider.GetService<ApplicationRoleManager>();
|
||||
var manager = provider.GetService<RoleManager<EntityRole>>();
|
||||
Assert.NotNull(manager);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(new EntityRole("someRole")));
|
||||
}
|
||||
|
|
@ -56,7 +48,7 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
[Fact]
|
||||
public async Task RoleStoreMethodsThrowWhenDisposedTest()
|
||||
{
|
||||
var store = new EntityRoleStore<EntityRole, string>(new IdentityContext());
|
||||
var store = new EntityRoleStore<EntityRole>(new IdentityContext());
|
||||
store.Dispose();
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByIdAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(async () => await store.FindByNameAsync(null));
|
||||
|
|
@ -71,8 +63,8 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
[Fact]
|
||||
public async Task RoleStorePublicNullCheckTest()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>("context", () => new EntityRoleStore<EntityRole, string>(null));
|
||||
var store = new EntityRoleStore<EntityRole, string>(new IdentityContext());
|
||||
Assert.Throws<ArgumentNullException>("context", () => new EntityRoleStore<EntityRole>(null));
|
||||
var store = new EntityRoleStore<EntityRole>(new IdentityContext());
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await store.GetRoleIdAsync(null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await store.GetRoleNameAsync(null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("role", async () => await store.SetRoleNameAsync(null, null));
|
||||
|
|
|
|||
|
|
@ -17,11 +17,20 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
{
|
||||
public class SqlUserStoreTest
|
||||
{
|
||||
private const string ConnectionString = @"Server=(localdb)\v11.0;Database=SqlUserStoreTest;Trusted_Connection=True;";
|
||||
|
||||
public class ApplicationUser : User { }
|
||||
|
||||
public class ApplicationDbContext : IdentitySqlContext<ApplicationUser>
|
||||
{
|
||||
public ApplicationDbContext(IServiceProvider services) : base(services) { }
|
||||
public ApplicationDbContext(IServiceProvider services, IOptionsAccessor<DbContextOptions> options) : base(services, options.Options) { }
|
||||
}
|
||||
|
||||
[TestPriority(0)]
|
||||
[Fact]
|
||||
public void RecreateDatabase()
|
||||
{
|
||||
CreateContext(true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -32,9 +41,10 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
|
||||
builder.UseServices(services =>
|
||||
{
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddEntityFramework().AddSqlServer();
|
||||
services.AddIdentityEntityFramework<ApplicationDbContext, ApplicationUser>();
|
||||
services.AddIdentity<ApplicationUser>().AddEntityFramework<ApplicationUser, ApplicationDbContext>();
|
||||
services.SetupOptions<DbContextOptions>(options =>
|
||||
options.UseSqlServer(ConnectionString));
|
||||
});
|
||||
|
||||
var userStore = builder.ApplicationServices.GetService<IUserStore<ApplicationUser>>();
|
||||
|
|
@ -58,19 +68,23 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
var guid = Guid.NewGuid().ToString();
|
||||
db.Users.Add(new User {Id = guid, UserName = guid});
|
||||
db.SaveChanges();
|
||||
Assert.True(db.Users.Any(u => u.UserName == guid));
|
||||
Assert.NotNull(db.Users.FirstOrDefault(u => u.UserName == guid));
|
||||
}
|
||||
}
|
||||
|
||||
public static IdentitySqlContext CreateContext()
|
||||
public static IdentitySqlContext CreateContext(bool delete = false)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddEntityFramework().AddSqlServer();
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
var db = new IdentitySqlContext(serviceProvider);
|
||||
var db = new IdentitySqlContext(serviceProvider, ConnectionString);
|
||||
if (delete)
|
||||
{
|
||||
db.Database.EnsureDeleted();
|
||||
}
|
||||
db.Database.EnsureCreated();
|
||||
|
||||
return db;
|
||||
}
|
||||
|
||||
|
|
@ -81,45 +95,20 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
|
||||
public static ApplicationDbContext CreateAppContext()
|
||||
{
|
||||
CreateContext();
|
||||
var services = new ServiceCollection();
|
||||
services.AddEntityFramework().AddSqlServer();
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
var db = new ApplicationDbContext(serviceProvider);
|
||||
|
||||
// TODO: Recreate DB, doesn't support String ID or Identity context yet
|
||||
var db = new ApplicationDbContext(serviceProvider, serviceProvider.GetService<IOptionsAccessor<DbContextOptions>>());
|
||||
db.Database.EnsureCreated();
|
||||
|
||||
// TODO: CreateAsync DB?
|
||||
return db;
|
||||
}
|
||||
|
||||
public static UserManager<User> CreateManager(DbContext context)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddTransient<IUserValidator<User>, UserValidator<User>>();
|
||||
services.AddTransient<IPasswordValidator<User>, PasswordValidator<User>>();
|
||||
//services.AddInstance<IUserStore<User>>(new UserStore<User>(context));
|
||||
//services.AddSingleton<UserManager<User>>();
|
||||
var options = new IdentityOptions
|
||||
{
|
||||
Password = new PasswordOptions
|
||||
{
|
||||
RequireDigit = false,
|
||||
RequireLowercase = false,
|
||||
RequireNonLetterOrDigit = false,
|
||||
RequireUppercase = false
|
||||
},
|
||||
User = new UserOptions
|
||||
{
|
||||
AllowOnlyAlphanumericNames = false
|
||||
}
|
||||
|
||||
};
|
||||
var optionsAccessor = new OptionsAccessor<IdentityOptions>(new[] { new TestIdentityFactory.TestSetup(options) });
|
||||
//services.AddInstance<IOptionsAccessor<IdentityOptions>>(new OptionsAccessor<IdentityOptions>(new[] { new TestSetup(options) }));
|
||||
//return services.BuildServiceProvider().GetService<UserManager<User>>();
|
||||
return new UserManager<User>(services.BuildServiceProvider(), new UserStore<User>(context), optionsAccessor);
|
||||
return MockHelpers.CreateManager(() => new UserStore<User>(context));
|
||||
}
|
||||
|
||||
public static UserManager<User> CreateManager()
|
||||
|
|
@ -151,13 +140,14 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
public async Task CanUpdateUserName()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = new User("UpdateAsync");
|
||||
var oldName = Guid.NewGuid().ToString();
|
||||
var user = new User(oldName);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
Assert.Null(await manager.FindByNameAsync("New"));
|
||||
user.UserName = "New";
|
||||
var newName = Guid.NewGuid().ToString();
|
||||
user.UserName = newName;
|
||||
IdentityResultAssert.IsSuccess(await manager.UpdateAsync(user));
|
||||
Assert.NotNull(await manager.FindByNameAsync("New"));
|
||||
Assert.Null(await manager.FindByNameAsync("UpdateAsync"));
|
||||
Assert.NotNull(await manager.FindByNameAsync(newName));
|
||||
Assert.Null(await manager.FindByNameAsync(oldName));
|
||||
IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user));
|
||||
}
|
||||
|
||||
|
|
@ -165,12 +155,13 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
public async Task CanSetUserName()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = new User("UpdateAsync");
|
||||
var oldName = Guid.NewGuid().ToString();
|
||||
var user = new User(oldName);
|
||||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
Assert.Null(await manager.FindByNameAsync("New"));
|
||||
IdentityResultAssert.IsSuccess(await manager.SetUserNameAsync(user, "New"));
|
||||
Assert.NotNull(await manager.FindByNameAsync("New"));
|
||||
Assert.Null(await manager.FindByNameAsync("UpdateAsync"));
|
||||
var newName = Guid.NewGuid().ToString();
|
||||
IdentityResultAssert.IsSuccess(await manager.SetUserNameAsync(user, newName));
|
||||
Assert.NotNull(await manager.FindByNameAsync(newName));
|
||||
Assert.Null(await manager.FindByNameAsync(oldName));
|
||||
IdentityResultAssert.IsSuccess(await manager.DeleteAsync(user));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Identity.Test;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
|
|
@ -16,95 +15,39 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
public class StartupTest
|
||||
{
|
||||
public class ApplicationUser : EntityUser { }
|
||||
public class ApplicationUserManager : UserManager<ApplicationUser>
|
||||
|
||||
public class ApplicationDbContext : IdentityContext<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.Builder(new ServiceCollection().BuildServiceProvider());
|
||||
builder.UseServices(services => {
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
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.Builder(new ServiceCollection().BuildServiceProvider());
|
||||
app.UseServices(services => {
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
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);
|
||||
public ApplicationDbContext(IServiceProvider services) : base(services) { }
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnsureStartupUsageWorks()
|
||||
{
|
||||
EnsureDatabase();
|
||||
|
||||
IBuilder builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider());
|
||||
|
||||
builder.UseServices(services =>
|
||||
{
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddEntityFramework();
|
||||
services.AddTransient<DbContext, IdentityContext>();
|
||||
services.AddEntityFramework().AddInMemoryStore();
|
||||
services.AddIdentity<ApplicationUser, EntityRole>(s =>
|
||||
{
|
||||
s.AddEntity();
|
||||
s.AddUserManager<ApplicationUserManager>();
|
||||
s.AddRoleManager<ApplicationRoleManager>();
|
||||
s.AddEntityFrameworkInMemory<ApplicationUser, EntityRole, ApplicationDbContext>();
|
||||
});
|
||||
});
|
||||
|
||||
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>();
|
||||
var userManager = builder.ApplicationServices.GetService<UserManager<ApplicationUser>>();
|
||||
var roleManager = builder.ApplicationServices.GetService<RoleManager<EntityRole>>();
|
||||
|
||||
Assert.NotNull(userStore);
|
||||
Assert.NotNull(userManager);
|
||||
Assert.NotNull(roleStore);
|
||||
Assert.NotNull(roleManager);
|
||||
|
||||
//await CreateAdminUser(builder.ApplicationServices);
|
||||
await CreateAdminUser(builder.ApplicationServices);
|
||||
}
|
||||
|
||||
private static async Task CreateAdminUser(IServiceProvider serviceProvider)
|
||||
|
|
@ -112,13 +55,23 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
const string userName = "admin";
|
||||
const string roleName = "Admins";
|
||||
const string password = "1qaz@WSX";
|
||||
var userManager = serviceProvider.GetService<ApplicationUserManager>();
|
||||
var roleManager = serviceProvider.GetService<ApplicationRoleManager>();
|
||||
var userManager = serviceProvider.GetService<UserManager<ApplicationUser>>();
|
||||
var roleManager = serviceProvider.GetService<RoleManager<EntityRole>>();
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
public static void EnsureDatabase()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddEntityFramework().AddInMemoryStore();
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
var db = new ApplicationDbContext(serviceProvider);
|
||||
db.Database.EnsureCreated();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNet.Identity.Test;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Entity.Test
|
||||
{
|
||||
|
|
@ -13,61 +15,18 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
public static IdentityContext CreateContext()
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
|
||||
//#if NET45
|
||||
// services.AddEntityFramework().AddSqlServer();
|
||||
//#else
|
||||
services.AddEntityFramework().AddInMemoryStore();
|
||||
//#endif
|
||||
var serviceProvider = services.BuildServiceProvider();
|
||||
|
||||
var db = new IdentityContext(serviceProvider);
|
||||
|
||||
// TODO: Recreate DB, doesn't support String ID or Identity context yet
|
||||
db.Database.EnsureCreated();
|
||||
|
||||
// TODO: CreateAsync DB?
|
||||
return db;
|
||||
}
|
||||
|
||||
public class TestSetup : IOptionsSetup<IdentityOptions>
|
||||
public static UserManager<EntityUser> CreateManager(IdentityContext context)
|
||||
{
|
||||
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)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddTransient<IUserValidator<EntityUser>, UserValidator<EntityUser>>();
|
||||
services.AddTransient<IPasswordValidator<IdentityUser>, PasswordValidator<IdentityUser>>();
|
||||
services.AddInstance<IUserStore<EntityUser>>(new InMemoryUserStore<EntityUser>(context));
|
||||
services.AddSingleton<UserManager<EntityUser>, UserManager<EntityUser>>();
|
||||
var options = new IdentityOptions
|
||||
{
|
||||
Password = new PasswordOptions
|
||||
{
|
||||
RequireDigit = false,
|
||||
RequireLowercase = false,
|
||||
RequireNonLetterOrDigit = false,
|
||||
RequireUppercase = false
|
||||
}
|
||||
};
|
||||
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 InMemoryUserStore<EntityUser>(context), optionsAccessor);
|
||||
return MockHelpers.CreateManager<EntityUser>(() => new InMemoryUserStore<EntityUser>(context));
|
||||
}
|
||||
|
||||
public static UserManager<EntityUser> CreateManager()
|
||||
|
|
@ -75,13 +34,12 @@ namespace Microsoft.AspNet.Identity.Entity.Test
|
|||
return CreateManager(CreateContext());
|
||||
}
|
||||
|
||||
public static RoleManager<EntityRole> CreateRoleManager(DbContext context)
|
||||
public static RoleManager<EntityRole> CreateRoleManager(IdentityContext context)
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.AddTransient<IRoleValidator<EntityRole>, RoleValidator<EntityRole>>();
|
||||
services.AddInstance<IRoleStore<EntityRole>>(new EntityRoleStore<EntityRole, string>(context));
|
||||
// return services.BuildServiceProvider().GetService<RoleManager<EntityRole>>();
|
||||
return new RoleManager<EntityRole>(services.BuildServiceProvider(), new EntityRoleStore<EntityRole, string>(context));
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddIdentity<EntityUser, EntityRole>(b => b.AddRoleStore(() => new EntityRoleStore<EntityRole>(context)));
|
||||
return services.BuildServiceProvider().GetService<RoleManager<EntityRole>>();
|
||||
}
|
||||
|
||||
public static RoleManager<EntityRole> CreateRoleManager()
|
||||
|
|
|
|||
|
|
@ -16,24 +16,17 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
|||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddTransient<IUserValidator<IdentityUser>, UserValidator<IdentityUser>>();
|
||||
services.AddTransient<IPasswordValidator<IdentityUser>, PasswordValidator<IdentityUser>>();
|
||||
var options = new IdentityOptions
|
||||
services.AddSingleton<IUserStore<IdentityUser>, InMemoryUserStore<IdentityUser>>();
|
||||
services.AddSingleton<UserManager<IdentityUser>>();
|
||||
services.SetupOptions<IdentityOptions>(options =>
|
||||
{
|
||||
Password = new PasswordOptions {
|
||||
RequireDigit = false,
|
||||
RequireLowercase = false,
|
||||
RequireNonLetterOrDigit = false,
|
||||
RequireUppercase = false
|
||||
},
|
||||
User = new UserOptions {
|
||||
AllowOnlyAlphanumericNames = false
|
||||
}
|
||||
};
|
||||
var optionsAccessor = new OptionsAccessor<IdentityOptions>(new[] {new TestSetup(options)});
|
||||
//services.AddInstance<IOptionsAccessor<IdentityOptions>>(optionsAccessor);
|
||||
//services.AddInstance<IUserStore<IdentityUser>>(new InMemoryUserStore<IdentityUser>());
|
||||
//services.AddSingleton<UserManager<IdentityUser>, UserManager<IdentityUser>>();
|
||||
//return services.BuildServiceProvider().GetService<UserManager<IdentityUser>>();
|
||||
return new UserManager<IdentityUser>(services.BuildServiceProvider(), new InMemoryUserStore<IdentityUser>(), optionsAccessor);
|
||||
options.Password.RequireDigit = false;
|
||||
options.Password.RequireLowercase = false;
|
||||
options.Password.RequireNonLetterOrDigit = false;
|
||||
options.Password.RequireUppercase = false;
|
||||
options.User.AllowOnlyAlphanumericNames = false;
|
||||
});
|
||||
return services.BuildServiceProvider().GetService<UserManager<IdentityUser>>();
|
||||
}
|
||||
|
||||
protected override RoleManager<IdentityRole> CreateRoleManager()
|
||||
|
|
@ -41,8 +34,8 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
|||
var services = new ServiceCollection();
|
||||
services.AddTransient<IRoleValidator<IdentityRole>, RoleValidator<IdentityRole>>();
|
||||
services.AddInstance<IRoleStore<IdentityRole>>(new InMemoryRoleStore<IdentityRole>());
|
||||
//return services.BuildServiceProvider().GetService<RoleManager<IdentityRole>>();
|
||||
return new RoleManager<IdentityRole>(services.BuildServiceProvider(), new InMemoryRoleStore<IdentityRole>());
|
||||
services.AddSingleton<RoleManager<IdentityRole>>();
|
||||
return services.BuildServiceProvider().GetService<RoleManager<IdentityRole>>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,4 +25,4 @@
|
|||
<Compile Include="StartupTest.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Identity.Test;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.InMemory.Test
|
||||
|
|
@ -16,56 +16,6 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
|||
{
|
||||
public class ApplicationUser : IdentityUser { }
|
||||
|
||||
public class PasswordsNegativeLengthSetup : IOptionsSetup<IdentityOptions>
|
||||
{
|
||||
public int Order { get { return 0; } }
|
||||
public void Setup(IdentityOptions options)
|
||||
{
|
||||
options.Password.RequiredLength = -1;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanCustomizeIdentityOptions()
|
||||
{
|
||||
var builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider());
|
||||
builder.UseServices(services => {
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
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()
|
||||
{
|
||||
var app = new Builder.Builder(new ServiceCollection().BuildServiceProvider());
|
||||
app.UseServices(services =>
|
||||
{
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
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()
|
||||
{
|
||||
|
|
@ -73,7 +23,6 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
|||
|
||||
builder.UseServices(services => services.AddIdentity<ApplicationUser>(s =>
|
||||
{
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
s.AddInMemory();
|
||||
}));
|
||||
|
||||
|
|
@ -96,7 +45,6 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
|||
var builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider());
|
||||
builder.UseServices(services =>
|
||||
{
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddIdentity<ApplicationUser>(s => s.AddInMemory());
|
||||
|
||||
});
|
||||
|
|
@ -116,6 +64,7 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
|
|||
var userManager2 = builder.ApplicationServices.GetService<UserManager<ApplicationUser>>();
|
||||
var roleManager2 = builder.ApplicationServices.GetService<RoleManager<IdentityRole>>();
|
||||
|
||||
// Stores are singleton, managers are scoped
|
||||
Assert.Equal(userStore, userStore2);
|
||||
Assert.Equal(userManager, userManager2);
|
||||
Assert.Equal(roleStore, roleStore2);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ using Microsoft.AspNet.Identity.Test;
|
|||
using Microsoft.AspNet.Security.Cookies;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Microsoft.Framework.Logging;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Moq;
|
||||
using System.Security.Claims;
|
||||
|
|
@ -19,7 +18,9 @@ using Microsoft.AspNet.Builder;
|
|||
|
||||
namespace Microsoft.AspNet.Identity.Security.Test
|
||||
{
|
||||
public class SignInManagerTest
|
||||
public class ApplicationUser : IdentityUser { }
|
||||
|
||||
public class HttpSignInTest
|
||||
{
|
||||
#if NET45
|
||||
[Theory]
|
||||
|
|
@ -43,7 +44,6 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
{
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddInstance(contextAccessor.Object);
|
||||
services.AddInstance<ILoggerFactory>(new NullLoggerFactory());
|
||||
services.AddIdentity<ApplicationUser, IdentityRole>(s =>
|
||||
{
|
||||
s.AddInMemory();
|
||||
|
|
@ -95,7 +95,7 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
// s.AddRoleStore(() => new InMemoryRoleStore<IdentityRole>());
|
||||
// s.AddRoleManager<ApplicationRoleManager>();
|
||||
// });
|
||||
// services.AddTransient<ApplicationSignInManager>();
|
||||
// services.AddTransient<ApplicationHttpSignInManager>();
|
||||
// });
|
||||
|
||||
// // Act
|
||||
|
|
@ -105,10 +105,10 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
// };
|
||||
// const string password = "Yol0Sw@g!";
|
||||
// var userManager = app.ApplicationServices.GetService<ApplicationUserManager>();
|
||||
// var signInManager = app.ApplicationServices.GetService<ApplicationSignInManager>();
|
||||
// var HttpSignInManager = app.ApplicationServices.GetService<ApplicationHttpSignInManager>();
|
||||
|
||||
// IdentityResultAssert.IsSuccess(await userManager.CreateAsync(user, password));
|
||||
// var result = await signInManager.PasswordSignInAsync(user.UserName, password, isPersistent, false);
|
||||
// var result = await HttpSignInManager.PasswordSignInAsync(user.UserName, password, isPersistent, false);
|
||||
|
||||
// // Assert
|
||||
// Assert.Equal(SignInStatus.Success, result);
|
||||
|
|
@ -120,41 +120,38 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
{
|
||||
Assert.Throws<ArgumentNullException>("userManager", () => new SignInManager<IdentityUser>(null, null));
|
||||
var userManager = MockHelpers.MockUserManager<IdentityUser>().Object;
|
||||
Assert.Throws<ArgumentNullException>("contextAccessor", () => new SignInManager<IdentityUser>(userManager, null));
|
||||
Assert.Throws<ArgumentNullException>("authenticationManager", () => new SignInManager<IdentityUser>(userManager, null));
|
||||
}
|
||||
|
||||
//TODO: Mock fails in K (this works fine in net45)
|
||||
[Fact]
|
||||
public async Task EnsureClaimsIdentityFactoryCreateIdentityCalled()
|
||||
{
|
||||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
var userManager = MockHelpers.TestUserManager<TestUser>();
|
||||
var identityFactory = new Mock<IClaimsIdentityFactory<TestUser>>();
|
||||
const string authType = "Test";
|
||||
var testIdentity = new ClaimsIdentity(authType);
|
||||
identityFactory.Setup(s => s.CreateAsync(userManager, user, authType, CancellationToken.None)).ReturnsAsync(testIdentity).Verifiable();
|
||||
userManager.ClaimsIdentityFactory = identityFactory.Object;
|
||||
var context = new Mock<HttpContext>();
|
||||
var response = new Mock<HttpResponse>();
|
||||
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||
response.Setup(r => r.SignIn(testIdentity, It.IsAny<AuthenticationProperties>())).Verifiable();
|
||||
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||
var helper = new SignInManager<TestUser>(userManager, contextAccessor.Object)
|
||||
{
|
||||
AuthenticationType = authType
|
||||
};
|
||||
//[Fact]
|
||||
//public async Task EnsureClaimsIdentityFactoryCreateIdentityCalled()
|
||||
//{
|
||||
// // Setup
|
||||
// var user = new TestUser { UserName = "Foo" };
|
||||
// var userManager = MockHelpers.TestUserManager<TestUser>();
|
||||
// var identityFactory = new Mock<IClaimsIdentityFactory<TestUser>>();
|
||||
// const string authType = "Test";
|
||||
// var testIdentity = new ClaimsIdentity(authType);
|
||||
// identityFactory.Setup(s => s.CreateAsync(userManager, user, authType, CancellationToken.None)).ReturnsAsync(testIdentity).Verifiable();
|
||||
// userManager.ClaimsIdentityFactory = identityFactory.Object;
|
||||
// var context = new Mock<HttpContext>();
|
||||
// var response = new Mock<HttpResponse>();
|
||||
// context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||
// response.Setup(r => r.SignIn(testIdentity, It.IsAny<AuthenticationProperties>())).Verifiable();
|
||||
// var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||
// contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||
// var helper = new HttpAuthenticationManager(contextAccessor.Object);
|
||||
|
||||
// Act
|
||||
await helper.SignInAsync(user, false, false);
|
||||
// // Act
|
||||
// helper.SignIn(user, false);
|
||||
|
||||
// Assert
|
||||
identityFactory.VerifyAll();
|
||||
context.VerifyAll();
|
||||
contextAccessor.VerifyAll();
|
||||
response.VerifyAll();
|
||||
}
|
||||
// // Assert
|
||||
// identityFactory.VerifyAll();
|
||||
// context.VerifyAll();
|
||||
// contextAccessor.VerifyAll();
|
||||
// response.VerifyAll();
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task PasswordSignInReturnsLockedOutWhenLockedOut()
|
||||
|
|
@ -168,7 +165,7 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
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);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object));
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
||||
|
|
@ -197,7 +194,138 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
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);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object));
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SignInStatus.Success, result);
|
||||
manager.VerifyAll();
|
||||
context.VerifyAll();
|
||||
response.VerifyAll();
|
||||
contextAccessor.VerifyAll();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PasswordSignInRequiresVerification()
|
||||
{
|
||||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||
manager.Setup(m => m.SupportsUserLockout).Returns(true).Verifiable();
|
||||
manager.Setup(m => m.GetTwoFactorEnabledAsync(user, CancellationToken.None)).ReturnsAsync(true).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.GetUserIdAsync(user, CancellationToken.None)).ReturnsAsync(user.Id).Verifiable();
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password", CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var response = new Mock<HttpResponse>();
|
||||
response.Setup(r => r.SignIn(It.Is<ClaimsIdentity>(id => id.Name == user.Id))).Verifiable();
|
||||
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object));
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", false, false);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SignInStatus.RequiresVerification, result);
|
||||
manager.VerifyAll();
|
||||
context.VerifyAll();
|
||||
response.VerifyAll();
|
||||
contextAccessor.VerifyAll();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task CanTwoFactorSignIn(bool isPersistent)
|
||||
{
|
||||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||
var provider = "twofactorprovider";
|
||||
var code = "123456";
|
||||
manager.Setup(m => m.IsLockedOutAsync(user, CancellationToken.None)).ReturnsAsync(false).Verifiable();
|
||||
manager.Setup(m => m.FindByIdAsync(user.Id, CancellationToken.None)).ReturnsAsync(user).Verifiable();
|
||||
manager.Setup(m => m.VerifyTwoFactorTokenAsync(user, provider, code, CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
||||
var context = new Mock<HttpContext>();
|
||||
var response = new Mock<HttpResponse>();
|
||||
response.Setup(r => r.SignIn(It.IsAny<ClaimsIdentity>(), It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent))).Verifiable();
|
||||
context.Setup(c => c.Response).Returns(response.Object).Verifiable();
|
||||
var id = new ClaimsIdentity(HttpAuthenticationManager.TwoFactorUserIdAuthenticationType);
|
||||
id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
|
||||
var authResult = new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription());
|
||||
context.Setup(c => c.AuthenticateAsync(HttpAuthenticationManager.TwoFactorUserIdAuthenticationType)).ReturnsAsync(authResult).Verifiable();
|
||||
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object));
|
||||
|
||||
// Act
|
||||
var result = await helper.TwoFactorSignInAsync(provider, code, isPersistent);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(SignInStatus.Success, result);
|
||||
manager.VerifyAll();
|
||||
context.VerifyAll();
|
||||
response.VerifyAll();
|
||||
contextAccessor.VerifyAll();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RememberClientStoresUserId()
|
||||
{
|
||||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
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.Is<ClaimsIdentity>(i => i.AuthenticationType == HttpAuthenticationManager.TwoFactorRememberedAuthenticationType))).Verifiable();
|
||||
var id = new ClaimsIdentity(HttpAuthenticationManager.TwoFactorRememberedAuthenticationType);
|
||||
id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
|
||||
var authResult = new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription());
|
||||
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||
var signInService = new HttpAuthenticationManager(contextAccessor.Object);
|
||||
|
||||
// Act
|
||||
signInService.RememberClient(user.Id);
|
||||
|
||||
// Assert
|
||||
context.VerifyAll();
|
||||
response.VerifyAll();
|
||||
contextAccessor.VerifyAll();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task RememberBrowserSkipsTwoFactorVerificationSignIn(bool isPersistent)
|
||||
{
|
||||
// Setup
|
||||
var user = new TestUser { UserName = "Foo" };
|
||||
var manager = MockHelpers.MockUserManager<TestUser>();
|
||||
manager.Setup(m => m.GetTwoFactorEnabledAsync(user, CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
||||
manager.Setup(m => m.SupportsUserLockout).Returns(true).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.GetUserIdAsync(user, CancellationToken.None)).ReturnsAsync(user.Id).Verifiable();
|
||||
manager.Setup(m => m.CheckPasswordAsync(user, "password", CancellationToken.None)).ReturnsAsync(true).Verifiable();
|
||||
manager.Setup(m => m.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie, CancellationToken.None)).ReturnsAsync(new ClaimsIdentity(DefaultAuthenticationTypes.ApplicationCookie)).Verifiable();
|
||||
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.Is<ClaimsIdentity>(i => i.AuthenticationType == DefaultAuthenticationTypes.ApplicationCookie), It.Is<AuthenticationProperties>(v => v.IsPersistent == isPersistent))).Verifiable();
|
||||
var id = new ClaimsIdentity(HttpAuthenticationManager.TwoFactorRememberedAuthenticationType);
|
||||
id.AddClaim(new Claim(ClaimTypes.Name, user.Id));
|
||||
var authResult = new AuthenticationResult(id, new AuthenticationProperties(), new AuthenticationDescription());
|
||||
context.Setup(c => c.AuthenticateAsync(HttpAuthenticationManager.TwoFactorRememberedAuthenticationType)).ReturnsAsync(authResult).Verifiable();
|
||||
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||
var signInService = new HttpAuthenticationManager(contextAccessor.Object);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, signInService);
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "password", isPersistent, false);
|
||||
|
|
@ -223,7 +351,7 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
response.Setup(r => r.SignOut(authenticationType)).Verifiable();
|
||||
var contextAccessor = new Mock<IContextAccessor<HttpContext>>();
|
||||
contextAccessor.Setup(a => a.Value).Returns(context.Object);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, contextAccessor.Object)
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object))
|
||||
{
|
||||
AuthenticationType = authenticationType
|
||||
};
|
||||
|
|
@ -249,7 +377,7 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
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);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object));
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, false);
|
||||
|
||||
|
|
@ -258,7 +386,6 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
manager.VerifyAll();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task PasswordSignInFailsWithUnknownUser()
|
||||
{
|
||||
|
|
@ -268,7 +395,7 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
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);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object));
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync("bogus", "bogus", false, false);
|
||||
|
|
@ -297,7 +424,7 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
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);
|
||||
var helper = new SignInManager<TestUser>(manager.Object, new HttpAuthenticationManager(contextAccessor.Object));
|
||||
|
||||
// Act
|
||||
var result = await helper.PasswordSignInAsync(user.UserName, "bogus", false, true);
|
||||
|
|
@ -307,30 +434,5 @@ namespace Microsoft.AspNet.Identity.Security.Test
|
|||
manager.VerifyAll();
|
||||
}
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -21,8 +21,8 @@
|
|||
<Content Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="HttpSignInTest.cs" />
|
||||
<Compile Include="IdentityExtensionsTest.cs" />
|
||||
<Compile Include="SignInManagerTest.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.Framework.ConfigurationModel;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
|
|
@ -37,13 +38,6 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
Assert.Equal(ClaimTypeOptions.DefaultSecurityStampClaimType, options.ClaimType.SecurityStamp);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CopyNullIsNoop()
|
||||
{
|
||||
var options = new IdentityOptions();
|
||||
options.Copy(null);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IdentityOptionsFromConfig()
|
||||
{
|
||||
|
|
@ -91,47 +85,54 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
Assert.Equal(1000, options.Lockout.MaxFailedAccessAttempts);
|
||||
}
|
||||
|
||||
//[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);
|
||||
//}
|
||||
public class PasswordsNegativeLengthSetup : IOptionsSetup<IdentityOptions>
|
||||
{
|
||||
public int Order { get { return 0; } }
|
||||
public void Setup(IdentityOptions options)
|
||||
{
|
||||
options.Password.RequiredLength = -1;
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanCustomizeIdentityOptions()
|
||||
{
|
||||
var builder = new Builder.Builder(new ServiceCollection().BuildServiceProvider());
|
||||
builder.UseServices(services =>
|
||||
{
|
||||
services.AddIdentity<IdentityUser>();
|
||||
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()
|
||||
{
|
||||
var app = new Builder.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 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);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -34,4 +34,4 @@
|
|||
<Compile Include="UserValidatorTest.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
@ -503,7 +503,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
async () => await manager.GeneratePasswordResetTokenAsync(null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
async () => await manager.ResetPassword(null, null, null));
|
||||
async () => await manager.ResetPasswordAsync(null, null, null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
async () => await manager.IsEmailConfirmedAsync(null));
|
||||
await Assert.ThrowsAsync<ArgumentNullException>("user",
|
||||
|
|
@ -594,7 +594,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.UpdateSecurityStampAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GetSecurityStampAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GeneratePasswordResetTokenAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ResetPassword(null, null, null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ResetPasswordAsync(null, null, null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.GenerateEmailConfirmationTokenAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.IsEmailConfirmedAsync(null));
|
||||
await Assert.ThrowsAsync<ObjectDisposedException>(() => manager.ConfirmEmailAsync(null, null));
|
||||
|
|
|
|||
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Framework.DependencyInjection;
|
||||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Test
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
{
|
||||
"version": "0.1-alpha-*",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Http" : "0.1-alpha-*",
|
||||
"Microsoft.AspNet.Identity" : "0.1-alpha-*",
|
||||
"Microsoft.AspNet.PipelineCore" : "0.1-alpha-*",
|
||||
"Microsoft.AspNet.RequestContainer" : "0.1-alpha-*",
|
||||
"Microsoft.AspNet.Testing" : "0.1-alpha-*",
|
||||
"Microsoft.Framework.ConfigurationModel" : "0.1-alpha-*",
|
||||
"Microsoft.Framework.DependencyInjection" : "0.1-alpha-*",
|
||||
|
|
|
|||
|
|
@ -7,11 +7,28 @@ using Microsoft.Framework.DependencyInjection;
|
|||
using Microsoft.Framework.DependencyInjection.Fallback;
|
||||
using Microsoft.Framework.OptionsModel;
|
||||
using Moq;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Test
|
||||
{
|
||||
public static class MockHelpers
|
||||
{
|
||||
public static UserManager<TUser> CreateManager<TUser>(Func<IUserStore<TUser>> storeFunc) where TUser : class
|
||||
{
|
||||
var services = new ServiceCollection();
|
||||
services.Add(OptionsServices.GetDefaultServices());
|
||||
services.AddIdentity<TUser>(b => b.AddUserStore(storeFunc));
|
||||
services.SetupOptions<IdentityOptions>(options =>
|
||||
{
|
||||
options.Password.RequireDigit = false;
|
||||
options.Password.RequireLowercase = false;
|
||||
options.Password.RequireNonLetterOrDigit = false;
|
||||
options.Password.RequireUppercase = false;
|
||||
options.User.AllowOnlyAlphanumericNames = false;
|
||||
});
|
||||
return services.BuildServiceProvider().GetService<UserManager<TUser>>();
|
||||
}
|
||||
|
||||
public static Mock<UserManager<TUser>> MockUserManager<TUser>() where TUser : class
|
||||
{
|
||||
var store = new Mock<IUserStore<TUser>>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.AspNet.Identity.Test
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit.Abstractions;
|
||||
using Xunit.Sdk;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
||||
public class TestPriorityAttribute : Attribute
|
||||
{
|
||||
public TestPriorityAttribute(int priority)
|
||||
{
|
||||
Priority = priority;
|
||||
}
|
||||
|
||||
public int Priority { get; private set; }
|
||||
}
|
||||
|
||||
public class PriorityOrderer : ITestCaseOrderer
|
||||
{
|
||||
public IEnumerable<XunitTestCase> OrderTestCases<XunitTestCase>(IEnumerable<XunitTestCase> testCases) where XunitTestCase : ITestCase
|
||||
{
|
||||
var sortedMethods = new SortedDictionary<int, List<XunitTestCase>>();
|
||||
|
||||
foreach (XunitTestCase testCase in testCases)
|
||||
{
|
||||
int priority = 0;
|
||||
|
||||
foreach (IAttributeInfo attr in testCase.Method.GetCustomAttributes((typeof(TestPriorityAttribute))))
|
||||
priority = attr.GetNamedArgument<int>("Priority");
|
||||
|
||||
GetOrCreate(sortedMethods, priority).Add(testCase);
|
||||
}
|
||||
|
||||
foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority]))
|
||||
{
|
||||
list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.Method.Name, y.Method.Name));
|
||||
foreach (XunitTestCase testCase in list)
|
||||
yield return testCase;
|
||||
}
|
||||
}
|
||||
|
||||
static TValue GetOrCreate<TKey, TValue>(IDictionary<TKey, TValue> dictionary, TKey key) where TValue : new()
|
||||
{
|
||||
TValue result;
|
||||
|
||||
if (dictionary.TryGetValue(key, out result)) return result;
|
||||
|
||||
result = new TValue();
|
||||
dictionary[key] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -466,7 +466,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
Assert.NotNull(stamp);
|
||||
var token = await manager.GeneratePasswordResetTokenAsync(user);
|
||||
Assert.NotNull(token);
|
||||
IdentityResultAssert.IsSuccess(await manager.ResetPassword(user, token, newPassword));
|
||||
IdentityResultAssert.IsSuccess(await manager.ResetPasswordAsync(user, token, newPassword));
|
||||
Assert.Null(await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, newPassword));
|
||||
Assert.NotEqual(stamp, user.SecurityStamp);
|
||||
|
|
@ -486,7 +486,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
var token = await manager.GeneratePasswordResetTokenAsync(user);
|
||||
Assert.NotNull(token);
|
||||
manager.PasswordValidator = new AlwaysBadValidator();
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPassword(user, token, newPassword),
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, token, newPassword),
|
||||
AlwaysBadValidator.ErrorMessage);
|
||||
Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
|
|
@ -504,7 +504,7 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user, password));
|
||||
var stamp = user.SecurityStamp;
|
||||
Assert.NotNull(stamp);
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPassword(user, "bogus", newPassword), "Invalid token.");
|
||||
IdentityResultAssert.IsFailure(await manager.ResetPasswordAsync(user, "bogus", newPassword), "Invalid token.");
|
||||
Assert.NotNull(await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(user, await manager.FindByUserNamePasswordAsync(user.UserName, password));
|
||||
Assert.Equal(stamp, user.SecurityStamp);
|
||||
|
|
@ -1443,21 +1443,5 @@ namespace Microsoft.AspNet.Identity.Test
|
|||
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
|
||||
Assert.False(await manager.VerifyTwoFactorTokenAsync(user, factorId, "bogus"));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue