New source control repo for Biskilog POS - secure hub to store & manage source code. Streamlines dev process, tracks changes, & improves collaboration. Ensures reliable software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
9.8 KiB

using Biskilog_Accounting.Shared.ClientContractModels;
using Biskilog_Accounting.Shared.Enums;
using Biskilog_Accounting.Shared.Interfaces;
using Blazored.LocalStorage;
using Blazored.SessionStorage;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
namespace Biskilog_Accounting.ServiceRepo
{
public class TokenService : ITokenService
{
private IConfiguration m_configuration { get; }
private readonly ISessionStorageService m_sessionStorage;
private readonly ILocalStorageService m_localStorage;
public TokenService(IConfiguration a_configuration, ISessionStorageService a_sessionStorage = null, ILocalStorageService a_localStorage = null)
{
m_configuration = a_configuration;
m_sessionStorage = a_sessionStorage;
m_localStorage = a_localStorage;
}
/// <summary>
/// Validates a user access token
/// </summary>
/// <returns>AuthEnums.Valid if token is a valid and unexpired token</returns>
public AuthEnums ValidateToken(string a_token)
{
try
{
string token = a_token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)handler.ReadToken(token);
if (jwtToken.ValidFrom <= DateTime.Now && jwtToken.ValidTo > DateTime.Now)
return AuthEnums.Valid;
return AuthEnums.Expired;
}
catch (Exception ex)
{
return AuthEnums.Invalid;
}
}
/// <summary>
/// Generates an access token based on the user
/// </summary>
/// <returns>A tokenized string</returns>
public string GenerateToken(Userauth a_user, Contract a_clientContract, Databasemap a_database, List<string> a_business, bool a_comparison)
{
try
{
//create claims details based on the user information
var claims = new[] {
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()),
new Claim("ContractStart",a_clientContract.StartDate !.Value.ToString()),
new Claim("ContractEnd",a_clientContract.EndDate!.Value.ToString()),
new Claim("UserId", a_user.UserId.ToString()),
new Claim("Username", a_user.Username.ToString()),
new Claim("DbId",a_database.DbNo.ToString()),
new Claim("ComparisonMode",a_comparison.ToString()),
new Claim("BranchId",a_business[0].ToString()),
new Claim("BranchAccess",string.Join(", ", a_business.ToArray())),
new Claim("ClientId", a_user.ClientId.ToString()),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(m_configuration["Jwt:Key"]!));
var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var token = new JwtSecurityToken(m_configuration["Jwt:Issuer"], m_configuration["Jwt:Audience"], claims, expires: DateTime.UtcNow.AddDays(14), signingCredentials: signIn);
return $"{new JwtSecurityTokenHandler().WriteToken(token)}";
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return AuthEnums.Error.ToString();
}
}
/// <summary>
///Deserializes the token string if valid to return the specified user role id in the token string
/// </summary>
/// <param name="a_token"></param>
/// <returns>RoleId</returns>
public int? GetDatabaseIdFromToken(string a_token)
{
if (ValidateToken(a_token) == AuthEnums.Valid)
{
string token = a_token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)handler.ReadToken(token);
return int.Parse(jwtToken.Claims.First(claim => claim.Type == "DbId").Value);
}
return null;
}
/// <summary>
///Deserializes the token string if valid to return the specified user id in the token string
/// </summary>
/// <param name="a_token"></param>
/// <returns>UserId</returns>
public int? GetUserIdFromToken(string a_token)
{
if (ValidateToken(a_token) == AuthEnums.Valid)
{
string token = a_token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)handler.ReadToken(token);
return int.Parse(jwtToken.Claims.First(claim => claim.Type == "UserId").Value);
}
return null;
}
/// <summary>
///Deserializes the token string if valid to return the specified username in the token string
/// </summary>
/// <param name="a_token"></param>
/// <returns>Username</returns>
public string? GetUserNameFromToken(string a_token)
{
if (ValidateToken(a_token) == AuthEnums.Valid)
{
string token = a_token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)handler.ReadToken(token);
return jwtToken.Claims.First(claim => claim.Type == "Username").Value;
}
return null;
}
/// <summary>
///Deserializes the token string if valid to return the specified branchId in the token string
/// </summary>
/// <param name="a_token"></param>
/// <returns>Username</returns>
public string? GetBaseBranch(string a_token)
{
if (ValidateToken(a_token) == AuthEnums.Valid)
{
string token = a_token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)handler.ReadToken(token);
return jwtToken.Claims.First(claim => claim.Type == "BranchId").Value;
}
return null;
}
public bool? GetComparison(string a_token)
{
if (ValidateToken(a_token) == AuthEnums.Valid)
{
string token = a_token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)handler.ReadToken(token);
return bool.Parse(jwtToken.Claims.First(claim => claim.Type == "ComparisonMode").Value);
}
return null;
}
/// <summary>
///Deserializes the token string if valid to return the specified list of branches a user has access to in the token string
/// </summary>
/// <param name="a_token"></param>
/// <returns>Username</returns>
public string? GetAllBranch(string a_token)
{
if (ValidateToken(a_token) == AuthEnums.Valid)
{
string token = a_token.Substring(6).Trim();
var handler = new JwtSecurityTokenHandler();
JwtSecurityToken jwtToken = (JwtSecurityToken)handler.ReadToken(token);
return jwtToken.Claims.First(claim => claim.Type == "BranchAccess").Value;
}
return null;
}
/// <summary>
/// Return a specified list of branches a user has access if comparison mode is set otherwise returns only the
/// active branch on the list
/// </summary>
/// <param name="a_token"></param>
/// <returns></returns>
public IEnumerable<string> BranchIds(string a_token)
{
List<string> branchIds = new List<string>();
if (ValidateToken(a_token) == AuthEnums.Valid)
{
bool comparison = GetComparison(a_token)!.Value;
if (comparison)
{
string? branches = GetAllBranch(a_token);
if (branches != null)
{
string[] branchArray = branches!.Split();
branchIds.AddRange(branchArray);
}
}
else
{
string? baseBranch = GetBaseBranch(a_token);
branchIds.Add(baseBranch!);
}
}
return branchIds.AsEnumerable();
}
public async Task SetToken(string a_token, bool a_remember)
{
if (a_remember)
{
await m_localStorage.SetItemAsStringAsync("token", $"Bearer {a_token}");
}
else
{
await m_sessionStorage.SetItemAsStringAsync("token", $"Bearer {a_token}");
}
}
public async Task<string> GetToken()
{
string token = await m_localStorage.GetItemAsStringAsync("token");
if (String.IsNullOrEmpty(token))
{
token = await m_sessionStorage.GetItemAsStringAsync("token");
}
return token;
}
public async Task ClearToken()
{
await m_localStorage.ClearAsync();
await m_sessionStorage.ClearAsync();
}
public async Task<bool> IsTokenSet()
{
return await m_localStorage.ContainKeyAsync("token") || await m_sessionStorage.ContainKeyAsync("token");
}
}
}