using Hcs.WebApp.Data.Identity; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; namespace Hcs.WebApp.Services { public class UsersService( IDbContextFactory factory, UserManager userManager, IPasswordHasher passwordHasher) { private readonly IDbContextFactory factory = factory; private readonly UserManager userManager = userManager; private readonly IPasswordHasher passwordHasher = passwordHasher; public async Task> GetUsersWithRoleAsync() { using var context = factory.CreateDbContext(); return await (from user in context.Users join userRole in context.UserRoles on user.Id equals userRole.UserId join role in context.Roles on userRole.RoleId equals role.Id orderby role.Priority select new AppUserWithRole() { User = user, Role = role }).ToListAsync(); } public async Task CreateUserAsync(string userName, string roleName, string password) { var user = new AppUser() { UserName = userName, NormalizedUserName = userName.Normalize() }; var result = await userManager.CreateAsync(user, password); if (result.Succeeded) { result = await userManager.AddToRolesAsync(user, [roleName]); } return result; } public async Task UpdateUserAsync(string userId, string roleId, string password) { using var context = factory.CreateDbContext(); var executionStrategy = context.Database.CreateExecutionStrategy(); await executionStrategy.ExecuteAsync(async () => { using var transaction = await context.Database.BeginTransactionAsync(); try { var curUserRole = await (from userRole in context.UserRoles where userRole.UserId == userId select userRole).SingleAsync(); var curRole = await (from role in context.Roles where role.Id == curUserRole.RoleId select role).SingleAsync(); if (curRole.Id != roleId) { context.UserRoles.Remove(curUserRole); var newRole = await (from role in context.Roles where role.Id == roleId select role).SingleAsync(); await context.UserRoles.AddAsync(new IdentityUserRole() { UserId = userId, RoleId = newRole.Id }); } var curUser = await (from user in context.Users where user.Id == userId select user).SingleAsync(); var newPasswordHash = passwordHasher.HashPassword(curUser, password); if (curUser.PasswordHash != newPasswordHash) { curUser.PasswordHash = newPasswordHash; context.Users.Update(curUser); } await context.SaveChangesAsync(); await transaction.CommitAsync(); } catch { await transaction.RollbackAsync(); throw; } }); } public async Task DeleteUserAsync(string userId) { var user = await userManager.FindByIdAsync(userId); return await userManager.DeleteAsync(user); } } }