From c21f0bac5bc616d7bf4bbb3f277e4e1f01704c39 Mon Sep 17 00:00:00 2001 From: Vincent Cloutier Date: Thu, 30 Mar 2023 20:47:53 -0400 Subject: [PATCH] auth changes --- .../Tools/TwitterAuthenticationInitializer.cs | 77 +++++++------------ .../TimelineTests.cs | 6 +- .../BirdsiteLive.Twitter.Tests/TweetTests.cs | 1 + 3 files changed, 29 insertions(+), 55 deletions(-) diff --git a/src/BirdsiteLive.Twitter/Tools/TwitterAuthenticationInitializer.cs b/src/BirdsiteLive.Twitter/Tools/TwitterAuthenticationInitializer.cs index 7ffbb42..ffc87f6 100644 --- a/src/BirdsiteLive.Twitter/Tools/TwitterAuthenticationInitializer.cs +++ b/src/BirdsiteLive.Twitter/Tools/TwitterAuthenticationInitializer.cs @@ -27,7 +27,7 @@ namespace BirdsiteLive.Twitter.Tools private static bool _initialized; private readonly IHttpClientFactory _httpClientFactory; private List _twitterClients = new List(); - private List _tokens = new List(); + private List<(String, String)> _tokens = new List<(string,string)>(); static Random rnd = new Random(); private RateLimiter _rateLimiter; static SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1, 1); @@ -57,7 +57,7 @@ namespace BirdsiteLive.Twitter.Tools } #endregion - private async Task GenerateBearerToken() + private async Task GenerateBearerToken() { var httpClient = _httpClientFactory.CreateClient(); using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.twitter.com/oauth2/token?grant_type=client_credentials")) @@ -65,7 +65,7 @@ namespace BirdsiteLive.Twitter.Tools int r = rnd.Next(_apiKeys.Length); var (login, password) = _apiKeys[r]; var authValue = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{login}:{password}"))); - request.Headers.TryAddWithoutValidation("Basic", $"Bearer " + authValue); + request.Headers.Authorization = authValue; var httpResponse = await httpClient.SendAsync(request); @@ -73,6 +73,7 @@ namespace BirdsiteLive.Twitter.Tools httpResponse.EnsureSuccessStatusCode(); var doc = JsonDocument.Parse(c); var token = doc.RootElement.GetProperty("access_token").GetString(); + return token; } } @@ -81,8 +82,9 @@ namespace BirdsiteLive.Twitter.Tools public async Task RefreshClient(HttpRequestMessage req) { string token = req.Headers.GetValues("x-guest-token").First(); + string bearer = req.Headers.GetValues("Authorization").First().Replace("Bearer ", ""); - var i = _tokens.IndexOf(token); + var i = _tokens.IndexOf((bearer, token)); // this is prabably not thread safe but yolo try @@ -96,46 +98,37 @@ namespace BirdsiteLive.Twitter.Tools } await RefreshCred(); + await Task.Delay(1000); + await RefreshCred(); } private async Task RefreshCred() { - await semaphoreSlim.WaitAsync(); - try + (string bearer, string guest) = await GetCred(); + + HttpClient client = _httpClientFactory.CreateClient(); + //HttpClient client = new HttpClient(); + + _twitterClients.Add(client); + _tokens.Add((bearer,guest)); + + if (_twitterClients.Count > _targetClients) { - (string bearer, string guest) = await GetCred(); - - HttpClient client = _httpClientFactory.CreateClient(); - //HttpClient client = new HttpClient(); - client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", $"Bearer " + bearer); - client.DefaultRequestHeaders.TryAddWithoutValidation("x-guest-token", guest); - client.DefaultRequestHeaders.TryAddWithoutValidation("Referer", "https://twitter.com/"); - client.DefaultRequestHeaders.TryAddWithoutValidation("x-twitter-active-user", "yes"); - - _twitterClients.Add(client); - _tokens.Add(guest); - - if (_twitterClients.Count > _targetClients) - { - _twitterClients.RemoveAt(0); - _tokens.RemoveAt(0); - } - - } - finally - { - semaphoreSlim.Release(); + _twitterClients.RemoveAt(0); + _tokens.RemoveAt(0); } + } private async Task<(string, string)> GetCred() { string token; var httpClient = _httpClientFactory.CreateClient(); + string bearer = await GenerateBearerToken(); using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.twitter.com/1.1/guest/activate.json")) { - request.Headers.TryAddWithoutValidation("Authorization", $"Bearer " + BearerToken); + request.Headers.TryAddWithoutValidation("Authorization", $"Bearer " + bearer); var httpResponse = await httpClient.SendAsync(request); @@ -145,30 +138,13 @@ namespace BirdsiteLive.Twitter.Tools token = doc.RootElement.GetProperty("guest_token").GetString(); } - return (BearerToken, token); + return (bearer, token); } - private async Task InitTwitterCredentials() - { - for (;;) - { - try - { - await RefreshCred(); - _initialized = true; - return; - } - catch (Exception e) - { - _logger.LogError(e, "Twitter Authentication Failed"); - await Task.Delay(3600*1000); - } - } - } public async Task MakeHttpClient() { - if (_twitterClients.Count < _targetClients) + if (_twitterClients.Count < 2) await RefreshCred(); int r = rnd.Next(_twitterClients.Count); return _twitterClients[r]; @@ -177,11 +153,12 @@ namespace BirdsiteLive.Twitter.Tools { var request = new HttpRequestMessage(m, endpoint); int r = rnd.Next(_twitterClients.Count); - request.Headers.TryAddWithoutValidation("Authorization", $"Bearer " + BearerToken); + (string bearer, string token) = _tokens[r]; + request.Headers.TryAddWithoutValidation("Authorization", $"Bearer " + bearer); request.Headers.TryAddWithoutValidation("Referer", "https://twitter.com/"); request.Headers.TryAddWithoutValidation("x-twitter-active-user", "yes"); if (addToken) - request.Headers.TryAddWithoutValidation("x-guest-token", _tokens[r]); + request.Headers.TryAddWithoutValidation("x-guest-token", token); //request.Headers.TryAddWithoutValidation("Referer", "https://twitter.com/"); //request.Headers.TryAddWithoutValidation("x-twitter-active-user", "yes"); return request; diff --git a/src/Tests/BirdsiteLive.Twitter.Tests/TimelineTests.cs b/src/Tests/BirdsiteLive.Twitter.Tests/TimelineTests.cs index f09f28f..80b69b1 100644 --- a/src/Tests/BirdsiteLive.Twitter.Tests/TimelineTests.cs +++ b/src/Tests/BirdsiteLive.Twitter.Tests/TimelineTests.cs @@ -41,11 +41,7 @@ namespace BirdsiteLive.ActivityPub.Tests ITwitterUserService user = new TwitterUserService(auth, stats.Object, logger2.Object); ICachedTwitterUserService user2 = new CachedTwitterUserService(user, settings); _tweetService = new TwitterTweetsService(auth, stats.Object, user2, twitterDal.Object, settings, logger3.Object); - - await Task.Delay(1000); - await auth.MakeHttpClient(); - await Task.Delay(1000); - await auth.MakeHttpClient(); + } [TestMethod] diff --git a/src/Tests/BirdsiteLive.Twitter.Tests/TweetTests.cs b/src/Tests/BirdsiteLive.Twitter.Tests/TweetTests.cs index e25ab59..b40674b 100644 --- a/src/Tests/BirdsiteLive.Twitter.Tests/TweetTests.cs +++ b/src/Tests/BirdsiteLive.Twitter.Tests/TweetTests.cs @@ -78,6 +78,7 @@ namespace BirdsiteLive.ActivityPub.Tests Assert.IsTrue(tweet.Media[0].Url.StartsWith("https://video.twimg.com/")); } + [Ignore] [TestMethod] public async Task GifAndQT() {