Files
Swarm/DysonNetwork.Pass/Features/Auth/Models/AuthChallenge.cs

123 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json;
using System.Text.Json.Serialization;
using DysonNetwork.Common.Models.Auth;
using DysonNetwork.Pass.Models;
using NetTopologySuite.Geometries;
using NodaTime;
namespace DysonNetwork.Pass.Features.Auth.Models;
public class AuthChallenge : ModelBase
{
[Required]
public Guid AccountId { get; set; }
[ForeignKey(nameof(AccountId))]
[JsonIgnore]
public virtual Account Account { get; set; } = null!;
[Required]
[Column(TypeName = "varchar(50)")]
public AuthChallengeType Type { get; set; }
[Required]
[Column(TypeName = "varchar(50)")]
public AuthChallengePlatform Platform { get; set; }
public Instant? ExpiredAt { get; set; }
[Required]
public int StepRemain { get; set; } = 1;
[Required]
public int StepTotal { get; set; } = 1;
[Required]
public int FailedAttempts { get; set; } = 0;
[MaxLength(128)]
public string? IpAddress { get; set; }
[MaxLength(512)]
public string? UserAgent { get; set; }
[MaxLength(256)]
public string? DeviceId { get; set; }
[MaxLength(1024)]
public string? Nonce { get; set; }
[Column(TypeName = "jsonb")]
public JsonDocument? BlacklistFactors { get; set; }
[Column(TypeName = "jsonb")]
public JsonDocument? Audiences { get; set; }
[Column(TypeName = "jsonb")]
public JsonDocument? Scopes { get; set; }
[NotMapped]
public Point? Location { get; set; }
// Navigation property for AuthSession
[JsonIgnore]
public virtual ICollection<AuthSession> Sessions { get; set; } = new List<AuthSession>();
public bool IsExpired() => ExpiredAt != null && SystemClock.Instance.GetCurrentInstant() >= ExpiredAt.Value;
public bool CanAttempt(int maxAttempts = 5) => !IsExpired() && FailedAttempts < maxAttempts;
public void RecordAttempt()
{
if (IsExpired())
return;
FailedAttempts++;
}
public void UpdateStep(int step, int totalSteps)
{
StepRemain = step;
StepTotal = totalSteps;
}
public void UpdateExpiration(Instant? expiresAt)
{
ExpiredAt = expiresAt;
}
public void UpdateBlacklistFactors(IEnumerable<string> factors)
{
BlacklistFactors = JsonSerializer.SerializeToDocument(factors);
}
public void UpdateAudiences(IEnumerable<string> audiences)
{
Audiences = JsonSerializer.SerializeToDocument(audiences);
}
public void UpdateScopes(IEnumerable<string> scopes)
{
Scopes = JsonSerializer.SerializeToDocument(scopes);
}
public void UpdateLocation(double? latitude, double? longitude)
{
if (latitude.HasValue && longitude.HasValue)
{
Location = new Point(longitude.Value, latitude.Value) { SRID = 4326 };
}
}
public void UpdateDeviceInfo(string? ipAddress, string? userAgent, string? deviceId = null)
{
IpAddress = ipAddress;
UserAgent = userAgent;
DeviceId = deviceId;
}
}