143 lines
5.3 KiB
C#
143 lines
5.3 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using QRRapidoApp.Data;
|
|
using QRRapidoApp.Models;
|
|
using MongoDB.Driver;
|
|
|
|
namespace QRRapidoApp.Controllers
|
|
{
|
|
/// <summary>
|
|
/// Admin controller - ONLY accessible from localhost for security
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class AdminController : ControllerBase
|
|
{
|
|
private readonly MongoDbContext _context;
|
|
private readonly ILogger<AdminController> _logger;
|
|
|
|
public AdminController(MongoDbContext context, ILogger<AdminController> logger)
|
|
{
|
|
_context = context;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Seed/Update MongoDB Plans collection
|
|
/// Only accessible from localhost (127.0.0.1 or ::1)
|
|
/// </summary>
|
|
[HttpPost("SeedPlans")]
|
|
public async Task<IActionResult> SeedPlans([FromBody] List<Plan> plans)
|
|
{
|
|
// SECURITY: Only allow from localhost
|
|
var remoteIp = HttpContext.Connection.RemoteIpAddress;
|
|
var isLocalhost = remoteIp != null &&
|
|
(remoteIp.ToString() == "127.0.0.1" ||
|
|
remoteIp.ToString() == "::1" ||
|
|
remoteIp.ToString() == "localhost");
|
|
|
|
if (!isLocalhost)
|
|
{
|
|
_logger.LogWarning($"Unauthorized admin access attempt from {remoteIp}");
|
|
return Forbid("This endpoint is only accessible from localhost");
|
|
}
|
|
|
|
try
|
|
{
|
|
_logger.LogInformation($"SeedPlans called from localhost - Upserting {plans.Count} plans");
|
|
|
|
foreach (var plan in plans)
|
|
{
|
|
// Upsert based on interval (month/year)
|
|
var filter = Builders<Plan>.Filter.Eq(p => p.Interval, plan.Interval);
|
|
var options = new ReplaceOptions { IsUpsert = true };
|
|
|
|
await _context.Plans.ReplaceOneAsync(filter, plan, options);
|
|
_logger.LogInformation($"Upserted plan: {plan.Interval}");
|
|
}
|
|
|
|
return Ok(new {
|
|
success = true,
|
|
message = $"{plans.Count} plans seeded successfully",
|
|
plans = plans.Select(p => new {
|
|
interval = p.Interval,
|
|
priceIds = p.PricesByCountry.ToDictionary(
|
|
kvp => kvp.Key,
|
|
kvp => kvp.Value.StripePriceId
|
|
)
|
|
})
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error seeding plans");
|
|
return StatusCode(500, new { success = false, error = ex.Message });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get all plans from MongoDB
|
|
/// Only accessible from localhost
|
|
/// </summary>
|
|
[HttpGet("Plans")]
|
|
public async Task<IActionResult> GetPlans()
|
|
{
|
|
// SECURITY: Only allow from localhost
|
|
var remoteIp = HttpContext.Connection.RemoteIpAddress;
|
|
var isLocalhost = remoteIp != null &&
|
|
(remoteIp.ToString() == "127.0.0.1" ||
|
|
remoteIp.ToString() == "::1" ||
|
|
remoteIp.ToString() == "localhost");
|
|
|
|
if (!isLocalhost)
|
|
{
|
|
_logger.LogWarning($"Unauthorized admin access attempt from {remoteIp}");
|
|
return Forbid("This endpoint is only accessible from localhost");
|
|
}
|
|
|
|
try
|
|
{
|
|
var plans = await _context.Plans.Find(_ => true).ToListAsync();
|
|
return Ok(new { success = true, count = plans.Count, plans });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error retrieving plans");
|
|
return StatusCode(500, new { success = false, error = ex.Message });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete all plans from MongoDB
|
|
/// Only accessible from localhost
|
|
/// </summary>
|
|
[HttpDelete("Plans")]
|
|
public async Task<IActionResult> DeleteAllPlans()
|
|
{
|
|
// SECURITY: Only allow from localhost
|
|
var remoteIp = HttpContext.Connection.RemoteIpAddress;
|
|
var isLocalhost = remoteIp != null &&
|
|
(remoteIp.ToString() == "127.0.0.1" ||
|
|
remoteIp.ToString() == "::1" ||
|
|
remoteIp.ToString() == "localhost");
|
|
|
|
if (!isLocalhost)
|
|
{
|
|
_logger.LogWarning($"Unauthorized admin access attempt from {remoteIp}");
|
|
return Forbid("This endpoint is only accessible from localhost");
|
|
}
|
|
|
|
try
|
|
{
|
|
var result = await _context.Plans.DeleteManyAsync(_ => true);
|
|
_logger.LogInformation($"Deleted {result.DeletedCount} plans");
|
|
return Ok(new { success = true, deletedCount = result.DeletedCount });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error deleting plans");
|
|
return StatusCode(500, new { success = false, error = ex.Message });
|
|
}
|
|
}
|
|
}
|
|
}
|