AccessService.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. using System;
  2. using System.Security.Principal;
  3. using System.Threading.Tasks;
  4. using BO.AppServer.Business.Mapper;
  5. using BO.AppServer.Data.Entity;
  6. using BO.AppServer.Metadata.Configuration;
  7. using BO.AppServer.Metadata.Dto;
  8. using BO.AppServer.Metadata.Enums;
  9. using Microsoft.AspNetCore.Http;
  10. using Microsoft.AspNetCore.Identity;
  11. using Microsoft.Extensions.Logging;
  12. using Microsoft.Extensions.Options;
  13. using Quadarax.Foundation.Core.Business;
  14. using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
  15. using Quadarax.Foundation.Core.Exceptions;
  16. namespace BO.AppServer.Business.Services
  17. {
  18. public class AccessService : AbstractService
  19. {
  20. private const string CS_SESSION_MAGIC = "magic";
  21. private const string CS_SESSION_TOKEN = "token";
  22. private SignInManager<IdentityUser> _manSignIn;
  23. private readonly UserManager<IdentityUser> _manUsers;
  24. private readonly UserRepo _repoUsers;
  25. private readonly IHttpContextAccessor _context;
  26. private readonly Configuration _configuration;
  27. public AccessService(IOptions<Configuration> config,
  28. SignInManager<IdentityUser> manSignIn,
  29. UserManager<IdentityUser> manUsers,
  30. UserRepo repoUsers,
  31. IPrincipal currentPrincipal, ILoggerFactory logger,
  32. IHttpContextAccessor context) : base(currentPrincipal, logger)
  33. {
  34. _configuration = config.Value;
  35. _manUsers = manUsers ?? throw new ArgumentNullException(nameof(manUsers));
  36. _repoUsers = repoUsers ?? throw new ArgumentNullException(nameof(repoUsers));
  37. _context = context ?? throw new ArgumentNullException(nameof(context));
  38. _manSignIn = manSignIn ?? throw new ArgumentNullException(nameof(manSignIn));
  39. }
  40. public void OpenMagic(string magic)
  41. {
  42. _context.HttpContext.Session.SetString(CS_SESSION_MAGIC , magic);
  43. CheckMagic();
  44. _context.HttpContext.Session.SetString(CS_SESSION_TOKEN , "TKN" + Guid.NewGuid().ToString("N"));
  45. }
  46. public string GetToken()
  47. {
  48. return _context.HttpContext.Session.GetString(CS_SESSION_TOKEN);
  49. }
  50. public void CheckMagic()
  51. {
  52. if (!_configuration.Api.Console.MagicKeys.Contains(_context.HttpContext.Session.GetString(CS_SESSION_MAGIC)))
  53. throw new UnauthorizedAccessException("Wrong magic key to access to BO.AppServer api!");
  54. }
  55. public void CheckToken(string token)
  56. {
  57. if (string.IsNullOrEmpty(token) || _context.HttpContext.Session.GetString(CS_SESSION_TOKEN) != token)
  58. throw new UnauthorizedAccessException("Wrong token to access to BO.AppServer api!");
  59. }
  60. public async Task<ResultValueDto<UserRDto>> Login(string userName, string userPassword, RoleEnum loginForRole)
  61. {
  62. var idtUser = await _manUsers.FindByNameAsync(userName);
  63. if (idtUser == null)
  64. {
  65. return new ResultValueDto<UserRDto>(new CodeException(1201,
  66. $"User '{userName}' doesn't exists!"));
  67. }
  68. var isApproved = await _manUsers.IsInRoleAsync(idtUser, loginForRole.ToString());
  69. if (!isApproved)
  70. {
  71. return new ResultValueDto<UserRDto>(new CodeException(1200,
  72. $"User '{userName}' has no permission to login in. Access denied!"));
  73. }
  74. var user = _repoUsers.GetByIfReference(idtUser.Id);
  75. if (!user.IsEnabled)
  76. {
  77. Log.LogWarning($"User '{userName}' is disabled for log-in!");
  78. return new ResultValueDto<UserRDto>(new CodeException(1202,
  79. $"User '{userName}' is disabled for log-in!"));
  80. }
  81. var result = await _manSignIn.PasswordSignInAsync(userName, userPassword, false, lockoutOnFailure: false);
  82. if (result.Succeeded)
  83. {
  84. user.LastLogged = DateTime.Now;
  85. _repoUsers.Set(user);
  86. _repoUsers.Commit();
  87. Log.LogInformation($"User '{userName}' [{user.Id}/{idtUser.Id}] logged in.");
  88. return new ResultValueDto<UserRDto>(user.Map<User, UserRDto>());
  89. }
  90. if (result.RequiresTwoFactor)
  91. {
  92. Log.LogWarning($"Two-factor sign for '{userName}' is set but not supported. Contact administrator.");
  93. return new ResultValueDto<UserRDto>(new Exception(
  94. $"Two-factor sign for '{userName}' is set but not supported. Contact administrator."));
  95. }
  96. if (result.IsLockedOut)
  97. {
  98. Log.LogWarning($"User '{userName}' is locked out.");
  99. return new ResultValueDto<UserRDto>(new CodeException(1202, $"User '{userName}' is locked out!"));
  100. }
  101. Log.LogWarning($"Invalid login attempt for user '{userName}'.");
  102. return new ResultValueDto<UserRDto>(new CodeException(1203, $"Invalid login attempt for user '{userName}'."));
  103. }
  104. }
  105. }