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