using JetBrains.Annotations; using Microsoft.Extensions.Options; using SteamLib.Account; using SteamLib.Core.Enums; using SteamLib.Core.Interfaces; using SteamLib.Exceptions; namespace SteamLib.Authentication; public static class SessionDataValidator { [PublicAPI] public static Dictionary> Validators { get; } = new(); public static ValidateOptionsResult Validate(string? name, ISessionData data) { if(Validators.TryGetValue(data.GetType(), out var validator)) return validator.Validate(name, data); return Validate(data); } public static ValidateOptionsResult Validate(string? name, T data) where T : ISessionData { if (Validators.TryGetValue(typeof(T), out var validator)) return validator.Validate(name, data); return Validate(data); } private static ValidateOptionsResult Validate(ISessionData data) { if (data == null!) { return ValidateOptionsResult.Fail("SessionData cannot be null"); } if (string.IsNullOrWhiteSpace(data.SessionId)) { return ValidateOptionsResult.Fail("SessionId cannot be null or empty"); } if (data.SteamId.Steam64.Id < SteamId64.SEED) { return ValidateOptionsResult.Fail($"SteamId '{data.SteamId.Steam64}' is invalid."); } if (string.IsNullOrWhiteSpace(data.RefreshToken.Token)) { return ValidateOptionsResult.Fail("RefreshToken cannot be null or empty"); } if (data.RefreshToken.SteamId.Steam64.Id < SteamId64.SEED) { return ValidateOptionsResult.Fail($"SteamId in RefreshToken '{data.SteamId.Steam64}' is invalid."); } if (data is IMobileSessionData && data.RefreshToken.Type != SteamAccessTokenType.MobileRefresh) { return ValidateOptionsResult.Fail($"RefreshToken '{data.RefreshToken.Token}' is not of type MobileRefresh"); } else if (data.RefreshToken.Type is not (SteamAccessTokenType.Refresh or SteamAccessTokenType.MobileRefresh)) { return ValidateOptionsResult.Fail($"RefreshToken '{data.RefreshToken.Token}' is not of type Refresh or MobileRefresh"); } if (data.RefreshToken.Expires.ToLong() == 0L) { return ValidateOptionsResult.Fail($"RefreshToken '{data.RefreshToken.Token}' has invalid expiration date"); } return ValidateOptionsResult.Success; } public static bool IsValid(this ISessionData data) { return Validate(null, data).Succeeded; } public static void EnsureValidated(this ISessionData data) { if(data.IsValid == true) return; if (data.IsValid == false) throw new SessionInvalidException( "SessionData was validated before and validation was not passed. Session is invalid"); var validation = Validate(null, data); data.IsValid = validation.Succeeded; if (validation.Failed) { throw new SessionInvalidException("SessionData is invalid. " + validation.FailureMessage); } } }