diff --git a/Controllers/Error.cs b/Controllers/Error.cs new file mode 100644 index 0000000..5f72cb0 --- /dev/null +++ b/Controllers/Error.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CarCareTracker.Controllers +{ + public class ErrorController : Controller + { + public IActionResult Unauthorized() + { + return View("401"); + } + } +} diff --git a/Controllers/VehicleController.cs b/Controllers/VehicleController.cs index b6590e3..cbb8392 100644 --- a/Controllers/VehicleController.cs +++ b/Controllers/VehicleController.cs @@ -9,6 +9,7 @@ using Microsoft.AspNetCore.Authorization; using CarCareTracker.MapProfile; using System.Security.Claims; using CarCareTracker.Logic; +using CarCareTracker.Filter; namespace CarCareTracker.Controllers { @@ -72,13 +73,10 @@ namespace CarCareTracker.Controllers { return int.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)); } + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult Index(int vehicleId) { - if (!_userLogic.UserCanAccessVehicle(GetUserID(), vehicleId)) - { - return View("401"); - } var data = _dataAccess.GetVehicleById(vehicleId); return View(data); } @@ -87,13 +85,10 @@ namespace CarCareTracker.Controllers { return PartialView("_VehicleModal", new Vehicle()); } + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetEditVehiclePartialViewById(int vehicleId) { - if (!_userLogic.UserCanEditVehicle(GetUserID(), vehicleId)) - { - return View("401"); - } var data = _dataAccess.GetVehicleById(vehicleId); return PartialView("_VehicleModal", data); } @@ -116,7 +111,7 @@ namespace CarCareTracker.Controllers var result = _dataAccess.SaveVehicle(vehicleInput); if (isNewAddition) { - _userLogic.AddUserAccessToVehicle(GetUserID(), vehicleInput.Id, UserAccessType.Editor); + _userLogic.AddUserAccessToVehicle(GetUserID(), vehicleInput.Id); } return Json(result); } @@ -126,6 +121,7 @@ namespace CarCareTracker.Controllers return Json(false); } } + [TypeFilter(typeof(CollaboratorFilter))] [HttpPost] public IActionResult DeleteVehicle(int vehicleId) { @@ -147,6 +143,7 @@ namespace CarCareTracker.Controllers { return PartialView("_BulkDataImporter", mode); } + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult ExportFromVehicleToCsv(int vehicleId, ImportMode mode) { @@ -250,6 +247,7 @@ namespace CarCareTracker.Controllers } return Json(false); } + [TypeFilter(typeof(CollaboratorFilter))] [HttpPost] public IActionResult ImportToVehicleIdFromCsv(int vehicleId, ImportMode mode, string fileName) { @@ -383,6 +381,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Gas Records" + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetGasRecordsByVehicleId(int vehicleId) { @@ -449,6 +448,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Service Records" + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetServiceRecordsByVehicleId(int vehicleId) { @@ -502,6 +502,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Collision Records" + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetCollisionRecordsByVehicleId(int vehicleId) { @@ -555,6 +556,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Tax Records" + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetTaxRecordsByVehicleId(int vehicleId) { @@ -607,6 +609,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Reports" + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetReportPartialView(int vehicleId) { @@ -677,6 +680,14 @@ namespace CarCareTracker.Controllers viewModel.Collaborators = collaborators; return PartialView("_Report", viewModel); } + [TypeFilter(typeof(CollaboratorFilter))] + [HttpGet] + public IActionResult GetCollaboratorsForVehicle(int vehicleId) + { + var result = _userLogic.GetCollaboratorsForVehicle(vehicleId); + return PartialView("_Collaborators", result); + } + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetCostMakeUpForVehicle(int vehicleId, int year = 0) { @@ -703,6 +714,7 @@ namespace CarCareTracker.Controllers }; return PartialView("_CostMakeUpReport", viewModel); } + [TypeFilter(typeof(CollaboratorFilter))] public IActionResult GetReminderMakeUpByVehicle(int vehicleId, int daysToAdd) { var reminders = GetRemindersAndUrgency(vehicleId, DateTime.Now.AddDays(daysToAdd)); @@ -715,6 +727,7 @@ namespace CarCareTracker.Controllers }; return PartialView("_ReminderMakeUpReport", viewModel); } + [TypeFilter(typeof(CollaboratorFilter))] public IActionResult GetVehicleHistory(int vehicleId) { var vehicleHistory = new VehicleHistoryViewModel(); @@ -778,6 +791,7 @@ namespace CarCareTracker.Controllers vehicleHistory.VehicleHistory = reportData.OrderBy(x=>x.Date).ThenBy(x=>x.Odometer).ToList(); return PartialView("_VehicleHistory", vehicleHistory); } + [TypeFilter(typeof(CollaboratorFilter))] [HttpPost] public IActionResult GetCostByMonthByVehicle(int vehicleId, List selectedMetrics, int year = 0) { @@ -816,6 +830,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Reminders" + [TypeFilter(typeof(CollaboratorFilter))] private int GetMaxMileage(int vehicleId) { var numbersArray = new List(); @@ -848,6 +863,7 @@ namespace CarCareTracker.Controllers List results = _reminderHelper.GetReminderRecordViewModels(reminders, currentMileage, dateCompare); return results; } + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetVehicleHaveUrgentOrPastDueReminders(int vehicleId) { @@ -858,6 +874,7 @@ namespace CarCareTracker.Controllers } return Json(false); } + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetReminderRecordsByVehicleId(int vehicleId) { @@ -908,6 +925,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Upgrade Records" + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetUpgradeRecordsByVehicleId(int vehicleId) { @@ -961,6 +979,7 @@ namespace CarCareTracker.Controllers } #endregion #region "Notes" + [TypeFilter(typeof(CollaboratorFilter))] [HttpGet] public IActionResult GetNotesByVehicleId(int vehicleId) { diff --git a/Enum/UserAccessType.cs b/Enum/UserAccessType.cs deleted file mode 100644 index 4f61d58..0000000 --- a/Enum/UserAccessType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace CarCareTracker.Models -{ - public enum UserAccessType - { - Viewer = 0, - Editor = 1 - } -} diff --git a/Filter/CollaboratorFilter.cs b/Filter/CollaboratorFilter.cs new file mode 100644 index 0000000..550c458 --- /dev/null +++ b/Filter/CollaboratorFilter.cs @@ -0,0 +1,28 @@ +using CarCareTracker.Logic; +using CarCareTracker.Models; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using System.Security.Claims; + +namespace CarCareTracker.Filter +{ + public class CollaboratorFilter: ActionFilterAttribute + { + private readonly IUserLogic _userLogic; + public CollaboratorFilter(IUserLogic userLogic) { + _userLogic = userLogic; + } + public override void OnActionExecuting(ActionExecutingContext filterContext) + { + if (!filterContext.HttpContext.User.IsInRole(nameof(UserData.IsRootUser))) + { + var vehicleId = int.Parse(filterContext.ActionArguments["vehicleId"].ToString()); + var userId = int.Parse(filterContext.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier)); + if (!_userLogic.UserCanEditVehicle(userId, vehicleId)) + { + filterContext.Result = new RedirectResult("/Error/Unauthorized"); + } + } + } + } +} diff --git a/Logic/UserLogic.cs b/Logic/UserLogic.cs index 187904a..a5b3889 100644 --- a/Logic/UserLogic.cs +++ b/Logic/UserLogic.cs @@ -1,4 +1,5 @@ using CarCareTracker.External.Interfaces; +using CarCareTracker.Helper; using CarCareTracker.Models; using Microsoft.AspNetCore.Mvc.Formatters; @@ -7,7 +8,8 @@ namespace CarCareTracker.Logic public interface IUserLogic { List GetCollaboratorsForVehicle(int vehicleId); - bool AddUserAccessToVehicle(int userId, int vehicleId, UserAccessType accessType); + bool AddUserAccessToVehicle(int userId, int vehicleId); + OperationResponse AddCollaboratorToVehicle(int vehicleId, string username); List FilterUserVehicles(List results, int userId); bool UserCanAccessVehicle(int userId, int vehicleId); bool UserCanEditVehicle(int userId, int vehicleId); @@ -33,21 +35,36 @@ namespace CarCareTracker.Logic var userCollaborator = new UserCollaborator { UserName = _userData.GetUserRecordById(userAccess.Id.UserId).UserName, - AccessType = userAccess.AccessType, UserVehicle = userAccess.Id }; convertedResult.Add(userCollaborator); } return convertedResult; } - public bool AddUserAccessToVehicle(int userId, int vehicleId, UserAccessType accessType) + public OperationResponse AddCollaboratorToVehicle(int vehicleId, string username) + { + //try to find existing user. + var existingUser = _userData.GetUserRecordByUserName(username); + if (existingUser.Id != default) + { + //user exists. + var result = AddUserAccessToVehicle(existingUser.Id, vehicleId); + if (result) + { + return new OperationResponse { Success = true, Message = "Collaborator Added" }; + } + return new OperationResponse { Success = false, Message = StaticHelper.GenericErrorMessage }; + } + return new OperationResponse { Success = false, Message = $"Unable to find user {username} in the system" }; + } + public bool AddUserAccessToVehicle(int userId, int vehicleId) { if (userId == -1) { return true; } var userVehicle = new UserVehicle { UserId = userId, VehicleId = vehicleId }; - var userAccess = new UserAccess { Id = userVehicle, AccessType = accessType }; + var userAccess = new UserAccess { Id = userVehicle }; var result = _userAccess.SaveUserAccess(userAccess); return result; } @@ -89,7 +106,7 @@ namespace CarCareTracker.Logic return true; } var userAccess = _userAccess.GetUserAccessByVehicleAndUserId(userId, vehicleId); - if (userAccess != null && userAccess.AccessType == UserAccessType.Editor) + if (userAccess != null) { return true; } diff --git a/Models/User/UserAccess.cs b/Models/User/UserAccess.cs index 960cde7..039da7c 100644 --- a/Models/User/UserAccess.cs +++ b/Models/User/UserAccess.cs @@ -8,6 +8,5 @@ public class UserAccess { public UserVehicle Id { get; set; } - public UserAccessType AccessType { get; set; } } } diff --git a/Models/User/UserCollaborator.cs b/Models/User/UserCollaborator.cs index d46c88e..0d050d0 100644 --- a/Models/User/UserCollaborator.cs +++ b/Models/User/UserCollaborator.cs @@ -3,7 +3,6 @@ public class UserCollaborator { public string UserName { get; set; } - public UserAccessType AccessType { get; set; } public UserVehicle UserVehicle { get; set; } } } diff --git a/Views/Vehicle/_Collaborators.cshtml b/Views/Vehicle/_Collaborators.cshtml index abe4f93..ef793e9 100644 --- a/Views/Vehicle/_Collaborators.cshtml +++ b/Views/Vehicle/_Collaborators.cshtml @@ -1,4 +1,9 @@ @model List +
+
+ Collaborators +
+
    @foreach (UserCollaborator user in Model) {