mirror of
https://github.com/hargata/lubelog.git
synced 2026-02-03 17:53:02 -06:00
commit
7e94ccfdf4
@ -78,11 +78,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/equipmentrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddEquipmentRecordJson(int vehicleId, [FromBody] EquipmentRecordExportModel input) => AddEquipmentRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/equipmentrecords/add")]
|
||||
@ -129,6 +131,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/equipmentrecords/delete")]
|
||||
public IActionResult DeleteEquipmentRecord(int id)
|
||||
@ -163,10 +166,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Equipment Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/equipmentrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateEquipmentRecordJson([FromBody] EquipmentRecordExportModel input) => UpdateEquipmentRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/equipmentrecords/update")]
|
||||
public IActionResult UpdateEquipmentRecord(EquipmentRecordExportModel input)
|
||||
|
||||
@ -121,11 +121,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/gasrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddGasRecordJson(int vehicleId, [FromBody] GasRecordExportModel input) => AddGasRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/gasrecords/add")]
|
||||
@ -193,6 +195,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/gasrecords/delete")]
|
||||
public IActionResult DeleteGasRecord(int id)
|
||||
@ -216,10 +219,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Gas Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/gasrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateGasRecordJson([FromBody] GasRecordExportModel input) => UpdateGasRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/gasrecords/update")]
|
||||
public IActionResult UpdateGasRecord(GasRecordExportModel input)
|
||||
|
||||
@ -21,6 +21,7 @@ namespace CarCareTracker.Controllers
|
||||
var result = _vehicleLogic.GetMaxMileage(vehicleId);
|
||||
return Json(result);
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/odometerrecords/recalculate")]
|
||||
@ -123,11 +124,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/odometerrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddOdometerRecordJson(int vehicleId, [FromBody] OdometerRecordExportModel input) => AddOdometerRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/odometerrecords/add")]
|
||||
@ -207,6 +210,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/odometerrecords/delete")]
|
||||
public IActionResult DeleteOdometerRecord(int id)
|
||||
@ -230,10 +234,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Odometer Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/odometerrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateOdometerRecordJson([FromBody] OdometerRecordExportModel input) => UpdateOdometerRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/odometerrecords/update")]
|
||||
public IActionResult UpdateOdometerRecord(OdometerRecordExportModel input)
|
||||
|
||||
@ -105,11 +105,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/planrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddPlanRecordJson(int vehicleId, [FromBody] PlanRecordExportModel input) => AddPlanRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/planrecords/add")]
|
||||
@ -182,6 +184,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/planrecords/delete")]
|
||||
public IActionResult DeletePlanRecord(int id)
|
||||
@ -210,10 +213,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Plan Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/planrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdatePlanRecordJson([FromBody] PlanRecordExportModel input) => UpdatePlanRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/planrecords/update")]
|
||||
public IActionResult UpdatePlanRecord(PlanRecordExportModel input)
|
||||
|
||||
@ -88,11 +88,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(results);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/reminders/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddReminderRecordJson(int vehicleId, [FromBody] ReminderExportModel input) => AddReminderRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/reminders/add")]
|
||||
@ -162,10 +164,12 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/reminders/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateReminderRecordJson([FromBody] ReminderExportModel input) => UpdateReminderRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/reminders/update")]
|
||||
public IActionResult UpdateReminderRecord(ReminderExportModel input)
|
||||
@ -242,6 +246,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/reminders/delete")]
|
||||
public IActionResult DeleteReminderRecord(int id)
|
||||
|
||||
@ -89,11 +89,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/repairrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddRepairRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddRepairRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/repairrecords/add")]
|
||||
@ -157,6 +159,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/repairrecords/delete")]
|
||||
public IActionResult DeleteRepairRecord(int id)
|
||||
@ -185,10 +188,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Repair Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/repairrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateRepairRecordJson([FromBody] GenericRecordExportModel input) => UpdateRepairRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/repairrecords/update")]
|
||||
public IActionResult UpdateRepairRecord(GenericRecordExportModel input)
|
||||
|
||||
@ -89,11 +89,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/servicerecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddServiceRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddServiceRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/servicerecords/add")]
|
||||
@ -156,6 +158,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/servicerecords/delete")]
|
||||
public IActionResult DeleteServiceRecord(int id)
|
||||
@ -184,10 +187,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Service Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/servicerecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateServiceRecordJson([FromBody] GenericRecordExportModel input) => UpdateServiceRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/servicerecords/update")]
|
||||
public IActionResult UpdateServiceRecord(GenericRecordExportModel input)
|
||||
|
||||
@ -121,11 +121,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/supplyrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddSupplyRecordJson(int vehicleId, [FromBody] SupplyRecordExportModel input) => AddSupplyRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/supplyrecords/add")]
|
||||
@ -178,6 +180,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/supplyrecords/delete")]
|
||||
public IActionResult DeleteSupplyRecord(int id)
|
||||
@ -211,10 +214,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Supply Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/supplyrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateSupplyRecordJson([FromBody] SupplyRecordExportModel input) => UpdateSupplyRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/supplyrecords/update")]
|
||||
public IActionResult UpdateSupplyRecord(SupplyRecordExportModel input)
|
||||
|
||||
@ -125,11 +125,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed($"No Recurring Taxes Updated Due To Error: {ex.Message}"));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/taxrecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddTaxRecordJson(int vehicleId, [FromBody] TaxRecordExportModel input) => AddTaxRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/taxrecords/add")]
|
||||
@ -179,6 +181,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/taxrecords/delete")]
|
||||
public IActionResult DeleteTaxRecord(int id)
|
||||
@ -202,10 +205,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Tax Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/taxrecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateTaxRecordJson([FromBody] TaxRecordExportModel input) => UpdateTaxRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/taxrecords/update")]
|
||||
public IActionResult UpdateTaxRecord(TaxRecordExportModel input)
|
||||
|
||||
@ -89,11 +89,13 @@ namespace CarCareTracker.Controllers
|
||||
return Json(result);
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/upgraderecords/add")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult AddUpgradeRecordJson(int vehicleId, [FromBody] GenericRecordExportModel input) => AddUpgradeRecord(vehicleId, input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[TypeFilter(typeof(CollaboratorFilter), Arguments = new object[] { false, true, HouseholdPermission.Edit })]
|
||||
[HttpPost]
|
||||
[Route("/api/vehicle/upgraderecords/add")]
|
||||
@ -156,6 +158,7 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Delete })]
|
||||
[HttpDelete]
|
||||
[Route("/api/vehicle/upgraderecords/delete")]
|
||||
public IActionResult DeleteUpgradeRecord(int id)
|
||||
@ -184,10 +187,12 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
return Json(OperationResponse.Conditional(result, "Upgrade Record Deleted"));
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/upgraderecords/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateUpgradeRecordJson([FromBody] GenericRecordExportModel input) => UpdateUpgradeRecord(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicle/upgraderecords/update")]
|
||||
public IActionResult UpdateUpgradeRecord(GenericRecordExportModel input)
|
||||
|
||||
@ -317,10 +317,12 @@ namespace CarCareTracker.Controllers
|
||||
return Json(OperationResponse.Failed(ex.Message));
|
||||
}
|
||||
}
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicles/update")]
|
||||
[Consumes("application/json")]
|
||||
public IActionResult UpdateVehicleJson([FromBody] VehicleImportModel input) => UpdateVehicle(input);
|
||||
[TypeFilter(typeof(APIKeyFilter), Arguments = new object[] { HouseholdPermission.Edit })]
|
||||
[HttpPut]
|
||||
[Route("/api/vehicles/update")]
|
||||
public IActionResult UpdateVehicle(VehicleImportModel input)
|
||||
|
||||
@ -76,7 +76,8 @@ namespace CarCareTracker.Controllers
|
||||
&& _configHelper.DeleteUserConfig(userId)
|
||||
&& _loginLogic.DeleteUser(userId)
|
||||
&& _userLogic.DeleteAllHouseholdByChildUserId(userId)
|
||||
&& _userLogic.DeleteAllHouseholdByParentUserId(userId);
|
||||
&& _userLogic.DeleteAllHouseholdByParentUserId(userId)
|
||||
&& _userLogic.DeleteAllAPIKeysByUserId(userId);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
|
||||
@ -336,6 +336,29 @@ namespace CarCareTracker.Controllers
|
||||
var result = _userLogic.AddUserToHousehold(GetUserID(), username);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetUserAPIKeys()
|
||||
{
|
||||
var result = _userLogic.GetAPIKeysByUserId(GetUserID());
|
||||
return PartialView("_UserApiKeysModal", result);
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult GetCreateApiKeyModal()
|
||||
{
|
||||
return PartialView("_CreateApiKeyModal");
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult CreateAPIKeyForUser(string keyName, List<HouseholdPermission> permissions)
|
||||
{
|
||||
var result = _userLogic.CreateAPIKey(GetUserID(), keyName, permissions);
|
||||
return Json(result);
|
||||
}
|
||||
[HttpPost]
|
||||
public IActionResult DeleteAPIKeyForUser(int keyId)
|
||||
{
|
||||
var result = _userLogic.DeleteAPIKeyByKeyIdAndUserId(keyId, GetUserID());
|
||||
return Json(OperationResponse.Conditional(result, "API Key Deleted", StaticHelper.GenericErrorMessage));
|
||||
}
|
||||
[Authorize(Roles = nameof(UserData.IsRootUser))]
|
||||
[HttpGet]
|
||||
public IActionResult GetRootAccountInformationModal()
|
||||
|
||||
@ -56,7 +56,8 @@ namespace CarCareTracker.Controllers
|
||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.inspectionrecordtemplates (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.equipmentrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, vehicleId INT not null, data jsonb not null)",
|
||||
"CREATE TABLE IF NOT EXISTS app.userhouseholdrecords (parentUserId INT, childUserId INT, data jsonb not null, PRIMARY KEY(parentUserId, childUserId))"
|
||||
"CREATE TABLE IF NOT EXISTS app.userhouseholdrecords (parentUserId INT, childUserId INT, data jsonb not null, PRIMARY KEY(parentUserId, childUserId))",
|
||||
"CREATE TABLE IF NOT EXISTS app.apikeyrecords (id INT GENERATED BY DEFAULT AS IDENTITY primary key, userId INT not null, apiKey TEXT not null, data jsonb not null)"
|
||||
};
|
||||
foreach(string cmd in cmds)
|
||||
{
|
||||
@ -108,6 +109,7 @@ namespace CarCareTracker.Controllers
|
||||
var equipmentrecords = new List<EquipmentRecord>();
|
||||
|
||||
var userhouseholdrecords = new List<UserHousehold>();
|
||||
var apikeyrecords = new List<APIKey>();
|
||||
#region "Part1"
|
||||
string cmd = $"SELECT data FROM app.vehicles";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
@ -499,6 +501,25 @@ namespace CarCareTracker.Controllers
|
||||
}
|
||||
;
|
||||
}
|
||||
cmd = $"SELECT data FROM app.apikeyrecords";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
APIKey result = JsonSerializer.Deserialize<APIKey>(reader["data"] as string);
|
||||
apikeyrecords.Add(result);
|
||||
}
|
||||
}
|
||||
foreach (var record in apikeyrecords)
|
||||
{
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
var table = db.GetCollection<APIKey>("apikeyrecords");
|
||||
table.Upsert(record);
|
||||
}
|
||||
;
|
||||
}
|
||||
#endregion
|
||||
var destFilePath = $"{fullFolderPath}.zip";
|
||||
ZipFile.CreateFromDirectory(fullFolderPath, destFilePath);
|
||||
@ -552,6 +573,7 @@ namespace CarCareTracker.Controllers
|
||||
var equipmentrecords = new List<EquipmentRecord>();
|
||||
|
||||
var userhouseholdrecords = new List<UserHousehold>();
|
||||
var apikeyrecords = new List<APIKey>();
|
||||
#region "Part1"
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
@ -899,6 +921,24 @@ namespace CarCareTracker.Controllers
|
||||
ctext.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
using (var db = new LiteDatabase(fullFileName))
|
||||
{
|
||||
var table = db.GetCollection<APIKey>("apikeyrecords");
|
||||
apikeyrecords = table.FindAll().ToList();
|
||||
}
|
||||
;
|
||||
foreach (var record in apikeyrecords)
|
||||
{
|
||||
string cmd = $"INSERT INTO app.apikeyrecords (id, userId, apiKey, data) VALUES(@id, @userId, @apiKey, CAST(@data AS jsonb)); SELECT setval('app.apikeyrecords_id_seq', (SELECT MAX(id) from app.apikeyrecords));";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", record.Id);
|
||||
ctext.Parameters.AddWithValue("userId", record.UserId);
|
||||
ctext.Parameters.AddWithValue("apiKey", record.Key);
|
||||
ctext.Parameters.AddWithValue("data", JsonSerializer.Serialize(record));
|
||||
ctext.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
return Json(OperationResponse.Succeed("Data Imported Successfully"));
|
||||
}
|
||||
|
||||
61
External/Implementations/Litedb/ApiKeyRecordDataAccess.cs
vendored
Normal file
61
External/Implementations/Litedb/ApiKeyRecordDataAccess.cs
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
using CarCareTracker.External.Interfaces;
|
||||
using CarCareTracker.Models;
|
||||
using LiteDB;
|
||||
using CarCareTracker.Helper;
|
||||
|
||||
namespace CarCareTracker.External.Implementations
|
||||
{
|
||||
public class ApiKeyRecordDataAccess : IApiKeyRecordDataAccess
|
||||
{
|
||||
private ILiteDBHelper _liteDB { get; set; }
|
||||
private static string tableName = "apikeyrecords";
|
||||
public ApiKeyRecordDataAccess(ILiteDBHelper liteDB)
|
||||
{
|
||||
_liteDB = liteDB;
|
||||
}
|
||||
public List<APIKey> GetAPIKeyRecordsByUserId(int userId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<APIKey>(tableName);
|
||||
var apiKeyRecords = table.Find(Query.EQ(nameof(APIKey.UserId), userId));
|
||||
return apiKeyRecords.ToList() ?? new List<APIKey>();
|
||||
}
|
||||
public APIKey GetAPIKeyById(int apiKeyId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<APIKey>(tableName);
|
||||
return table.FindById(apiKeyId);
|
||||
}
|
||||
public APIKey GetAPIKeyByKey(string hashedKey)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<APIKey>(tableName);
|
||||
var apiKeyRecord = table.FindOne(Query.EQ(nameof(APIKey.Key), hashedKey));
|
||||
return apiKeyRecord ?? new APIKey();
|
||||
}
|
||||
public bool SaveAPIKey(APIKey apiKey)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<APIKey>(tableName);
|
||||
table.Upsert(apiKey);
|
||||
db.Checkpoint();
|
||||
return true;
|
||||
}
|
||||
public bool DeleteAPIKeyById(int apiKeyId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<APIKey>(tableName);
|
||||
table.Delete(apiKeyId);
|
||||
db.Checkpoint();
|
||||
return true;
|
||||
}
|
||||
public bool DeleteAllAPIKeysByUserId(int userId)
|
||||
{
|
||||
var db = _liteDB.GetLiteDB();
|
||||
var table = db.GetCollection<APIKey>(tableName);
|
||||
var apiKeyRecords = table.DeleteMany(Query.EQ(nameof(APIKey.UserId), userId));
|
||||
db.Checkpoint();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
186
External/Implementations/Postgres/ApiKeyRecordDataAccess.cs
vendored
Normal file
186
External/Implementations/Postgres/ApiKeyRecordDataAccess.cs
vendored
Normal file
@ -0,0 +1,186 @@
|
||||
using CarCareTracker.External.Interfaces;
|
||||
using CarCareTracker.Models;
|
||||
using Npgsql;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace CarCareTracker.External.Implementations
|
||||
{
|
||||
public class PGApiKeyRecordDataAccess : IApiKeyRecordDataAccess
|
||||
{
|
||||
private NpgsqlDataSource pgDataSource;
|
||||
private readonly ILogger<PGApiKeyRecordDataAccess> _logger;
|
||||
private static string tableName = "apikeyrecords";
|
||||
public PGApiKeyRecordDataAccess(IConfiguration config, ILogger<PGApiKeyRecordDataAccess> logger)
|
||||
{
|
||||
pgDataSource = NpgsqlDataSource.Create(config["POSTGRES_CONNECTION"]);
|
||||
|
||||
_logger = logger;
|
||||
try
|
||||
{
|
||||
//create table if not exist.
|
||||
string initCMD = $"CREATE SCHEMA IF NOT EXISTS app; CREATE TABLE IF NOT EXISTS app.{tableName} (id INT GENERATED BY DEFAULT AS IDENTITY primary key, userId INT not null, apiKey TEXT not null, data jsonb not null)";
|
||||
using (var ctext = pgDataSource.CreateCommand(initCMD))
|
||||
{
|
||||
ctext.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
}
|
||||
}
|
||||
public List<APIKey> GetAPIKeyRecordsByUserId(int userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"SELECT data FROM app.{tableName} WHERE userId = @userId";
|
||||
var results = new List<APIKey>();
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("userId", userId);
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
APIKey apiKeyRecord = JsonSerializer.Deserialize<APIKey>(reader["data"] as string);
|
||||
results.Add(apiKeyRecord);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return new List<APIKey>();
|
||||
}
|
||||
}
|
||||
public APIKey GetAPIKeyById(int apiKeyId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"SELECT data FROM app.{tableName} WHERE id = @id";
|
||||
var result = new APIKey();
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", apiKeyId);
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
APIKey apiKeyRecord = JsonSerializer.Deserialize<APIKey>(reader["data"] as string);
|
||||
result = apiKeyRecord;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return new APIKey();
|
||||
}
|
||||
}
|
||||
public APIKey GetAPIKeyByKey(string hashedKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"SELECT data FROM app.{tableName} WHERE apiKey = @apiKey";
|
||||
var result = new APIKey();
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("apiKey", hashedKey);
|
||||
using (NpgsqlDataReader reader = ctext.ExecuteReader())
|
||||
while (reader.Read())
|
||||
{
|
||||
APIKey apiKeyRecord = JsonSerializer.Deserialize<APIKey>(reader["data"] as string);
|
||||
result = apiKeyRecord;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return new APIKey();
|
||||
}
|
||||
}
|
||||
public bool DeleteAPIKeyById(int apiKeyId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"DELETE FROM app.{tableName} WHERE id = @id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", apiKeyId);
|
||||
return ctext.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool SaveAPIKey(APIKey apiKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (apiKey.Id == default)
|
||||
{
|
||||
string cmd = $"INSERT INTO app.{tableName} (userId, apiKey, data) VALUES(@userId, @apiKey, CAST(@data AS jsonb)) RETURNING id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("userId", apiKey.UserId);
|
||||
ctext.Parameters.AddWithValue("apiKey", apiKey.Key);
|
||||
ctext.Parameters.AddWithValue("data", "{}");
|
||||
apiKey.Id = Convert.ToInt32(ctext.ExecuteScalar());
|
||||
//update json data
|
||||
if (apiKey.Id != default)
|
||||
{
|
||||
string cmdU = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
|
||||
using (var ctextU = pgDataSource.CreateCommand(cmdU))
|
||||
{
|
||||
var serializedData = JsonSerializer.Serialize(apiKey);
|
||||
ctextU.Parameters.AddWithValue("id", apiKey.Id);
|
||||
ctextU.Parameters.AddWithValue("data", serializedData);
|
||||
return ctextU.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
return apiKey.Id != default;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string cmd = $"UPDATE app.{tableName} SET data = CAST(@data AS jsonb) WHERE id = @id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
var serializedData = JsonSerializer.Serialize(apiKey);
|
||||
ctext.Parameters.AddWithValue("id", apiKey.Id);
|
||||
ctext.Parameters.AddWithValue("data", serializedData);
|
||||
return ctext.ExecuteNonQuery() > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public bool DeleteAllAPIKeysByUserId(int userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
string cmd = $"DELETE FROM app.{tableName} WHERE userId = @id";
|
||||
using (var ctext = pgDataSource.CreateCommand(cmd))
|
||||
{
|
||||
ctext.Parameters.AddWithValue("id", userId);
|
||||
ctext.ExecuteNonQuery();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex.Message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
14
External/Interfaces/IApiKeyRecordDataAccess.cs
vendored
Normal file
14
External/Interfaces/IApiKeyRecordDataAccess.cs
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
using CarCareTracker.Models;
|
||||
|
||||
namespace CarCareTracker.External.Interfaces
|
||||
{
|
||||
public interface IApiKeyRecordDataAccess
|
||||
{
|
||||
public List<APIKey> GetAPIKeyRecordsByUserId(int userId);
|
||||
public APIKey GetAPIKeyById(int apiKeyId);
|
||||
public APIKey GetAPIKeyByKey(string hashedKey);
|
||||
public bool SaveAPIKey(APIKey apiKey);
|
||||
public bool DeleteAPIKeyById(int apiKeyId);
|
||||
public bool DeleteAllAPIKeysByUserId(int userId);
|
||||
}
|
||||
}
|
||||
37
Filter/APIKeyFilter.cs
Normal file
37
Filter/APIKeyFilter.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using CarCareTracker.Logic;
|
||||
using CarCareTracker.Models;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
|
||||
namespace CarCareTracker.Filter
|
||||
{
|
||||
public class APIKeyFilter: ActionFilterAttribute
|
||||
{
|
||||
private readonly IUserLogic _userLogic;
|
||||
private readonly HouseholdPermission _permission;
|
||||
public APIKeyFilter(IUserLogic userLogic, HouseholdPermission? permission = HouseholdPermission.View) {
|
||||
_userLogic = userLogic;
|
||||
_permission = permission ?? HouseholdPermission.View;
|
||||
}
|
||||
public override void OnActionExecuting(ActionExecutingContext filterContext)
|
||||
{
|
||||
if (filterContext.HttpContext.User.IsInRole("APIKeyAuth"))
|
||||
{
|
||||
var apikey_header = filterContext.HttpContext.Request.Headers["x-api-key"];
|
||||
if (string.IsNullOrWhiteSpace(apikey_header))
|
||||
{
|
||||
apikey_header = filterContext.HttpContext.Request.Query["apiKey"];
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(apikey_header))
|
||||
{
|
||||
var permissions = _userLogic.GetAPIKeyPermissions(apikey_header);
|
||||
if (!permissions.Contains(_permission))
|
||||
{
|
||||
filterContext.Result = new JsonResult(OperationResponse.Failed("Access Denied"));
|
||||
filterContext.HttpContext.Response.StatusCode = 401;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -992,5 +992,20 @@ namespace CarCareTracker.Helper
|
||||
return "primary";
|
||||
}
|
||||
}
|
||||
public static string GetHash(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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ namespace CarCareTracker.Logic
|
||||
OperationResponse SendRegistrationToken(LoginModel credentials);
|
||||
UserData ValidateUserCredentials(LoginModel credentials);
|
||||
UserData ValidateOpenIDUser(LoginModel credentials);
|
||||
UserData ValidateAPIKey(string apiKey);
|
||||
bool CheckIfUserIsValid(int userId);
|
||||
bool CreateRootUserCredentials(LoginModel credentials);
|
||||
bool DeleteRootUserCredentials();
|
||||
@ -36,17 +37,20 @@ namespace CarCareTracker.Logic
|
||||
{
|
||||
private readonly IUserRecordDataAccess _userData;
|
||||
private readonly ITokenRecordDataAccess _tokenData;
|
||||
private readonly IApiKeyRecordDataAccess _apiKeyData;
|
||||
private readonly IMailHelper _mailHelper;
|
||||
private readonly IConfigHelper _configHelper;
|
||||
private IMemoryCache _cache;
|
||||
public LoginLogic(IUserRecordDataAccess userData,
|
||||
ITokenRecordDataAccess tokenData,
|
||||
IApiKeyRecordDataAccess apiKeyData,
|
||||
IMailHelper mailHelper,
|
||||
IConfigHelper configHelper,
|
||||
IMemoryCache memoryCache)
|
||||
{
|
||||
_userData = userData;
|
||||
_tokenData = tokenData;
|
||||
_apiKeyData = apiKeyData;
|
||||
_mailHelper = mailHelper;
|
||||
_configHelper = configHelper;
|
||||
_cache = memoryCache;
|
||||
@ -103,7 +107,7 @@ namespace CarCareTracker.Logic
|
||||
if (!string.IsNullOrWhiteSpace(credentials.Password))
|
||||
{
|
||||
//update password
|
||||
existingUser.Password = GetHash(credentials.Password);
|
||||
existingUser.Password = StaticHelper.GetHash(credentials.Password);
|
||||
}
|
||||
//delete token
|
||||
_tokenData.DeleteToken(existingToken.Id);
|
||||
@ -136,7 +140,7 @@ namespace CarCareTracker.Logic
|
||||
var newUser = new UserData()
|
||||
{
|
||||
UserName = credentials.UserName,
|
||||
Password = GetHash(NewToken()), //generate a password for OpenID User
|
||||
Password = StaticHelper.GetHash(NewToken()), //generate a password for OpenID User
|
||||
EmailAddress = credentials.EmailAddress
|
||||
};
|
||||
var result = _userData.SaveUserRecord(newUser);
|
||||
@ -178,7 +182,7 @@ namespace CarCareTracker.Logic
|
||||
var newUser = new UserData()
|
||||
{
|
||||
UserName = credentials.UserName,
|
||||
Password = GetHash(credentials.Password),
|
||||
Password = StaticHelper.GetHash(credentials.Password),
|
||||
EmailAddress = credentials.EmailAddress
|
||||
};
|
||||
var result = _userData.SaveUserRecord(newUser);
|
||||
@ -235,7 +239,7 @@ namespace CarCareTracker.Logic
|
||||
{
|
||||
return OperationResponse.Failed("Unable to locate user");
|
||||
}
|
||||
existingUser.Password = GetHash(credentials.Password);
|
||||
existingUser.Password = StaticHelper.GetHash(credentials.Password);
|
||||
var result = _userData.SaveUserRecord(existingUser);
|
||||
//delete token
|
||||
_tokenData.DeleteToken(existingToken.Id);
|
||||
@ -262,7 +266,7 @@ namespace CarCareTracker.Logic
|
||||
{
|
||||
//authenticate via DB.
|
||||
var result = _userData.GetUserRecordByUserName(credentials.UserName);
|
||||
if (GetHash(credentials.Password) == result.Password)
|
||||
if (StaticHelper.GetHash(credentials.Password) == result.Password)
|
||||
{
|
||||
result.Password = string.Empty;
|
||||
return result;
|
||||
@ -293,6 +297,26 @@ namespace CarCareTracker.Logic
|
||||
return new UserData();
|
||||
}
|
||||
}
|
||||
public UserData ValidateAPIKey(string apiKey)
|
||||
{
|
||||
var hashedAPIKey = StaticHelper.GetHash(apiKey);
|
||||
var apiKeyUser = _apiKeyData.GetAPIKeyByKey(hashedAPIKey);
|
||||
if (apiKeyUser.UserId != default)
|
||||
{
|
||||
if (apiKeyUser.UserId == -1)
|
||||
{
|
||||
var rootUserData = GetRootUserData(apiKeyUser.Name);
|
||||
return rootUserData;
|
||||
}
|
||||
var result = _userData.GetUserRecordById(apiKeyUser.UserId);
|
||||
if (result.Id != default)
|
||||
{
|
||||
result.Password = string.Empty;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return new UserData();
|
||||
}
|
||||
#region "Admin Functions"
|
||||
public bool MakeUserAdmin(int userId, bool isAdmin)
|
||||
{
|
||||
@ -376,7 +400,7 @@ namespace CarCareTracker.Logic
|
||||
return OperationResponse.Failed("Unable to find user");
|
||||
}
|
||||
var newPassword = Guid.NewGuid().ToString().Substring(0, 8);
|
||||
existingUser.Password = GetHash(newPassword);
|
||||
existingUser.Password = StaticHelper.GetHash(newPassword);
|
||||
var result = _userData.SaveUserRecord(existingUser);
|
||||
if (result)
|
||||
{
|
||||
@ -399,8 +423,8 @@ namespace CarCareTracker.Logic
|
||||
if (existingUserConfig is not null)
|
||||
{
|
||||
//create hashes of the login credentials.
|
||||
var hashedUserName = GetHash(credentials.UserName);
|
||||
var hashedPassword = GetHash(credentials.Password);
|
||||
var hashedUserName = StaticHelper.GetHash(credentials.UserName);
|
||||
var hashedPassword = StaticHelper.GetHash(credentials.Password);
|
||||
//copy over settings that are off limits on the settings page.
|
||||
existingUserConfig.EnableAuth = true;
|
||||
existingUserConfig.UserNameHash = hashedUserName;
|
||||
@ -412,8 +436,8 @@ namespace CarCareTracker.Logic
|
||||
var newUserConfig = new UserConfig()
|
||||
{
|
||||
EnableAuth = true,
|
||||
UserNameHash = GetHash(credentials.UserName),
|
||||
UserPasswordHash = GetHash(credentials.Password)
|
||||
UserNameHash = StaticHelper.GetHash(credentials.UserName),
|
||||
UserPasswordHash = StaticHelper.GetHash(credentials.Password)
|
||||
};
|
||||
File.WriteAllText(StaticHelper.UserConfigPath, JsonSerializer.Serialize(newUserConfig));
|
||||
}
|
||||
@ -438,8 +462,8 @@ namespace CarCareTracker.Logic
|
||||
}
|
||||
private bool UserIsRoot(LoginModel credentials)
|
||||
{
|
||||
var hashedUserName = GetHash(credentials.UserName);
|
||||
var hashedPassword = GetHash(credentials.Password);
|
||||
var hashedUserName = StaticHelper.GetHash(credentials.UserName);
|
||||
var hashedPassword = StaticHelper.GetHash(credentials.Password);
|
||||
return _configHelper.AuthenticateRootUser(hashedUserName, hashedPassword);
|
||||
}
|
||||
private UserData GetRootUserData(string username)
|
||||
@ -454,21 +478,7 @@ namespace CarCareTracker.Logic
|
||||
};
|
||||
}
|
||||
#endregion
|
||||
private static string GetHash(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();
|
||||
}
|
||||
|
||||
private string NewToken()
|
||||
{
|
||||
return Guid.NewGuid().ToString().Substring(0, 8);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using CarCareTracker.External.Interfaces;
|
||||
using CarCareTracker.Helper;
|
||||
using CarCareTracker.Models;
|
||||
|
||||
namespace CarCareTracker.Logic
|
||||
@ -22,18 +23,26 @@ namespace CarCareTracker.Logic
|
||||
bool DeleteUserFromHousehold(int parentUserId, int childUserId);
|
||||
bool DeleteAllHouseholdByParentUserId(int parentUserId);
|
||||
bool DeleteAllHouseholdByChildUserId(int childUserId);
|
||||
OperationResponse CreateAPIKey(int userId, string keyName, List<HouseholdPermission> permisions);
|
||||
List<APIKey> GetAPIKeysByUserId(int userId);
|
||||
List<HouseholdPermission> GetAPIKeyPermissions(string apiKey);
|
||||
bool DeleteAPIKeyByKeyIdAndUserId(int keyId, int userId);
|
||||
bool DeleteAllAPIKeysByUserId(int userId);
|
||||
}
|
||||
public class UserLogic: IUserLogic
|
||||
{
|
||||
private readonly IUserAccessDataAccess _userAccess;
|
||||
private readonly IUserRecordDataAccess _userData;
|
||||
private readonly IUserHouseholdDataAccess _userHouseholdData;
|
||||
private readonly IApiKeyRecordDataAccess _apiKeyData;
|
||||
public UserLogic(IUserAccessDataAccess userAccess,
|
||||
IUserRecordDataAccess userData,
|
||||
IUserHouseholdDataAccess userHouseholdData) {
|
||||
IUserHouseholdDataAccess userHouseholdData,
|
||||
IApiKeyRecordDataAccess apiKeyData) {
|
||||
_userAccess = userAccess;
|
||||
_userData = userData;
|
||||
_userHouseholdData = userHouseholdData;
|
||||
_apiKeyData = apiKeyData;
|
||||
}
|
||||
public List<UserCollaborator> GetCollaboratorsForVehicle(int vehicleId)
|
||||
{
|
||||
@ -287,5 +296,60 @@ namespace CarCareTracker.Logic
|
||||
var result = _userHouseholdData.DeleteAllHouseholdRecordsByChildUserId(childUserId);
|
||||
return result;
|
||||
}
|
||||
public OperationResponse CreateAPIKey(int userId, string keyName, List<HouseholdPermission> permisions)
|
||||
{
|
||||
//check if user already has an API key by that name.
|
||||
var existingApiKeys = _apiKeyData.GetAPIKeyRecordsByUserId(userId);
|
||||
if (existingApiKeys.Any(x=>x.Name.ToLower() == keyName.ToLower()))
|
||||
{
|
||||
return OperationResponse.Failed("An API Key with that name already exists");
|
||||
}
|
||||
//generate key pair
|
||||
var unhashedKey = Guid.NewGuid().ToString().Replace("-", string.Empty);
|
||||
var hashedKey = StaticHelper.GetHash(unhashedKey);
|
||||
var keyToSave = new APIKey
|
||||
{
|
||||
UserId = userId,
|
||||
Name = keyName,
|
||||
Permissions = permisions,
|
||||
Key = hashedKey
|
||||
};
|
||||
var result = _apiKeyData.SaveAPIKey(keyToSave);
|
||||
if (result && keyToSave.Id != default)
|
||||
{
|
||||
return OperationResponse.Succeed("API Key Created", new {apiKey = unhashedKey});
|
||||
}
|
||||
return OperationResponse.Failed("Unable to create API Key");
|
||||
}
|
||||
public List<APIKey> GetAPIKeysByUserId(int userId)
|
||||
{
|
||||
var result = _apiKeyData.GetAPIKeyRecordsByUserId(userId);
|
||||
return result;
|
||||
}
|
||||
public List<HouseholdPermission> GetAPIKeyPermissions(string apiKey)
|
||||
{
|
||||
var hashedKey = StaticHelper.GetHash(apiKey);
|
||||
var existingKey = _apiKeyData.GetAPIKeyByKey(hashedKey);
|
||||
if (existingKey.Id != default)
|
||||
{
|
||||
return existingKey.Permissions;
|
||||
}
|
||||
return new List<HouseholdPermission>();
|
||||
}
|
||||
public bool DeleteAPIKeyByKeyIdAndUserId(int keyId, int userId)
|
||||
{
|
||||
var existingKey = _apiKeyData.GetAPIKeyById(keyId);
|
||||
if (existingKey.Id != default && existingKey.UserId == userId)
|
||||
{
|
||||
var result = _apiKeyData.DeleteAPIKeyById(keyId);
|
||||
return result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public bool DeleteAllAPIKeysByUserId(int userId)
|
||||
{
|
||||
var result = _apiKeyData.DeleteAllAPIKeysByUserId(userId);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +53,13 @@ namespace CarCareTracker.Middleware
|
||||
var access_token = _httpContext.HttpContext.Request.Cookies[StaticHelper.LoginCookieName];
|
||||
//auth using Basic Auth for API.
|
||||
var request_header = _httpContext.HttpContext.Request.Headers["Authorization"];
|
||||
if (string.IsNullOrWhiteSpace(access_token) && string.IsNullOrWhiteSpace(request_header))
|
||||
//auth using API Key for API.
|
||||
var apikey_header = _httpContext.HttpContext.Request.Headers["x-api-key"];
|
||||
if (string.IsNullOrWhiteSpace(apikey_header))
|
||||
{
|
||||
apikey_header = _httpContext.HttpContext.Request.Query["apiKey"];
|
||||
}
|
||||
if (string.IsNullOrWhiteSpace(access_token) && string.IsNullOrWhiteSpace(request_header) && string.IsNullOrWhiteSpace(apikey_header))
|
||||
{
|
||||
return AuthenticateResult.Fail("Cookie is invalid or does not exist.");
|
||||
}
|
||||
@ -146,20 +152,45 @@ namespace CarCareTracker.Middleware
|
||||
{
|
||||
return AuthenticateResult.Fail("Corrupted credentials");
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(apikey_header) && _httpContext.HttpContext.Request.Path.StartsWithSegments("/api"))
|
||||
{
|
||||
//only do API Key Auth for API methods
|
||||
var userData = _loginLogic.ValidateAPIKey(apikey_header);
|
||||
if (userData.Id != default)
|
||||
{
|
||||
var appIdentity = new ClaimsIdentity("Custom");
|
||||
var userIdentity = new List<Claim>
|
||||
{
|
||||
new(ClaimTypes.Name, userData.UserName),
|
||||
new(ClaimTypes.NameIdentifier, userData.Id.ToString()),
|
||||
new(ClaimTypes.Email, userData.EmailAddress),
|
||||
new(ClaimTypes.Role, "APIAuth"),
|
||||
new(ClaimTypes.Role, "APIKeyAuth")
|
||||
};
|
||||
if (userData.IsAdmin)
|
||||
{
|
||||
userIdentity.Add(new(ClaimTypes.Role, nameof(UserData.IsAdmin)));
|
||||
}
|
||||
if (userData.IsRootUser)
|
||||
{
|
||||
userIdentity.Add(new(ClaimTypes.Role, nameof(UserData.IsRootUser)));
|
||||
}
|
||||
appIdentity.AddClaims(userIdentity);
|
||||
AuthenticationTicket ticket = new AuthenticationTicket(new ClaimsPrincipal(appIdentity), Scheme.Name);
|
||||
return AuthenticateResult.Success(ticket);
|
||||
}
|
||||
}
|
||||
return AuthenticateResult.Fail("Invalid credentials");
|
||||
}
|
||||
}
|
||||
protected override Task HandleChallengeAsync(AuthenticationProperties properties)
|
||||
{
|
||||
if (Request.RouteValues.TryGetValue("controller", out object value))
|
||||
if (Request.RouteValues.TryGetValue("controller", out object value) && value?.ToString()?.ToLower() == "api")
|
||||
{
|
||||
if (value.ToString().ToLower() == "api")
|
||||
{
|
||||
Response.StatusCode = 401;
|
||||
Response.Headers.Append("WWW-Authenticate", "Basic");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
Response.StatusCode = 401;
|
||||
Response.Headers.Append("WWW-Authenticate", "Basic");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
if (Request.Path.Value == "/Vehicle/Index" && Request.QueryString.HasValue)
|
||||
{
|
||||
|
||||
11
Models/API/APIKey.cs
Normal file
11
Models/API/APIKey.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace CarCareTracker.Models
|
||||
{
|
||||
public class APIKey
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Key { get; set; }
|
||||
public List<HouseholdPermission> Permissions { get; set; } = new List<HouseholdPermission>();
|
||||
}
|
||||
}
|
||||
@ -62,6 +62,7 @@ if (!string.IsNullOrWhiteSpace(builder.Configuration["POSTGRES_CONNECTION"])){
|
||||
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, PGInspectionRecordTemplateDataAccess>();
|
||||
builder.Services.AddSingleton<IEquipmentRecordDataAccess, PGEquipmentRecordDataAccess>();
|
||||
builder.Services.AddSingleton<IUserHouseholdDataAccess, PGUserHouseholdDataAccess>();
|
||||
builder.Services.AddSingleton<IApiKeyRecordDataAccess, PGApiKeyRecordDataAccess>();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -86,6 +87,7 @@ else
|
||||
builder.Services.AddSingleton<IInspectionRecordTemplateDataAccess, InspectionRecordTemplateDataAccess>();
|
||||
builder.Services.AddSingleton<IEquipmentRecordDataAccess, EquipmentRecordDataAccess>();
|
||||
builder.Services.AddSingleton<IUserHouseholdDataAccess, UserHouseholdDataAccess>();
|
||||
builder.Services.AddSingleton<IApiKeyRecordDataAccess, ApiKeyRecordDataAccess>();
|
||||
}
|
||||
|
||||
//configure helpers
|
||||
|
||||
@ -202,6 +202,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" data-bs-focus="false" id="createApiKeyModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content" id="createApiKeyModalContent">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" data-bs-focus="false" id="userApiKeyModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content" id="userApiKeyModalContent">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stickerPrintContainer hideOnPrint">
|
||||
</div>
|
||||
<script>
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-warning me-auto" onclick="showUserApiKeyModalFromUserModal()">@translator.Translate(userLanguage, "Manage API Keys")</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="hideAccountInformationModal()">@translator.Translate(userLanguage, "Cancel")</button>
|
||||
<button type="button" onclick="validateAndSaveUserAccount()" class="btn btn-primary">@translator.Translate(userLanguage, "Update")</button>
|
||||
</div>
|
||||
30
Views/Home/_CreateApiKeyModal.cshtml
Normal file
30
Views/Home/_CreateApiKeyModal.cshtml
Normal file
@ -0,0 +1,30 @@
|
||||
@using CarCareTracker.Helper
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="createApiKeyLabel">@translator.Translate(userLanguage, "Create API Key")</h5>
|
||||
<button type="button" class="btn-close" onclick="hideCreateApiKeyModal()" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body" onkeydown="handleEnter(this)">
|
||||
<form class="form-inline">
|
||||
<div class="form-group">
|
||||
<input type="text" id="workAroundInput" style="height:0px; width:0px; display:none;">
|
||||
<label for="inputApiKeyName">@translator.Translate(userLanguage, "Name")</label>
|
||||
<input type="text" id="inputApiKeyName" class="form-control" placeholder="@translator.Translate(userLanguage, "Name for API Key")">
|
||||
<label for="inputApiKeyRole">@translator.Translate(userLanguage, "Role")</label>
|
||||
<select class="form-select" id="inputApiKeyRole">
|
||||
<!option value="viewer">@translator.Translate(userLanguage, "Viewer")</!option>
|
||||
<!option value="editor">@translator.Translate(userLanguage, "Editor")</!option>
|
||||
<!option value="manager">@translator.Translate(userLanguage, "Manager")</!option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" onclick="hideCreateApiKeyModal()">@translator.Translate(userLanguage, "Cancel")</button>
|
||||
<button type="button" onclick="createApiKey()" class="btn btn-primary">@translator.Translate(userLanguage, "Create")</button>
|
||||
</div>
|
||||
@ -26,6 +26,7 @@
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-warning me-auto" onclick="showUserApiKeyModalFromUserModal()">@translator.Translate(userLanguage, "Manage API Keys")</button>
|
||||
<button type="button" class="btn btn-secondary" onclick="hideAccountInformationModal()">@translator.Translate(userLanguage, "Cancel")</button>
|
||||
<button type="button" onclick="validateAndSaveRootUserAccount()" class="btn btn-primary">@translator.Translate(userLanguage, "Update")</button>
|
||||
</div>
|
||||
60
Views/Home/_UserApiKeysModal.cshtml
Normal file
60
Views/Home/_UserApiKeysModal.cshtml
Normal file
@ -0,0 +1,60 @@
|
||||
@using CarCareTracker.Helper
|
||||
@inject IConfigHelper config
|
||||
@inject ITranslationHelper translator
|
||||
@model List<APIKey>
|
||||
@{
|
||||
var userConfig = config.GetUserConfig(User);
|
||||
var userLanguage = userConfig.UserLanguage;
|
||||
}
|
||||
<div class="modal-header">
|
||||
<div class="d-flex align-items-center">
|
||||
<h5 class="modal-title">@translator.Translate(userLanguage, "Manage API Keys")</h5>
|
||||
</div>
|
||||
<div class="d-flex align-items-center ms-auto">
|
||||
<button onclick="showCreateApiKeyModal()" class="btn btn-primary">
|
||||
<i class="bi bi-pencil-square me-2"></i>@translator.Translate(userLanguage, "Add API Key")
|
||||
</button>
|
||||
<button type="button" class="btn-close ms-2" onclick="hideUserApiKeyModal()" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
@if (Model.Any())
|
||||
{
|
||||
<div style="max-height:30vh; overflow-y:auto;">
|
||||
<table class="table table-hover">
|
||||
<thead class="sticky-top">
|
||||
<tr class="d-flex">
|
||||
<th scope="col" class="col-6">@translator.Translate(userLanguage, "Name")</th>
|
||||
<th scope="col" class="col-4">@translator.Translate(userLanguage, "Role")</th>
|
||||
<th scope="col" class="col-2">@translator.Translate(userLanguage, "Remove")</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (APIKey viewModel in Model)
|
||||
{
|
||||
<tr class="d-flex">
|
||||
<td class="col-6">@viewModel.Name</td>
|
||||
<td class="col-4">
|
||||
@if (!viewModel.Permissions.Contains(HouseholdPermission.Edit) && !viewModel.Permissions.Contains(HouseholdPermission.Delete))
|
||||
{
|
||||
@translator.Translate(userLanguage, "Viewer")
|
||||
}
|
||||
else if (viewModel.Permissions.Contains(HouseholdPermission.Edit) && !viewModel.Permissions.Contains(HouseholdPermission.Delete))
|
||||
{
|
||||
@translator.Translate(userLanguage, "Editor")
|
||||
}
|
||||
else if (viewModel.Permissions.Contains(HouseholdPermission.Edit) && viewModel.Permissions.Contains(HouseholdPermission.Delete))
|
||||
{
|
||||
@translator.Translate(userLanguage, "Manager")
|
||||
}
|
||||
</td>
|
||||
<td class="col-2">
|
||||
<button type="button" class="btn btn-danger" onclick="deleteApiKey(@viewModel.Id)"><i class="bi bi-trash"></i></button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
File diff suppressed because one or more lines are too long
@ -661,6 +661,87 @@ function addUserToHousehold() {
|
||||
});
|
||||
}
|
||||
|
||||
function showUserApiKeyModalFromUserModal() {
|
||||
$('#accountInformationModal').modal('hide');
|
||||
showUserApiKeyModal();
|
||||
}
|
||||
|
||||
function showUserApiKeyModal() {
|
||||
$.get('/Home/GetUserAPIKeys', function (data) {
|
||||
$('#userApiKeyModalContent').html(data);
|
||||
$("#userApiKeyModal").modal('show');
|
||||
});
|
||||
}
|
||||
|
||||
function hideUserApiKeyModal() {
|
||||
$('#userApiKeyModal').modal('hide');
|
||||
}
|
||||
|
||||
function showCreateApiKeyModal() {
|
||||
$.get('/Home/GetCreateApiKeyModal', function (data) {
|
||||
$('#createApiKeyModalContent').html(data);
|
||||
hideUserApiKeyModal();
|
||||
$("#createApiKeyModal").modal('show');
|
||||
});
|
||||
}
|
||||
|
||||
function hideCreateApiKeyModal() {
|
||||
$("#createApiKeyModal").modal('hide');
|
||||
showUserApiKeyModal();
|
||||
}
|
||||
|
||||
function createApiKey() {
|
||||
let apiKeyName = $("#inputApiKeyName").val();
|
||||
let apiKeyRole = $("#inputApiKeyRole").val();
|
||||
//validate
|
||||
if (apiKeyName.trim() == '') {
|
||||
$("#inputApiKeyName").addClass('is-invalid');
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$("#inputApiKeyName").removeClass('is-invalid');
|
||||
}
|
||||
let permissions = [];
|
||||
switch (apiKeyRole) {
|
||||
case 'editor':
|
||||
permissions.push('Edit');
|
||||
break;
|
||||
case 'manager':
|
||||
permissions.push('Edit');
|
||||
permissions.push('Delete');
|
||||
break;
|
||||
}
|
||||
$.post('/Home/CreateAPIKeyForUser', { keyName: apiKeyName, permissions: permissions }, function (data) {
|
||||
if (data.success) {
|
||||
$("#createApiKeyModal").modal('hide');
|
||||
showUserApiKeyModal();
|
||||
Swal.fire({
|
||||
title: data.message,
|
||||
icon: 'success',
|
||||
html: `<div class="input-group"><input type="text" class="form-control" readonly value="${data.additionalData.apiKey}"><div class="input-group-text"><button type="button" class="btn btn-sm text-secondary password-visible-button" onclick="copyApiKey(this)"><i class="bi bi-copy"></i></button></div></div>`
|
||||
})
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
function copyApiKey(elem) {
|
||||
let textToCopy = $(elem).parent().siblings("input").val();
|
||||
navigator.clipboard.writeText(textToCopy);
|
||||
Swal.showValidationMessage(`API Key Copied to Clipboard`);
|
||||
}
|
||||
|
||||
function deleteApiKey(keyId) {
|
||||
$.post('/Home/DeleteAPIKeyForUser', { keyId: keyId }, function (data) {
|
||||
if (data.success) {
|
||||
successToast(data.message);
|
||||
showUserApiKeyModal();
|
||||
} else {
|
||||
errorToast(data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function showAccountInformationModal() {
|
||||
$.get('/Home/GetUserAccountInformationModal', function (data) {
|
||||
$('#accountInformationModalContent').html(data);
|
||||
|
||||
@ -74,6 +74,11 @@ function executeAPIEndpoint(sender) {
|
||||
if (hasError) {
|
||||
return;
|
||||
}
|
||||
let currentParams = new URLSearchParams(window.location.search);
|
||||
let apiKey = currentParams.get('apiKey');
|
||||
if (apiKey != null) {
|
||||
apiPath = `${apiPath}?apiKey=${apiKey}`;
|
||||
}
|
||||
let ajaxConfig = {
|
||||
url: apiPath,
|
||||
type: apiMethodType,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user