Add page size input validation to relevant controllers

This commit is contained in:
kurt-mcrae
2025-02-06 22:28:55 +11:00
parent 3ba3c6fd75
commit 2b42be2368
6 changed files with 114 additions and 3 deletions
+40 -1
View File
@@ -1,6 +1,7 @@
using backend.Models.NswFuelApi;
using backend.Models.Utilities;
using backend.Services;
using backend.Validators;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Swashbuckle.AspNetCore.Annotations;
@@ -14,11 +15,14 @@ public class PriceController : ControllerBase
{
private readonly ILogger<PriceController> _logger;
private readonly IPriceService _priceService;
private readonly IGlobalControllerValidators _globalControllerValidators;
public PriceController(IPriceService priceService, ILogger<PriceController> logger)
public PriceController(IPriceService priceService, ILogger<PriceController> logger,
IGlobalControllerValidators globalControllerValidators)
{
_priceService = priceService;
_logger = logger;
_globalControllerValidators = globalControllerValidators;
}
[HttpGet("current")]
@@ -29,6 +33,13 @@ public class PriceController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/prices/current request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest($"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var prices = await _priceService.GetAllCurrentPrices(pageNumber, pageSize);
if (!prices.Data.Any()) return NoContent();
@@ -45,6 +56,13 @@ public class PriceController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/prices/current/station request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest($"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var prices = await _priceService.GetCurrentPricesByStationCode(stationCode, fuelType, pageNumber, pageSize);
if (!prices.Data.Any()) return NotFound($"No prices found for station code {stationCode}");
@@ -60,6 +78,13 @@ public class PriceController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/prices/current/fuel-type request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest($"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var prices = await _priceService.GetCurrentPricesByFuelType(fuelType.Trim().ToUpper(), pageNumber, pageSize);
if (!prices.Data.Any()) return NotFound($"No prices found for fuel type {fuelType.Trim().ToUpper()}");
@@ -75,6 +100,13 @@ public class PriceController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/prices/current/fuel-type/lowest request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest($"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var prices =
await _priceService.GetCurrentLowestPricesByFuelType(fuelType.Trim().ToUpper(), pageNumber, pageSize);
if (!prices.Data.Any()) return NotFound($"No prices found for fuel type {fuelType.Trim().ToUpper()}");
@@ -93,6 +125,13 @@ public class PriceController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/prices/period request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest($"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var prices = await _priceService.GetPricesForTimePeriod(start, end, pageNumber, pageSize);
if (!prices.Data.Any()) return NoContent();
+21 -1
View File
@@ -1,6 +1,7 @@
using backend.Models.NswFuelApi;
using backend.Models.Utilities;
using backend.Services;
using backend.Validators;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Swashbuckle.AspNetCore.Annotations;
@@ -14,11 +15,14 @@ public class StationController : ControllerBase
{
private readonly ILogger<StationController> _logger;
private readonly IStationService _stationService;
private readonly IGlobalControllerValidators _globalControllerValidators;
public StationController(IStationService stationService, ILogger<StationController> logger)
public StationController(IStationService stationService, ILogger<StationController> logger,
IGlobalControllerValidators globalControllerValidators)
{
_stationService = stationService;
_logger = logger;
_globalControllerValidators = globalControllerValidators;
}
[HttpGet("all")]
@@ -28,6 +32,14 @@ public class StationController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/stations/all request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest(
$"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var stations = await _stationService.GetAllStations(pageNumber, pageSize);
if (!stations.Data.Any()) return NoContent();
@@ -58,6 +70,14 @@ public class StationController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/stations/within-radius request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest(
$"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var stations =
await _stationService.GetStationsWithinRadius(latitude, longitude, radiusInMetres, brand, pageNumber,
pageSize);
@@ -1,6 +1,7 @@
using backend.Models.Aggregations;
using backend.Models.Utilities;
using backend.Services;
using backend.Validators;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.RateLimiting;
using Swashbuckle.AspNetCore.Annotations;
@@ -14,12 +15,14 @@ public class StationWithPricesController : ControllerBase
{
private readonly ILogger<StationWithPricesController> _logger;
private readonly IStationWithPricesService _stationWithPricesService;
private readonly IGlobalControllerValidators _globalControllerValidators;
public StationWithPricesController(IStationWithPricesService stationWithPricesService,
ILogger<StationWithPricesController> logger)
ILogger<StationWithPricesController> logger, IGlobalControllerValidators globalControllerValidators)
{
_stationWithPricesService = stationWithPricesService;
_logger = logger;
_globalControllerValidators = globalControllerValidators;
}
[HttpGet("station-code")]
@@ -49,6 +52,14 @@ public class StationWithPricesController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/stations-with-prices/within-radius request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest(
$"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var result =
await _stationWithPricesService.GetStationsWithPricesWithinRadius(latitude, longitude, radiusInMetres,
fuelType?.Trim().ToUpper(), brand, pageNumber, pageSize);
@@ -66,6 +77,14 @@ public class StationWithPricesController : ControllerBase
[FromQuery] int pageSize = 10)
{
_logger.LogInformation("Processing api/stations-with-prices/lowest-prices request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest(
$"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var result =
await _stationWithPricesService.GetStationsWithLowestPricesByFuelType(fuelType.Trim().ToUpper(),
pageNumber, pageSize);
@@ -87,6 +106,14 @@ public class StationWithPricesController : ControllerBase
[FromQuery] int pageSize = 3)
{
_logger.LogInformation("Processing api/stations-with-prices/lowest-prices/by-fuel-type/within-radius request");
if (!_globalControllerValidators.ValidatePageSize(pageSize))
{
_logger.LogError("Page size too large");
return BadRequest(
$"Page size too large, maximum page size is {_globalControllerValidators.GetGlobalMaxPageSize()}");
}
var result =
await _stationWithPricesService.GetStationsWithLowestPricesByFuelTypeWithinRadius(fuelType.Trim().ToUpper(),
latitude, longitude, radiusInMetres, pageNumber, pageSize);
@@ -2,6 +2,7 @@ using System.Threading.RateLimiting;
using backend.Config;
using backend.Services;
using backend.Services.Init;
using backend.Validators;
using Hangfire;
using Hangfire.PostgreSql;
using Microsoft.AspNetCore.RateLimiting;
@@ -26,6 +27,7 @@ public static class ServiceCollectionExtensions
.AddSingleton<IStationWithPricesService, StationWithPricesService>()
.AddSingleton<IPriceTrendsService, PriceTrendsService>()
.AddSingleton<ISuburbBoundariesService, SuburbBoundariesService>()
.AddSingleton<IGlobalControllerValidators, GlobalControllerValidators>()
.AddSingleton<DatabaseInitialiser>()
.AddSingleton<HangfireInitialiser>()
.AddLogging(options =>
@@ -0,0 +1,16 @@
namespace backend.Validators;
public class GlobalControllerValidators : IGlobalControllerValidators
{
private const int MaxPageSize = 100;
public bool ValidatePageSize(int requestedPageSize)
{
return requestedPageSize <= MaxPageSize;
}
public int GetGlobalMaxPageSize()
{
return MaxPageSize;
}
}
@@ -0,0 +1,7 @@
namespace backend.Validators;
public interface IGlobalControllerValidators
{
public bool ValidatePageSize(int requestedPageSize);
public int GetGlobalMaxPageSize();
}