Почистить комментарии от упоминаний процесса
Удалены <remarks>, <summary> сжаты до короткой фразы, вырезаны ссылки на Task/Ruling/этап/python/прототип; //-комментарии со ссылками на процесс удалены; то же в .proto. Правила обновлены в docs/spec/Код-стайл-Дейл.md. Строк комментариев 27210 -> ~19100.
This commit is contained in:
@@ -12,15 +12,8 @@ using OperatorCookieOptions = Deal.Api.Configuration.OperatorCookieOptions;
|
||||
namespace Deal.Api.Endpoints;
|
||||
|
||||
/// <summary>
|
||||
/// HTTP-эндпоинты аутентификации оператора (группа /api/operator/auth). Зеркало AuthEndpoints для операторов (Ruling 1).
|
||||
/// HTTP-эндпоинты аутентификации оператора
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Оператор ≠ пользователь тенанта: вход по отдельным public-таблицам (OperatorAuthService/IOperatorAuthStore),
|
||||
/// сессия — в куке deal_operator_session (отдельная от deal_session; 12 ч, httpOnly, SameSite=Lax).
|
||||
/// Успех-ответы — <c>{ok:true,...}</c>, ошибки — HTTP-код + <c>{"detail":"..."}</c> (Ruling 10). Защищённые
|
||||
/// ручки (me) требуют операторскую сессию (401 «Требуется вход оператора») — тенантная кука не проходит.
|
||||
/// Результаты входа пишутся в аудит (operator_login_ok/failed, Task 4/Ruling 4).
|
||||
/// </remarks>
|
||||
public static class OperatorAuthEndpoints
|
||||
{
|
||||
private const string InvalidCredentialsDetail = "Неверный логин или пароль оператора";
|
||||
@@ -28,7 +21,7 @@ public static class OperatorAuthEndpoints
|
||||
private const string OperatorAuthOpenApiTag = "operator-auth";
|
||||
|
||||
/// <summary>
|
||||
/// Регистрирует группу /api/operator/auth: login, logout, me.
|
||||
/// Регистрирует группу /api/operator/auth
|
||||
/// </summary>
|
||||
/// <param name="app">Построитель маршрутов приложения.</param>
|
||||
/// <returns>Построитель маршрутов для цепочки вызовов.</returns>
|
||||
@@ -36,7 +29,6 @@ public static class OperatorAuthEndpoints
|
||||
{
|
||||
var group = app.MapGroup(OperatorAuthGroupPrefix).WithTags(OperatorAuthOpenApiTag);
|
||||
|
||||
// Политика "auth" rate limiter (план Task 11, Ruling 5): фиксированное окно 10/мин на IP ручки
|
||||
// входа оператора; остальные ручки группы — под глобальной API-политикой (по тенанту/IP).
|
||||
group.MapPost("/login", LoginAsync).RequireRateLimiting(RateLimitPolicies.AuthPolicy);
|
||||
group.MapPost("/logout", LogoutAsync);
|
||||
@@ -45,8 +37,6 @@ public static class OperatorAuthEndpoints
|
||||
return app;
|
||||
}
|
||||
|
||||
// POST /api/operator/auth/login: проверка учётных данных оператора, выдача куки сессии; результат пишется в аудит (Task 4).
|
||||
// До OperatorAuthService отрабатывает LoginAttemptGuard (5 неудач ip|login за 15 мин → 429, Ruling 5).
|
||||
private static async Task<IResult> LoginAsync(
|
||||
LoginRequest body,
|
||||
OperatorAuthService operatorAuthService,
|
||||
@@ -58,7 +48,6 @@ public static class OperatorAuthEndpoints
|
||||
{
|
||||
string? attemptedLogin = NormalizeLogin(body.Login);
|
||||
|
||||
// Защита входа оператора (план Task 11, Ruling 5): зеркало AuthEndpoints — блокировка ключа
|
||||
// ip|login до проверки учётных данных (в dev при RateLimit:Enabled=false гвард выключен).
|
||||
if (await loginAttemptGuard.IsBlockedAsync(ClientIp(context), attemptedLogin, ct))
|
||||
{
|
||||
@@ -69,7 +58,6 @@ public static class OperatorAuthEndpoints
|
||||
if (result.Login is null || result.Token is null)
|
||||
{
|
||||
// Неверные учётные данные оператора — одно сообщение (зеркало AuthEndpoints).
|
||||
// Аудит operator_login_failed — только для реальной попытки (непустой логин), без пароля (Ruling 4);
|
||||
// счётчик неудач гварда растёт там же (пустые логины ключа не имеют).
|
||||
if (attemptedLogin is not null)
|
||||
{
|
||||
@@ -86,7 +74,6 @@ public static class OperatorAuthEndpoints
|
||||
return EndpointResults.Unauthorized(InvalidCredentialsDetail);
|
||||
}
|
||||
|
||||
// Успешный вход оператора сбрасывает счётчик неудач ключа ip|login (Ruling 5).
|
||||
await loginAttemptGuard.ResetAsync(ClientIp(context), result.Login, ct);
|
||||
|
||||
await auditService.AppendAsync(new AuditRecordDto(
|
||||
@@ -115,7 +102,6 @@ public static class OperatorAuthEndpoints
|
||||
await operatorAuthService.LogoutAsync(rawToken, ct);
|
||||
context.Response.Cookies.Delete(cookieName);
|
||||
|
||||
// Выход оператора (этап 10, T1): событие пишется при живой разрешённой сессии.
|
||||
if (operatorIdentity is not null)
|
||||
{
|
||||
await AuditAppender.AppendOperatorAsync(context, AuditEvents.OperatorLogout, new { login = operatorIdentity.Login }, ct);
|
||||
@@ -124,7 +110,6 @@ public static class OperatorAuthEndpoints
|
||||
return Results.Ok(new { ok = true });
|
||||
}
|
||||
|
||||
// GET /api/operator/auth/me: проверка живой операторской сессии (401 без неё, Ruling 1).
|
||||
private static IResult MeAsync(HttpContext context)
|
||||
{
|
||||
var operatorIdentity = context.GetCurrentOperator();
|
||||
|
||||
Reference in New Issue
Block a user