UserService.cs 9.1 KB

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