VEU.WathBody/3-app/2-cli/Server.WatchBody.Web/Controllers/Admin/AdminAthletesController.cs

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;
}
}
}