test: cover core bot and web scenarios
This commit is contained in:
@@ -66,6 +66,27 @@ public sealed class AuthorizedSessionServiceTests
|
||||
Assert.Equal(sessionId, session.Id);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetSessionForGmAsync_ReturnsNull_WhenSessionBelongsToAnotherGm()
|
||||
{
|
||||
var groupId = Guid.NewGuid();
|
||||
var sessionId = Guid.NewGuid();
|
||||
var store = new FakeSessionStore(
|
||||
groups:
|
||||
[
|
||||
new(groupId, 42, "Alpha", 2002L)
|
||||
],
|
||||
sessions:
|
||||
[
|
||||
new(sessionId, groupId, "Session A", DateTime.UtcNow, "Planned", "https://example.test/a", Guid.NewGuid(), 10, 42)
|
||||
]);
|
||||
var service = new AuthorizedSessionService(store);
|
||||
|
||||
var session = await service.GetSessionForGmAsync(sessionId, 1001L);
|
||||
|
||||
Assert.Null(session);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateSessionForGmAsync_Throws_WhenSessionBelongsToAnotherGm()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using GmRelay.Web.Services;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace GmRelay.Bot.Tests.Web;
|
||||
|
||||
public sealed class TelegramAuthServiceTests
|
||||
{
|
||||
[Fact]
|
||||
public void Verify_ShouldAcceptValidTelegramPayload()
|
||||
{
|
||||
const string botToken = "test-bot-token";
|
||||
var authDate = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
|
||||
var query = CreateQueryCollection(
|
||||
botToken,
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["auth_date"] = authDate,
|
||||
["first_name"] = "Ada",
|
||||
["id"] = "424242",
|
||||
["last_name"] = "Lovelace",
|
||||
["username"] = "ada"
|
||||
});
|
||||
var service = new TelegramAuthService(CreateConfiguration(botToken));
|
||||
|
||||
var verified = service.Verify(query, out var telegramId, out var name);
|
||||
|
||||
Assert.True(verified);
|
||||
Assert.Equal(424242L, telegramId);
|
||||
Assert.Equal("Ada Lovelace", name);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Verify_ShouldRejectTamperedHash()
|
||||
{
|
||||
const string botToken = "test-bot-token";
|
||||
var values = new Dictionary<string, string>
|
||||
{
|
||||
["auth_date"] = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(),
|
||||
["first_name"] = "Ada",
|
||||
["id"] = "424242"
|
||||
};
|
||||
var query = CreateQueryCollection(botToken, values);
|
||||
var invalidQuery = new QueryCollection(new Dictionary<string, StringValues>(query.ToDictionary(
|
||||
pair => pair.Key,
|
||||
pair => pair.Value))
|
||||
{
|
||||
["hash"] = "00"
|
||||
});
|
||||
var service = new TelegramAuthService(CreateConfiguration(botToken));
|
||||
|
||||
var verified = service.Verify(invalidQuery, out _, out _);
|
||||
|
||||
Assert.False(verified);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Verify_ShouldRejectExpiredPayload()
|
||||
{
|
||||
const string botToken = "test-bot-token";
|
||||
var expiredAuthDate = DateTimeOffset.UtcNow.AddDays(-2).ToUnixTimeSeconds().ToString();
|
||||
var query = CreateQueryCollection(
|
||||
botToken,
|
||||
new Dictionary<string, string>
|
||||
{
|
||||
["auth_date"] = expiredAuthDate,
|
||||
["first_name"] = "Ada",
|
||||
["id"] = "424242"
|
||||
});
|
||||
var service = new TelegramAuthService(CreateConfiguration(botToken));
|
||||
|
||||
var verified = service.Verify(query, out _, out _);
|
||||
|
||||
Assert.False(verified);
|
||||
}
|
||||
|
||||
private static IConfiguration CreateConfiguration(string botToken) =>
|
||||
new ConfigurationBuilder()
|
||||
.AddInMemoryCollection(new Dictionary<string, string?>
|
||||
{
|
||||
["Telegram:BotToken"] = botToken
|
||||
})
|
||||
.Build();
|
||||
|
||||
private static QueryCollection CreateQueryCollection(string botToken, Dictionary<string, string> values)
|
||||
{
|
||||
var hash = ComputeTelegramHash(botToken, values);
|
||||
var queryValues = values.ToDictionary(
|
||||
pair => pair.Key,
|
||||
pair => new StringValues(pair.Value));
|
||||
queryValues["hash"] = new StringValues(hash);
|
||||
return new QueryCollection(queryValues);
|
||||
}
|
||||
|
||||
private static string ComputeTelegramHash(string botToken, IReadOnlyDictionary<string, string> values)
|
||||
{
|
||||
var dataCheckString = string.Join(
|
||||
"\n",
|
||||
values
|
||||
.OrderBy(pair => pair.Key, StringComparer.Ordinal)
|
||||
.Select(pair => $"{pair.Key}={pair.Value}"));
|
||||
var secretKey = SHA256.HashData(Encoding.UTF8.GetBytes(botToken));
|
||||
var hashBytes = HMACSHA256.HashData(secretKey, Encoding.UTF8.GetBytes(dataCheckString));
|
||||
return Convert.ToHexString(hashBytes).ToLowerInvariant();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user