namespace EntitlementSL.Common;
///
/// Rate-limit thresholds for Entitlement's client-facing auth endpoints (Login/RefreshToken/
/// CreateClientAdmin) — DXP has zero rate limiting anywhere; this closes that gap for
/// Entitlement's own client-auth surface. Bound directly from appsettings
/// "Entitlement:ClientAuthRateLimit" once at startup in Program.cs (read via IConfiguration, not
/// IOptions<T> — nothing outside Program.cs's own AddRateLimiter call ever needs this, unlike
/// EntitlementBLL's Options classes which BLL services inject).
///
/// Distinct from GB5Shared.RateLimit.GB5RateLimitExtensions' generic per-tenant limiter (used by
/// other GB5Shared SL projects for overall API abuse protection, partitioned by ClientId extracted
/// from the "Login" header): these three endpoints specifically need per-IP partitioning instead,
/// since Login/RefreshToken are AllowAnonymous and a caller could vary the ClientId they claim on
/// every request to dodge a per-tenant bucket — IP is the only durable signal available before
/// authentication succeeds. This turn does not touch or enable the generic per-tenant limiter for
/// EntitlementSL; that would be a separate, broader decision.
///
public class ClientAuthRateLimitOptions
{
public const string SectionName = "Entitlement:ClientAuthRateLimit";
/// Requests permitted per client IP, per window, for Login and RefreshToken combined
/// — they share one policy/bucket since both are credential-guessing surfaces with the same
/// risk profile.
public int LoginRefreshPermitLimit { get; set; } = 10;
public int LoginRefreshWindowSeconds { get; set; } = 60;
/// Requests permitted per client IP, per window, for CreateClientAdmin — tighter than
/// Login/RefreshToken: legitimate use is GOODBOOKS_ADMIN-only and inherently low-frequency
/// (creating a new client's first admin is a rare, deliberate action, not something a real
/// admin does repeatedly in a tight loop), so a lower ceiling costs nothing in practice while
/// still meaningfully slowing an attacker who somehow obtained/guessed admin credentials.
///
public int CreateClientAdminPermitLimit { get; set; } = 3;
public int CreateClientAdminWindowSeconds { get; set; } = 60;
/// Requests permitted per client IP, per window, for SelfProvisionTrial —
/// genuinely public/anonymous and each successful call creates a real MCLIENT/MUSER row
/// plus submits a real database-provisioning ChangeRequest, so this needs the tightest
/// ceiling of any endpoint in this options class: legitimate use is one signup per visitor,
/// not a burst.
public int SelfProvisionTrialPermitLimit { get; set; } = 3;
public int SelfProvisionTrialWindowSeconds { get; set; } = 3600;
}
/// ASP.NET Core rate-limiter policy names, registered once in Program.cs via
/// AddRateLimiter and referenced from each protected endpoint's Configure() via
/// Options(x => x.RequireRateLimiting(...)).
public static class ClientAuthRateLimitPolicies
{
public const string LoginAndRefresh = "client-auth-login-refresh";
public const string CreateClientAdmin = "client-auth-create-admin";
public const string SelfProvisionTrial = "client-auth-self-provision-trial";
}