AccessService.cs 5.0 KB

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