♻️ Basically completed the separate of account service
This commit is contained in:
@@ -65,7 +65,7 @@ public class DysonTokenAuthHandler(
|
||||
return AuthenticateResult.Fail("Invalid token.");
|
||||
|
||||
// Try to get session from cache first
|
||||
var session = await cache.GetAsync<Session>($"{AuthCachePrefix}{sessionId}");
|
||||
var session = await cache.GetAsync<AuthSession>($"{AuthCachePrefix}{sessionId}");
|
||||
|
||||
// If not in cache, load from database
|
||||
if (session is null)
|
||||
|
@@ -27,7 +27,7 @@ public class AuthController(
|
||||
}
|
||||
|
||||
[HttpPost("challenge")]
|
||||
public async Task<ActionResult<Challenge>> StartChallenge([FromBody] ChallengeRequest request)
|
||||
public async Task<ActionResult<AuthChallenge>> StartChallenge([FromBody] ChallengeRequest request)
|
||||
{
|
||||
var account = await accounts.LookupAccount(request.Account);
|
||||
if (account is null) return NotFound("Account was not found.");
|
||||
@@ -47,7 +47,7 @@ public class AuthController(
|
||||
.FirstOrDefaultAsync();
|
||||
if (existingChallenge is not null) return existingChallenge;
|
||||
|
||||
var challenge = new Challenge
|
||||
var challenge = new AuthChallenge
|
||||
{
|
||||
ExpiredAt = Instant.FromDateTimeUtc(DateTime.UtcNow.AddHours(1)),
|
||||
StepTotal = await auth.DetectChallengeRisk(Request, account),
|
||||
@@ -72,7 +72,7 @@ public class AuthController(
|
||||
}
|
||||
|
||||
[HttpGet("challenge/{id:guid}")]
|
||||
public async Task<ActionResult<Challenge>> GetChallenge([FromRoute] Guid id)
|
||||
public async Task<ActionResult<AuthChallenge>> GetChallenge([FromRoute] Guid id)
|
||||
{
|
||||
var challenge = await db.AuthChallenges
|
||||
.Include(e => e.Account)
|
||||
@@ -132,7 +132,7 @@ public class AuthController(
|
||||
}
|
||||
|
||||
[HttpPatch("challenge/{id:guid}")]
|
||||
public async Task<ActionResult<Challenge>> DoChallenge(
|
||||
public async Task<ActionResult<AuthChallenge>> DoChallenge(
|
||||
[FromRoute] Guid id,
|
||||
[FromBody] PerformChallengeRequest request
|
||||
)
|
||||
@@ -236,7 +236,7 @@ public class AuthController(
|
||||
if (session is not null)
|
||||
return BadRequest("Session already exists for this challenge.");
|
||||
|
||||
session = new Session
|
||||
session = new AuthSession
|
||||
{
|
||||
LastGrantedAt = Instant.FromDateTimeUtc(DateTime.UtcNow),
|
||||
ExpiredAt = Instant.FromDateTimeUtc(DateTime.UtcNow.AddDays(30)),
|
||||
|
@@ -73,9 +73,9 @@ public class AuthService(
|
||||
return totalRequiredSteps;
|
||||
}
|
||||
|
||||
public async Task<Session> CreateSessionForOidcAsync(Account.Account account, Instant time, Guid? customAppId = null)
|
||||
public async Task<AuthSession> CreateSessionForOidcAsync(Account.Account account, Instant time, Guid? customAppId = null)
|
||||
{
|
||||
var challenge = new Challenge
|
||||
var challenge = new AuthChallenge
|
||||
{
|
||||
AccountId = account.Id,
|
||||
IpAddress = HttpContext.Connection.RemoteIpAddress?.ToString(),
|
||||
@@ -85,7 +85,7 @@ public class AuthService(
|
||||
Type = customAppId is not null ? ChallengeType.OAuth : ChallengeType.Oidc
|
||||
};
|
||||
|
||||
var session = new Session
|
||||
var session = new AuthSession
|
||||
{
|
||||
AccountId = account.Id,
|
||||
CreatedAt = time,
|
||||
@@ -154,7 +154,7 @@ public class AuthService(
|
||||
}
|
||||
}
|
||||
|
||||
public string CreateToken(Session session)
|
||||
public string CreateToken(AuthSession session)
|
||||
{
|
||||
// Load the private key for signing
|
||||
var privateKeyPem = File.ReadAllText(config["AuthToken:PrivateKeyPath"]!);
|
||||
@@ -183,7 +183,7 @@ public class AuthService(
|
||||
return $"{payloadBase64}.{signatureBase64}";
|
||||
}
|
||||
|
||||
public async Task<bool> ValidateSudoMode(Session session, string? pinCode)
|
||||
public async Task<bool> ValidateSudoMode(AuthSession session, string? pinCode)
|
||||
{
|
||||
// Check if the session is already in sudo mode (cached)
|
||||
var sudoModeKey = $"accounts:{session.Id}:sudo";
|
||||
|
@@ -7,7 +7,7 @@ public class CompactTokenService(IConfiguration config)
|
||||
private readonly string _privateKeyPath = config["AuthToken:PrivateKeyPath"]
|
||||
?? throw new InvalidOperationException("AuthToken:PrivateKeyPath configuration is missing");
|
||||
|
||||
public string CreateToken(Session session)
|
||||
public string CreateToken(AuthSession session)
|
||||
{
|
||||
// Load the private key for signing
|
||||
var privateKeyPem = File.ReadAllText(_privateKeyPath);
|
||||
|
@@ -114,7 +114,7 @@ public class OidcProviderController(
|
||||
public async Task<IActionResult> GetUserInfo()
|
||||
{
|
||||
if (HttpContext.Items["CurrentUser"] is not Account.Account currentUser ||
|
||||
HttpContext.Items["CurrentSession"] is not Session currentSession) return Unauthorized();
|
||||
HttpContext.Items["CurrentSession"] is not AuthSession currentSession) return Unauthorized();
|
||||
|
||||
// Get requested scopes from the token
|
||||
var scopes = currentSession.Challenge.Scopes;
|
||||
|
@@ -37,7 +37,7 @@ public class OidcProviderService(
|
||||
.FirstOrDefaultAsync(c => c.Id == appId);
|
||||
}
|
||||
|
||||
public async Task<Session?> FindValidSessionAsync(Guid accountId, Guid clientId)
|
||||
public async Task<AuthSession?> FindValidSessionAsync(Guid accountId, Guid clientId)
|
||||
{
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
|
||||
@@ -76,7 +76,7 @@ public class OidcProviderService(
|
||||
if (client == null)
|
||||
throw new InvalidOperationException("Client not found");
|
||||
|
||||
Session session;
|
||||
AuthSession session;
|
||||
var clock = SystemClock.Instance;
|
||||
var now = clock.GetCurrentInstant();
|
||||
|
||||
@@ -126,7 +126,7 @@ public class OidcProviderService(
|
||||
|
||||
private string GenerateJwtToken(
|
||||
CustomApp client,
|
||||
Session session,
|
||||
AuthSession session,
|
||||
Instant expiresAt,
|
||||
IEnumerable<string>? scopes = null
|
||||
)
|
||||
@@ -199,7 +199,7 @@ public class OidcProviderService(
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Session?> FindSessionByIdAsync(Guid sessionId)
|
||||
public async Task<AuthSession?> FindSessionByIdAsync(Guid sessionId)
|
||||
{
|
||||
return await db.AuthSessions
|
||||
.Include(s => s.Account)
|
||||
@@ -208,7 +208,7 @@ public class OidcProviderService(
|
||||
.FirstOrDefaultAsync(s => s.Id == sessionId);
|
||||
}
|
||||
|
||||
private static string GenerateRefreshToken(Session session)
|
||||
private static string GenerateRefreshToken(AuthSession session)
|
||||
{
|
||||
return Convert.ToBase64String(session.Id.ToByteArray());
|
||||
}
|
||||
@@ -221,7 +221,7 @@ public class OidcProviderService(
|
||||
}
|
||||
|
||||
public async Task<string> GenerateAuthorizationCodeForReuseSessionAsync(
|
||||
Session session,
|
||||
AuthSession session,
|
||||
Guid clientId,
|
||||
string redirectUri,
|
||||
IEnumerable<string> scopes,
|
||||
|
@@ -68,7 +68,7 @@ public class OidcController(
|
||||
/// Handles Apple authentication directly from mobile apps
|
||||
/// </summary>
|
||||
[HttpPost("apple/mobile")]
|
||||
public async Task<ActionResult<Challenge>> AppleMobileLogin(
|
||||
public async Task<ActionResult<AuthChallenge>> AppleMobileLogin(
|
||||
[FromBody] AppleMobileSignInRequest request)
|
||||
{
|
||||
try
|
||||
|
@@ -187,7 +187,7 @@ public abstract class OidcService(
|
||||
/// Creates a challenge and session for an authenticated user
|
||||
/// Also creates or updates the account connection
|
||||
/// </summary>
|
||||
public async Task<Challenge> CreateChallengeForUserAsync(
|
||||
public async Task<AuthChallenge> CreateChallengeForUserAsync(
|
||||
OidcUserInfo userInfo,
|
||||
Account.Account account,
|
||||
HttpContext request,
|
||||
@@ -217,7 +217,7 @@ public abstract class OidcService(
|
||||
|
||||
// Create a challenge that's already completed
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
var challenge = new Challenge
|
||||
var challenge = new AuthChallenge
|
||||
{
|
||||
ExpiredAt = now.Plus(Duration.FromHours(1)),
|
||||
StepTotal = await auth.DetectChallengeRisk(request.Request, account),
|
||||
|
@@ -2,12 +2,13 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Text.Json.Serialization;
|
||||
using DysonNetwork.Pass;
|
||||
using DysonNetwork.Shared.Data;
|
||||
using NodaTime;
|
||||
using Point = NetTopologySuite.Geometries.Point;
|
||||
|
||||
namespace DysonNetwork.Pass.Auth;
|
||||
|
||||
public class Session : ModelBase
|
||||
public class AuthSession : ModelBase
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
[MaxLength(1024)] public string? Label { get; set; }
|
||||
@@ -17,7 +18,7 @@ public class Session : ModelBase
|
||||
public Guid AccountId { get; set; }
|
||||
[JsonIgnore] public Account.Account Account { get; set; } = null!;
|
||||
public Guid ChallengeId { get; set; }
|
||||
public Challenge Challenge { get; set; } = null!;
|
||||
public AuthChallenge Challenge { get; set; } = null!;
|
||||
public Guid? AppId { get; set; }
|
||||
// public CustomApp? App { get; set; }
|
||||
}
|
||||
@@ -40,7 +41,7 @@ public enum ChallengePlatform
|
||||
Linux
|
||||
}
|
||||
|
||||
public class Challenge : ModelBase
|
||||
public class AuthChallenge : ModelBase
|
||||
{
|
||||
public Guid Id { get; set; } = Guid.NewGuid();
|
||||
public Instant? ExpiredAt { get; set; }
|
||||
@@ -61,7 +62,7 @@ public class Challenge : ModelBase
|
||||
public Guid AccountId { get; set; }
|
||||
[JsonIgnore] public Account.Account Account { get; set; } = null!;
|
||||
|
||||
public Challenge Normalize()
|
||||
public AuthChallenge Normalize()
|
||||
{
|
||||
if (StepRemain == 0 && BlacklistFactors.Count == 0) StepRemain = StepTotal;
|
||||
return this;
|
||||
|
Reference in New Issue
Block a user