using ScoreTracker.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading.Tasks; namespace ScoreTracker.API { internal class AuthHelper { public bool IsLoggedIn; public string FailReason = ""; /// /// Ensure the user is logged in /// /// the task public async Task EnsureLoggedIn() { if (Authentication.IsSignedIn() && await Authentication.ValidateAuthToken()) { return; // Already logged in with a valid token } await Authentication.LoginUser( token => { IsLoggedIn = true; Request.PersistHeaders(new Dictionary { { "Authorization", $"Bearer {token}" } }); }, reason => { FailReason = reason; // Store the reason for failure Request.HttpClient.DefaultRequestHeaders.Clear(); // Clear headers } ); } } internal class Authentication { private static bool _signedIn = false; private static string _authToken; /// /// Are we signed in? /// public static bool IsSignedIn() { return _signedIn; } /// /// Get the steam ticket and user info /// /// the steam ticket private static async Task GetSteamTicket() { Plugin.Log.Info("Getting steam ticket..."); return (await new SteamPlatformUserModel().GetUserAuthToken()).token; } /// /// Login the user /// /// callback for successful login, returns the token /// callback for failed login /// an IEnumerator public static async Task LoginUser(Action onSuccess, Action onFail) { if (_signedIn && !string.IsNullOrEmpty(_authToken)) { onSuccess(_authToken); return; } var ticketTask = GetSteamTicket(); await Task.Run(() => ticketTask.Wait()); var ticket = ticketTask.Result; if (string.IsNullOrEmpty(ticket)) { Plugin.Log.Error("Login failed :( no steam auth token"); onFail("No Steam Auth Token"); return; } Plugin.Log.Info("Logging in..."); var request = await Request.PostJsonAsync($"{PluginConfig.Instance.ApiUrl}/auth/login", new Dictionary { { "ticket", ticket } }, false); if (request.IsSuccessStatusCode) { var authToken = request.Headers.GetValues("Authorization").First(); Plugin.Log.Info($"Login successful! auth token: {authToken}"); onSuccess(authToken); _signedIn = true; _authToken = authToken; } else { Plugin.Log.Error($"Login failed! body: {request.StatusCode}"); onFail($"Login failed: {request.StatusCode}"); _signedIn = false; _authToken = null; } } /// /// Validates the auth token and logs out if it's invalid /// /// whether the token is valid public static async Task ValidateAuthToken() { if (!_signedIn || string.IsNullOrEmpty(_authToken)) // If we're not signed in, return false { return false; } var request = await Request.PostJsonAsync($"{PluginConfig.Instance.ApiUrl}/auth/validate", new Dictionary { { "token", _authToken } }, false); if (request.IsSuccessStatusCode) { return true; } else { _signedIn = false; _authToken = null; return false; } } } }