-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
IdentityRepository.cs
368 lines (289 loc) · 15 KB
/
IdentityRepository.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Enums;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Extensions;
using Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories.Interfaces;
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories
{
public class IdentityRepository<TIdentityDbContext, TUserKey, TRoleKey, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
: IIdentityRepository<TUserKey, TRoleKey, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TIdentityDbContext : IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
{
protected readonly TIdentityDbContext DbContext;
protected readonly UserManager<TUser> UserManager;
protected readonly RoleManager<TRole> RoleManager;
protected readonly IMapper Mapper;
public bool AutoSaveChanges { get; set; } = true;
public IdentityRepository(TIdentityDbContext dbContext,
UserManager<TUser> userManager,
RoleManager<TRole> roleManager,
IMapper mapper)
{
DbContext = dbContext;
UserManager = userManager;
RoleManager = roleManager;
Mapper = mapper;
}
public virtual TUserKey ConvertUserKeyFromString(string id)
{
if (id == null)
{
return default(TUserKey);
}
return (TUserKey)TypeDescriptor.GetConverter(typeof(TUserKey)).ConvertFromInvariantString(id);
}
public virtual TRoleKey ConvertRoleKeyFromString(string id)
{
if (id == null)
{
return default(TRoleKey);
}
return (TRoleKey)TypeDescriptor.GetConverter(typeof(TRoleKey)).ConvertFromInvariantString(id);
}
public virtual Task<bool> ExistsUserAsync(string userId)
{
var id = ConvertUserKeyFromString(userId);
return UserManager.Users.AnyAsync(x => x.Id.Equals(id));
}
public virtual Task<bool> ExistsRoleAsync(string roleId)
{
var id = ConvertRoleKeyFromString(roleId);
return RoleManager.Roles.AnyAsync(x => x.Id.Equals(id));
}
public virtual async Task<PagedList<TUser>> GetUsersAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TUser>();
Expression<Func<TUser, bool>> searchCondition = x => x.UserName.Contains(search) || x.Email.Contains(search);
var users = await UserManager.Users.WhereIf(!string.IsNullOrEmpty(search), searchCondition).PageBy(x => x.Id, page, pageSize).ToListAsync();
pagedList.Data.AddRange(users);
pagedList.TotalCount = await UserManager.Users.WhereIf(!string.IsNullOrEmpty(search), searchCondition).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TUser>> GetRoleUsersAsync(string roleId, string search, int page = 1, int pageSize = 10)
{
var id = ConvertRoleKeyFromString(roleId);
var pagedList = new PagedList<TUser>();
var users = DbContext.Set<TUser>()
.Join(DbContext.Set<TUserRole>(), u => u.Id, ur => ur.UserId, (u, ur) => new {u, ur})
.Where(t => t.ur.RoleId.Equals(id))
.WhereIf(!string.IsNullOrEmpty(search), t => t.u.UserName.Contains(search) || t.u.Email.Contains(search))
.Select(t => t.u);
var pagedUsers = await users.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(pagedUsers);
pagedList.TotalCount = await users.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<List<TRole>> GetRolesAsync()
{
return RoleManager.Roles.ToListAsync();
}
public virtual async Task<PagedList<TRole>> GetRolesAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TRole>();
Expression<Func<TRole, bool>> searchCondition = x => x.Name.Contains(search);
var roles = await RoleManager.Roles.WhereIf(!string.IsNullOrEmpty(search), searchCondition).PageBy(x => x.Id, page, pageSize).ToListAsync();
pagedList.Data.AddRange(roles);
pagedList.TotalCount = await RoleManager.Roles.WhereIf(!string.IsNullOrEmpty(search), searchCondition).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<TRole> GetRoleAsync(TKey roleId)
{
return RoleManager.Roles.Where(x => x.Id.Equals(roleId)).SingleOrDefaultAsync();
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRole role)
{
var identityResult = await RoleManager.CreateAsync(role);
return (identityResult, role.Id);
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRole role)
{
var thisRole = await RoleManager.FindByIdAsync(role.Id.ToString());
thisRole.Name = role.Name;
var identityResult = await RoleManager.UpdateAsync(thisRole);
return (identityResult, role.Id);
}
public virtual async Task<IdentityResult> DeleteRoleAsync(TRole role)
{
var thisRole = await RoleManager.FindByIdAsync(role.Id.ToString());
return await RoleManager.DeleteAsync(thisRole);
}
public virtual Task<TUser> GetUserAsync(string userId)
{
return UserManager.FindByIdAsync(userId);
}
/// <summary>
/// Create a new user
/// </summary>
/// <param name="user"></param>
/// <returns>This method returns identity result and new user id</returns>
public virtual async Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUser user)
{
var identityResult = await UserManager.CreateAsync(user);
return (identityResult, user.Id);
}
public virtual async Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUser user)
{
var userIdentity = await UserManager.FindByIdAsync(user.Id.ToString());
Mapper.Map(user, userIdentity);
var identityResult = await UserManager.UpdateAsync(userIdentity);
return (identityResult, user.Id);
}
public virtual async Task<IdentityResult> CreateUserRoleAsync(string userId, string roleId)
{
var user = await UserManager.FindByIdAsync(userId);
var selectRole = await RoleManager.FindByIdAsync(roleId);
return await UserManager.AddToRoleAsync(user, selectRole.Name);
}
public virtual async Task<PagedList<TRole>> GetUserRolesAsync(string userId, int page = 1, int pageSize = 10)
{
var id = ConvertUserKeyFromString(userId);
var pagedList = new PagedList<TRole>();
var roles = from r in DbContext.Set<TRole>()
join ur in DbContext.Set<TUserRole>() on r.Id equals ur.RoleId
where ur.UserId.Equals(id)
select r;
var userIdentityRoles = await roles.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(userIdentityRoles);
pagedList.TotalCount = await roles.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<IdentityResult> DeleteUserRoleAsync(string userId, string roleId)
{
var role = await RoleManager.FindByIdAsync(roleId);
var user = await UserManager.FindByIdAsync(userId);
return await UserManager.RemoveFromRoleAsync(user, role.Name);
}
public virtual async Task<PagedList<TUserClaim>> GetUserClaimsAsync(string userId, int page, int pageSize)
{
var id = ConvertUserKeyFromString(userId);
var pagedList = new PagedList<TUserClaim>();
var claims = await DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(id))
.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(id)).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TRoleClaim>> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10)
{
var id = ConvertRoleKeyFromString(roleId);
var pagedList = new PagedList<TRoleClaim>();
var claims = await DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(id))
.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(id)).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TRoleClaim>> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10)
{
var id = ConvertUserKeyFromString(userId);
Expression<Func<TRoleClaim, bool>> searchCondition = x => x.ClaimType.Contains(claimSearchText);
var claimsQ = DbContext.Set<TUserRole>().Where(x => x.UserId.Equals(id))
.Join(DbContext.Set<TRoleClaim>().WhereIf(!string.IsNullOrEmpty(claimSearchText), searchCondition), ur => ur.RoleId, rc => rc.RoleId, (ur, rc) => rc);
var claims= await claimsQ.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
var pagedList = new PagedList<TRoleClaim>();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await claimsQ.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<TUserClaim> GetUserClaimAsync(string userId, int claimId)
{
var userIdConverted = ConvertUserKeyFromString(userId);
return DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(userIdConverted) && x.Id == claimId)
.SingleOrDefaultAsync();
}
public virtual Task<TRoleClaim> GetRoleClaimAsync(string roleId, int claimId)
{
var roleIdConverted = ConvertRoleKeyFromString(roleId);
return DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(roleIdConverted) && x.Id == claimId)
.SingleOrDefaultAsync();
}
public virtual async Task<IdentityResult> CreateUserClaimsAsync(TUserClaim claims)
{
var user = await UserManager.FindByIdAsync(claims.UserId.ToString());
return await UserManager.AddClaimAsync(user, new Claim(claims.ClaimType, claims.ClaimValue));
}
public virtual async Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaim claims)
{
var role = await RoleManager.FindByIdAsync(claims.RoleId.ToString());
return await RoleManager.AddClaimAsync(role, new Claim(claims.ClaimType, claims.ClaimValue));
}
public virtual async Task<int> DeleteUserClaimsAsync(string userId, int claimId)
{
var user = await UserManager.FindByIdAsync(userId);
var userClaim = await DbContext.Set<TUserClaim>().Where(x => x.Id == claimId).SingleOrDefaultAsync();
await UserManager.RemoveClaimAsync(user, new Claim(userClaim.ClaimType, userClaim.ClaimValue));
return await AutoSaveChangesAsync();
}
public virtual async Task<int> DeleteRoleClaimsAsync(string roleId, int claimId)
{
var role = await RoleManager.FindByIdAsync(roleId);
var roleClaim = await DbContext.Set<TRoleClaim>().Where(x => x.Id == claimId).SingleOrDefaultAsync();
await RoleManager.RemoveClaimAsync(role, new Claim(roleClaim.ClaimType, roleClaim.ClaimValue));
return await AutoSaveChangesAsync();
}
public virtual async Task<List<UserLoginInfo>> GetUserProvidersAsync(string userId)
{
var user = await UserManager.FindByIdAsync(userId);
var userLoginInfos = await UserManager.GetLoginsAsync(user);
return userLoginInfos.ToList();
}
public virtual Task<TUserLogin> GetUserProviderAsync(string userId, string providerKey)
{
var userIdConverted = ConvertUserKeyFromString(userId);
return DbContext.Set<TUserLogin>().Where(x => x.UserId.Equals(userIdConverted) && x.ProviderKey == providerKey)
.SingleOrDefaultAsync();
}
public virtual async Task<IdentityResult> DeleteUserProvidersAsync(string userId, string providerKey, string loginProvider)
{
var userIdConverted = ConvertUserKeyFromString(userId);
var user = await UserManager.FindByIdAsync(userId);
var login = await DbContext.Set<TUserLogin>().Where(x => x.UserId.Equals(userIdConverted) && x.ProviderKey == providerKey && x.LoginProvider == loginProvider).SingleOrDefaultAsync();
return await UserManager.RemoveLoginAsync(user, login.LoginProvider, login.ProviderKey);
}
public virtual async Task<IdentityResult> UserChangePasswordAsync(string userId, string password)
{
var user = await UserManager.FindByIdAsync(userId);
var token = await UserManager.GeneratePasswordResetTokenAsync(user);
return await UserManager.ResetPasswordAsync(user, token, password);
}
public virtual async Task<IdentityResult> DeleteUserAsync(string userId)
{
var userIdentity = await UserManager.FindByIdAsync(userId);
return await UserManager.DeleteAsync(userIdentity);
}
private async Task<int> AutoSaveChangesAsync()
{
return AutoSaveChanges ? await DbContext.SaveChangesAsync() : (int)SavedStatus.WillBeSavedExplicitly;
}
}
}