Compare commits

..

2 Commits

Author SHA1 Message Date
90cd5d7998 fix: rapidapi key
All checks were successful
Deploy QR Rapido / test (push) Successful in 1m6s
Deploy QR Rapido / build-and-push (push) Successful in 14m48s
Deploy QR Rapido / deploy-staging (push) Has been skipped
Deploy QR Rapido / deploy-production (push) Successful in 2m12s
2026-03-30 19:58:57 -03:00
78bed0fbb1 feat: RapidAPI 2026-03-30 11:49:08 -03:00
4 changed files with 46 additions and 2 deletions

View File

@ -180,9 +180,25 @@ jobs:
docker secret ls | grep -q "microsoft_client_id" || echo "AVISO: Secret microsoft_client_id não existe!"
docker secret ls | grep -q "microsoft_client_secret" || echo "AVISO: Secret microsoft_client_secret não existe!"
# Cria secret do RapidAPI automaticamente se não existir
echo "Gerenciando secret rapidapi_proxy_secret..."
if ! docker secret inspect rapidapi_proxy_secret > /dev/null 2>&1; then
printf '%s' '${{ secrets.RAPIDAPI_PROXY_SECRET }}' | docker secret create rapidapi_proxy_secret -
echo "Secret rapidapi_proxy_secret criado."
else
echo "Secret rapidapi_proxy_secret já existe."
fi
# Verifica se o service existe
if docker service inspect qrrapido-prod > /dev/null 2>&1; then
echo "Service existe, atualizando imagem..."
# Migração: adiciona o secret ao service se ainda não estiver configurado
if ! docker service inspect qrrapido-prod --format '{{range .Spec.TaskTemplate.ContainerSpec.Secrets}}{{.SecretName}} {{end}}' | grep -q "rapidapi_proxy_secret"; then
echo "Adicionando rapidapi_proxy_secret ao service existente..."
docker service update --secret-add rapidapi_proxy_secret --update-order start-first qrrapido-prod
fi
docker service update \
--image ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest \
--env-add Serilog__OpenSearchUrl="http://141.148.162.114:19201" \
@ -208,6 +224,7 @@ jobs:
--secret google_client_secret \
--secret microsoft_client_id \
--secret microsoft_client_secret \
--secret rapidapi_proxy_secret \
--env ASPNETCORE_ENVIRONMENT=Production \
--env ASPNETCORE_URLS=http://+:8080 \
--env Serilog__OpenSearchUrl="http://141.148.162.114:19201" \

View File

@ -100,6 +100,9 @@ namespace QRRapidoApp.Configuration
// OAuth - Microsoft
["microsoft_client_id"] = "Authentication:Microsoft:ClientId",
["microsoft_client_secret"] = "Authentication:Microsoft:ClientSecret",
// RapidAPI
["rapidapi_proxy_secret"] = "RapidApi:ProxySecret",
}
};

View File

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using QRRapidoApp.Models;
using QRRapidoApp.Services;
@ -9,6 +10,8 @@ namespace QRRapidoApp.Filters
public class ApiKeyAuthorizeAttribute : Attribute, IAsyncActionFilter
{
private const string ApiKeyHeaderName = "X-API-Key";
private const string RapidApiSecretHeaderName = "X-RapidAPI-Proxy-Secret";
private const string RapidApiUserHeaderName = "X-RapidAPI-User";
// Tracks 429 events per key for abuse logging (key: prefix, value: list of timestamps)
// In-process only; acceptable for the abuse detection use case.
@ -30,10 +33,28 @@ namespace QRRapidoApp.Filters
try
{
// ── RapidAPI flow ────────────────────────────────────────────
var config = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
var expectedSecret = config["RapidApi:ProxySecret"];
if (!string.IsNullOrWhiteSpace(expectedSecret) &&
context.HttpContext.Request.Headers.TryGetValue(RapidApiSecretHeaderName, out var incomingSecret) &&
string.Equals(incomingSecret, expectedSecret, StringComparison.Ordinal))
{
var rapidApiUser = context.HttpContext.Request.Headers[RapidApiUserHeaderName].ToString();
context.HttpContext.Items["AuthSource"] = "RapidAPI";
context.HttpContext.Items["RapidApiUser"] = rapidApiUser;
context.HttpContext.Items["ApiPlanTier"] = ApiPlanTier.Pro;
logger.LogInformation("RapidAPI request authorized. RapidAPI-User: {User}", rapidApiUser);
await next();
return;
}
// ── Direct X-API-Key flow ────────────────────────────────────
if (!context.HttpContext.Request.Headers.TryGetValue(ApiKeyHeaderName, out var extractedApiKey))
{
logger.LogWarning("API Key missing in request headers from {IP}", GetIp(context));
context.Result = JsonError(401, "API Key not provided. Use the X-API-Key header.");
context.Result = JsonError(401, "Unauthorized. Provide a valid X-API-Key header or use the RapidAPI marketplace.");
return;
}

View File

@ -188,5 +188,8 @@
"Microsoft.AspNetCore": "Warning"
}
},
"RapidApi": {
"ProxySecret": "c9a7c750-2c39-11f1-9fe6-59a87b6d6ae1"
},
"AllowedHosts": "*"
}