Add remaining project files
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
using DeluxeBackend.Models;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Numerics;
|
||||
using System.Security.Claims;
|
||||
using static DeluxeBackend.Enums;
|
||||
|
||||
namespace DeluxeBackend.Services
|
||||
{
|
||||
|
||||
public class LoginWithInfoResult
|
||||
{
|
||||
public required Account Account { get; set; }
|
||||
public PlatformType Platform { get; set; }
|
||||
public required string PlatformId { get; set; }
|
||||
public DeviceClassType DeviceClass { get; set; }
|
||||
public required string Locale { get; set; }
|
||||
public required string AppVersion { get; set; }
|
||||
}
|
||||
|
||||
public interface IJwtService
|
||||
{
|
||||
Task<string> GenAccessToken(Account account, List<string> roles, Dictionary<string, object>? customeClaims = null);
|
||||
Task<string> GenRefreshToken(Account acc);
|
||||
Task<Account?> GetLogin(ClaimsPrincipal? User);
|
||||
Task<LoginWithInfoResult?> GetLoginWithInfo(ClaimsPrincipal? User);
|
||||
}
|
||||
|
||||
public class JwtService : IJwtService
|
||||
{
|
||||
private readonly ILiteDbService db;
|
||||
private readonly IConfiguration configuration;
|
||||
private readonly DiscordBotService discord;
|
||||
|
||||
public JwtService(ILiteDbService _db, IConfiguration _configuration, DiscordBotService _discord)
|
||||
{
|
||||
db = _db;
|
||||
configuration = _configuration;
|
||||
discord = _discord;
|
||||
}
|
||||
|
||||
public async Task<string> GenAccessToken(Account account, List<string> roles, Dictionary<string, object>? customeClaims = null)
|
||||
{
|
||||
var issuer = configuration["JwtConfig:Issuer"];
|
||||
var key = new SymmetricSecurityKey(Convert.FromBase64String(configuration["JwtConfig:Key"]));
|
||||
var exp = DateTime.UtcNow.AddHours(1).AddMinutes(10);
|
||||
|
||||
roles.AddRange(account.Roles);
|
||||
if (account.DiscordId.HasValue)
|
||||
{
|
||||
roles.AddRange(await discord.UserRoles(account.DiscordId.Value));
|
||||
}
|
||||
if (account.IsJunior == null || account.IsJunior == true)
|
||||
{
|
||||
roles.Add("junior");
|
||||
}
|
||||
roles = roles.Distinct().ToList();
|
||||
|
||||
var claimsDictionary = new Dictionary<string, object>
|
||||
{
|
||||
["role"] = roles
|
||||
};
|
||||
|
||||
if (customeClaims != null)
|
||||
{
|
||||
foreach (var claim in customeClaims)
|
||||
{
|
||||
claimsDictionary[claim.Key] = claim.Value;
|
||||
}
|
||||
}
|
||||
|
||||
var tokenDect = new SecurityTokenDescriptor
|
||||
{
|
||||
Subject = new ClaimsIdentity(
|
||||
[
|
||||
new Claim("sub", account.Id.ToString())
|
||||
]),
|
||||
IssuedAt = DateTime.UtcNow,
|
||||
Claims = claimsDictionary,
|
||||
Expires = exp,
|
||||
Issuer = issuer,
|
||||
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature),
|
||||
};
|
||||
|
||||
var tokenHandler = new JwtSecurityTokenHandler();
|
||||
var token = tokenHandler.WriteToken(tokenHandler.CreateToken(tokenDect));
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
public Task<string> GenRefreshToken(Account acc)
|
||||
{
|
||||
RefreshToken refreshToken = new()
|
||||
{
|
||||
Token = Convert.ToBase64String(Guid.NewGuid().ToByteArray()),
|
||||
Expires = DateTime.UtcNow.AddDays(2),
|
||||
Account = acc
|
||||
};
|
||||
db.RefreshTokens.Insert(refreshToken);
|
||||
return Task.FromResult(refreshToken.Token);
|
||||
}
|
||||
|
||||
public Task<Account?> GetLogin(ClaimsPrincipal? User = null)
|
||||
{
|
||||
Console.WriteLine(User);
|
||||
if (User == null)
|
||||
return Task.FromResult<Account?>(null);
|
||||
|
||||
string? rawPlayerId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
||||
?? User.FindFirst("sub")?.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(rawPlayerId))
|
||||
return Task.FromResult<Account?>(null);
|
||||
|
||||
if (!long.TryParse(rawPlayerId, out long playerId))
|
||||
return Task.FromResult<Account?>(null);
|
||||
|
||||
Account? player = db.Accounts.FindById(playerId);
|
||||
|
||||
return Task.FromResult<Account?>(player);
|
||||
}
|
||||
public Task<LoginWithInfoResult?> GetLoginWithInfo(ClaimsPrincipal? User = null)
|
||||
{
|
||||
if (User == null)
|
||||
return Task.FromResult<LoginWithInfoResult?>(null);
|
||||
|
||||
string? rawPlayerId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value
|
||||
?? User.FindFirst("sub")?.Value;
|
||||
|
||||
if (string.IsNullOrEmpty(rawPlayerId) || !long.TryParse(rawPlayerId, out long playerId))
|
||||
return Task.FromResult<LoginWithInfoResult?>(null);
|
||||
|
||||
Account? player = db.Accounts.FindById(playerId);
|
||||
if (player == null)
|
||||
return Task.FromResult<LoginWithInfoResult?>(null);
|
||||
|
||||
var result = new LoginWithInfoResult
|
||||
{
|
||||
Account = player,
|
||||
PlatformId = User.FindFirst("db.platform.id")?.Value,
|
||||
Locale = User.FindFirst("db.locale")?.Value,
|
||||
AppVersion= User.FindFirst("db.appver")?.Value,
|
||||
};
|
||||
|
||||
string? rawPlatform = User.FindFirst("db.platform")?.Value;
|
||||
if (Enum.TryParse<PlatformType>(rawPlatform, out var platform))
|
||||
{
|
||||
result.Platform = platform;
|
||||
}
|
||||
|
||||
string? rawDeviceClass = User.FindFirst("db.deviceclass")?.Value;
|
||||
if (Enum.TryParse<DeviceClassType>(rawDeviceClass, out var deviceClass))
|
||||
{
|
||||
result.DeviceClass = deviceClass;
|
||||
}
|
||||
|
||||
return Task.FromResult<LoginWithInfoResult?>(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user