107 lines
3.6 KiB
C#
107 lines
3.6 KiB
C#
using System.Security.Cryptography;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Server.WatchBody.Core.Dal.Src.Domain;
|
|
using Server.WatchBody.Core.Dal.Src.Repository;
|
|
using Server.WatchBody.Web.Services;
|
|
|
|
namespace Server.WatchBody.Web.Controllers.Admin;
|
|
|
|
/// <summary>Атлеты (spec 02 m08): список/создание/смена ключа/блок.</summary>
|
|
public class AdminAthletesController(AdminAuthService auth, IAthleteRepository athletes)
|
|
: AdminControllerBase(auth)
|
|
{
|
|
public ActionResult List()
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
var items = athletes.Select(null)
|
|
.OrderBy(a => a.Id)
|
|
.Select(a => new
|
|
{
|
|
a.Id,
|
|
a.Name,
|
|
a.IsBlocked,
|
|
createdAt = a.CreatedAt,
|
|
});
|
|
return new JsonResult(new { items });
|
|
}
|
|
|
|
public ActionResult Create()
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
var name = ReadString("name");
|
|
if (string.IsNullOrWhiteSpace(name)) return ErrorJson(400, "name пуст");
|
|
|
|
var (key, hash) = NewKey();
|
|
var id = athletes.Insert(new Athlete { Name = name, ApiKeyHash = hash });
|
|
// ключ возвращается один раз (🛡2): дальше в БД только хэш
|
|
Response.StatusCode = 201;
|
|
return new JsonResult(new { id, apiKey = key });
|
|
}
|
|
|
|
public ActionResult NewKey(int id)
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
var athlete = athletes.Get(id);
|
|
if (athlete == null) return ErrorJson(404, "not_found");
|
|
|
|
var (key, hash) = NewKey();
|
|
athletes.Update(new Athlete
|
|
{
|
|
Id = id, Name = athlete.Name, ApiKeyHash = hash, IsBlocked = athlete.IsBlocked,
|
|
});
|
|
return new JsonResult(new { apiKey = key });
|
|
}
|
|
|
|
public ActionResult Block(int id)
|
|
{
|
|
if (Denied()) return UnauthorizedJson();
|
|
var athlete = athletes.Get(id);
|
|
if (athlete == null) return ErrorJson(404, "not_found");
|
|
var blocked = ReadBool("isBlocked") ?? !athlete.IsBlocked;
|
|
athletes.Update(new Athlete
|
|
{
|
|
Id = id, Name = athlete.Name, ApiKeyHash = athlete.ApiKeyHash, IsBlocked = blocked,
|
|
});
|
|
return new JsonResult(new { id, isBlocked = blocked });
|
|
}
|
|
|
|
private static (string Key, string Hash) NewKey()
|
|
{
|
|
var key = "wb-" + Convert.ToHexString(RandomNumberGenerator.GetBytes(12)).ToLowerInvariant();
|
|
return (key, Services.ApiKeyHash.Of(key));
|
|
}
|
|
|
|
private string? ReadString(string property)
|
|
{
|
|
using var reader = new StreamReader(Request.Body);
|
|
var json = reader.ReadToEndAsync().GetAwaiter().GetResult();
|
|
try
|
|
{
|
|
using var doc = System.Text.Json.JsonDocument.Parse(json);
|
|
return doc.RootElement.TryGetProperty(property, out var value) ? value.GetString() : null;
|
|
}
|
|
catch (System.Text.Json.JsonException)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private bool? ReadBool(string property)
|
|
{
|
|
using var reader = new StreamReader(Request.Body);
|
|
var json = reader.ReadToEndAsync().GetAwaiter().GetResult();
|
|
try
|
|
{
|
|
using var doc = System.Text.Json.JsonDocument.Parse(json);
|
|
return doc.RootElement.TryGetProperty(property, out var value) &&
|
|
value.ValueKind is System.Text.Json.JsonValueKind.True or System.Text.Json.JsonValueKind.False
|
|
? value.GetBoolean()
|
|
: null;
|
|
}
|
|
catch (System.Text.Json.JsonException)
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|