using Biskilog_Accounting.Shared.ClientContractModels; using Biskilog_Accounting.Shared.Enums; using Biskilog_Accounting.Shared.Interfaces; 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; } public TokenService(IConfiguration a_configuration) { m_configuration = a_configuration; } /// /// Validates a user access token /// /// AuthEnums.Valid if token is a valid and unexpired token 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) { Console.WriteLine(ex.Message); return AuthEnums.Invalid; } } /// /// Generates an access token based on the user /// /// A tokenized string public string GenerateToken(Userauth a_user, Contract a_clientContract, Databasemap a_database, List 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(); } } /// ///Deserializes the token string if valid to return the specified user role id in the token string /// /// /// RoleId 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; } /// ///Deserializes the token string if valid to return the specified user id in the token string /// /// /// UserId 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; } /// ///Deserializes the token string if valid to return the specified username in the token string /// /// /// Username 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; } /// ///Deserializes the token string if valid to return the specified branchId in the token string /// /// /// Username 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; } /// ///Deserializes the token string if valid to return the specified list of branches a user has access to in the token string /// /// /// Username 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; } /// /// Return a specified list of branches a user has access if comparison mode is set otherwise returns only the /// active branch on the list /// /// /// public IEnumerable BranchIds(string a_token) { List branchIds = new List(); 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(); } } }