CodeLiturgy.Dashboard/BlueWest.Api/Users/Auth/AuthManager.cs

130 lines
4.8 KiB
C#
Raw Normal View History

2022-09-17 22:13:35 +03:00
using System;
using System.Security.Claims;
2022-09-10 00:33:17 +03:00
using System.Threading.Tasks;
using BlueWest.Cryptography;
2022-09-17 22:13:35 +03:00
using BlueWest.Data.Application;
2022-09-19 05:50:15 +03:00
using Microsoft.AspNetCore.Authentication.JwtBearer;
2022-09-10 00:33:17 +03:00
using Microsoft.AspNetCore.Identity;
2022-09-19 05:50:15 +03:00
using static BlueWest.WebApi.Context.Users.AuthConsts;
2022-09-10 00:33:17 +03:00
2022-09-18 04:00:24 +03:00
namespace BlueWest.WebApi.Context.Users
2022-09-10 00:33:17 +03:00
{
2022-09-18 04:00:24 +03:00
internal class AuthManager : IAuthManager
{
2022-09-17 22:13:35 +03:00
private readonly ApplicationUserManager _userManager;
2022-09-10 00:33:17 +03:00
private readonly IHasher _hasher;
private readonly IJwtFactory _jwtFactory;
2022-09-18 04:00:24 +03:00
private readonly ISessionCache _sessionCache;
2022-09-10 07:12:03 +03:00
/// <summary>
/// Auth manager constructor
/// </summary>
/// <param name="userManager"></param>
/// <param name="hasher"></param>
/// <param name="jwtFactory"></param>
2022-09-18 04:00:24 +03:00
/// <param name="sessionCache"></param>
2022-09-17 22:13:35 +03:00
public AuthManager(
2022-09-18 04:00:24 +03:00
ApplicationUserManager userManager,
IHasher hasher,
IJwtFactory jwtFactory,
ISessionCache sessionCache)
2022-09-10 00:33:17 +03:00
{
_userManager = userManager;
_hasher = hasher;
_jwtFactory = jwtFactory;
2022-09-18 04:00:24 +03:00
_sessionCache = sessionCache;
2022-09-17 22:13:35 +03:00
}
2022-09-18 04:00:24 +03:00
private async Task<SessionToken> GetSessionToken(LoginRequest loginRequest)
2022-09-17 22:13:35 +03:00
{
2022-09-18 04:00:24 +03:00
var uuid = loginRequest.GetUuid();
var hashUuid = GetHashFromUuid(uuid);
var sessionToken = await _sessionCache.GetSessionTokenByIdAsync(hashUuid);
2022-09-19 05:50:15 +03:00
return sessionToken;
2022-09-18 04:00:24 +03:00
}
2022-09-17 22:13:35 +03:00
2022-09-18 04:00:24 +03:00
private string GetHashFromUuid(string uuid)
{
return _hasher.CreateHash(uuid, BaseCryptoItem.HashAlgorithm.SHA2_512);
}
private SessionToken GetNewSessionToken(LoginRequest loginRequest, ApplicationUser user, string token)
{
2022-09-19 05:50:15 +03:00
long timeNow = DateTimeOffset.Now.ToUnixTimeMilliseconds();
2022-09-18 04:00:24 +03:00
var newToken = new SessionToken
2022-09-17 22:13:35 +03:00
{
2022-09-18 04:00:24 +03:00
Id = GetHashFromUuid(loginRequest.GetUuid()),
UserId = user.Id,
2022-09-19 05:50:15 +03:00
CreatedDate = timeNow,
2022-09-18 04:00:24 +03:00
IsValid = true,
2022-09-19 05:50:15 +03:00
ValidFor = SessionConstants.DefaultSessionMaxAge.Milliseconds,
2022-09-18 04:00:24 +03:00
AccessToken = token
};
2022-09-19 05:50:15 +03:00
2022-09-18 04:00:24 +03:00
return newToken;
}
public bool SessionTokenIsValid(SessionToken token)
{
2022-09-19 05:50:15 +03:00
var hasChanges = token.Validate();
2022-09-18 04:00:24 +03:00
2022-09-19 05:50:15 +03:00
if (hasChanges)
2022-09-18 04:00:24 +03:00
{
_sessionCache.SaveAsync();
2022-09-17 22:13:35 +03:00
}
2022-09-18 04:00:24 +03:00
return token.IsValid;
2022-09-10 00:33:17 +03:00
}
2022-09-18 04:00:24 +03:00
2022-09-19 05:50:15 +03:00
public async Task<(bool, SessionTokenUnique, ClaimsIdentity)> GetSessionTokenIdByLoginRequest(LoginRequest loginRequest)
2022-09-10 00:33:17 +03:00
{
2022-09-18 04:00:24 +03:00
var user = await _userManager.FindByEmailAsync(loginRequest.Email);
2022-09-19 05:50:15 +03:00
if (user == null) return NegativeToken;
2022-09-18 04:00:24 +03:00
2022-09-19 05:50:15 +03:00
if (!await _userManager.CheckPasswordAsync(user, loginRequest.Password)) return NegativeToken;
2022-09-18 04:00:24 +03:00
2022-09-19 05:50:15 +03:00
var identity = new ClaimsIdentity(JwtBearerDefaults.AuthenticationScheme);
2022-09-18 04:00:24 +03:00
identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
var sessionToken = await GetSessionToken(loginRequest);
2022-09-19 05:50:15 +03:00
if (sessionToken == null || !SessionTokenIsValid(sessionToken))
2022-09-10 00:33:17 +03:00
{
2022-09-19 05:50:15 +03:00
var (success, bearerToken) = await GenerateBearerToken(identity, user);
var newSessionToken = GetNewSessionToken(loginRequest, user, bearerToken);
await _sessionCache.AddSessionToken(newSessionToken);
var tokenUnique = new SessionTokenUnique(newSessionToken);
2022-09-10 00:33:17 +03:00
2022-09-19 05:50:15 +03:00
return OkAuth(tokenUnique, identity, success);
}
2022-09-18 04:00:24 +03:00
2022-09-19 05:50:15 +03:00
var response = new SessionTokenUnique(sessionToken);
return OkAuth(response, identity);
2022-09-10 00:33:17 +03:00
}
2022-09-18 04:00:24 +03:00
private async Task<(bool, string)> GenerateBearerToken(ClaimsIdentity identity, ApplicationUser user)
{
var jwtToken = await _jwtFactory.GenerateEncodedToken(user.Id, user.UserName);
var completed = await _userManager.SetAuthenticationTokenAsync(user, SessionConstants.ApiNamePolicy,
SessionConstants.ApiNamePolicy, jwtToken.Token);
return (completed == IdentityResult.Success, jwtToken.Token);
}
2022-09-17 22:13:35 +03:00
public async Task<bool> VerifyLoginByEmailAsync(string email, string password)
2022-09-10 00:33:17 +03:00
{
var user = await _userManager.FindByEmailAsync(email);
2022-09-19 05:50:15 +03:00
return user != null && await _userManager.CheckPasswordAsync(user, password);
2022-09-10 00:33:17 +03:00
}
2022-09-10 07:12:03 +03:00
2022-09-10 00:33:17 +03:00
public async Task<IdentityResult> CreateUserAsync(RegisterViewModel userSignupDto)
{
2022-09-19 05:50:15 +03:00
userSignupDto.Password = _hasher.CreateHash(userSignupDto.Password, BaseCryptoItem.HashAlgorithm.SHA3_512);;
var newUser = userSignupDto.ToUser();
return await _userManager.CreateAsync(newUser);
2022-09-10 00:33:17 +03:00
}
2022-09-18 04:00:24 +03:00
}
2022-09-10 00:33:17 +03:00
}