using System.Security.Cryptography;
using System.Text;
using Kit.Helpers.SqlHelperAbstract;
using Server.WatchBody.Core.Dal.Src.Domain;
using Server.WatchBody.Core.Dal.Src.Repository;
using Server.WatchBody.Web.Config;
namespace Server.WatchBody.Web.Services;
/// SHA-256 ключа в hex (lower-case) — формат src.athlete.api_key_hash.
public static class ApiKeyHash
{
public static string Of(string apiKey)
{
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(apiKey));
return Convert.ToHexString(bytes).ToLowerInvariant();
}
}
///
/// Стартовая синхронизация атлетов конфига с src.athlete
/// (upsert по хэшу ключа; spec 01-config-bootstrap). is_blocked
/// конфигом не переопределяется — источник блокировки только БД.
///
public static class AthleteBootstrap
{
public static void Sync(IConnectionString connectionString, IReadOnlyList athletes)
{
var repo = new AthleteRepository(connectionString);
foreach (var configAthlete in athletes)
{
var hash = ApiKeyHash.Of(configAthlete.ApiKey);
var existing = repo.Select(new AthleteFilter { ApiKeyHash = hash }).FirstOrDefault();
if (existing == null)
{
repo.Insert(new Athlete { Name = configAthlete.Name, ApiKeyHash = hash });
}
else if (!string.Equals(existing.Name, configAthlete.Name, StringComparison.Ordinal))
{
existing.Name = configAthlete.Name;
repo.Update(existing);
}
}
}
}