rate limiting e cpf masking

This commit is contained in:
Jose Henrique 2025-06-19 19:56:17 -03:00
parent 68d91b8151
commit ecbf2f07d6
4 changed files with 42 additions and 3 deletions

View File

@ -8,6 +8,7 @@ namespace OpenCand.API.Config
public const string DefaultPolicy = "DefaultPolicy";
public const string CandidatoSearchPolicy = "CandidatoSearchPolicy";
public const string CpfRevealPolicy = "CpfRevealPolicy";
public const string EstatisticaPolicy = "EstatisticaPolicy";
public static void ConfigureRateLimiting(this IServiceCollection services)
{
@ -50,6 +51,15 @@ namespace OpenCand.API.Config
options.QueueLimit = 0; // No burst
});
// CPF Reveal policy: 25 requests per minute with 10 burst
options.AddFixedWindowLimiter(policyName: EstatisticaPolicy, options =>
{
options.PermitLimit = 25;
options.Window = TimeSpan.FromMinutes(1);
options.QueueProcessingOrder = QueueProcessingOrder.OldestFirst;
options.QueueLimit = 10; // No burst
});
options.OnRejected = async (context, token) =>
{
context.HttpContext.Response.StatusCode = 429;

View File

@ -5,6 +5,7 @@ using OpenCand.API.Config;
using OpenCand.API.Model;
using OpenCand.API.Services;
using OpenCand.Core.Models;
using OpenCand.Core.Utils;
namespace OpenCand.API.Controllers
{
@ -27,7 +28,11 @@ namespace OpenCand.API.Controllers
throw new ArgumentException("Query parameter 'q' cannot be null/empty.", nameof(q));
}
return await openCandService.SearchCandidatosAsync(q);
var result = await openCandService.SearchCandidatosAsync(q);
result.Candidatos.ForEach(c => c.Cpf = CpfMasking.MaskCpf(c.Cpf));
return result;
}
[HttpGet("random")]
@ -42,7 +47,10 @@ namespace OpenCand.API.Controllers
[HttpGet("{id}")]
public async Task<Candidato> GetCandidatoById([FromRoute] Guid id)
{
return await openCandService.GetCandidatoAsync(id);
var result = await openCandService.GetCandidatoAsync(id);
result.Cpf = CpfMasking.MaskCpf(result.Cpf);
return result;
}
[HttpGet("{id}/bens")]

View File

@ -6,7 +6,7 @@ using OpenCand.API.Services;
namespace OpenCand.API.Controllers
{
[EnableRateLimiting(RateLimitingConfig.DefaultPolicy)]
[EnableRateLimiting(RateLimitingConfig.EstatisticaPolicy)]
public class EstatisticaController : BaseController
{
private readonly EstatisticaService estatisticaService;

View File

@ -0,0 +1,21 @@
namespace OpenCand.Core.Utils
{
public static class CpfMasking
{
/// <summary>
/// Masks a CPF number by replacing the middle 3 digits with '*'
/// </summary>
/// <param name="cpf">The CPF number to mask.</param>
/// <returns>The masked CPF number.</returns>
public static string MaskCpf(string cpf)
{
if (string.IsNullOrEmpty(cpf) || cpf.Length != 11)
{
return cpf;
}
// Mask the middle 3 digits
return $"{cpf.Substring(0, 3)}***{cpf.Substring(6)}";
}
}
}