Browse Source

Refactor token conversion logic into it's own testable method

pull/1206/head
Chris Johnston 6 years ago
parent
commit
35a1fcab55
2 changed files with 54 additions and 24 deletions
  1. +36
    -24
      src/Discord.Net.Core/Utils/TokenUtils.cs
  2. +18
    -0
      test/Discord.Net.Tests/Tests.TokenUtils.cs

+ 36
- 24
src/Discord.Net.Core/Utils/TokenUtils.cs View File

@@ -17,6 +17,40 @@ namespace Discord
/// </remarks>
internal const int MinBotTokenLength = 58;

/// <summary>
/// Decodes a base 64 encoded string into a ulong value.
/// </summary>
/// <param name="encoded"> A base 64 encoded string containing a User Id.</param>
/// <returns> A ulong containing the decoded value of the string, or null if the value was invalid. </returns>
internal static ulong? DecodeBase64UserId(string encoded)
{
if (string.IsNullOrWhiteSpace(encoded))
return null;

try
{
// decode the base64 string
var bytes = Convert.FromBase64String(encoded);
var idStr = Encoding.UTF8.GetString(bytes);
// try to parse a ulong from the resulting string
if (ulong.TryParse(idStr, out var id))
return id;
}
catch (DecoderFallbackException)
{
// ignore exception, can be thrown by GetString
}
catch (FormatException)
{
// ignore exception, can be thrown if base64 string is invalid
}
catch (ArgumentException)
{
// ignore exception, can be thrown by BitConverter
}
return null;
}

/// <summary>
/// Checks the validity of a bot token by attempting to decode a ulong userid
/// from the bot token.
@@ -38,30 +72,8 @@ namespace Discord
// ensure that there are three parts
if (segments.Length != 3)
return false;

try
{
// decode the first segment as base64
var bytes = Convert.FromBase64String(segments[0]);
var idStr = Encoding.UTF8.GetString(bytes);
// discard id
return ulong.TryParse(idStr, out var id);
}
catch (DecoderFallbackException)
{
// can be thrown by GetString
return false;
}
catch (FormatException)
{
// ignore exception, if contains invalid base64 characters return false
return false;
}
catch (ArgumentException)
{
// ignore exceptions thrown by BitConverter
return false;
}
// return true if the user id could be determined
return DecodeBase64UserId(segments[0]).HasValue;
}

/// <summary>


+ 18
- 0
test/Discord.Net.Tests/Tests.TokenUtils.cs View File

@@ -146,5 +146,23 @@ namespace Discord
{
Assert.Equal(expected, TokenUtils.CheckBotTokenValidity(token));
}

[Theory]
// cannot pass a ulong? as a param in InlineData, so have to have a separate param
// indicating if a value is null
[InlineData("NDI4NDc3OTQ0MDA5MTk1NTIw", false, 428477944009195520)]
// should return null w/o throwing other exceptions
[InlineData("", true, 0)]
[InlineData(" ", true, 0)]
[InlineData(null, true, 0)]
[InlineData("these chars aren't allowed @U#)*@#!)*", true, 0)]
public void TestDecodeBase64UserId(string encodedUserId, bool isNull, ulong expectedUserId)
{
var result = TokenUtils.DecodeBase64UserId(encodedUserId);
if (isNull)
Assert.Null(result);
else
Assert.Equal(expectedUserId, result);
}
}
}

Loading…
Cancel
Save