UserService.cs 8.6 KB

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