diff --git a/WotBlitzStatisticsPro.Common/Model/WargamingProlongInfo.cs b/WotBlitzStatisticsPro.Common/Model/WargamingProlongInfo.cs new file mode 100644 index 0000000..5c9c5ad --- /dev/null +++ b/WotBlitzStatisticsPro.Common/Model/WargamingProlongInfo.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WotBlitzStatisticsPro.Common.Model +{ + /// + /// Prolong Wargaming Auth token response + /// + public class WargamingProlongInfo + { + /// + /// Player Account Id + /// + public long AccountId { get; set; } + + /// + /// New access token + /// + public string AccessToken { get; set; } = string.Empty; + + /// + /// New expiration unix timestamp + /// + public int ExpirationTimeStamp { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.GraphQl/Mutation/WargamingAuthMutation.cs b/WotBlitzStatisticsPro.GraphQl/Mutation/WargamingAuthMutation.cs new file mode 100644 index 0000000..08ed2ed --- /dev/null +++ b/WotBlitzStatisticsPro.GraphQl/Mutation/WargamingAuthMutation.cs @@ -0,0 +1,29 @@ +using HotChocolate.Types; +using System.Threading.Tasks; +using WotBlitzStatisticsPro.Common.Model; +using WotBlitzStatisticsPro.WgApiClient; + +namespace WotBlitzStatisticsPro.GraphQl.Mutation +{ + [ExtendObjectType(Name = "Mutation")] + public class WargamingAuthMutation + { + private readonly IWargamingAuthenticationClient _wargamingAuthenticationClient; + + public WargamingAuthMutation(IWargamingAuthenticationClient wargamingAuthenticationClient) + { + _wargamingAuthenticationClient = wargamingAuthenticationClient; + } + + /// + /// Prolongates Wargaming authentication token + /// + /// Wargaming realm + /// Old token to prolongate + /// + public Task ProlongAuthToken(RealmType realm, string oldToken) + { + return _wargamingAuthenticationClient.ProlongAuthToken(realm, oldToken); + } + } +} diff --git a/WotBlitzStatisticsPro.GraphQl/Startup.cs b/WotBlitzStatisticsPro.GraphQl/Startup.cs index 17a7541..5f207d2 100644 --- a/WotBlitzStatisticsPro.GraphQl/Startup.cs +++ b/WotBlitzStatisticsPro.GraphQl/Startup.cs @@ -94,6 +94,7 @@ namespace WotBlitzStatisticsPro.GraphQl .AddMutationType(d => d.Name("Mutation")) .AddType() .AddType() + .AddType() .AddType() .AddEnumType() .AddEnumType() diff --git a/WotBlitzStatisticsPro.WgApiClient/IWargamingAuthenticationClient.cs b/WotBlitzStatisticsPro.WgApiClient/IWargamingAuthenticationClient.cs index 5f1c51a..746e28c 100644 --- a/WotBlitzStatisticsPro.WgApiClient/IWargamingAuthenticationClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/IWargamingAuthenticationClient.cs @@ -6,5 +6,7 @@ namespace WotBlitzStatisticsPro.WgApiClient public interface IWargamingAuthenticationClient { string LoginUrl(RealmType realm); + + Task ProlongAuthToken(RealmType realm, string oldToken); } } diff --git a/WotBlitzStatisticsPro.WgApiClient/Model/WotAuthProlongateResponse.cs b/WotBlitzStatisticsPro.WgApiClient/Model/WotAuthProlongateResponse.cs new file mode 100644 index 0000000..593e718 --- /dev/null +++ b/WotBlitzStatisticsPro.WgApiClient/Model/WotAuthProlongateResponse.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; + +namespace WotBlitzStatisticsPro.WgApiClient.Model +{ + public class WotAuthProlongateResponse + { + [JsonProperty("access_token")] + public string AccessToken { get; set; } = string.Empty; + + [JsonProperty("account_id")] + public long AccountId { get; set; } + + [JsonProperty("expires_at")] + public int ExpirationTimeStamp { get; set; } + } +} diff --git a/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs index 25c52d6..34a8efb 100644 --- a/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs +++ b/WotBlitzStatisticsPro.WgApiClient/WagramingApiClientBase.cs @@ -41,7 +41,7 @@ namespace WotBlitzStatisticsPro.WgApiClient _wotApiUrls[RealmType.Asia] = "https://api.worldoftanks.asia/wot/"; } - protected async Task GetFromBlitzApi( + protected Task GetFromBlitzApi( RealmType realmType, RequestLanguage language, string method, @@ -49,10 +49,27 @@ namespace WotBlitzStatisticsPro.WgApiClient { string uri = GetBlitzUri(realmType, language, method, queryParameters); + return CallWgApi(uri); + } + + protected async Task CallWgApi(string uri, bool postMethod = false) where T : class + { _httpClient.DefaultRequestHeaders.Accept.Clear(); _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - var response = await _httpClient.GetAsync(uri); + HttpResponseMessage? response; + if(postMethod) + { + // Create httpContent + var requestBody = TransformUriToRequestBody(uri); + var httpContent = new StringContent(requestBody, Encoding.UTF8, "application/x-www-form-urlencoded"); + + response = await _httpClient.PostAsync(uri, httpContent); + } + else + { + response = await _httpClient.GetAsync(uri); + } response.EnsureSuccessStatusCode(); var responseString = await response.Content.ReadAsStringAsync(); @@ -61,19 +78,20 @@ namespace WotBlitzStatisticsPro.WgApiClient _logger.LogInformation($"HTTP GET {uri} - {responseBody.Status}"); switch (responseBody.Status) - { - case "ok": - return responseBody.Data; - case "error": - { - var error = responseBody.Error; - var message = $"Field:{(error?.Field ?? "undefined")} Message:{(error?.Message ?? "undefined")} Value:{(error?.Value ?? "undefined")} Code:{(error?.Code ?? "undefined")}"; - throw new ArgumentException(message); - } - default: - throw new ArgumentException($"Unexpected response body status '{responseBody.Status}'"); - } - } + { + case "ok": + return responseBody.Data; + case "error": + { + var error = responseBody.Error; + var message = $"Field:{(error?.Field ?? "undefined")} Message:{(error?.Message ?? "undefined")} Value:{(error?.Value ?? "undefined")} Code:{(error?.Code ?? "undefined")}"; + throw new ArgumentException(message); + } + default: + throw new ArgumentException($"Unexpected response body status '{responseBody.Status}'"); + } + } + protected string GetWotUri(RealmType realmType, string method, string[]? queryParameters) { @@ -108,5 +126,10 @@ namespace WotBlitzStatisticsPro.WgApiClient } return uri.ToString(); } + + private string TransformUriToRequestBody(string request) + { + return request.Substring(request.IndexOf('?') + 1); + } } } diff --git a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs index 02bd27d..46672ae 100644 --- a/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs +++ b/WotBlitzStatisticsPro.WgApiClient/WargamingApiClient.cs @@ -215,6 +215,23 @@ namespace WotBlitzStatisticsPro.WgApiClient return GetWotUri(realm, "auth/login/", null); } + public async Task ProlongAuthToken(RealmType realm, string oldToken) + { + // https://api.worldoftanks.ru/wot/auth/prolongate/?application_id=98805e6ac535e88491ae64d37b764370&access_token=1234566 + string prolongUri = GetWotUri( + realm, + "auth/prolongate/", + new string[] { $"access_token={oldToken}" }); + var prolongResult = await CallWgApi(prolongUri, true); + + return new WargamingProlongInfo + { + AccessToken = prolongResult!.AccessToken, + AccountId = prolongResult.AccountId, + ExpirationTimeStamp = prolongResult.ExpirationTimeStamp + }; + } + #endregion } }