Added get methods to API.
This commit is contained in:
@@ -1,10 +1,12 @@
|
|||||||
using CarCareTracker.External.Interfaces;
|
using CarCareTracker.External.Interfaces;
|
||||||
using CarCareTracker.Helper;
|
using CarCareTracker.Helper;
|
||||||
using CarCareTracker.Models;
|
using CarCareTracker.Models;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace CarCareTracker.Controllers
|
namespace CarCareTracker.Controllers
|
||||||
{
|
{
|
||||||
|
[Authorize]
|
||||||
public class APIController : Controller
|
public class APIController : Controller
|
||||||
{
|
{
|
||||||
private readonly IVehicleDataAccess _dataAccess;
|
private readonly IVehicleDataAccess _dataAccess;
|
||||||
@@ -15,7 +17,11 @@ namespace CarCareTracker.Controllers
|
|||||||
private readonly ITaxRecordDataAccess _taxRecordDataAccess;
|
private readonly ITaxRecordDataAccess _taxRecordDataAccess;
|
||||||
private readonly IReminderRecordDataAccess _reminderRecordDataAccess;
|
private readonly IReminderRecordDataAccess _reminderRecordDataAccess;
|
||||||
private readonly IUpgradeRecordDataAccess _upgradeRecordDataAccess;
|
private readonly IUpgradeRecordDataAccess _upgradeRecordDataAccess;
|
||||||
|
private readonly IReminderHelper _reminderHelper;
|
||||||
|
private readonly IGasHelper _gasHelper;
|
||||||
public APIController(IVehicleDataAccess dataAccess,
|
public APIController(IVehicleDataAccess dataAccess,
|
||||||
|
IGasHelper gasHelper,
|
||||||
|
IReminderHelper reminderHelper,
|
||||||
INoteDataAccess noteDataAccess,
|
INoteDataAccess noteDataAccess,
|
||||||
IServiceRecordDataAccess serviceRecordDataAccess,
|
IServiceRecordDataAccess serviceRecordDataAccess,
|
||||||
IGasRecordDataAccess gasRecordDataAccess,
|
IGasRecordDataAccess gasRecordDataAccess,
|
||||||
@@ -32,6 +38,8 @@ namespace CarCareTracker.Controllers
|
|||||||
_taxRecordDataAccess = taxRecordDataAccess;
|
_taxRecordDataAccess = taxRecordDataAccess;
|
||||||
_reminderRecordDataAccess = reminderRecordDataAccess;
|
_reminderRecordDataAccess = reminderRecordDataAccess;
|
||||||
_upgradeRecordDataAccess = upgradeRecordDataAccess;
|
_upgradeRecordDataAccess = upgradeRecordDataAccess;
|
||||||
|
_gasHelper = gasHelper;
|
||||||
|
_reminderHelper = reminderHelper;
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult Vehicles()
|
public IActionResult Vehicles()
|
||||||
@@ -42,19 +50,22 @@ namespace CarCareTracker.Controllers
|
|||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult ServiceRecords(int vehicleId)
|
public IActionResult ServiceRecords(int vehicleId)
|
||||||
{
|
{
|
||||||
var result = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
var vehicleRecords = _serviceRecordDataAccess.GetServiceRecordsByVehicleId(vehicleId);
|
||||||
|
var result = vehicleRecords.Select(x => new ServiceRecordExportModel { Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString() });
|
||||||
return Json(result);
|
return Json(result);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult RepairRecords(int vehicleId)
|
public IActionResult RepairRecords(int vehicleId)
|
||||||
{
|
{
|
||||||
var result = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
var vehicleRecords = _collisionRecordDataAccess.GetCollisionRecordsByVehicleId(vehicleId);
|
||||||
|
var result = vehicleRecords.Select(x => new ServiceRecordExportModel { Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString() });
|
||||||
return Json(result);
|
return Json(result);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult UpgradeRecords(int vehicleId)
|
public IActionResult UpgradeRecords(int vehicleId)
|
||||||
{
|
{
|
||||||
var result = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
var vehicleRecords = _upgradeRecordDataAccess.GetUpgradeRecordsByVehicleId(vehicleId);
|
||||||
|
var result = vehicleRecords.Select(x => new ServiceRecordExportModel { Date = x.Date.ToShortDateString(), Description = x.Description, Cost = x.Cost.ToString(), Notes = x.Notes, Odometer = x.Mileage.ToString() });
|
||||||
return Json(result);
|
return Json(result);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
@@ -64,10 +75,19 @@ namespace CarCareTracker.Controllers
|
|||||||
return Json(result);
|
return Json(result);
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
|
public IActionResult GasRecords(int vehicleId, bool useMPG, bool useUKMPG)
|
||||||
|
{
|
||||||
|
var vehicleRecords = _gasRecordDataAccess.GetGasRecordsByVehicleId(vehicleId);
|
||||||
|
var result = _gasHelper.GetGasRecordViewModels(vehicleRecords, useMPG, useUKMPG).Select(x => new GasRecordExportModel { Date = x.Date, Odometer = x.Mileage.ToString(), Cost = x.Cost.ToString(), FuelConsumed = x.Gallons.ToString(), FuelEconomy = x.MilesPerGallon.ToString()});
|
||||||
|
return Json(result);
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
public IActionResult Reminders(int vehicleId)
|
public IActionResult Reminders(int vehicleId)
|
||||||
{
|
{
|
||||||
var result = GetRemindersAndUrgency(vehicleId);
|
var currentMileage = GetMaxMileage(vehicleId);
|
||||||
return Json(result);
|
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
||||||
|
var results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage).Select(x=> new ReminderExportModel { Description = x.Description, Urgency = x.Urgency.ToString(), Metric = x.Metric.ToString(), Notes = x.Notes});
|
||||||
|
return Json(results);
|
||||||
}
|
}
|
||||||
private int GetMaxMileage(int vehicleId)
|
private int GetMaxMileage(int vehicleId)
|
||||||
{
|
{
|
||||||
@@ -94,92 +114,5 @@ namespace CarCareTracker.Controllers
|
|||||||
}
|
}
|
||||||
return numbersArray.Any() ? numbersArray.Max() : 0;
|
return numbersArray.Any() ? numbersArray.Max() : 0;
|
||||||
}
|
}
|
||||||
private List<ReminderRecordViewModel> GetRemindersAndUrgency(int vehicleId)
|
|
||||||
{
|
|
||||||
var currentMileage = GetMaxMileage(vehicleId);
|
|
||||||
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
|
||||||
List<ReminderRecordViewModel> reminderViewModels = new List<ReminderRecordViewModel>();
|
|
||||||
foreach (var reminder in reminders)
|
|
||||||
{
|
|
||||||
var reminderViewModel = new ReminderRecordViewModel()
|
|
||||||
{
|
|
||||||
Id = reminder.Id,
|
|
||||||
VehicleId = reminder.VehicleId,
|
|
||||||
Date = reminder.Date,
|
|
||||||
Mileage = reminder.Mileage,
|
|
||||||
Description = reminder.Description,
|
|
||||||
Notes = reminder.Notes,
|
|
||||||
Metric = reminder.Metric
|
|
||||||
};
|
|
||||||
if (reminder.Metric == ReminderMetric.Both)
|
|
||||||
{
|
|
||||||
if (reminder.Date < DateTime.Now)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(7))
|
|
||||||
{
|
|
||||||
//if less than a week from today or less than 50 miles from current mileage then very urgent.
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
//have to specify by which metric this reminder is urgent.
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 50)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(30))
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 100)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (reminder.Metric == ReminderMetric.Date)
|
|
||||||
{
|
|
||||||
if (reminder.Date < DateTime.Now)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(7))
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(30))
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (reminder.Metric == ReminderMetric.Odometer)
|
|
||||||
{
|
|
||||||
if (reminder.Mileage < currentMileage)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 50)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 100)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reminderViewModels.Add(reminderViewModel);
|
|
||||||
}
|
|
||||||
return reminderViewModels;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,14 +13,17 @@ namespace CarCareTracker.Controllers
|
|||||||
public class LoginController : Controller
|
public class LoginController : Controller
|
||||||
{
|
{
|
||||||
private IDataProtector _dataProtector;
|
private IDataProtector _dataProtector;
|
||||||
|
private ILoginHelper _loginHelper;
|
||||||
private readonly ILogger<LoginController> _logger;
|
private readonly ILogger<LoginController> _logger;
|
||||||
public LoginController(
|
public LoginController(
|
||||||
ILogger<LoginController> logger,
|
ILogger<LoginController> logger,
|
||||||
IDataProtectionProvider securityProvider
|
IDataProtectionProvider securityProvider,
|
||||||
|
ILoginHelper loginHelper
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
_dataProtector = securityProvider.CreateProtector("login");
|
_dataProtector = securityProvider.CreateProtector("login");
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
|
_loginHelper = loginHelper;
|
||||||
}
|
}
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
{
|
{
|
||||||
@@ -37,30 +40,19 @@ namespace CarCareTracker.Controllers
|
|||||||
//compare it against hashed credentials
|
//compare it against hashed credentials
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var configFileContents = System.IO.File.ReadAllText(StaticHelper.UserConfigPath);
|
var loginIsValid = _loginHelper.ValidateUserCredentials(credentials);
|
||||||
var existingUserConfig = System.Text.Json.JsonSerializer.Deserialize<UserConfig>(configFileContents);
|
if (loginIsValid)
|
||||||
if (existingUserConfig is not null)
|
|
||||||
{
|
{
|
||||||
//create hashes of the login credentials.
|
AuthCookie authCookie = new AuthCookie
|
||||||
var hashedUserName = Sha256_hash(credentials.UserName);
|
|
||||||
var hashedPassword = Sha256_hash(credentials.Password);
|
|
||||||
//compare against stored hash.
|
|
||||||
if (hashedUserName == existingUserConfig.UserNameHash &&
|
|
||||||
hashedPassword == existingUserConfig.UserPasswordHash)
|
|
||||||
{
|
{
|
||||||
//auth success, create auth cookie
|
Id = 1, //this is hardcoded for now
|
||||||
//encrypt stuff.
|
UserName = credentials.UserName,
|
||||||
AuthCookie authCookie = new AuthCookie
|
ExpiresOn = DateTime.Now.AddDays(credentials.IsPersistent ? 30 : 1)
|
||||||
{
|
};
|
||||||
Id = 1, //this is hardcoded for now
|
var serializedCookie = JsonSerializer.Serialize(authCookie);
|
||||||
UserName = credentials.UserName,
|
var encryptedCookie = _dataProtector.Protect(serializedCookie);
|
||||||
ExpiresOn = DateTime.Now.AddDays(credentials.IsPersistent ? 30 : 1)
|
Response.Cookies.Append("ACCESS_TOKEN", encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
|
||||||
};
|
return Json(true);
|
||||||
var serializedCookie = JsonSerializer.Serialize(authCookie);
|
|
||||||
var encryptedCookie = _dataProtector.Protect(serializedCookie);
|
|
||||||
Response.Cookies.Append("ACCESS_TOKEN", encryptedCookie, new CookieOptions { Expires = new DateTimeOffset(authCookie.ExpiresOn) });
|
|
||||||
return Json(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -27,9 +27,13 @@ namespace CarCareTracker.Controllers
|
|||||||
private readonly bool _useDescending;
|
private readonly bool _useDescending;
|
||||||
private readonly IConfiguration _config;
|
private readonly IConfiguration _config;
|
||||||
private readonly IFileHelper _fileHelper;
|
private readonly IFileHelper _fileHelper;
|
||||||
|
private readonly IGasHelper _gasHelper;
|
||||||
|
private readonly IReminderHelper _reminderHelper;
|
||||||
|
|
||||||
public VehicleController(ILogger<VehicleController> logger,
|
public VehicleController(ILogger<VehicleController> logger,
|
||||||
IFileHelper fileHelper,
|
IFileHelper fileHelper,
|
||||||
|
IGasHelper gasHelper,
|
||||||
|
IReminderHelper reminderHelper,
|
||||||
IVehicleDataAccess dataAccess,
|
IVehicleDataAccess dataAccess,
|
||||||
INoteDataAccess noteDataAccess,
|
INoteDataAccess noteDataAccess,
|
||||||
IServiceRecordDataAccess serviceRecordDataAccess,
|
IServiceRecordDataAccess serviceRecordDataAccess,
|
||||||
@@ -45,6 +49,8 @@ namespace CarCareTracker.Controllers
|
|||||||
_dataAccess = dataAccess;
|
_dataAccess = dataAccess;
|
||||||
_noteDataAccess = noteDataAccess;
|
_noteDataAccess = noteDataAccess;
|
||||||
_fileHelper = fileHelper;
|
_fileHelper = fileHelper;
|
||||||
|
_gasHelper = gasHelper;
|
||||||
|
_reminderHelper = reminderHelper;
|
||||||
_serviceRecordDataAccess = serviceRecordDataAccess;
|
_serviceRecordDataAccess = serviceRecordDataAccess;
|
||||||
_gasRecordDataAccess = gasRecordDataAccess;
|
_gasRecordDataAccess = gasRecordDataAccess;
|
||||||
_collisionRecordDataAccess = collisionRecordDataAccess;
|
_collisionRecordDataAccess = collisionRecordDataAccess;
|
||||||
@@ -333,71 +339,7 @@ namespace CarCareTracker.Controllers
|
|||||||
//check if the user uses MPG or Liters per 100km.
|
//check if the user uses MPG or Liters per 100km.
|
||||||
bool useMPG = bool.Parse(_config[nameof(UserConfig.UseMPG)]);
|
bool useMPG = bool.Parse(_config[nameof(UserConfig.UseMPG)]);
|
||||||
bool useUKMPG = bool.Parse(_config[nameof(UserConfig.UseUKMPG)]);
|
bool useUKMPG = bool.Parse(_config[nameof(UserConfig.UseUKMPG)]);
|
||||||
var computedResults = new List<GasRecordViewModel>();
|
var computedResults = _gasHelper.GetGasRecordViewModels(result, useMPG, useUKMPG);
|
||||||
int previousMileage = 0;
|
|
||||||
decimal unFactoredConsumption = 0.00M;
|
|
||||||
int unFactoredMileage = 0;
|
|
||||||
//perform computation.
|
|
||||||
for (int i = 0; i < result.Count; i++)
|
|
||||||
{
|
|
||||||
var currentObject = result[i];
|
|
||||||
decimal convertedConsumption;
|
|
||||||
if (useUKMPG && useMPG)
|
|
||||||
{
|
|
||||||
//if we're using UK MPG and the user wants imperial calculation insteace of l/100km
|
|
||||||
//if UK MPG is selected then the gas consumption are stored in liters but need to convert into UK gallons for computation.
|
|
||||||
convertedConsumption = currentObject.Gallons / 4.546M;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
convertedConsumption = currentObject.Gallons;
|
|
||||||
}
|
|
||||||
if (i > 0)
|
|
||||||
{
|
|
||||||
var deltaMileage = currentObject.Mileage - previousMileage;
|
|
||||||
var gasRecordViewModel = new GasRecordViewModel()
|
|
||||||
{
|
|
||||||
Id = currentObject.Id,
|
|
||||||
VehicleId = currentObject.VehicleId,
|
|
||||||
Date = currentObject.Date.ToShortDateString(),
|
|
||||||
Mileage = currentObject.Mileage,
|
|
||||||
Gallons = convertedConsumption,
|
|
||||||
Cost = currentObject.Cost,
|
|
||||||
DeltaMileage = deltaMileage,
|
|
||||||
CostPerGallon = (currentObject.Cost / convertedConsumption)
|
|
||||||
};
|
|
||||||
if (currentObject.IsFillToFull)
|
|
||||||
{
|
|
||||||
//if user filled to full.
|
|
||||||
gasRecordViewModel.MilesPerGallon = useMPG ? ((unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption)) : 100 / ((unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption));
|
|
||||||
//reset unFactored vars
|
|
||||||
unFactoredConsumption = 0;
|
|
||||||
unFactoredMileage = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unFactoredConsumption += convertedConsumption;
|
|
||||||
unFactoredMileage += deltaMileage;
|
|
||||||
gasRecordViewModel.MilesPerGallon = 0;
|
|
||||||
}
|
|
||||||
computedResults.Add(gasRecordViewModel);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
computedResults.Add(new GasRecordViewModel()
|
|
||||||
{
|
|
||||||
Id = currentObject.Id,
|
|
||||||
VehicleId = currentObject.VehicleId,
|
|
||||||
Date = currentObject.Date.ToShortDateString(),
|
|
||||||
Mileage = currentObject.Mileage,
|
|
||||||
Gallons = convertedConsumption,
|
|
||||||
Cost = currentObject.Cost,
|
|
||||||
DeltaMileage = 0,
|
|
||||||
MilesPerGallon = 0,
|
|
||||||
CostPerGallon = (currentObject.Cost / convertedConsumption)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
previousMileage = currentObject.Mileage;
|
|
||||||
}
|
|
||||||
if (_useDescending)
|
if (_useDescending)
|
||||||
{
|
{
|
||||||
computedResults = computedResults.OrderByDescending(x => DateTime.Parse(x.Date)).ThenByDescending(x => x.Mileage).ToList();
|
computedResults = computedResults.OrderByDescending(x => DateTime.Parse(x.Date)).ThenByDescending(x => x.Mileage).ToList();
|
||||||
@@ -687,88 +629,8 @@ namespace CarCareTracker.Controllers
|
|||||||
{
|
{
|
||||||
var currentMileage = GetMaxMileage(vehicleId);
|
var currentMileage = GetMaxMileage(vehicleId);
|
||||||
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
var reminders = _reminderRecordDataAccess.GetReminderRecordsByVehicleId(vehicleId);
|
||||||
List<ReminderRecordViewModel> reminderViewModels = new List<ReminderRecordViewModel>();
|
List<ReminderRecordViewModel> results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage);
|
||||||
foreach (var reminder in reminders)
|
return results;
|
||||||
{
|
|
||||||
var reminderViewModel = new ReminderRecordViewModel()
|
|
||||||
{
|
|
||||||
Id = reminder.Id,
|
|
||||||
VehicleId = reminder.VehicleId,
|
|
||||||
Date = reminder.Date,
|
|
||||||
Mileage = reminder.Mileage,
|
|
||||||
Description = reminder.Description,
|
|
||||||
Notes = reminder.Notes,
|
|
||||||
Metric = reminder.Metric
|
|
||||||
};
|
|
||||||
if (reminder.Metric == ReminderMetric.Both)
|
|
||||||
{
|
|
||||||
if (reminder.Date < DateTime.Now)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(7))
|
|
||||||
{
|
|
||||||
//if less than a week from today or less than 50 miles from current mileage then very urgent.
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
//have to specify by which metric this reminder is urgent.
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 50)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(30))
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Date;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 100)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (reminder.Metric == ReminderMetric.Date)
|
|
||||||
{
|
|
||||||
if (reminder.Date < DateTime.Now)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(7))
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
}
|
|
||||||
else if (reminder.Date < DateTime.Now.AddDays(30))
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (reminder.Metric == ReminderMetric.Odometer)
|
|
||||||
{
|
|
||||||
if (reminder.Mileage < currentMileage)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
|
||||||
reminderViewModel.Metric = ReminderMetric.Odometer;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 50)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
|
||||||
}
|
|
||||||
else if (reminder.Mileage < currentMileage + 100)
|
|
||||||
{
|
|
||||||
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reminderViewModels.Add(reminderViewModel);
|
|
||||||
}
|
|
||||||
return reminderViewModels;
|
|
||||||
}
|
}
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId)
|
public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId)
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
public interface IFileHelper
|
public interface IFileHelper
|
||||||
{
|
{
|
||||||
string GetFullFilePath(string currentFilePath, bool mustExist = true);
|
string GetFullFilePath(string currentFilePath, bool mustExist = true);
|
||||||
public string MoveFileFromTemp(string currentFilePath, string newFolder);
|
string MoveFileFromTemp(string currentFilePath, string newFolder);
|
||||||
public bool DeleteFile(string currentFilePath);
|
bool DeleteFile(string currentFilePath);
|
||||||
}
|
}
|
||||||
public class FileHelper: IFileHelper
|
public class FileHelper: IFileHelper
|
||||||
{
|
{
|
||||||
|
|||||||
82
Helper/GasHelper.cs
Normal file
82
Helper/GasHelper.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using CarCareTracker.Models;
|
||||||
|
|
||||||
|
namespace CarCareTracker.Helper
|
||||||
|
{
|
||||||
|
public interface IGasHelper
|
||||||
|
{
|
||||||
|
List<GasRecordViewModel> GetGasRecordViewModels(List<GasRecord> result, bool useMPG, bool useUKMPG);
|
||||||
|
}
|
||||||
|
public class GasHelper : IGasHelper
|
||||||
|
{
|
||||||
|
public List<GasRecordViewModel> GetGasRecordViewModels(List<GasRecord> result, bool useMPG, bool useUKMPG)
|
||||||
|
{
|
||||||
|
var computedResults = new List<GasRecordViewModel>();
|
||||||
|
int previousMileage = 0;
|
||||||
|
decimal unFactoredConsumption = 0.00M;
|
||||||
|
int unFactoredMileage = 0;
|
||||||
|
//perform computation.
|
||||||
|
for (int i = 0; i < result.Count; i++)
|
||||||
|
{
|
||||||
|
var currentObject = result[i];
|
||||||
|
decimal convertedConsumption;
|
||||||
|
if (useUKMPG && useMPG)
|
||||||
|
{
|
||||||
|
//if we're using UK MPG and the user wants imperial calculation insteace of l/100km
|
||||||
|
//if UK MPG is selected then the gas consumption are stored in liters but need to convert into UK gallons for computation.
|
||||||
|
convertedConsumption = currentObject.Gallons / 4.546M;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
convertedConsumption = currentObject.Gallons;
|
||||||
|
}
|
||||||
|
if (i > 0)
|
||||||
|
{
|
||||||
|
var deltaMileage = currentObject.Mileage - previousMileage;
|
||||||
|
var gasRecordViewModel = new GasRecordViewModel()
|
||||||
|
{
|
||||||
|
Id = currentObject.Id,
|
||||||
|
VehicleId = currentObject.VehicleId,
|
||||||
|
Date = currentObject.Date.ToShortDateString(),
|
||||||
|
Mileage = currentObject.Mileage,
|
||||||
|
Gallons = convertedConsumption,
|
||||||
|
Cost = currentObject.Cost,
|
||||||
|
DeltaMileage = deltaMileage,
|
||||||
|
CostPerGallon = currentObject.Cost / convertedConsumption
|
||||||
|
};
|
||||||
|
if (currentObject.IsFillToFull)
|
||||||
|
{
|
||||||
|
//if user filled to full.
|
||||||
|
gasRecordViewModel.MilesPerGallon = useMPG ? (unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption) : 100 / ((unFactoredMileage + deltaMileage) / (unFactoredConsumption + convertedConsumption));
|
||||||
|
//reset unFactored vars
|
||||||
|
unFactoredConsumption = 0;
|
||||||
|
unFactoredMileage = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unFactoredConsumption += convertedConsumption;
|
||||||
|
unFactoredMileage += deltaMileage;
|
||||||
|
gasRecordViewModel.MilesPerGallon = 0;
|
||||||
|
}
|
||||||
|
computedResults.Add(gasRecordViewModel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
computedResults.Add(new GasRecordViewModel()
|
||||||
|
{
|
||||||
|
Id = currentObject.Id,
|
||||||
|
VehicleId = currentObject.VehicleId,
|
||||||
|
Date = currentObject.Date.ToShortDateString(),
|
||||||
|
Mileage = currentObject.Mileage,
|
||||||
|
Gallons = convertedConsumption,
|
||||||
|
Cost = currentObject.Cost,
|
||||||
|
DeltaMileage = 0,
|
||||||
|
MilesPerGallon = 0,
|
||||||
|
CostPerGallon = currentObject.Cost / convertedConsumption
|
||||||
|
});
|
||||||
|
}
|
||||||
|
previousMileage = currentObject.Mileage;
|
||||||
|
}
|
||||||
|
return computedResults;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
47
Helper/LoginHelper.cs
Normal file
47
Helper/LoginHelper.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using CarCareTracker.Models;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace CarCareTracker.Helper
|
||||||
|
{
|
||||||
|
public interface ILoginHelper
|
||||||
|
{
|
||||||
|
bool ValidateUserCredentials(LoginModel credentials);
|
||||||
|
}
|
||||||
|
public class LoginHelper: ILoginHelper
|
||||||
|
{
|
||||||
|
public bool ValidateUserCredentials(LoginModel credentials)
|
||||||
|
{
|
||||||
|
var configFileContents = System.IO.File.ReadAllText(StaticHelper.UserConfigPath);
|
||||||
|
var existingUserConfig = System.Text.Json.JsonSerializer.Deserialize<UserConfig>(configFileContents);
|
||||||
|
if (existingUserConfig is not null)
|
||||||
|
{
|
||||||
|
//create hashes of the login credentials.
|
||||||
|
var hashedUserName = Sha256_hash(credentials.UserName);
|
||||||
|
var hashedPassword = Sha256_hash(credentials.Password);
|
||||||
|
//compare against stored hash.
|
||||||
|
if (hashedUserName == existingUserConfig.UserNameHash &&
|
||||||
|
hashedPassword == existingUserConfig.UserPasswordHash)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private static string Sha256_hash(string value)
|
||||||
|
{
|
||||||
|
StringBuilder Sb = new StringBuilder();
|
||||||
|
|
||||||
|
using (var hash = SHA256.Create())
|
||||||
|
{
|
||||||
|
Encoding enc = Encoding.UTF8;
|
||||||
|
byte[] result = hash.ComputeHash(enc.GetBytes(value));
|
||||||
|
|
||||||
|
foreach (byte b in result)
|
||||||
|
Sb.Append(b.ToString("x2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
97
Helper/ReminderHelper.cs
Normal file
97
Helper/ReminderHelper.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
using CarCareTracker.Models;
|
||||||
|
|
||||||
|
namespace CarCareTracker.Helper
|
||||||
|
{
|
||||||
|
public interface IReminderHelper
|
||||||
|
{
|
||||||
|
List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage);
|
||||||
|
}
|
||||||
|
public class ReminderHelper: IReminderHelper
|
||||||
|
{
|
||||||
|
public List<ReminderRecordViewModel> GetReminderRecordViewModels(List<ReminderRecord> reminders, int currentMileage)
|
||||||
|
{
|
||||||
|
List<ReminderRecordViewModel> reminderViewModels = new List<ReminderRecordViewModel>();
|
||||||
|
foreach (var reminder in reminders)
|
||||||
|
{
|
||||||
|
var reminderViewModel = new ReminderRecordViewModel()
|
||||||
|
{
|
||||||
|
Id = reminder.Id,
|
||||||
|
VehicleId = reminder.VehicleId,
|
||||||
|
Date = reminder.Date,
|
||||||
|
Mileage = reminder.Mileage,
|
||||||
|
Description = reminder.Description,
|
||||||
|
Notes = reminder.Notes,
|
||||||
|
Metric = reminder.Metric
|
||||||
|
};
|
||||||
|
if (reminder.Metric == ReminderMetric.Both)
|
||||||
|
{
|
||||||
|
if (reminder.Date < DateTime.Now)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
||||||
|
reminderViewModel.Metric = ReminderMetric.Date;
|
||||||
|
}
|
||||||
|
else if (reminder.Mileage < currentMileage)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
||||||
|
reminderViewModel.Metric = ReminderMetric.Odometer;
|
||||||
|
}
|
||||||
|
else if (reminder.Date < DateTime.Now.AddDays(7))
|
||||||
|
{
|
||||||
|
//if less than a week from today or less than 50 miles from current mileage then very urgent.
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
||||||
|
//have to specify by which metric this reminder is urgent.
|
||||||
|
reminderViewModel.Metric = ReminderMetric.Date;
|
||||||
|
}
|
||||||
|
else if (reminder.Mileage < currentMileage + 50)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
||||||
|
reminderViewModel.Metric = ReminderMetric.Odometer;
|
||||||
|
}
|
||||||
|
else if (reminder.Date < DateTime.Now.AddDays(30))
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
||||||
|
reminderViewModel.Metric = ReminderMetric.Date;
|
||||||
|
}
|
||||||
|
else if (reminder.Mileage < currentMileage + 100)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
||||||
|
reminderViewModel.Metric = ReminderMetric.Odometer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reminder.Metric == ReminderMetric.Date)
|
||||||
|
{
|
||||||
|
if (reminder.Date < DateTime.Now)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
||||||
|
}
|
||||||
|
else if (reminder.Date < DateTime.Now.AddDays(7))
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
||||||
|
}
|
||||||
|
else if (reminder.Date < DateTime.Now.AddDays(30))
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (reminder.Metric == ReminderMetric.Odometer)
|
||||||
|
{
|
||||||
|
if (reminder.Mileage < currentMileage)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.PastDue;
|
||||||
|
reminderViewModel.Metric = ReminderMetric.Odometer;
|
||||||
|
}
|
||||||
|
else if (reminder.Mileage < currentMileage + 50)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.VeryUrgent;
|
||||||
|
}
|
||||||
|
else if (reminder.Mileage < currentMileage + 100)
|
||||||
|
{
|
||||||
|
reminderViewModel.Urgency = ReminderUrgency.Urgent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reminderViewModels.Add(reminderViewModel);
|
||||||
|
}
|
||||||
|
return reminderViewModels;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using CarCareTracker.Models;
|
using CarCareTracker.Helper;
|
||||||
|
using CarCareTracker.Models;
|
||||||
using Microsoft.AspNetCore.Authentication;
|
using Microsoft.AspNetCore.Authentication;
|
||||||
using Microsoft.AspNetCore.Components.Web;
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
@@ -14,17 +15,20 @@ namespace CarCareTracker.Middleware
|
|||||||
{
|
{
|
||||||
private IHttpContextAccessor _httpContext;
|
private IHttpContextAccessor _httpContext;
|
||||||
private IDataProtector _dataProtector;
|
private IDataProtector _dataProtector;
|
||||||
|
private ILoginHelper _loginHelper;
|
||||||
private bool enableAuth;
|
private bool enableAuth;
|
||||||
public Authen(
|
public Authen(
|
||||||
IOptionsMonitor<AuthenticationSchemeOptions> options,
|
IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||||
UrlEncoder encoder,
|
UrlEncoder encoder,
|
||||||
ILoggerFactory logger,
|
ILoggerFactory logger,
|
||||||
IConfiguration configuration,
|
IConfiguration configuration,
|
||||||
|
ILoginHelper loginHelper,
|
||||||
IDataProtectionProvider securityProvider,
|
IDataProtectionProvider securityProvider,
|
||||||
IHttpContextAccessor httpContext) : base(options, logger, encoder)
|
IHttpContextAccessor httpContext) : base(options, logger, encoder)
|
||||||
{
|
{
|
||||||
_httpContext = httpContext;
|
_httpContext = httpContext;
|
||||||
_dataProtector = securityProvider.CreateProtector("login");
|
_dataProtector = securityProvider.CreateProtector("login");
|
||||||
|
_loginHelper = loginHelper;
|
||||||
enableAuth = bool.Parse(configuration["EnableAuth"]);
|
enableAuth = bool.Parse(configuration["EnableAuth"]);
|
||||||
}
|
}
|
||||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||||
@@ -45,11 +49,38 @@ namespace CarCareTracker.Middleware
|
|||||||
{
|
{
|
||||||
//auth is enabled by user, we will have to authenticate the user via a ticket retrieved from the auth cookie.
|
//auth is enabled by user, we will have to authenticate the user via a ticket retrieved from the auth cookie.
|
||||||
var access_token = _httpContext.HttpContext.Request.Cookies["ACCESS_TOKEN"];
|
var access_token = _httpContext.HttpContext.Request.Cookies["ACCESS_TOKEN"];
|
||||||
if (string.IsNullOrWhiteSpace(access_token))
|
//auth using Basic Auth for API.
|
||||||
|
var request_header = _httpContext.HttpContext.Request.Headers["Authorization"];
|
||||||
|
if (string.IsNullOrWhiteSpace(access_token) && string.IsNullOrWhiteSpace(request_header))
|
||||||
{
|
{
|
||||||
return AuthenticateResult.Fail("Cookie is invalid or does not exist.");
|
return AuthenticateResult.Fail("Cookie is invalid or does not exist.");
|
||||||
}
|
}
|
||||||
else
|
else if (!string.IsNullOrWhiteSpace(request_header))
|
||||||
|
{
|
||||||
|
var cleanedHeader = request_header.ToString().Replace("Basic ", "").Trim();
|
||||||
|
byte[] data = Convert.FromBase64String(cleanedHeader);
|
||||||
|
string decodedString = System.Text.Encoding.UTF8.GetString(data);
|
||||||
|
var splitString = decodedString.Split(":");
|
||||||
|
if (splitString.Count() != 2)
|
||||||
|
{
|
||||||
|
return AuthenticateResult.Fail("Invalid credentials");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
var validUser = _loginHelper.ValidateUserCredentials(new LoginModel { UserName = splitString[0], Password = splitString[1] });
|
||||||
|
if (validUser)
|
||||||
|
{
|
||||||
|
var appIdentity = new ClaimsIdentity("Custom");
|
||||||
|
var userIdentity = new List<Claim>
|
||||||
|
{
|
||||||
|
new(ClaimTypes.Name, splitString[0])
|
||||||
|
};
|
||||||
|
appIdentity.AddClaims(userIdentity);
|
||||||
|
AuthenticationTicket ticket = new AuthenticationTicket(new ClaimsPrincipal(appIdentity), this.Scheme.Name);
|
||||||
|
return AuthenticateResult.Success(ticket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!string.IsNullOrWhiteSpace(access_token))
|
||||||
{
|
{
|
||||||
//decrypt the access token.
|
//decrypt the access token.
|
||||||
var decryptedCookie = _dataProtector.Unprotect(access_token);
|
var decryptedCookie = _dataProtector.Unprotect(access_token);
|
||||||
@@ -84,6 +115,14 @@ namespace CarCareTracker.Middleware
|
|||||||
}
|
}
|
||||||
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
|
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
|
||||||
{
|
{
|
||||||
|
if (Request.RouteValues.TryGetValue("controller", out object value))
|
||||||
|
{
|
||||||
|
if (value.ToString().ToLower() == "api")
|
||||||
|
{
|
||||||
|
Response.StatusCode = 401;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
Response.Redirect("/Login/Index");
|
Response.Redirect("/Login/Index");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,4 +23,19 @@
|
|||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
public string Cost { get; set; }
|
public string Cost { get; set; }
|
||||||
}
|
}
|
||||||
|
public class GasRecordExportModel
|
||||||
|
{
|
||||||
|
public string Date { get; set; }
|
||||||
|
public string Odometer { get; set; }
|
||||||
|
public string FuelConsumed { get; set; }
|
||||||
|
public string Cost { get; set; }
|
||||||
|
public string FuelEconomy { get; set; }
|
||||||
|
}
|
||||||
|
public class ReminderExportModel
|
||||||
|
{
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Urgency { get; set; }
|
||||||
|
public string Metric { get; set; }
|
||||||
|
public string Notes { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,12 @@ builder.Services.AddSingleton<ICollisionRecordDataAccess, CollisionRecordDataAcc
|
|||||||
builder.Services.AddSingleton<ITaxRecordDataAccess, TaxRecordDataAccess>();
|
builder.Services.AddSingleton<ITaxRecordDataAccess, TaxRecordDataAccess>();
|
||||||
builder.Services.AddSingleton<IReminderRecordDataAccess, ReminderRecordDataAccess>();
|
builder.Services.AddSingleton<IReminderRecordDataAccess, ReminderRecordDataAccess>();
|
||||||
builder.Services.AddSingleton<IUpgradeRecordDataAccess, UpgradeRecordDataAccess>();
|
builder.Services.AddSingleton<IUpgradeRecordDataAccess, UpgradeRecordDataAccess>();
|
||||||
|
|
||||||
|
//configure helpers
|
||||||
builder.Services.AddSingleton<IFileHelper, FileHelper>();
|
builder.Services.AddSingleton<IFileHelper, FileHelper>();
|
||||||
|
builder.Services.AddSingleton<IGasHelper, GasHelper>();
|
||||||
|
builder.Services.AddSingleton<IReminderHelper, ReminderHelper>();
|
||||||
|
builder.Services.AddSingleton<ILoginHelper, LoginHelper>();
|
||||||
|
|
||||||
if (!Directory.Exists("data"))
|
if (!Directory.Exists("data"))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user