1 // Copyright (c) .NET Foundation. All rights reserved. 2 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. 3 4 using System; 5 using System.Collections.Generic; 6 using System.Linq; 7 using System.Security.Claims; 8 using System.Threading; 9 using System.Threading.Tasks; 10 using Microsoft.AspNetCore.Identity.Test; 11 12 namespace Microsoft.AspNetCore.Identity.InMemory 13 { 14 public class InMemoryStore<TUser, TRole> : 15 InMemoryUserStore<TUser>, 16 IUserRoleStore<TUser>, 17 IQueryableRoleStore<TRole>, 18 IRoleClaimStore<TRole> 19 where TRole : PocoRole 20 where TUser : PocoUser 21 { 22 // RoleId == roleName for InMemory AddToRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken))23 public Task AddToRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken)) 24 { 25 var roleEntity = _roles.Values.SingleOrDefault(r => r.NormalizedName == role); 26 if (roleEntity != null) 27 { 28 user.Roles.Add(new PocoUserRole { RoleId = roleEntity.Id, UserId = user.Id }); 29 } 30 return Task.FromResult(0); 31 } 32 33 // RoleId == roleName for InMemory RemoveFromRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken))34 public Task RemoveFromRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken)) 35 { 36 var roleObject = _roles.Values.SingleOrDefault(r => r.NormalizedName == role); 37 var roleEntity = user.Roles.SingleOrDefault(ur => ur.RoleId == roleObject.Id); 38 if (roleEntity != null) 39 { 40 user.Roles.Remove(roleEntity); 41 } 42 return Task.FromResult(0); 43 } 44 GetRolesAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken))45 public Task<IList<string>> GetRolesAsync(TUser user, CancellationToken cancellationToken = default(CancellationToken)) 46 { 47 IList<string> roles = new List<string>(); 48 foreach (var r in user.Roles.Select(ur => ur.RoleId)) 49 { 50 roles.Add(_roles[r].Name); 51 } 52 return Task.FromResult(roles); 53 } 54 IsInRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken))55 public Task<bool> IsInRoleAsync(TUser user, string role, CancellationToken cancellationToken = default(CancellationToken)) 56 { 57 var roleObject = _roles.Values.SingleOrDefault(r => r.NormalizedName == role); 58 bool result = roleObject != null && user.Roles.Any(ur => ur.RoleId == roleObject.Id); 59 return Task.FromResult(result); 60 } 61 62 // RoleId == rolename for inmemory store tests GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken))63 public Task<IList<TUser>> GetUsersInRoleAsync(string roleName, CancellationToken cancellationToken = default(CancellationToken)) 64 { 65 if (String.IsNullOrEmpty(roleName)) 66 { 67 throw new ArgumentNullException(nameof(roleName)); 68 } 69 70 var role = _roles.Values.Where(x => x.NormalizedName.Equals(roleName)).SingleOrDefault(); 71 if (role == null) 72 { 73 return Task.FromResult<IList<TUser>>(new List<TUser>()); 74 } 75 return Task.FromResult<IList<TUser>>(Users.Where(u => (u.Roles.Where(x => x.RoleId == role.Id).Count() > 0)).Select(x => x).ToList()); 76 } 77 78 private readonly Dictionary<string, TRole> _roles = new Dictionary<string, TRole>(); 79 CreateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))80 public Task<IdentityResult> CreateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) 81 { 82 _roles[role.Id] = role; 83 return Task.FromResult(IdentityResult.Success); 84 } 85 DeleteAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))86 public Task<IdentityResult> DeleteAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) 87 { 88 if (role == null || !_roles.ContainsKey(role.Id)) 89 { 90 throw new InvalidOperationException("Unknown role"); 91 } 92 _roles.Remove(role.Id); 93 return Task.FromResult(IdentityResult.Success); 94 } 95 GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))96 public Task<string> GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) 97 { 98 return Task.FromResult(role.Id); 99 } 100 GetRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))101 public Task<string> GetRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) 102 { 103 return Task.FromResult(role.Name); 104 } 105 SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken))106 public Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) 107 { 108 role.Name = roleName; 109 return Task.FromResult(0); 110 } 111 UpdateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))112 public Task<IdentityResult> UpdateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) 113 { 114 _roles[role.Id] = role; 115 return Task.FromResult(IdentityResult.Success); 116 } 117 FindByIdAsync(string roleId, CancellationToken cancellationToken)118 Task<TRole> IRoleStore<TRole>.FindByIdAsync(string roleId, CancellationToken cancellationToken) 119 { 120 if (_roles.ContainsKey(roleId)) 121 { 122 return Task.FromResult(_roles[roleId]); 123 } 124 return Task.FromResult<TRole>(null); 125 } 126 FindByNameAsync(string roleName, CancellationToken cancellationToken)127 Task<TRole> IRoleStore<TRole>.FindByNameAsync(string roleName, CancellationToken cancellationToken) 128 { 129 return 130 Task.FromResult( 131 Roles.SingleOrDefault(r => String.Equals(r.NormalizedName, roleName, StringComparison.OrdinalIgnoreCase))); 132 } 133 GetClaimsAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))134 public Task<IList<Claim>> GetClaimsAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) 135 { 136 var claims = role.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList(); 137 return Task.FromResult<IList<Claim>>(claims); 138 } 139 AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken))140 public Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)) 141 { 142 role.Claims.Add(new PocoRoleClaim<string> { ClaimType = claim.Type, ClaimValue = claim.Value, RoleId = role.Id }); 143 return Task.FromResult(0); 144 } 145 RemoveClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken))146 public Task RemoveClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)) 147 { 148 var entity = 149 role.Claims.FirstOrDefault( 150 ur => ur.RoleId == role.Id && ur.ClaimType == claim.Type && ur.ClaimValue == claim.Value); 151 if (entity != null) 152 { 153 role.Claims.Remove(entity); 154 } 155 return Task.FromResult(0); 156 } 157 GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken))158 public Task<string> GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) 159 { 160 return Task.FromResult(role.NormalizedName); 161 } 162 SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken = default(CancellationToken))163 public Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken = default(CancellationToken)) 164 { 165 role.NormalizedName = normalizedName; 166 return Task.FromResult(0); 167 } 168 169 public IQueryable<TRole> Roles 170 { 171 get { return _roles.Values.AsQueryable(); } 172 } 173 } 174 } 175