46 lines
1.7 KiB
C#
46 lines
1.7 KiB
C#
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;
|
||
|
||
/// <summary>SHA-256 ключа в hex (lower-case) — формат src.athlete.api_key_hash.</summary>
|
||
public static class ApiKeyHash
|
||
{
|
||
public static string Of(string apiKey)
|
||
{
|
||
var bytes = SHA256.HashData(Encoding.UTF8.GetBytes(apiKey));
|
||
return Convert.ToHexString(bytes).ToLowerInvariant();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Стартовая синхронизация атлетов конфига с src.athlete
|
||
/// (upsert по хэшу ключа; spec 01-config-bootstrap). is_blocked
|
||
/// конфигом не переопределяется — источник блокировки только БД.
|
||
/// </summary>
|
||
public static class AthleteBootstrap
|
||
{
|
||
public static void Sync(IConnectionString connectionString, IReadOnlyList<ConfigAthlete> 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);
|
||
}
|
||
}
|
||
}
|
||
}
|