using ScoreTracker.Configuration; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ScoreTracker.API { internal class SigninResponse { public bool Success { get; set; } public string Response { get; set; } } internal class Authentication { private static bool _signedIn = false; private static string _authToken; /// /// Validate the auth token and sign in if necessary /// public static async Task ValidateAndSignIn() { if (_signedIn && await ValidateAuthToken()) { return new SigninResponse { Success = true, Response = null }; // Already signed in } bool success = false; string response = null; await LoginUser( token => { success = true; Request.PersistHeaders(new Dictionary { { "Authorization", $"Bearer {token}" } }); }, reason => { response = reason; Request.HttpClient.DefaultRequestHeaders.Clear(); // Clear headers } ); return new SigninResponse { Success = success, Response = response }; } /// /// 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; } } } }