UserService.cs 8.7 KB

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