127 lines
4.8 KiB
C#
127 lines
4.8 KiB
C#
using BCards.Web.Services;
|
|
using BCards.Web.Repositories;
|
|
using System.Security.Claims;
|
|
|
|
namespace BCards.Web.Middleware;
|
|
|
|
public class PlanLimitationMiddleware
|
|
{
|
|
private readonly RequestDelegate _next;
|
|
private readonly ILogger<PlanLimitationMiddleware> _logger;
|
|
|
|
public PlanLimitationMiddleware(RequestDelegate next, ILogger<PlanLimitationMiddleware> logger)
|
|
{
|
|
_next = next;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context, IServiceProvider serviceProvider)
|
|
{
|
|
// Only check for authenticated users on specific endpoints
|
|
if (context.User.Identity?.IsAuthenticated == true && ShouldCheckLimitations(context))
|
|
{
|
|
using var scope = serviceProvider.CreateScope();
|
|
var authService = scope.ServiceProvider.GetRequiredService<IAuthService>();
|
|
var subscriptionRepository = scope.ServiceProvider.GetRequiredService<ISubscriptionRepository>();
|
|
var userPageRepository = scope.ServiceProvider.GetRequiredService<IUserPageRepository>();
|
|
|
|
try
|
|
{
|
|
var user = await authService.GetCurrentUserAsync(context.User);
|
|
if (user != null)
|
|
{
|
|
var subscription = await subscriptionRepository.GetByUserIdAsync(user.Id);
|
|
var limitations = GetPlanLimitations(subscription?.PlanType ?? "free");
|
|
|
|
// Check specific limitations based on the request
|
|
if (IsLinkCreationRequest(context))
|
|
{
|
|
var userPage = await userPageRepository.GetByUserIdAsync(user.Id);
|
|
var currentLinksCount = userPage?.Links?.Count(l => l.IsActive) ?? 0;
|
|
|
|
if (limitations.MaxLinks != -1 && currentLinksCount >= limitations.MaxLinks)
|
|
{
|
|
context.Response.StatusCode = 403;
|
|
await context.Response.WriteAsync("Limite de links atingido. Faça upgrade do seu plano.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Add limitations to context for use in controllers
|
|
context.Items["PlanLimitations"] = limitations;
|
|
context.Items["CurrentSubscription"] = subscription;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error checking plan limitations for user");
|
|
// Continue without blocking the request
|
|
}
|
|
}
|
|
|
|
await _next(context);
|
|
}
|
|
|
|
private static bool ShouldCheckLimitations(HttpContext context)
|
|
{
|
|
var path = context.Request.Path.Value?.ToLowerInvariant() ?? "";
|
|
|
|
return path.StartsWith("/admin/") ||
|
|
path.StartsWith("/api/") ||
|
|
(context.Request.Method == "POST" && path.Contains("/editpage"));
|
|
}
|
|
|
|
private static bool IsLinkCreationRequest(HttpContext context)
|
|
{
|
|
var path = context.Request.Path.Value?.ToLowerInvariant() ?? "";
|
|
return context.Request.Method == "POST" &&
|
|
(path.Contains("/editpage") || path.Contains("/addlink"));
|
|
}
|
|
|
|
private static Models.PlanLimitations GetPlanLimitations(string planType)
|
|
{
|
|
return planType.ToLower() switch
|
|
{
|
|
"basic" => new Models.PlanLimitations
|
|
{
|
|
MaxLinks = 5,
|
|
AllowCustomThemes = false,
|
|
AllowAnalytics = true,
|
|
AllowCustomDomain = false,
|
|
AllowMultipleDomains = false,
|
|
PrioritySupport = false,
|
|
PlanType = "basic"
|
|
},
|
|
"professional" => new Models.PlanLimitations
|
|
{
|
|
MaxLinks = 15,
|
|
AllowCustomThemes = false,
|
|
AllowAnalytics = true,
|
|
AllowCustomDomain = true,
|
|
AllowMultipleDomains = false,
|
|
PrioritySupport = false,
|
|
PlanType = "professional"
|
|
},
|
|
"premium" => new Models.PlanLimitations
|
|
{
|
|
MaxLinks = -1, // Unlimited
|
|
AllowCustomThemes = true,
|
|
AllowAnalytics = true,
|
|
AllowCustomDomain = true,
|
|
AllowMultipleDomains = true,
|
|
PrioritySupport = true,
|
|
PlanType = "premium"
|
|
},
|
|
_ => new Models.PlanLimitations
|
|
{
|
|
MaxLinks = 5,
|
|
AllowCustomThemes = false,
|
|
AllowAnalytics = false,
|
|
AllowCustomDomain = false,
|
|
AllowMultipleDomains = false,
|
|
PrioritySupport = false,
|
|
PlanType = "free"
|
|
}
|
|
};
|
|
}
|
|
} |