зеркало из https://github.com/aspnet/Identity.git
Flesh out implementation, add InMemoryTests
- Implement RoleManager - Replace IIdentityValidator with IUser/Role/Password Validator - Add test project.json and working tests for InMemoryUserStore
This commit is contained in:
Родитель
06f9b90aea
Коммит
b13d26cab6
17
Identity.sln
17
Identity.sln
|
@ -23,6 +23,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.I
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.InMemory.k10", "src\Microsoft.AspNet.Identity.InMemory\Microsoft.AspNet.Identity.InMemory.k10.csproj", "{D2E7A146-C39F-4302-8EA3-BFA8C1082939}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNet.Identity.Test.net45", "test\Microsoft.AspNet.Identity.Test\Microsoft.AspNet.Identity.Test.net45.csproj", "{E00E23B0-79B8-41E1-9998-57FECA1F2535}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Aspnet.Identity.InMemory.Test.net45", "test\Microsoft.Aspnet.Identity.InMemory.Test\Microsoft.Aspnet.Identity.InMemory.Test.net45.csproj", "{9022EBC9-BAD4-4BCB-85F5-2BB0DD155825}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -34,7 +38,6 @@ Global
|
|||
{B72401D7-47F6-4A98-89D5-CCBFEFC5B2B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B72401D7-47F6-4A98-89D5-CCBFEFC5B2B8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6211450F-FFB8-431F-84E2-9A7620875260}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6211450F-FFB8-431F-84E2-9A7620875260}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6211450F-FFB8-431F-84E2-9A7620875260}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6211450F-FFB8-431F-84E2-9A7620875260}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E52361C9-1F0B-4229-86A0-E5C7C12A5429}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
@ -42,7 +45,6 @@ Global
|
|||
{E52361C9-1F0B-4229-86A0-E5C7C12A5429}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E52361C9-1F0B-4229-86A0-E5C7C12A5429}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D32483A4-B617-480C-81E6-49CD596B9A34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D32483A4-B617-480C-81E6-49CD596B9A34}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D32483A4-B617-480C-81E6-49CD596B9A34}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D32483A4-B617-480C-81E6-49CD596B9A34}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{054B3FFA-7196-466F-9A8A-593FFE037A69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
@ -50,9 +52,16 @@ Global
|
|||
{054B3FFA-7196-466F-9A8A-593FFE037A69}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{054B3FFA-7196-466F-9A8A-593FFE037A69}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D2E7A146-C39F-4302-8EA3-BFA8C1082939}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D2E7A146-C39F-4302-8EA3-BFA8C1082939}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D2E7A146-C39F-4302-8EA3-BFA8C1082939}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D2E7A146-C39F-4302-8EA3-BFA8C1082939}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E00E23B0-79B8-41E1-9998-57FECA1F2535}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E00E23B0-79B8-41E1-9998-57FECA1F2535}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E00E23B0-79B8-41E1-9998-57FECA1F2535}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E00E23B0-79B8-41E1-9998-57FECA1F2535}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9022EBC9-BAD4-4BCB-85F5-2BB0DD155825}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9022EBC9-BAD4-4BCB-85F5-2BB0DD155825}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9022EBC9-BAD4-4BCB-85F5-2BB0DD155825}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9022EBC9-BAD4-4BCB-85F5-2BB0DD155825}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -60,6 +69,8 @@ Global
|
|||
GlobalSection(NestedProjects) = preSolution
|
||||
{F6B0C0E9-C346-49D0-B583-95B6CE04BB1B} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
|
||||
{77CEDA6C-A833-455D-8357-649BFD944724} = {0F647068-6602-4E24-B1DC-8ED91481A50A}
|
||||
{E00E23B0-79B8-41E1-9998-57FECA1F2535} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
|
||||
{9022EBC9-BAD4-4BCB-85F5-2BB0DD155825} = {52D59F18-62D2-4D17-8CF2-BE192445AF8E}
|
||||
{B72401D7-47F6-4A98-89D5-CCBFEFC5B2B8} = {F6B0C0E9-C346-49D0-B583-95B6CE04BB1B}
|
||||
{E52361C9-1F0B-4229-86A0-E5C7C12A5429} = {F6B0C0E9-C346-49D0-B583-95B6CE04BB1B}
|
||||
{054B3FFA-7196-466F-9A8A-593FFE037A69} = {F6B0C0E9-C346-49D0-B583-95B6CE04BB1B}
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if NET45
|
||||
using System.Security.Claims;
|
||||
#else
|
||||
using System.Security.ClaimsK;
|
||||
#endif
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Identity;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.InMemory
|
||||
{
|
||||
|
@ -17,12 +14,16 @@ namespace Microsoft.AspNet.Identity.InMemory
|
|||
private readonly IList<UserLoginInfo> _logins;
|
||||
private readonly IList<string> _roles;
|
||||
|
||||
public InMemoryUser(string name)
|
||||
public InMemoryUser()
|
||||
{
|
||||
Id = Guid.NewGuid().ToString();
|
||||
_logins = new List<UserLoginInfo>();
|
||||
_claims = new List<Claim>();
|
||||
_roles = new List<string>();
|
||||
}
|
||||
|
||||
public InMemoryUser(string name) : this()
|
||||
{
|
||||
UserName = name;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,55 +10,57 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace Microsoft.AspNet.Identity.InMemory
|
||||
{
|
||||
public class InMemoryUserStore :
|
||||
IUserStore<InMemoryUser, string>,
|
||||
IUserLoginStore<InMemoryUser, string>,
|
||||
IUserRoleStore<InMemoryUser, string>,
|
||||
IUserClaimStore<InMemoryUser, string>,
|
||||
IUserPasswordStore<InMemoryUser, string>,
|
||||
IUserSecurityStampStore<InMemoryUser, string>,
|
||||
IUserEmailStore<InMemoryUser, string>,
|
||||
IUserLockoutStore<InMemoryUser, string>,
|
||||
IUserPhoneNumberStore<InMemoryUser, string>
|
||||
public class InMemoryUserStore<TUser> :
|
||||
IUserStore<TUser, string>,
|
||||
IUserLoginStore<TUser, string>,
|
||||
IUserRoleStore<TUser, string>,
|
||||
IUserClaimStore<TUser, string>,
|
||||
IUserPasswordStore<TUser, string>,
|
||||
IUserSecurityStampStore<TUser, string>,
|
||||
IUserEmailStore<TUser, string>,
|
||||
IUserLockoutStore<TUser, string>,
|
||||
IUserPhoneNumberStore<TUser, string>
|
||||
where TUser : InMemoryUser
|
||||
{
|
||||
private readonly Dictionary<UserLoginInfo, InMemoryUser> _logins =
|
||||
new Dictionary<UserLoginInfo, InMemoryUser>(new LoginComparer());
|
||||
private readonly Dictionary<UserLoginInfo, TUser> _logins =
|
||||
new Dictionary<UserLoginInfo, TUser>(new LoginComparer());
|
||||
|
||||
private readonly Dictionary<string, InMemoryUser> _users = new Dictionary<string, InMemoryUser>();
|
||||
private readonly Dictionary<string, TUser> _users = new Dictionary<string, TUser>();
|
||||
|
||||
public IQueryable<InMemoryUser> Users
|
||||
public IQueryable<TUser> Users
|
||||
{
|
||||
get { return _users.Values.AsQueryable(); }
|
||||
}
|
||||
|
||||
public Task<IList<Claim>> GetClaims(InMemoryUser user)
|
||||
public Task<IList<Claim>> GetClaims(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.Claims);
|
||||
}
|
||||
|
||||
public Task AddClaim(InMemoryUser user, Claim claim)
|
||||
public Task AddClaim(TUser user, Claim claim)
|
||||
{
|
||||
user.Claims.Add(claim);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task RemoveClaim(InMemoryUser user, Claim claim)
|
||||
public Task RemoveClaim(TUser user, Claim claim)
|
||||
{
|
||||
user.Claims.Remove(claim);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task AddLogin(InMemoryUser user, UserLoginInfo login)
|
||||
public Task AddLogin(TUser user, UserLoginInfo login)
|
||||
{
|
||||
user.Logins.Add(login);
|
||||
_logins[login] = user;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task RemoveLogin(InMemoryUser user, UserLoginInfo login)
|
||||
public Task RemoveLogin(TUser user, UserLoginInfo login)
|
||||
{
|
||||
var logs =
|
||||
user.Logins.Where(l => l.ProviderKey == login.ProviderKey && l.LoginProvider == login.LoginProvider);
|
||||
user.Logins.Where(l => l.ProviderKey == login.ProviderKey && l.LoginProvider == login.LoginProvider)
|
||||
.ToList();
|
||||
foreach (var l in logs)
|
||||
{
|
||||
user.Logins.Remove(l);
|
||||
|
@ -67,100 +69,100 @@ namespace Microsoft.AspNet.Identity.InMemory
|
|||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<IList<UserLoginInfo>> GetLogins(InMemoryUser user)
|
||||
public Task<IList<UserLoginInfo>> GetLogins(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.Logins);
|
||||
}
|
||||
|
||||
public Task<InMemoryUser> Find(UserLoginInfo login)
|
||||
public Task<TUser> Find(UserLoginInfo login)
|
||||
{
|
||||
if (_logins.ContainsKey(login))
|
||||
{
|
||||
return Task.FromResult(_logins[login]);
|
||||
}
|
||||
return Task.FromResult<InMemoryUser>(null);
|
||||
return Task.FromResult<TUser>(null);
|
||||
}
|
||||
|
||||
public Task SetPasswordHash(InMemoryUser user, string passwordHash)
|
||||
public Task SetPasswordHash(TUser user, string passwordHash)
|
||||
{
|
||||
user.PasswordHash = passwordHash;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<string> GetPasswordHash(InMemoryUser user)
|
||||
public Task<string> GetPasswordHash(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.PasswordHash);
|
||||
}
|
||||
|
||||
public Task<bool> HasPassword(InMemoryUser user)
|
||||
public Task<bool> HasPassword(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.PasswordHash != null);
|
||||
}
|
||||
|
||||
public Task AddToRole(InMemoryUser user, string role)
|
||||
public Task AddToRole(TUser user, string role)
|
||||
{
|
||||
user.Roles.Add(role);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task RemoveFromRole(InMemoryUser user, string role)
|
||||
public Task RemoveFromRole(TUser user, string role)
|
||||
{
|
||||
user.Roles.Remove(role);
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<IList<string>> GetRoles(InMemoryUser user)
|
||||
public Task<IList<string>> GetRoles(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.Roles);
|
||||
}
|
||||
|
||||
public Task<bool> IsInRole(InMemoryUser user, string role)
|
||||
public Task<bool> IsInRole(TUser user, string role)
|
||||
{
|
||||
return Task.FromResult(user.Roles.Contains(role));
|
||||
}
|
||||
|
||||
public Task SetSecurityStamp(InMemoryUser user, string stamp)
|
||||
public Task SetSecurityStamp(TUser user, string stamp)
|
||||
{
|
||||
user.SecurityStamp = stamp;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<string> GetSecurityStamp(InMemoryUser user)
|
||||
public Task<string> GetSecurityStamp(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.SecurityStamp);
|
||||
}
|
||||
|
||||
public Task Create(InMemoryUser user)
|
||||
public Task Create(TUser user)
|
||||
{
|
||||
_users[user.Id] = user;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task Update(InMemoryUser user)
|
||||
public Task Update(TUser user)
|
||||
{
|
||||
_users[user.Id] = user;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<InMemoryUser> FindById(string userId)
|
||||
public Task<TUser> FindById(string userId)
|
||||
{
|
||||
if (_users.ContainsKey(userId))
|
||||
{
|
||||
return Task.FromResult(_users[userId]);
|
||||
}
|
||||
return Task.FromResult<InMemoryUser>(null);
|
||||
return Task.FromResult<TUser>(null);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public Task<InMemoryUser> FindByName(string userName)
|
||||
public Task<TUser> FindByName(string userName)
|
||||
{
|
||||
return Task.FromResult(Users.FirstOrDefault(u => String.Equals(u.UserName, userName, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
public Task Delete(InMemoryUser user)
|
||||
public Task Delete(TUser user)
|
||||
{
|
||||
if (user == null || !_users.ContainsKey(user.Id))
|
||||
{
|
||||
|
@ -170,89 +172,89 @@ namespace Microsoft.AspNet.Identity.InMemory
|
|||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SetEmail(InMemoryUser user, string email)
|
||||
public Task SetEmail(TUser user, string email)
|
||||
{
|
||||
user.Email = email;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<string> GetEmail(InMemoryUser user)
|
||||
public Task<string> GetEmail(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.Email);
|
||||
}
|
||||
|
||||
public Task<bool> GetEmailConfirmed(InMemoryUser user)
|
||||
public Task<bool> GetEmailConfirmed(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.EmailConfirmed);
|
||||
}
|
||||
|
||||
public Task SetEmailConfirmed(InMemoryUser user, bool confirmed)
|
||||
public Task SetEmailConfirmed(TUser user, bool confirmed)
|
||||
{
|
||||
user.EmailConfirmed = confirmed;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<InMemoryUser> FindByEmail(string email)
|
||||
public Task<TUser> FindByEmail(string email)
|
||||
{
|
||||
return Task.FromResult(Users.FirstOrDefault(u => String.Equals(u.Email, email, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
public Task<DateTimeOffset> GetLockoutEndDate(InMemoryUser user)
|
||||
public Task<DateTimeOffset> GetLockoutEndDate(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.LockoutEnd);
|
||||
}
|
||||
|
||||
public Task SetLockoutEndDate(InMemoryUser user, DateTimeOffset lockoutEnd)
|
||||
public Task SetLockoutEndDate(TUser user, DateTimeOffset lockoutEnd)
|
||||
{
|
||||
user.LockoutEnd = lockoutEnd;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<int> IncrementAccessFailedCount(InMemoryUser user)
|
||||
public Task<int> IncrementAccessFailedCount(TUser user)
|
||||
{
|
||||
user.AccessFailedCount++;
|
||||
return Task.FromResult(user.AccessFailedCount);
|
||||
}
|
||||
|
||||
public Task ResetAccessFailedCount(InMemoryUser user)
|
||||
public Task ResetAccessFailedCount(TUser user)
|
||||
{
|
||||
user.AccessFailedCount = 0;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<int> GetAccessFailedCount(InMemoryUser user)
|
||||
public Task<int> GetAccessFailedCount(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.AccessFailedCount);
|
||||
}
|
||||
|
||||
public Task<bool> GetLockoutEnabled(InMemoryUser user)
|
||||
public Task<bool> GetLockoutEnabled(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.LockoutEnabled);
|
||||
}
|
||||
|
||||
public Task SetLockoutEnabled(InMemoryUser user, bool enabled)
|
||||
public Task SetLockoutEnabled(TUser user, bool enabled)
|
||||
{
|
||||
user.LockoutEnabled = enabled;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task SetPhoneNumber(InMemoryUser user, string phoneNumber)
|
||||
public Task SetPhoneNumber(TUser user, string phoneNumber)
|
||||
{
|
||||
user.PhoneNumber = phoneNumber;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<string> GetPhoneNumber(InMemoryUser user)
|
||||
public Task<string> GetPhoneNumber(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.PhoneNumber);
|
||||
}
|
||||
|
||||
public Task<bool> GetPhoneNumberConfirmed(InMemoryUser user)
|
||||
public Task<bool> GetPhoneNumberConfirmed(TUser user)
|
||||
{
|
||||
return Task.FromResult(user.PhoneNumberConfirmed);
|
||||
}
|
||||
|
||||
public Task SetPhoneNumberConfirmed(InMemoryUser user, bool confirmed)
|
||||
public Task SetPhoneNumberConfirmed(TUser user, bool confirmed)
|
||||
{
|
||||
user.PhoneNumberConfirmed = confirmed;
|
||||
return Task.FromResult(0);
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to validate an item
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface IIdentityValidator<in T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate the item
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
Task<IdentityResult> Validate(T item);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to validate passwords
|
||||
/// </summary>
|
||||
public interface IPasswordValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate the item
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<IdentityResult> Validate(string password);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to validate a role
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface IRoleValidator<in T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate the user
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
Task<IdentityResult> Validate(T role);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to validate a user
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public interface IUserValidator<in T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Validate the user
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
Task<IdentityResult> Validate(T user);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to validate some basic password policy like length and number of non alphanumerics
|
||||
/// </summary>
|
||||
public class PasswordValidator : IPasswordValidator
|
||||
{
|
||||
/// <summary>
|
||||
/// Minimum required length
|
||||
/// </summary>
|
||||
public int RequiredLength { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Require a non letter or digit character
|
||||
/// </summary>
|
||||
public bool RequireNonLetterOrDigit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Require a lower case letter ('a' - 'z')
|
||||
/// </summary>
|
||||
public bool RequireLowercase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Require an upper case letter ('A' - 'Z')
|
||||
/// </summary>
|
||||
public bool RequireUppercase { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Require a digit ('0' - '9')
|
||||
/// </summary>
|
||||
public bool RequireDigit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the string is of the required length and meets the configured requirements
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public virtual Task<IdentityResult> Validate(string item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException("item");
|
||||
}
|
||||
var errors = new List<string>();
|
||||
if (string.IsNullOrWhiteSpace(item) || item.Length < RequiredLength)
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PasswordTooShort, RequiredLength));
|
||||
}
|
||||
if (RequireNonLetterOrDigit && item.All(IsLetterOrDigit))
|
||||
{
|
||||
errors.Add(Resources.PasswordRequireNonLetterOrDigit);
|
||||
}
|
||||
if (RequireDigit && item.All(c => !IsDigit(c)))
|
||||
{
|
||||
errors.Add(Resources.PasswordRequireDigit);
|
||||
}
|
||||
if (RequireLowercase && item.All(c => !IsLower(c)))
|
||||
{
|
||||
errors.Add(Resources.PasswordRequireLower);
|
||||
}
|
||||
if (RequireUppercase && item.All(c => !IsUpper(c)))
|
||||
{
|
||||
errors.Add(Resources.PasswordRequireUpper);
|
||||
}
|
||||
if (errors.Count == 0)
|
||||
{
|
||||
return Task.FromResult(IdentityResult.Success);
|
||||
}
|
||||
return Task.FromResult(IdentityResult.Failed(String.Join(" ", errors)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the character is a digit between '0' and '9'
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsDigit(char c)
|
||||
{
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the character is between 'a' and 'z'
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsLower(char c)
|
||||
{
|
||||
return c >= 'a' && c <= 'z';
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the character is between 'A' and 'Z'
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsUpper(char c)
|
||||
{
|
||||
return c >= 'A' && c <= 'Z';
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the character is upper, lower, or a digit
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
/// <returns></returns>
|
||||
public virtual bool IsLetterOrDigit(char c)
|
||||
{
|
||||
return IsUpper(c) || IsLower(c) || IsDigit(c);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,213 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Exposes role related api which will automatically save changes to the RoleStore
|
||||
/// </summary>
|
||||
/// <typeparam name="TRole"></typeparam>
|
||||
public class RoleManager<TRole> : RoleManager<TRole, string> where TRole : class, IRole<string>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="store"></param>
|
||||
public RoleManager(IRoleStore<TRole, string> store)
|
||||
: base(store)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exposes role related api which will automatically save changes to the RoleStore
|
||||
/// </summary>
|
||||
/// <typeparam name="TRole"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
public class RoleManager<TRole, TKey> : IDisposable
|
||||
where TRole : class, IRole<TKey>
|
||||
where TKey : IEquatable<TKey>
|
||||
{
|
||||
private bool _disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="store">The IRoleStore is responsible for commiting changes via the UpdateAsync/CreateAsync methods</param>
|
||||
public RoleManager(IRoleStore<TRole, TKey> store)
|
||||
{
|
||||
if (store == null)
|
||||
{
|
||||
throw new ArgumentNullException("store");
|
||||
}
|
||||
Store = store;
|
||||
RoleValidator = new RoleValidator<TRole, TKey>(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Persistence abstraction that the Manager operates against
|
||||
/// </summary>
|
||||
protected IRoleStore<TRole, TKey> Store { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to validate roles before persisting changes
|
||||
/// </summary>
|
||||
public IRoleValidator<TRole> RoleValidator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns an IQueryable of roles if the store is an IQueryableRoleStore
|
||||
/// </summary>
|
||||
public virtual IQueryable<TRole> Roles
|
||||
{
|
||||
get
|
||||
{
|
||||
var queryableStore = Store as IQueryableRoleStore<TRole, TKey>;
|
||||
if (queryableStore == null)
|
||||
{
|
||||
throw new NotSupportedException(Resources.StoreNotIQueryableRoleStore);
|
||||
}
|
||||
return queryableStore.Roles;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose this object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
private async Task<IdentityResult> ValidateRoleInternal(TRole role)
|
||||
{
|
||||
return (RoleValidator == null) ? IdentityResult.Success : await RoleValidator.Validate(role).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a role
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> Create(TRole role)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (role == null)
|
||||
{
|
||||
throw new ArgumentNullException("role");
|
||||
}
|
||||
|
||||
var result = await ValidateRoleInternal(role);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
await Store.Create(role);
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update an existing role
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> Update(TRole role)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (role == null)
|
||||
{
|
||||
throw new ArgumentNullException("role");
|
||||
}
|
||||
|
||||
var result = await ValidateRoleInternal(role);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
await Store.Update(role).ConfigureAwait(false);
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete a role
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> Delete(TRole role)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (role == null)
|
||||
{
|
||||
throw new ArgumentNullException("role");
|
||||
}
|
||||
|
||||
await Store.Delete(role).ConfigureAwait(false);
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the role exists
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<bool> RoleExists(string roleName)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (roleName == null)
|
||||
{
|
||||
throw new ArgumentNullException("roleName");
|
||||
}
|
||||
|
||||
return await FindByName(roleName).ConfigureAwait(false) != null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a role by id
|
||||
/// </summary>
|
||||
/// <param name="roleId"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<TRole> FindById(TKey roleId)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
return await Store.FindById(roleId).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Find a role by name
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<TRole> FindByName(string roleName)
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (roleName == null)
|
||||
{
|
||||
throw new ArgumentNullException("roleName");
|
||||
}
|
||||
|
||||
return await Store.FindByName(roleName).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private void ThrowIfDisposed()
|
||||
{
|
||||
if (_disposed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType().Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When disposing, actually dipose the store
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && !_disposed)
|
||||
{
|
||||
Store.Dispose();
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Validates roles before they are saved
|
||||
/// </summary>
|
||||
/// <typeparam name="TRole"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
public class RoleValidator<TRole, TKey> : IRoleValidator<TRole>
|
||||
where TRole : class, IRole<TKey>
|
||||
where TKey : IEquatable<TKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="manager"></param>
|
||||
public RoleValidator(RoleManager<TRole, TKey> manager)
|
||||
{
|
||||
if (manager == null)
|
||||
{
|
||||
throw new ArgumentNullException("manager");
|
||||
}
|
||||
Manager = manager;
|
||||
}
|
||||
|
||||
private RoleManager<TRole, TKey> Manager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Validates a role before saving
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> Validate(TRole item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException("item");
|
||||
}
|
||||
var errors = new List<string>();
|
||||
await ValidateRoleName(item, errors);
|
||||
if (errors.Count > 0)
|
||||
{
|
||||
return IdentityResult.Failed(errors.ToArray());
|
||||
}
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
private async Task ValidateRoleName(TRole role, List<string> errors)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(role.Name))
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "Name"));
|
||||
}
|
||||
else
|
||||
{
|
||||
var owner = await Manager.FindByName(role.Name);
|
||||
if (owner != null && !EqualityComparer<TKey>.Default.Equals(owner.Id, role.Id))
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.DuplicateName, role.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,8 +29,6 @@ namespace Microsoft.AspNet.Identity
|
|||
private TimeSpan _defaultLockout = TimeSpan.Zero;
|
||||
private bool _disposed;
|
||||
private IPasswordHasher _passwordHasher;
|
||||
private IIdentityValidator<string> _passwordValidator;
|
||||
private IIdentityValidator<TUser> _userValidator;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor which takes a service provider to find the default interfaces to hook up
|
||||
|
@ -45,6 +43,8 @@ namespace Microsoft.AspNet.Identity
|
|||
Store = serviceProvider.GetService<IUserStore<TUser, TKey>>();
|
||||
ClaimsIdentityFactory = serviceProvider.GetService<IClaimsIdentityFactory<TUser, TKey>>();
|
||||
PasswordHasher = serviceProvider.GetService<IPasswordHasher>();
|
||||
UserValidator = serviceProvider.GetService<IUserValidator<TUser>>();
|
||||
PasswordValidator = serviceProvider.GetService<IPasswordValidator>();
|
||||
// TODO: validator interfaces, and maybe each optional store as well? Email and SMS services?
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,7 @@ namespace Microsoft.AspNet.Identity
|
|||
throw new ArgumentNullException("store");
|
||||
}
|
||||
Store = store;
|
||||
//UserValidator = new UserValidator<TUser, TKey>(this);
|
||||
//PasswordValidator = new MinimumLengthValidator(6);
|
||||
UserValidator = new UserValidator<TUser, TKey>(this);
|
||||
//PasswordHasher = new PasswordHasher();
|
||||
//ClaimsIdentityFactory = new ClaimsIdentityFactory<TUser, TKey>();
|
||||
}
|
||||
|
@ -94,44 +93,12 @@ namespace Microsoft.AspNet.Identity
|
|||
/// <summary>
|
||||
/// Used to validate users before persisting changes
|
||||
/// </summary>
|
||||
public IIdentityValidator<TUser> UserValidator
|
||||
{
|
||||
get
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
return _userValidator;
|
||||
}
|
||||
set
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
_userValidator = value;
|
||||
}
|
||||
}
|
||||
public IUserValidator<TUser> UserValidator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to validate passwords before persisting changes
|
||||
/// </summary>
|
||||
public IIdentityValidator<string> PasswordValidator
|
||||
{
|
||||
get
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
return _passwordValidator;
|
||||
}
|
||||
set
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException("value");
|
||||
}
|
||||
_passwordValidator = value;
|
||||
}
|
||||
}
|
||||
public IPasswordValidator PasswordValidator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to create claims identities from users
|
||||
|
@ -359,6 +326,10 @@ namespace Microsoft.AspNet.Identity
|
|||
return ClaimsIdentityFactory.Create(this, user, authenticationType);
|
||||
}
|
||||
|
||||
private async Task<IdentityResult> ValidateUserInternal(TUser user) {
|
||||
return (UserValidator == null) ? IdentityResult.Success : await UserValidator.Validate(user).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a user with no password
|
||||
/// </summary>
|
||||
|
@ -368,7 +339,7 @@ namespace Microsoft.AspNet.Identity
|
|||
{
|
||||
ThrowIfDisposed();
|
||||
await UpdateSecurityStampInternal(user).ConfigureAwait(false);
|
||||
var result = await UserValidator.Validate(user).ConfigureAwait(false);
|
||||
var result = await ValidateUserInternal(user);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
|
@ -393,8 +364,7 @@ namespace Microsoft.AspNet.Identity
|
|||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
var result = await UserValidator.Validate(user).ConfigureAwait(false);
|
||||
var result = await ValidateUserInternal(user);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
|
@ -612,10 +582,13 @@ namespace Microsoft.AspNet.Identity
|
|||
internal async Task<IdentityResult> UpdatePasswordInternal(IUserPasswordStore<TUser, TKey> passwordStore,
|
||||
TUser user, string newPassword)
|
||||
{
|
||||
var result = await PasswordValidator.Validate(newPassword).ConfigureAwait(false);
|
||||
if (!result.Succeeded)
|
||||
if (PasswordValidator != null)
|
||||
{
|
||||
return result;
|
||||
var result = await PasswordValidator.Validate(newPassword).ConfigureAwait(false);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
await
|
||||
passwordStore.SetPasswordHash(user, PasswordHasher.HashPassword(newPassword)).ConfigureAwait(false);
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Net.Mail;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNet.Identity
|
||||
{
|
||||
/// <summary>
|
||||
/// Validates users before they are saved
|
||||
/// </summary>
|
||||
/// <typeparam name="TUser"></typeparam>
|
||||
/// <typeparam name="TKey"></typeparam>
|
||||
public class UserValidator<TUser, TKey> : IUserValidator<TUser>
|
||||
where TUser : class, IUser<TKey>
|
||||
where TKey : IEquatable<TKey>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="manager"></param>
|
||||
public UserValidator(UserManager<TUser, TKey> manager)
|
||||
{
|
||||
if (manager == null)
|
||||
{
|
||||
throw new ArgumentNullException("manager");
|
||||
}
|
||||
AllowOnlyAlphanumericUserNames = true;
|
||||
Manager = manager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Only allow [A-Za-z0-9@_] in UserNames
|
||||
/// </summary>
|
||||
public bool AllowOnlyAlphanumericUserNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If set, enforces that emails are non empty, valid, and unique
|
||||
/// </summary>
|
||||
public bool RequireUniqueEmail { get; set; }
|
||||
|
||||
private UserManager<TUser, TKey> Manager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Validates a user before saving
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public virtual async Task<IdentityResult> Validate(TUser item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException("item");
|
||||
}
|
||||
var errors = new List<string>();
|
||||
await ValidateUserName(item, errors);
|
||||
if (RequireUniqueEmail)
|
||||
{
|
||||
await ValidateEmail(item, errors);
|
||||
}
|
||||
if (errors.Count > 0)
|
||||
{
|
||||
return IdentityResult.Failed(errors.ToArray());
|
||||
}
|
||||
return IdentityResult.Success;
|
||||
}
|
||||
|
||||
private async Task ValidateUserName(TUser user, List<string> errors)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(user.UserName))
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "Name"));
|
||||
}
|
||||
else if (AllowOnlyAlphanumericUserNames && !Regex.IsMatch(user.UserName, @"^[A-Za-z0-9@_\.]+$"))
|
||||
{
|
||||
// If any characters are not letters or digits, its an illegal user name
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.InvalidUserName, user.UserName));
|
||||
}
|
||||
else
|
||||
{
|
||||
var owner = await Manager.FindByName(user.UserName);
|
||||
if (owner != null && !EqualityComparer<TKey>.Default.Equals(owner.Id, user.Id))
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.DuplicateName, user.UserName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// make sure email is not empty, valid, and unique
|
||||
private async Task ValidateEmail(TUser user, List<string> errors)
|
||||
{
|
||||
var email = await Manager.GetEmailStore().GetEmail(user).ConfigureAwait(false);
|
||||
if (string.IsNullOrWhiteSpace(email))
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "Email"));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
var m = new MailAddress(email);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.InvalidEmail, email));
|
||||
return;
|
||||
}
|
||||
var owner = await Manager.FindByEmail(email);
|
||||
if (owner != null && !EqualityComparer<TKey>.Default.Equals(owner.Id, user.Id))
|
||||
{
|
||||
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.DuplicateEmail, email));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,691 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
#if NET45
|
||||
using System.Security.Claims;
|
||||
#else
|
||||
using System.Security.ClaimsK;
|
||||
#endif
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.InMemory.Test
|
||||
{
|
||||
public class InMemoryStoreTest
|
||||
{
|
||||
[Fact]
|
||||
public async Task DeleteUserTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = new InMemoryUser("Delete");
|
||||
UnitTestHelper.IsSuccess(await manager.Create(user));
|
||||
UnitTestHelper.IsSuccess(await manager.Delete(user));
|
||||
Assert.Null(await manager.FindById(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateUserNoPasswordTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
UnitTestHelper.IsSuccess(await manager.Create(new InMemoryUser("CreateUserTest")));
|
||||
var user = await manager.FindByName("CreateUserTest");
|
||||
Assert.NotNull(user);
|
||||
Assert.Null(user.PasswordHash);
|
||||
var logins = await manager.GetLogins(user.Id);
|
||||
Assert.NotNull(logins);
|
||||
Assert.Equal(0, logins.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateUserAddLoginTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
const string userName = "CreateExternalUserTest";
|
||||
const string provider = "ZzAuth";
|
||||
const string providerKey = "HaoKey";
|
||||
UnitTestHelper.IsSuccess(await manager.Create(new InMemoryUser(userName)));
|
||||
var user = await manager.FindByName(userName);
|
||||
var login = new UserLoginInfo(provider, providerKey);
|
||||
UnitTestHelper.IsSuccess(await manager.AddLogin(user.Id, login));
|
||||
var logins = await manager.GetLogins(user.Id);
|
||||
Assert.NotNull(logins);
|
||||
Assert.Equal(1, logins.Count());
|
||||
Assert.Equal(provider, logins.First().LoginProvider);
|
||||
Assert.Equal(providerKey, logins.First().ProviderKey);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task CreateUserLoginAndAddPasswordTest()
|
||||
//{
|
||||
// var manager = CreateManager();
|
||||
// var login = new UserLoginInfo("Provider", "key");
|
||||
// var user = new InMemoryUser("CreateUserLoginAddPasswordTest");
|
||||
// UnitTestHelper.IsSuccess(await manager.Create(user));
|
||||
// UnitTestHelper.IsSuccess(await manager.AddLogin(user.Id, login));
|
||||
// UnitTestHelper.IsSuccess(await manager.AddPassword(user.Id, "password"));
|
||||
// var logins = await manager.GetLogins(user.Id);
|
||||
// Assert.NotNull(logins);
|
||||
// Assert.Equal(1, logins.Count());
|
||||
// Assert.Equal(user, await manager.Find(login));
|
||||
// Assert.Equal(user, await manager.Find(user.UserName, "password"));
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateUserAddRemoveLoginTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = new InMemoryUser("CreateUserAddRemoveLoginTest");
|
||||
var login = new UserLoginInfo("Provider", "key");
|
||||
var result = await manager.Create(user);
|
||||
Assert.NotNull(user);
|
||||
UnitTestHelper.IsSuccess(result);
|
||||
UnitTestHelper.IsSuccess(await manager.AddLogin(user.Id, login));
|
||||
Assert.Equal(user, await manager.Find(login));
|
||||
var logins = await manager.GetLogins(user.Id);
|
||||
Assert.NotNull(logins);
|
||||
Assert.Equal(1, logins.Count());
|
||||
Assert.Equal(login.LoginProvider, logins.Last().LoginProvider);
|
||||
Assert.Equal(login.ProviderKey, logins.Last().ProviderKey);
|
||||
var stamp = user.SecurityStamp;
|
||||
UnitTestHelper.IsSuccess(await manager.RemoveLogin(user.Id, login));
|
||||
Assert.Null(await manager.Find(login));
|
||||
logins = await manager.GetLogins(user.Id);
|
||||
Assert.NotNull(logins);
|
||||
Assert.Equal(0, logins.Count());
|
||||
Assert.NotEqual(stamp, user.SecurityStamp);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task RemovePasswordTest()
|
||||
//{
|
||||
// var manager = CreateManager();
|
||||
// var user = new InMemoryUser("RemovePasswordTest");
|
||||
// const string password = "password";
|
||||
// UnitTestHelper.IsSuccess(await manager.Create(user, password));
|
||||
// var stamp = user.SecurityStamp;
|
||||
// UnitTestHelper.IsSuccess(await manager.RemovePassword(user.Id));
|
||||
// var u = await manager.FindByName(user.UserName);
|
||||
// Assert.NotNull(u);
|
||||
// Assert.Null(u.PasswordHash);
|
||||
// Assert.NotEqual(stamp, user.SecurityStamp);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public async Task ChangePasswordTest()
|
||||
//{
|
||||
// var manager = CreateManager();
|
||||
// var user = new InMemoryUser("ChangePasswordTest");
|
||||
// const string password = "password";
|
||||
// const string newPassword = "newpassword";
|
||||
// UnitTestHelper.IsSuccess(await manager.Create(user, password));
|
||||
// var stamp = user.SecurityStamp;
|
||||
// Assert.NotNull(stamp);
|
||||
// UnitTestHelper.IsSuccess(await manager.ChangePassword(user.Id, password, newPassword));
|
||||
// Assert.Null(await manager.Find(user.UserName, password));
|
||||
// Assert.Equal(user, await manager.Find(user.UserName, newPassword));
|
||||
// Assert.NotEqual(stamp, user.SecurityStamp);
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task AddRemoveUserClaimTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = new InMemoryUser("ClaimsAddRemove");
|
||||
UnitTestHelper.IsSuccess(await manager.Create(user));
|
||||
Claim[] claims = { new Claim("c", "v"), new Claim("c2", "v2"), new Claim("c2", "v3") };
|
||||
foreach (Claim c in claims)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await manager.AddClaim(user.Id, c));
|
||||
}
|
||||
var userClaims = await manager.GetClaims(user.Id);
|
||||
Assert.Equal(3, userClaims.Count);
|
||||
UnitTestHelper.IsSuccess(await manager.RemoveClaim(user.Id, claims[0]));
|
||||
userClaims = await manager.GetClaims(user.Id);
|
||||
Assert.Equal(2, userClaims.Count);
|
||||
UnitTestHelper.IsSuccess(await manager.RemoveClaim(user.Id, claims[1]));
|
||||
userClaims = await manager.GetClaims(user.Id);
|
||||
Assert.Equal(1, userClaims.Count);
|
||||
UnitTestHelper.IsSuccess(await manager.RemoveClaim(user.Id, claims[2]));
|
||||
userClaims = await manager.GetClaims(user.Id);
|
||||
Assert.Equal(0, userClaims.Count);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task ChangePasswordFallsIfPasswordTooShortTest()
|
||||
//{
|
||||
// var manager = CreateManager();
|
||||
// var user = new InMemoryUser("user");
|
||||
// const string password = "password";
|
||||
// UnitTestHelper.IsSuccess(await manager.Create(user, password));
|
||||
// var result = await manager.ChangePassword(user.Id, password, "n");
|
||||
// UnitTestHelper.IsFailure(result, "Passwords must be at least 6 characters.");
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public async Task ChangePasswordFallsIfPasswordWrongTest()
|
||||
//{
|
||||
// var manager = CreateManager();
|
||||
// var user = new InMemoryUser("user");
|
||||
// UnitTestHelper.IsSuccess(await manager.Create(user, "password"));
|
||||
// var result = await manager.ChangePassword(user.Id, "bogus", "newpassword");
|
||||
// UnitTestHelper.IsFailure(result, "Incorrect password.");
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task AddDupeUserFailsTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = new InMemoryUser("dupe");
|
||||
var user2 = new InMemoryUser("dupe");
|
||||
UnitTestHelper.IsSuccess(await manager.Create(user));
|
||||
UnitTestHelper.IsFailure(await manager.Create(user2), "Name dupe is already taken.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateSecurityStampTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var user = new InMemoryUser("stampMe");
|
||||
Assert.Null(user.SecurityStamp);
|
||||
UnitTestHelper.IsSuccess(await manager.Create(user));
|
||||
var stamp = user.SecurityStamp;
|
||||
Assert.NotNull(stamp);
|
||||
UnitTestHelper.IsSuccess(await manager.UpdateSecurityStamp(user.Id));
|
||||
Assert.NotEqual(stamp, user.SecurityStamp);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task AddDupeLoginFailsTest()
|
||||
//{
|
||||
// var manager = CreateManager();
|
||||
// var user = new InMemoryUser("DupeLogin");
|
||||
// var login = new UserLoginInfo("provder", "key");
|
||||
// UnitTestHelper.IsSuccess(await manager.Create(user));
|
||||
// UnitTestHelper.IsSuccess(await manager.AddLogin(user.Id, login));
|
||||
// var result = await manager.AddLogin(user.Id, login);
|
||||
// UnitTestHelper.IsFailure(result, "A user with that external login already exists.");
|
||||
//}
|
||||
|
||||
// Lockout tests
|
||||
|
||||
[Fact]
|
||||
public async Task SingleFailureLockout()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
var user = new InMemoryUser("fastLockout");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
UnitTestHelper.IsSuccess(await mgr.AccessFailed(user.Id));
|
||||
Assert.True(await mgr.IsLockedOut(user.Id));
|
||||
Assert.True(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
Assert.Equal(0, await mgr.GetAccessFailedCount(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TwoFailureLockout()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
mgr.MaxFailedAccessAttemptsBeforeLockout = 2;
|
||||
var user = new InMemoryUser("twoFailureLockout");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
UnitTestHelper.IsSuccess(await mgr.AccessFailed(user.Id));
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
Assert.False(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
Assert.Equal(1, await mgr.GetAccessFailedCount(user.Id));
|
||||
UnitTestHelper.IsSuccess(await mgr.AccessFailed(user.Id));
|
||||
Assert.True(await mgr.IsLockedOut(user.Id));
|
||||
Assert.True(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
Assert.Equal(0, await mgr.GetAccessFailedCount(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ResetLockoutTest()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
mgr.MaxFailedAccessAttemptsBeforeLockout = 2;
|
||||
var user = new InMemoryUser("resetLockout");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
UnitTestHelper.IsSuccess(await mgr.AccessFailed(user.Id));
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
Assert.False(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
Assert.Equal(1, await mgr.GetAccessFailedCount(user.Id));
|
||||
UnitTestHelper.IsSuccess(await mgr.ResetAccessFailedCount(user.Id));
|
||||
Assert.Equal(0, await mgr.GetAccessFailedCount(user.Id));
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
Assert.False(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
UnitTestHelper.IsSuccess(await mgr.AccessFailed(user.Id));
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
Assert.False(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
Assert.Equal(1, await mgr.GetAccessFailedCount(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnableLockoutManually()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.DefaultAccountLockoutTimeSpan = TimeSpan.FromHours(1);
|
||||
mgr.MaxFailedAccessAttemptsBeforeLockout = 2;
|
||||
var user = new InMemoryUser("manualLockout");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.False(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.False(user.LockoutEnabled);
|
||||
UnitTestHelper.IsSuccess(await mgr.SetLockoutEnabled(user.Id, true));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
UnitTestHelper.IsSuccess(await mgr.AccessFailed(user.Id));
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
Assert.False(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
Assert.Equal(1, await mgr.GetAccessFailedCount(user.Id));
|
||||
UnitTestHelper.IsSuccess(await mgr.AccessFailed(user.Id));
|
||||
Assert.True(await mgr.IsLockedOut(user.Id));
|
||||
Assert.True(await mgr.GetLockoutEndDate(user.Id) > DateTimeOffset.UtcNow.AddMinutes(55));
|
||||
Assert.Equal(0, await mgr.GetAccessFailedCount(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UserNotLockedOutWithNullDateTimeAndIsSetToNullDate()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
var user = new InMemoryUser("LockoutTest");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
UnitTestHelper.IsSuccess(await mgr.SetLockoutEndDate(user.Id, new DateTimeOffset()));
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
Assert.Equal(new DateTimeOffset(), await mgr.GetLockoutEndDate(user.Id));
|
||||
Assert.Equal(new DateTimeOffset(), user.LockoutEnd);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LockoutFailsIfNotEnabled()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
var user = new InMemoryUser("LockoutNotEnabledTest");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.False(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.False(user.LockoutEnabled);
|
||||
UnitTestHelper.IsFailure(await mgr.SetLockoutEndDate(user.Id, new DateTimeOffset()), "Lockout is not enabled for this user.");
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LockoutEndToUtcNowMinus1SecInUserShouldNotBeLockedOut()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
var user = new InMemoryUser("LockoutUtcNowTest") { LockoutEnd = DateTimeOffset.UtcNow.AddSeconds(-1) };
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LockoutEndToUtcNowSubOneSecondWithManagerShouldNotBeLockedOut()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
var user = new InMemoryUser("LockoutUtcNowTest");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
UnitTestHelper.IsSuccess(await mgr.SetLockoutEndDate(user.Id, DateTimeOffset.UtcNow.AddSeconds(-1)));
|
||||
Assert.False(await mgr.IsLockedOut(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task LockoutEndToUtcNowPlus5ShouldBeLockedOut()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
var user = new InMemoryUser("LockoutUtcNowTest") { LockoutEnd = DateTimeOffset.UtcNow.AddMinutes(5) };
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
Assert.True(await mgr.IsLockedOut(user.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UserLockedOutWithDateTimeLocalKindNowPlus30()
|
||||
{
|
||||
var mgr = CreateManager();
|
||||
mgr.UserLockoutEnabledByDefault = true;
|
||||
var user = new InMemoryUser("LockoutTest");
|
||||
UnitTestHelper.IsSuccess(await mgr.Create(user));
|
||||
Assert.True(await mgr.GetLockoutEnabled(user.Id));
|
||||
Assert.True(user.LockoutEnabled);
|
||||
var lockoutEnd = new DateTimeOffset(DateTime.Now.AddMinutes(30).ToLocalTime());
|
||||
UnitTestHelper.IsSuccess(await mgr.SetLockoutEndDate(user.Id, lockoutEnd));
|
||||
Assert.True(await mgr.IsLockedOut(user.Id));
|
||||
var end = await mgr.GetLockoutEndDate(user.Id);
|
||||
Assert.Equal(lockoutEnd, end);
|
||||
}
|
||||
|
||||
// Role Tests
|
||||
[Fact]
|
||||
public async Task CreateRoleTest()
|
||||
{
|
||||
var manager = CreateRoleManager();
|
||||
var role = new InMemoryRole("create");
|
||||
Assert.False(await manager.RoleExists(role.Name));
|
||||
UnitTestHelper.IsSuccess(await manager.Create(role));
|
||||
Assert.True(await manager.RoleExists(role.Name));
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task BadValidatorBlocksCreateTest()
|
||||
//{
|
||||
// var manager = CreateRoleManager();
|
||||
// manager.RoleValidator = new AlwaysBadValidator<InMemoryRole>();
|
||||
// UnitTestHelper.IsFailure(await manager.Create(new InMemoryRole("blocked")),
|
||||
// AlwaysBadValidator<InMemoryRole>.ErrorMessage);
|
||||
//}
|
||||
|
||||
//[Fact]
|
||||
//public async Task BadValidatorBlocksAllUpdatesTest()
|
||||
//{
|
||||
// var manager = CreateRoleManager();
|
||||
// var role = new InMemoryRole("poorguy");
|
||||
// UnitTestHelper.IsSuccess(await manager.Create(role));
|
||||
// var error = AlwaysBadValidator<InMemoryRole>.ErrorMessage;
|
||||
// manager.RoleValidator = new AlwaysBadValidator<InMemoryRole>();
|
||||
// UnitTestHelper.IsFailure(await manager.Update(role), error);
|
||||
//}
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteRoleTest()
|
||||
{
|
||||
var manager = CreateRoleManager();
|
||||
var role = new InMemoryRole("delete");
|
||||
Assert.False(await manager.RoleExists(role.Name));
|
||||
UnitTestHelper.IsSuccess(await manager.Create(role));
|
||||
UnitTestHelper.IsSuccess(await manager.Delete(role));
|
||||
Assert.False(await manager.RoleExists(role.Name));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RoleFindByIdTest()
|
||||
{
|
||||
var manager = CreateRoleManager();
|
||||
var role = new InMemoryRole("FindById");
|
||||
Assert.Null(await manager.FindById(role.Id));
|
||||
UnitTestHelper.IsSuccess(await manager.Create(role));
|
||||
Assert.Equal(role, await manager.FindById(role.Id));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RoleFindByNameTest()
|
||||
{
|
||||
var manager = CreateRoleManager();
|
||||
var role = new InMemoryRole("FindByName");
|
||||
Assert.Null(await manager.FindByName(role.Name));
|
||||
Assert.False(await manager.RoleExists(role.Name));
|
||||
UnitTestHelper.IsSuccess(await manager.Create(role));
|
||||
Assert.Equal(role, await manager.FindByName(role.Name));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateRoleNameTest()
|
||||
{
|
||||
var manager = CreateRoleManager();
|
||||
var role = new InMemoryRole("update");
|
||||
Assert.False(await manager.RoleExists(role.Name));
|
||||
UnitTestHelper.IsSuccess(await manager.Create(role));
|
||||
Assert.True(await manager.RoleExists(role.Name));
|
||||
role.Name = "Changed";
|
||||
UnitTestHelper.IsSuccess(await manager.Update(role));
|
||||
Assert.False(await manager.RoleExists("update"));
|
||||
Assert.Equal(role, await manager.FindByName(role.Name));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task QuerableRolesTest()
|
||||
{
|
||||
var manager = CreateRoleManager();
|
||||
InMemoryRole[] roles =
|
||||
{
|
||||
new InMemoryRole("r1"), new InMemoryRole("r2"), new InMemoryRole("r3"),
|
||||
new InMemoryRole("r4")
|
||||
};
|
||||
foreach (var r in roles)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await manager.Create(r));
|
||||
}
|
||||
Assert.Equal(roles.Length, manager.Roles.Count());
|
||||
var r1 = manager.Roles.FirstOrDefault(r => r.Name == "r1");
|
||||
Assert.Equal(roles[0], r1);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public async Task DeleteRoleNonEmptySucceedsTest()
|
||||
//{
|
||||
// // Need fail if not empty?
|
||||
// var userMgr = CreateManager();
|
||||
// var roleMgr = CreateRoleManager();
|
||||
// var role = new InMemoryRole("deleteNonEmpty");
|
||||
// Assert.False(await roleMgr.RoleExists(role.Name));
|
||||
// UnitTestHelper.IsSuccess(await roleMgr.Create(role));
|
||||
// var user = new InMemoryUser("t");
|
||||
// UnitTestHelper.IsSuccess(await userMgr.Create(user));
|
||||
// UnitTestHelper.IsSuccess(await userMgr.AddToRole(user.Id, role.Name));
|
||||
// UnitTestHelper.IsSuccess(await roleMgr.Delete(role));
|
||||
// Assert.Null(await roleMgr.FindByName(role.Name));
|
||||
// Assert.False(await roleMgr.RoleExists(role.Name));
|
||||
// // REVIEW: We should throw if deleteing a non empty role?
|
||||
// var roles = await userMgr.GetRoles(user.Id);
|
||||
|
||||
// // In memory this doesn't work since there's no concept of cascading deletes
|
||||
// //Assert.Equal(0, roles.Count());
|
||||
//}
|
||||
|
||||
////[Fact]
|
||||
////public async Task DeleteUserRemovesFromRoleTest()
|
||||
////{
|
||||
//// // Need fail if not empty?
|
||||
//// var userMgr = CreateManager();
|
||||
//// var roleMgr = CreateRoleManager();
|
||||
//// var role = new InMemoryRole("deleteNonEmpty");
|
||||
//// Assert.False(await roleMgr.RoleExists(role.Name));
|
||||
//// UnitTestHelper.IsSuccess(await roleMgr.Create(role));
|
||||
//// var user = new InMemoryUser("t");
|
||||
//// UnitTestHelper.IsSuccess(await userMgr.Create(user));
|
||||
//// UnitTestHelper.IsSuccess(await userMgr.AddToRole(user.Id, role.Name));
|
||||
//// UnitTestHelper.IsSuccess(await userMgr.Delete(user));
|
||||
//// role = roleMgr.FindById(role.Id);
|
||||
////}
|
||||
|
||||
[Fact]
|
||||
public async Task CreateRoleFailsIfExistsTest()
|
||||
{
|
||||
var manager = CreateRoleManager();
|
||||
var role = new InMemoryRole("dupeRole");
|
||||
Assert.False(await manager.RoleExists(role.Name));
|
||||
UnitTestHelper.IsSuccess(await manager.Create(role));
|
||||
Assert.True(await manager.RoleExists(role.Name));
|
||||
var role2 = new InMemoryRole("dupeRole");
|
||||
UnitTestHelper.IsFailure(await manager.Create(role2));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddUserToRoleTest()
|
||||
{
|
||||
var manager = CreateManager();
|
||||
var roleManager = CreateRoleManager();
|
||||
var role = new InMemoryRole("addUserTest");
|
||||
UnitTestHelper.IsSuccess(await roleManager.Create(role));
|
||||
InMemoryUser[] users =
|
||||
{
|
||||
new InMemoryUser("1"), new InMemoryUser("2"), new InMemoryUser("3"),
|
||||
new InMemoryUser("4")
|
||||
};
|
||||
foreach (InMemoryUser u in users)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await manager.Create(u));
|
||||
UnitTestHelper.IsSuccess(await manager.AddToRole(u.Id, role.Name));
|
||||
Assert.True(await manager.IsInRole(u.Id, role.Name));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetRolesForUserTest()
|
||||
{
|
||||
var userManager = CreateManager();
|
||||
var roleManager = CreateRoleManager();
|
||||
InMemoryUser[] users =
|
||||
{
|
||||
new InMemoryUser("u1"), new InMemoryUser("u2"), new InMemoryUser("u3"),
|
||||
new InMemoryUser("u4")
|
||||
};
|
||||
InMemoryRole[] roles =
|
||||
{
|
||||
new InMemoryRole("r1"), new InMemoryRole("r2"), new InMemoryRole("r3"),
|
||||
new InMemoryRole("r4")
|
||||
};
|
||||
foreach (var u in users)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await userManager.Create(u));
|
||||
}
|
||||
foreach (var r in roles)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await roleManager.Create(r));
|
||||
foreach (var u in users)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await userManager.AddToRole(u.Id, r.Name));
|
||||
Assert.True(await userManager.IsInRole(u.Id, r.Name));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var u in users)
|
||||
{
|
||||
var rs = await userManager.GetRoles(u.Id);
|
||||
Assert.Equal(roles.Length, rs.Count);
|
||||
foreach (var r in roles)
|
||||
{
|
||||
Assert.True(rs.Any(role => role == r.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task RemoveUserFromRoleWithMultipleRoles()
|
||||
{
|
||||
var userManager = CreateManager();
|
||||
var roleManager = CreateRoleManager();
|
||||
var user = new InMemoryUser("MultiRoleUser");
|
||||
UnitTestHelper.IsSuccess(await userManager.Create(user));
|
||||
InMemoryRole[] roles =
|
||||
{
|
||||
new InMemoryRole("r1"), new InMemoryRole("r2"), new InMemoryRole("r3"),
|
||||
new InMemoryRole("r4")
|
||||
};
|
||||
foreach (var r in roles)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await roleManager.Create(r));
|
||||
UnitTestHelper.IsSuccess(await userManager.AddToRole(user.Id, r.Name));
|
||||
Assert.True(await userManager.IsInRole(user.Id, r.Name));
|
||||
}
|
||||
UnitTestHelper.IsSuccess(await userManager.RemoveFromRole(user.Id, roles[2].Name));
|
||||
Assert.False(await userManager.IsInRole(user.Id, roles[2].Name));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RemoveUserFromRoleTest()
|
||||
{
|
||||
var userManager = CreateManager();
|
||||
var roleManager = CreateRoleManager();
|
||||
InMemoryUser[] users =
|
||||
{
|
||||
new InMemoryUser("1"), new InMemoryUser("2"), new InMemoryUser("3"),
|
||||
new InMemoryUser("4")
|
||||
};
|
||||
foreach (var u in users)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await userManager.Create(u));
|
||||
}
|
||||
var r = new InMemoryRole("r1");
|
||||
UnitTestHelper.IsSuccess(await roleManager.Create(r));
|
||||
foreach (var u in users)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await userManager.AddToRole(u.Id, r.Name));
|
||||
Assert.True(await userManager.IsInRole(u.Id, r.Name));
|
||||
}
|
||||
foreach (var u in users)
|
||||
{
|
||||
UnitTestHelper.IsSuccess(await userManager.RemoveFromRole(u.Id, r.Name));
|
||||
Assert.False(await userManager.IsInRole(u.Id, r.Name));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RemoveUserNotInRoleFailsTest()
|
||||
{
|
||||
var userMgr = CreateManager();
|
||||
var roleMgr = CreateRoleManager();
|
||||
var role = new InMemoryRole("addUserDupeTest");
|
||||
var user = new InMemoryUser("user1");
|
||||
UnitTestHelper.IsSuccess(await userMgr.Create(user));
|
||||
UnitTestHelper.IsSuccess(await roleMgr.Create(role));
|
||||
var result = await userMgr.RemoveFromRole(user.Id, role.Name);
|
||||
UnitTestHelper.IsFailure(result, "User is not in role.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AddUserToRoleFailsIfAlreadyInRoleTest()
|
||||
{
|
||||
var userMgr = CreateManager();
|
||||
var roleMgr = CreateRoleManager();
|
||||
var role = new InMemoryRole("addUserDupeTest");
|
||||
var user = new InMemoryUser("user1");
|
||||
UnitTestHelper.IsSuccess(await userMgr.Create(user));
|
||||
UnitTestHelper.IsSuccess(await roleMgr.Create(role));
|
||||
UnitTestHelper.IsSuccess(await userMgr.AddToRole(user.Id, role.Name));
|
||||
Assert.True(await userMgr.IsInRole(user.Id, role.Name));
|
||||
UnitTestHelper.IsFailure(await userMgr.AddToRole(user.Id, role.Name), "User already in role.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FindRoleByNameWithManagerTest()
|
||||
{
|
||||
var roleMgr = CreateRoleManager();
|
||||
var role = new InMemoryRole("findRoleByNameTest");
|
||||
UnitTestHelper.IsSuccess(await roleMgr.Create(role));
|
||||
Assert.Equal(role.Id, (await roleMgr.FindByName(role.Name)).Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task FindRoleWithManagerTest()
|
||||
{
|
||||
var roleMgr = CreateRoleManager();
|
||||
var role = new InMemoryRole("findRoleTest");
|
||||
UnitTestHelper.IsSuccess(await roleMgr.Create(role));
|
||||
Assert.Equal(role.Name, (await roleMgr.FindById(role.Id)).Name);
|
||||
}
|
||||
|
||||
|
||||
private static UserManager<InMemoryUser, string> CreateManager()
|
||||
{
|
||||
return new UserManager<InMemoryUser, string>(new InMemoryUserStore<InMemoryUser>());
|
||||
}
|
||||
|
||||
private static RoleManager<InMemoryRole> CreateRoleManager()
|
||||
{
|
||||
return new RoleManager<InMemoryRole>(new InMemoryRoleStore());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Identity.InMemory.Test
|
||||
{
|
||||
public static class UnitTestHelper
|
||||
{
|
||||
public static void IsSuccess(IdentityResult result)
|
||||
{
|
||||
Assert.NotNull(result);
|
||||
Assert.True(result.Succeeded);
|
||||
}
|
||||
|
||||
public static void IsFailure(IdentityResult result)
|
||||
{
|
||||
Assert.NotNull(result);
|
||||
Assert.False(result.Succeeded);
|
||||
}
|
||||
|
||||
public static void IsFailure(IdentityResult result, string error)
|
||||
{
|
||||
Assert.NotNull(result);
|
||||
Assert.False(result.Succeeded);
|
||||
Assert.Equal(error, result.Errors.First());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"version": "0.1-alpha-*",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Identity" : "0.1-alpha-*",
|
||||
"Microsoft.AspNet.Identity.InMemory" : "0.1-alpha-*",
|
||||
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*"
|
||||
},
|
||||
"configurations": {
|
||||
"net45": {
|
||||
"dependencies": {
|
||||
"xunit": "1.9.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"version": "0.1-alpha-*",
|
||||
"dependencies": {
|
||||
"Microsoft.AspNet.Identity" : "0.1-alpha-*",
|
||||
"Microsoft.AspNet.DependencyInjection" : "0.1-alpha-*"
|
||||
},
|
||||
"configurations": {
|
||||
"net45": {
|
||||
"dependencies": {
|
||||
"xunit": "1.9.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче