// 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.Collections.Generic; using System.Linq; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNet.Identity.Test; namespace Microsoft.AspNet.Identity.InMemory { public class InMemoryUserStore : IUserLoginStore, IUserRoleStore, IUserClaimStore, IUserPasswordStore, IUserSecurityStampStore, IUserEmailStore, IUserLockoutStore, IUserPhoneNumberStore, IQueryableUserStore, IUserTwoFactorStore where TUser : TestUser { private readonly Dictionary _logins = new Dictionary(); private readonly Dictionary _users = new Dictionary(); public IQueryable Users { get { return _users.Values.AsQueryable(); } } public Task> GetClaimsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { var claims = user.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList(); return Task.FromResult>(claims); } public Task AddClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)) { foreach (var claim in claims) { user.Claims.Add(new TestUserClaim { ClaimType = claim.Type, ClaimValue = claim.Value, UserId = user.Id }); } return Task.FromResult(0); } public Task ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default(CancellationToken)) { var matchedClaims = user.Claims.Where(uc => uc.ClaimValue == claim.Value && uc.ClaimType == claim.Type).ToList(); foreach (var matchedClaim in matchedClaims) { matchedClaim.ClaimValue = newClaim.Value; matchedClaim.ClaimType = newClaim.Type; } return Task.FromResult(0); } public Task RemoveClaimsAsync(TUser user, IEnumerable claims, CancellationToken cancellationToken = default(CancellationToken)) { foreach (var claim in claims) { var entity = user.Claims.FirstOrDefault( uc => uc.UserId == user.Id && uc.ClaimType == claim.Type && uc.ClaimValue == claim.Value); if (entity != null) { user.Claims.Remove(entity); } } return Task.FromResult(0); } public Task SetEmailAsync(TUser user, string email, CancellationToken cancellationToken = default(CancellationToken)) { user.Email = email; return Task.FromResult(0); } public Task GetEmailAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.Email); } public Task GetNormalizedEmailAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.NormalizedEmail); } public Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken = default(CancellationToken)) { user.NormalizedEmail = normalizedEmail; return Task.FromResult(0); } public Task GetEmailConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.EmailConfirmed); } public Task SetEmailConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) { user.EmailConfirmed = confirmed; return Task.FromResult(0); } public Task FindByEmailAsync(string email, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult( Users.FirstOrDefault(u => u.NormalizedEmail == email)); } public Task GetLockoutEndDateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.LockoutEnd); } public Task SetLockoutEndDateAsync(TUser user, DateTimeOffset? lockoutEnd, CancellationToken cancellationToken = default(CancellationToken)) { user.LockoutEnd = lockoutEnd; return Task.FromResult(0); } public Task IncrementAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { user.AccessFailedCount++; return Task.FromResult(user.AccessFailedCount); } public Task ResetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { user.AccessFailedCount = 0; return Task.FromResult(0); } public Task GetAccessFailedCountAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.AccessFailedCount); } public Task GetLockoutEnabledAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.LockoutEnabled); } public Task SetLockoutEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) { user.LockoutEnabled = enabled; return Task.FromResult(0); } private string GetLoginKey(string loginProvider, string providerKey) { return loginProvider + "|" + providerKey; } public virtual Task AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken = default(CancellationToken)) { user.Logins.Add(new TestUserLogin { UserId = user.Id, ProviderKey = login.ProviderKey, LoginProvider = login.LoginProvider, ProviderDisplayName = login.ProviderDisplayName }); _logins[GetLoginKey(login.LoginProvider, login.ProviderKey)] = user; return Task.FromResult(0); } public Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { var loginEntity = user.Logins.SingleOrDefault( l => l.ProviderKey == providerKey && l.LoginProvider == loginProvider && l.UserId == user.Id); if (loginEntity != null) { user.Logins.Remove(loginEntity); } _logins[GetLoginKey(loginProvider, providerKey)] = null; return Task.FromResult(0); } public Task> GetLoginsAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { IList result = user.Logins .Select(l => new UserLoginInfo(l.LoginProvider, l.ProviderKey, l.ProviderDisplayName)).ToList(); return Task.FromResult(result); } public Task FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken = default(CancellationToken)) { string key = GetLoginKey(loginProvider, providerKey); if (_logins.ContainsKey(key)) { return Task.FromResult(_logins[key]); } return Task.FromResult(null); } public Task GetUserIdAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.Id); } public Task GetUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.UserName); } public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { user.UserName = userName; return Task.FromResult(0); } public Task CreateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { _users[user.Id] = user; return Task.FromResult(IdentityResult.Success); } public Task UpdateAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { _users[user.Id] = user; return Task.FromResult(IdentityResult.Success); } public Task FindByIdAsync(string userId, CancellationToken cancellationToken = default(CancellationToken)) { if (_users.ContainsKey(userId)) { return Task.FromResult(_users[userId]); } return Task.FromResult(null); } public void Dispose() { } public Task FindByNameAsync(string userName, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult( Users.FirstOrDefault(u => u.NormalizedUserName == userName)); } public Task DeleteAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { if (user == null || !_users.ContainsKey(user.Id)) { throw new InvalidOperationException("Unknown user"); } _users.Remove(user.Id); return Task.FromResult(IdentityResult.Success); } public Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken = default(CancellationToken)) { user.PasswordHash = passwordHash; return Task.FromResult(0); } public Task GetPasswordHashAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.PasswordHash); } public Task HasPasswordAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.PasswordHash != null); } public Task SetPhoneNumberAsync(TUser user, string phoneNumber, CancellationToken cancellationToken = default(CancellationToken)) { user.PhoneNumber = phoneNumber; return Task.FromResult(0); } public Task GetPhoneNumberAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.PhoneNumber); } public Task GetPhoneNumberConfirmedAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.PhoneNumberConfirmed); } public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken = default(CancellationToken)) { user.PhoneNumberConfirmed = confirmed; return Task.FromResult(0); } // RoleId == roleName for InMemory public Task AddToRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken)) { user.Roles.Add(new TestUserRole { RoleId = role, UserId = user.Id }); return Task.FromResult(0); } // RoleId == roleName for InMemory public Task RemoveFromRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken)) { var roleEntity = user.Roles.SingleOrDefault(ur => ur.RoleId == role); if (roleEntity != null) { user.Roles.Remove(roleEntity); } return Task.FromResult(0); } public Task> GetRolesAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult>(user.Roles.Select(ur => ur.RoleId).ToList()); } public Task IsInRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.Roles.Any(ur => ur.RoleId == role)); } public Task SetSecurityStampAsync(TUser user, string stamp, CancellationToken cancellationToken = default(CancellationToken)) { user.SecurityStamp = stamp; return Task.FromResult(0); } public Task GetSecurityStampAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.SecurityStamp); } public Task SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken = default(CancellationToken)) { user.TwoFactorEnabled = enabled; return Task.FromResult(0); } public Task GetTwoFactorEnabledAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.TwoFactorEnabled); } public Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) { return Task.FromResult(user.NormalizedUserName); } public Task SetNormalizedUserNameAsync(TUser user, string userName, CancellationToken cancellationToken = default(CancellationToken)) { user.NormalizedUserName = userName; return Task.FromResult(0); } // RoleId == rolename for inmemory store tests public Task> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) { if (String.IsNullOrEmpty(roleName)) { throw new ArgumentNullException("role"); } return Task.FromResult>(Users.Where(u => (u.Roles.Where(x => x.RoleId == roleName).Count() > 0)).Select(x => x).ToList()); } public Task> GetUsersForClaimAsync(Claim claim, CancellationToken cancellationToken = default(CancellationToken)) { if (claim == null) { throw new ArgumentNullException("claim"); } var query = from user in Users where user.Claims.Where(x => x.ClaimType == claim.Type && x.ClaimValue == claim.Value).FirstOrDefault() != null select user; return Task.FromResult>(query.ToList()); } } }