UserService.cs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Security.Principal;
  6. using System.Threading.Tasks;
  7. using BO.AppServer.Business.Mapper;
  8. using BO.AppServer.Business.Services.Base;
  9. using BO.AppServer.Data.Entity;
  10. using BO.AppServer.Metadata.Dto;
  11. using BO.AppServer.Metadata.Enums;
  12. using Microsoft.AspNetCore.Identity;
  13. using Microsoft.Extensions.Logging;
  14. using Quadarax.Foundation.Core.Business.Security;
  15. using Quadarax.Foundation.Core.Data;
  16. using Quadarax.Foundation.Core.Data.Interface;
  17. using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
  18. using Quadarax.Foundation.Core.Exceptions;
  19. namespace BO.AppServer.Business.Services
  20. {
  21. public class UserService : UserContextService
  22. {
  23. #region *** Private fields ***
  24. private UserManager<IdentityUser> _manUser;
  25. private RoleManager<IdentityRole> _manRole;
  26. protected WorkspaceRepo _repoWorkspace;
  27. #endregion
  28. #region *** Constructor & DI ***
  29. public UserService(
  30. WorkspaceRepo repoWorkspace,
  31. AccessService srvAccessService,
  32. RoleManager<IdentityRole> roleManager,
  33. UserRepo repoUser,
  34. UserManager<IdentityUser> userManager,
  35. IPrincipal currentPrincipal,
  36. ILoggerFactory logger) : base(repoUser, userManager, currentPrincipal, logger)
  37. {
  38. _manUser = userManager ?? throw new ArgumentNullException(nameof(userManager));
  39. _manRole = roleManager ?? throw new ArgumentNullException(nameof(roleManager));
  40. _repoWorkspace = repoWorkspace ?? throw new ArgumentNullException(nameof(repoWorkspace));
  41. }
  42. #endregion
  43. #region *** Public Operations ***
  44. public async Task<ResultsValueDto<UserRDto>> GetAllUsersAsync(UserScopeEnums scope, PagingDto paging)
  45. {
  46. List<User> users = null;
  47. switch (scope)
  48. {
  49. case UserScopeEnums.All:
  50. users = _repoUser.Query(paging).ToList();
  51. break;
  52. case UserScopeEnums.Locked:
  53. users = _repoUser.Query(paging).Where(x=>x.IsEnabled==false).ToList();
  54. break;
  55. case UserScopeEnums.System:
  56. users = _repoUser.Query(paging).Where(x=>x.IsSystem==true).ToList();
  57. break;
  58. }
  59. return new ResultsValueDto<UserRDto>(users.MapList<User, UserRDto>());
  60. }
  61. public async Task<ResultValueDto<UserRDto>> GetUserAsync(long userId)
  62. {
  63. var user = _repoUser.Get(new []{userId}).FirstOrDefault();
  64. return new ResultValueDto<UserRDto>(user.Map<User, UserRDto>());
  65. }
  66. public async Task<ResultValueDto<UserRDto>> CreateUserAsync(UserCDto newUser)
  67. {
  68. //TODO: role validation
  69. return await CreateUserAsync(newUser.Name, newUser.Password,newUser.Email,newUser.LangLcid,newUser.Roles.Select(Enum.Parse<RoleEnum>).ToArray());
  70. }
  71. public async Task<ResultValueDto<UserRDto>> CreateUserAsync(string userName,string userPassword, string userEmail, int prefferedLCID, RoleEnum[] roles)
  72. {
  73. try
  74. {
  75. // Validations
  76. var exists = await ExistsUserByNameAsync(userName);
  77. if (exists.Value)
  78. throw new CodeException(1100, $"Cannot create user '{userName}', user name or email already exists.");
  79. // Create Identity User
  80. var idtUser = await _manUser.FindByNameAsync(userName);
  81. if (idtUser == null)
  82. {
  83. idtUser = new IdentityUser(userName)
  84. {
  85. NormalizedUserName = userName.ToLower(CultureInfo.InvariantCulture),
  86. Email = userEmail,
  87. NormalizedEmail = userEmail.ToLower(CultureInfo.InvariantCulture),
  88. LockoutEnabled = true,
  89. PasswordHash = PasswordHelper.HashPassword(userPassword)
  90. };
  91. await _manUser.CreateAsync(idtUser);
  92. Log.Log(LogLevel.Debug, $"User '{userName}' created in IF.");
  93. }
  94. else
  95. Log.Log(LogLevel.Debug, $"User '{userName}' already exists in IF.");
  96. // Append roles
  97. var currentRoles = await _manUser.GetRolesAsync(idtUser);
  98. await _manUser.RemoveFromRolesAsync(idtUser, currentRoles.ToArray());
  99. foreach (var role in roles)
  100. {
  101. await _manUser.AddToRoleAsync(idtUser, role.ToString().ToUpper());
  102. Log.Log(LogLevel.Debug, $"User '{userName}' add to role '{role}' in IF.");
  103. }
  104. // Create BO user
  105. var user = _repoUser.GetByIfReference(idtUser.Id);
  106. if (user == null)
  107. {
  108. user = _repoUser.New();
  109. user.Ifreference = idtUser.Id;
  110. user.Name = userName;
  111. user.LangLcid = prefferedLCID;
  112. user.Created = DateTime.Now;
  113. user.IsEnabled = false;
  114. user.LangLcid = prefferedLCID;
  115. user.IsSystem = roles.Contains(RoleEnum.System);
  116. user.IsEnabled = true;
  117. _repoUser.Set(user);
  118. Log.Log(LogLevel.Debug,
  119. $"User '{userName}' [{user.Id}] created as enabled={user.IsEnabled} in BO.");
  120. user = _repoUser.Get(user.Id);
  121. }
  122. else
  123. {
  124. user.Name = idtUser.UserName;
  125. user.LangLcid = prefferedLCID;
  126. user.Modified = DateTime.Now;
  127. user.IsSystem = roles.Contains(RoleEnum.System);
  128. _repoUser.Set(user);
  129. Log.Log(LogLevel.Debug,
  130. $"User '{userName}' [{user.Id}] was recovered in BO.");
  131. }
  132. _repoUser.Commit();
  133. return new ResultValueDto<UserRDto>(user.Map<User, UserRDto>());
  134. }
  135. catch (Exception e)
  136. {
  137. return new ResultValueDto<UserRDto>(e);
  138. }
  139. }
  140. public async Task<ResultBoolDto> ExistsUserByNameAsync(string userName)
  141. {
  142. var user = await _manUser.FindByNameAsync(userName);
  143. if (user == null)
  144. return new ResultBoolDto(false);
  145. var exists = _repoUser.Query(new Paging()).Any(x =>
  146. x.Name.ToLower() == userName.ToLower(CultureInfo.InvariantCulture) && x.Ifreference == user.Id);
  147. return new ResultBoolDto(exists);
  148. }
  149. public async Task<ResultBoolDto> EnusreUserRolesAsync(string userName, RoleEnum[] roles)
  150. {
  151. var idtUser = await _manUser.FindByNameAsync(userName);
  152. if (idtUser == null)
  153. return new ResultBoolDto(false);
  154. var currentRoles = await _manUser.GetRolesAsync(idtUser);
  155. await _manUser.RemoveFromRolesAsync(idtUser, currentRoles.ToArray());
  156. foreach (var role in roles)
  157. {
  158. await _manUser.AddToRoleAsync(idtUser, role.ToString().ToUpper());
  159. Log.Log(LogLevel.Debug, $"User '{userName}' add to role '{role}' in IF.");
  160. }
  161. return new ResultBoolDto(true);
  162. }
  163. public ResultBoolDto ExistsUserByIfReference(string ifReference)
  164. {
  165. var exists = _manUser.FindByIdAsync(ifReference).Result;
  166. return new ResultBoolDto(exists!=null);
  167. }
  168. public async Task EnsureRolesAsync()
  169. {
  170. var roles = Enum.GetNames(typeof(RoleEnum));
  171. foreach (var roleName in roles)
  172. {
  173. if (!await _manRole.RoleExistsAsync(roleName))
  174. {
  175. var role = new IdentityRole(roleName);
  176. role.NormalizedName = roleName.ToUpper(CultureInfo.InvariantCulture);
  177. await _manRole.CreateAsync(role);
  178. Log.Log(LogLevel.Information, $"Role '{roleName}' [{role.Id}] created.");
  179. }
  180. }
  181. }
  182. /*
  183. public ResultValueDto<UserRDto> SetUser(long userId, UserUDto user)
  184. {
  185. }
  186. public ResultValueDto<UserRDto> SetUserLock(long userId, bool flagEnabledDisabled)
  187. {
  188. }
  189. public ResultValueDto<UserRDto> SetUserLogAudit(long userId)
  190. {
  191. }
  192. */
  193. #endregion
  194. }
  195. }