Web API for the bulk printing desktop application.

LoginController.cs 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using BulkPrintingAPI.Configuration;
  2. using BulkPrintingAPI.Db;
  3. using BulkPrintingAPI.Services;
  4. using MAX.Models;
  5. using Microsoft.AspNetCore.Authorization;
  6. using Microsoft.AspNetCore.Mvc;
  7. using Microsoft.AspNetCore.Mvc.ModelBinding;
  8. using Microsoft.Extensions.Logging;
  9. using System;
  10. using System.ComponentModel.DataAnnotations;
  11. using System.IdentityModel.Tokens.Jwt;
  12. using System.Security.Claims;
  13. using System.Threading.Tasks;
  14. namespace BulkPrintingAPI.Controllers
  15. {
  16. //[Produces("application/json")]
  17. [Route("api/[controller]")]
  18. public class LoginController : Controller
  19. {
  20. public class LoginRequest
  21. {
  22. [Required]
  23. public int? VendorId { get; set; }
  24. [Required]
  25. public string SerialNumber { get; set; }
  26. [Required]
  27. public int? UserId { get; set; }
  28. [Required]
  29. public string Username { get; set; }
  30. [Required]
  31. public string Password { get; set; }
  32. }
  33. private ILogger logger;
  34. private TokenAuthenticationOptions tokenAuthenticationOptions;
  35. private MAXClientFactory clientFactory;
  36. private MAXDbContext dbContext;
  37. public LoginController(ILoggerFactory loggerFactory,
  38. TokenAuthenticationOptions tokenAuthenticationOptions,
  39. MAXClientFactory clientFactory,
  40. MAXDbContext dbContext)
  41. {
  42. logger = loggerFactory.CreateLogger(GetType().FullName);
  43. this.tokenAuthenticationOptions = tokenAuthenticationOptions;
  44. this.clientFactory = clientFactory;
  45. this.dbContext = dbContext;
  46. }
  47. [HttpPost]
  48. [AllowAnonymous]
  49. public async Task<IActionResult> Post([FromBody] LoginRequest loginRequest)
  50. {
  51. if (! ModelState.IsValid)
  52. return BadRequest();
  53. using (var client = clientFactory.GetClient(logger, loginRequest.VendorId.Value,
  54. loginRequest.SerialNumber, loginRequest.UserId.Value, loginRequest.Username,
  55. loginRequest.Password))
  56. {
  57. User user;
  58. try
  59. {
  60. user = await client.ConnectAsync();
  61. }
  62. catch (Exception e)
  63. {
  64. logger.LogError(
  65. "ConnectAsync failed for vendorId={0} serialNumber={1} userId={2} username={3}: {4}",
  66. loginRequest.VendorId, loginRequest.SerialNumber,
  67. loginRequest.UserId, loginRequest.Username, e.Message);
  68. return Unauthorized();
  69. }
  70. if (user == null)
  71. {
  72. logger.LogInformation(
  73. "Login failed for vendorId={0} serialNumber={1} userId={2} username={3}",
  74. loginRequest.VendorId, loginRequest.SerialNumber,
  75. loginRequest.UserId, loginRequest.Username);
  76. return Unauthorized();
  77. }
  78. try
  79. {
  80. await DbHelpers.SyncUserAndVendorWithDb(dbContext, user,
  81. loginRequest.VendorId.Value,
  82. loginRequest.SerialNumber);
  83. }
  84. catch (Exception e)
  85. {
  86. logger.LogError(
  87. "SyncUserAndVendorWithDb failed for vendorId={0} serialNumber={1} userId={2} username={3}: {4}",
  88. loginRequest.VendorId, loginRequest.SerialNumber,
  89. loginRequest.UserId, loginRequest.Username, e.Message);
  90. return Unauthorized();
  91. }
  92. var now = DateTime.UtcNow;
  93. var encodedJwt = new JwtSecurityTokenHandler().CreateEncodedJwt(
  94. issuer: tokenAuthenticationOptions.Issuer,
  95. audience: tokenAuthenticationOptions.Audience,
  96. subject: new ClaimsIdentity(new Claim[] {
  97. new Claim(JwtRegisteredClaimNames.Sub, user.Id.ToString()),
  98. new Claim("xpwd", loginRequest.Password),
  99. new Claim("xvid", loginRequest.VendorId.ToString()),
  100. new Claim(JwtRegisteredClaimNames.Jti, await tokenAuthenticationOptions.NonceGenerator())
  101. }),
  102. notBefore: now,
  103. expires: now.Add(tokenAuthenticationOptions.Lifetime),
  104. issuedAt: now,
  105. signingCredentials: tokenAuthenticationOptions.SigningCredentials,
  106. encryptingCredentials: tokenAuthenticationOptions.EncryptingCredentials
  107. );
  108. return Ok(new {
  109. access_token = encodedJwt,
  110. expires_in = (int)tokenAuthenticationOptions.Lifetime.TotalSeconds
  111. });
  112. }
  113. }
  114. }
  115. }