From f8dac2c9d071c45985f4343b658b3eaa7a04fcff Mon Sep 17 00:00:00 2001 From: Tyrrrz <1935960+Tyrrrz@users.noreply.github.com> Date: Fri, 16 Sep 2022 22:46:55 +0300 Subject: [PATCH] Simplify token kind resolution Extra request which makes it less efficient, but much simpler code --- .../Discord/DiscordClient.cs | 84 ++++++++++--------- DiscordChatExporter.Core/Discord/TokenKind.cs | 1 - 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/DiscordChatExporter.Core/Discord/DiscordClient.cs b/DiscordChatExporter.Core/Discord/DiscordClient.cs index 51b194c..9ec5b11 100644 --- a/DiscordChatExporter.Core/Discord/DiscordClient.cs +++ b/DiscordChatExporter.Core/Discord/DiscordClient.cs @@ -22,65 +22,67 @@ public class DiscordClient private readonly string _token; private readonly Uri _baseUri = new("https://discord.com/api/v9/", UriKind.Absolute); - private TokenKind _tokenKind = TokenKind.Unknown; + private TokenKind? _resolvedTokenKind; public DiscordClient(string token) => _token = token; private async ValueTask GetResponseAsync( string url, - bool isBot, + TokenKind tokenKind, CancellationToken cancellationToken = default) { - using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url)); + return await Http.ResponseResiliencePolicy.ExecuteAsync(async innerCancellationToken => + { + using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url)); + + // Don't validate because token can have invalid characters + // https://github.com/Tyrrrz/DiscordChatExporter/issues/828 + request.Headers.TryAddWithoutValidation( + "Authorization", + tokenKind == TokenKind.Bot + ? $"Bot {_token}" + : _token + ); + + return await Http.Client.SendAsync( + request, + HttpCompletionOption.ResponseHeadersRead, + innerCancellationToken + ); + }, cancellationToken); + } - // Don't validate because token can have invalid characters - // https://github.com/Tyrrrz/DiscordChatExporter/issues/828 - request.Headers.TryAddWithoutValidation( - "Authorization", - isBot ? $"Bot {_token}" : _token + private async ValueTask GetTokenKindAsync(CancellationToken cancellationToken = default) + { + // Try authenticating as a user + using var userResponse = await GetResponseAsync( + "users/@me", + TokenKind.User, + cancellationToken ); - return await Http.Client.SendAsync( - request, - HttpCompletionOption.ResponseHeadersRead, + if (userResponse.StatusCode != HttpStatusCode.Unauthorized) + return TokenKind.User; + + // Try authenticating as a bot + using var botResponse = await GetResponseAsync( + "users/@me", + TokenKind.Bot, cancellationToken ); + + if (botResponse.StatusCode != HttpStatusCode.Unauthorized) + return TokenKind.Bot; + + throw DiscordChatExporterException.Unauthorized(); } private async ValueTask GetResponseAsync( string url, CancellationToken cancellationToken = default) { - return await Http.ResponseResiliencePolicy.ExecuteAsync(async innerCancellationToken => - { - if (_tokenKind == TokenKind.User) - return await GetResponseAsync(url, false, innerCancellationToken); - - if (_tokenKind == TokenKind.Bot) - return await GetResponseAsync(url, true, innerCancellationToken); - - // Try to authenticate as user - var userResponse = await GetResponseAsync(url, false, innerCancellationToken); - if (userResponse.StatusCode != HttpStatusCode.Unauthorized) - { - _tokenKind = TokenKind.User; - return userResponse; - } - - userResponse.Dispose(); - - // Otherwise, try to authenticate as bot - var botResponse = await GetResponseAsync(url, true, innerCancellationToken); - if (botResponse.StatusCode != HttpStatusCode.Unauthorized) - { - _tokenKind = TokenKind.Bot; - return botResponse; - } - - // The token is probably invalid altogether. - // Return the last response anyway, upstream should handle the error. - return botResponse; - }, cancellationToken); + var tokenKind = _resolvedTokenKind ??= await GetTokenKindAsync(cancellationToken); + return await GetResponseAsync(url, tokenKind, cancellationToken); } private async ValueTask GetJsonResponseAsync( diff --git a/DiscordChatExporter.Core/Discord/TokenKind.cs b/DiscordChatExporter.Core/Discord/TokenKind.cs index f22afcc..fd2dbcd 100644 --- a/DiscordChatExporter.Core/Discord/TokenKind.cs +++ b/DiscordChatExporter.Core/Discord/TokenKind.cs @@ -2,7 +2,6 @@ public enum TokenKind { - Unknown, User, Bot } \ No newline at end of file