first commit
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
using System.Net.Mime;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using OpenWarehouse.auth.api.Common.AuthTokenRepo;
|
||||
using OpenWarehouse.auth.api.Common.CustomIdentifyManager;
|
||||
using OpenWarehouse.auth.api.Common.RegisterTokenManager;
|
||||
using OpenWarehouse.auth.lib.Model.Account;
|
||||
using OpenWarehouse.auth.lib.Model.Auth;
|
||||
|
||||
namespace OpenWarehouse.auth.api.Controller;
|
||||
|
||||
[ApiController]
|
||||
[Route("[action]")]
|
||||
public class Auth(
|
||||
SignInManager<ApplicationUser> signInManager, UserManager<ApplicationUser> userManager,
|
||||
AuthTokenRepo tokenRepo, ApplicationDbContext applicationDbContext,
|
||||
RegisterTokenManager registerTokenManager,
|
||||
ILogger<Auth> logger) : ControllerBase
|
||||
{
|
||||
|
||||
[HttpPost]
|
||||
[Consumes(MediaTypeNames.Application.Json, MediaTypeNames.Application.Xml)]
|
||||
public async Task<ActionResult<LoginModel>> Login([FromBody] LoginRequestModel requestModel)
|
||||
{
|
||||
logger.LogInformation("Login request received for user: {Login}", requestModel.Login);
|
||||
if (requestModel.Pass == null || requestModel.Login == null)
|
||||
{
|
||||
logger.LogWarning("Invalid login request model.");
|
||||
return BadRequest("Invalid request model.");
|
||||
}
|
||||
|
||||
var loginModel = new LoginModel();
|
||||
|
||||
if (requestModel.Pass == null)
|
||||
{
|
||||
loginModel.AccountProblem = "Login and password are required.";
|
||||
logger.LogWarning("Password is missing in the login request for user: {Login}", requestModel.Login);
|
||||
return BadRequest(loginModel);
|
||||
}
|
||||
|
||||
var applicationUser = await userManager.FindByNameAsync(requestModel.Login)
|
||||
?? await userManager.FindByEmailAsync(requestModel.Login);
|
||||
if (applicationUser == null)
|
||||
{
|
||||
logger.LogWarning("User not found for login: {Login}", requestModel.Login);
|
||||
loginModel.Message = "Incorrect login or password.";
|
||||
return Unauthorized(loginModel);
|
||||
}
|
||||
|
||||
loginModel.Login = applicationUser.UserName;
|
||||
loginModel.Email = applicationUser.Email;
|
||||
|
||||
var claims = await userManager.GetClaimsAsync(applicationUser);
|
||||
|
||||
if (claims.Any(claim => claim.Type.Equals(AccountType.Service.GetValue())))
|
||||
{
|
||||
logger.LogWarning("Service account attempted to login: {Login}", requestModel.Login);
|
||||
return Forbid("This is a service account.");
|
||||
}
|
||||
|
||||
if (applicationUser.LockoutEnabled)
|
||||
{
|
||||
logger.LogWarning("Locked account attempted to login: {Login}", requestModel.Login);
|
||||
return Forbid("Account is locked.");
|
||||
}
|
||||
|
||||
var signInResult = await signInManager.CheckPasswordSignInAsync(applicationUser, requestModel.Pass, false);
|
||||
|
||||
if (signInResult.Succeeded)
|
||||
{
|
||||
// var expiration = DateTime.UtcNow.AddHours(1);
|
||||
|
||||
var expiration = DateTime.UtcNow.AddMinutes(30);
|
||||
loginModel.Token = await tokenRepo.CreateJwtToken(applicationUser, expiration, null);
|
||||
loginModel.Exp = expiration.ToBinary();
|
||||
loginModel.IsLogged = true;
|
||||
logger.LogInformation("User logged in successfully: {Login}", requestModel.Login);
|
||||
return Ok(loginModel);
|
||||
}
|
||||
|
||||
if (signInResult.RequiresTwoFactor)
|
||||
{
|
||||
logger.LogInformation("Two-factor authentication required for user: {Login}", requestModel.Login);
|
||||
loginModel.Message = "Two-factor authentication is required.";
|
||||
loginModel.RequiresTwoFactor = true;
|
||||
return Ok(loginModel);
|
||||
}
|
||||
|
||||
logger.LogWarning("Incorrect login or password for user: {Login}", requestModel.Login);
|
||||
loginModel.Message = "Incorrect login or password.";
|
||||
return Unauthorized(loginModel);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Consumes(MediaTypeNames.Application.Json, otherContentTypes: [MediaTypeNames.Application.Xml])]
|
||||
public async Task<ActionResult<RegisterReturnModel>> Register([FromBody]RegisterModel registerModel)
|
||||
{
|
||||
logger.LogInformation("Registration request received for user: {Username}", registerModel.Username);
|
||||
var registerReturnModel = new RegisterReturnModel();
|
||||
registerReturnModel.IsCreated = true;
|
||||
if (registerModel.Username != null)
|
||||
{
|
||||
var user = new ApplicationUser(registerModel.Username);
|
||||
user.Email = registerModel.Email;
|
||||
|
||||
if (registerModel.RegisterToken != null)
|
||||
{
|
||||
var regToken = await registerTokenManager.GetToken(registerModel.RegisterToken);
|
||||
|
||||
if (regToken == null)
|
||||
{
|
||||
logger.LogWarning("Registration token not found: {RegisterToken}", registerModel.RegisterToken);
|
||||
registerReturnModel.IsCreated = false;
|
||||
registerReturnModel.ProblemWithToken = "Token Not found;";
|
||||
return Unauthorized(registerReturnModel);
|
||||
}
|
||||
|
||||
if (regToken.IsUsed)
|
||||
{
|
||||
logger.LogWarning("Registration token already used: {RegisterToken}", registerModel.RegisterToken);
|
||||
registerReturnModel.IsCreated = false;
|
||||
registerReturnModel.ProblemWithToken = "Token is alleredy used;";
|
||||
}
|
||||
|
||||
if (( registerModel.Password ?? "" ).Length > 6)
|
||||
{
|
||||
registerReturnModel.IsCreated = false;
|
||||
}
|
||||
|
||||
if (!registerReturnModel.IsCreated) return Unauthorized(registerReturnModel);
|
||||
|
||||
if (registerModel.Password != null)
|
||||
{
|
||||
var result = await userManager.CreateAsync(user, registerModel.Password);
|
||||
var resultClaim = await userManager.AddClaimAsync(user, AccountType.User.Claim());
|
||||
if (result.Succeeded && resultClaim.Succeeded)
|
||||
{
|
||||
regToken.IsUsed = true;
|
||||
await applicationDbContext.SaveChangesAsync();
|
||||
registerReturnModel.AuthToken =
|
||||
await tokenRepo.CreateJwtToken(user, DateTime.UtcNow.AddHours(1), null);
|
||||
logger.LogInformation("User registered successfully: {Username}", registerModel.Username);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
logger.LogError("Error during user registration: {Code} - {Description}", error.Code, error.Description);
|
||||
registerReturnModel.OtherWithOtherProblem += error.Code + "-" + error.Description + ";";
|
||||
return Unauthorized(registerReturnModel);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.LogWarning("Registration token is required but missing for user: {Username}", registerModel.Username);
|
||||
return BadRequest("Token are required.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Ok(registerReturnModel);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
public async Task<LogOutModel> LogOut()
|
||||
{
|
||||
logger.LogInformation("Logout request received.");
|
||||
if (Request.Headers.TryGetValue("Authorization", out var token))
|
||||
{
|
||||
var tokenStr = token.ToString();
|
||||
string?[] tokenSplit = tokenStr.Split(" ");
|
||||
if (tokenSplit.Length > 0) tokenStr = tokenSplit[1];
|
||||
if (await tokenRepo.LockTokenAsync(tokenStr) > 0)
|
||||
{
|
||||
logger.LogInformation("User logged out successfully.");
|
||||
return new LogOutModel(true, "Logout successful");
|
||||
}
|
||||
}
|
||||
logger.LogWarning("Logout failed due to missing or invalid token.");
|
||||
return new LogOutModel(false, "Logout Fail");
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
public async Task<ActionResult<RegeneratedTokenModel>> RegenerateToken()
|
||||
{
|
||||
logger.LogInformation("Token regeneration request received.");
|
||||
Request.Headers.TryGetValue("Authorization", out var token);
|
||||
|
||||
token = token.ToString().Split(" ")[1];
|
||||
|
||||
var newTokenStr = await tokenRepo.RegenerateJwtToken(token, DateTime.UtcNow.AddMinutes(30));
|
||||
|
||||
logger.LogInformation("Token regenerated successfully");
|
||||
|
||||
var respond = new RegeneratedTokenModel()
|
||||
{
|
||||
Mess = newTokenStr != null ? "Regeneration success" : "Regeneration fail",
|
||||
Token = newTokenStr
|
||||
};
|
||||
|
||||
return Ok(respond);
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
|
||||
[HasPrivilege(GlobalPrivilage.Privilege.GlobalDeleteExpiredToken)]
|
||||
public async Task<ActionResult<int>> DeleteExpiredToken()
|
||||
{
|
||||
logger.LogInformation("Delete expired tokens request received.");
|
||||
return Ok(await tokenRepo.DeleteInactiveToken());
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<bool>> TokenIsLock([FromBody] TokenAskIfIsLockModel req)
|
||||
{
|
||||
logger.LogInformation("Check if token is locked request received.");
|
||||
return Ok(await tokenRepo.IsTokenLockAsync(req.Token));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user