diff --git a/Server/Controllers/DriverController.cs b/Server/Controllers/DriverController.cs index e52a7e4..90cd044 100644 --- a/Server/Controllers/DriverController.cs +++ b/Server/Controllers/DriverController.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Server.Services; @@ -6,6 +7,7 @@ using SharedModels.QueryParameters.Objects; namespace Server.Controllers; +[Authorize] [Route("api/drivers")] [ApiController] public class DriverController : ControllerBase @@ -17,6 +19,7 @@ public class DriverController : ControllerBase _driverManagementService = driverManagementService; } + [Authorize(Policy = "CompanyAccess")] [HttpPost] public async Task AddDriver(CreateDriverDto Driver) { @@ -30,6 +33,7 @@ public class DriverController : ControllerBase return CreatedAtAction(nameof(GetDriver), new {id = result.driver.Id}, result.driver); } + [Authorize(Policy = "CompanyAccess")] [HttpGet] public async Task GetDrivers([FromQuery] CompanyDriverParameters parameters) { @@ -45,6 +49,7 @@ public class DriverController : ControllerBase return Ok(result.drivers); } + [Authorize(Policy = "CompanyAccess")] [HttpGet("{id}")] public async Task GetDriver(string id, [FromQuery] string? fields) { @@ -58,6 +63,7 @@ public class DriverController : ControllerBase return Ok(result.driver); } + [Authorize(Policy = "CompanyAccess")] [HttpPut("{id}")] public async Task UpdateDriver(string id, UpdateDriverDto driver) { @@ -71,6 +77,7 @@ public class DriverController : ControllerBase return Ok(result.driver); } + [Authorize(Policy = "CompanyAccess")] [HttpDelete("{id}")] public async Task DeleteDriver(string id) { diff --git a/Server/Controllers/ReportController.cs b/Server/Controllers/ReportController.cs index ab3d511..d68028e 100644 --- a/Server/Controllers/ReportController.cs +++ b/Server/Controllers/ReportController.cs @@ -1,8 +1,10 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Server.Services; namespace Server.Controllers; +[Authorize] [Route("api/[controller]")] [ApiController] public class ReportController : ControllerBase @@ -21,38 +23,41 @@ public class ReportController : ControllerBase if (!result.IsSucceed) { - return BadRequest(result.actionResult); + return result.actionResult; } return File(result.ticketPdf, "application/pdf", $"ticket.pdf"); } + [Authorize(Policy = "CompanyAccess")] [HttpGet("pdf/company")] - public async Task GetCompanyReportPdf(int companyId, DateTime fromDate, DateTime toDate) + public async Task GetCompanyReportPdf(int? companyId, DateTime fromDate, DateTime toDate) { var result = await _reportService.GetCompanyReportPdf(companyId, fromDate, toDate); if (!result.isSucceed) { - return BadRequest(result.actionResult); + return result.actionResult; } return File(result.reportPdf, "application/pdf", $"report.pdf"); } + [Authorize(Policy = "CompanyAccess")] [HttpGet("raw/company")] - public async Task GetCompanyReportRaw(int companyId, DateTime fromDate, DateTime toDate) + public async Task GetCompanyReportRaw(int? companyId, DateTime fromDate, DateTime toDate) { var result = await _reportService.GetCompanyReportRaw(companyId, fromDate, toDate); if (!result.isSucceed) { - return BadRequest(result.actionResult); + return result.actionResult; } return Ok(result.statistics); } + [Authorize(Policy = "AdministratorAccess")] [HttpGet("raw/admin")] public async Task GetAdminReportRaw(DateTime fromDate, DateTime toDate) { @@ -60,7 +65,7 @@ public class ReportController : ControllerBase if (!result.isSucceed) { - return BadRequest(result.actionResult); + return result.actionResult; } return Ok(result.statistics); diff --git a/Server/Controllers/ReviewController.cs b/Server/Controllers/ReviewController.cs index 0dc0250..bec5681 100644 --- a/Server/Controllers/ReviewController.cs +++ b/Server/Controllers/ReviewController.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Server.Services; @@ -6,6 +7,7 @@ using SharedModels.QueryParameters.Objects; namespace Server.Controllers; +[Authorize] [Route("api/reviews")] [ApiController] public class ReviewController : ControllerBase diff --git a/Server/Controllers/RouteController.cs b/Server/Controllers/RouteController.cs index c899e76..58ac123 100644 --- a/Server/Controllers/RouteController.cs +++ b/Server/Controllers/RouteController.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Server.Services; @@ -6,6 +7,7 @@ using SharedModels.QueryParameters.Objects; namespace Server.Controllers; +[Authorize] [Route("api/routes")] [ApiController] public class RouteController : ControllerBase @@ -17,6 +19,7 @@ public class RouteController : ControllerBase _routeManagementService = routeManagementService; } + [Authorize(Policy = "CompanyAccess")] [HttpPost] public async Task AddRoute(CreateRouteDto route) { @@ -30,6 +33,7 @@ public class RouteController : ControllerBase return CreatedAtAction(nameof(GetRoute), new {id = result.route.Id}, result.route); } + [Authorize(Policy = "CompanyAccess")] [HttpPost("withAddresses")] public async Task AddRouteWithAddresses(CreateRouteWithAddressesDto route) { @@ -43,6 +47,7 @@ public class RouteController : ControllerBase return CreatedAtAction(nameof(GetRoute), new {id = result.route.Id}, result.route); } + [Authorize(Policy = "DriverAccess")] [HttpGet] public async Task GetRoutes([FromQuery] RouteParameters parameters) { @@ -58,6 +63,7 @@ public class RouteController : ControllerBase return Ok(result.routes); } + [Authorize(Policy = "DriverAccess")] [HttpGet("withAddresses")] public async Task GetRouteWithAddresses([FromQuery] RouteWithAddressesParameters parameters) { @@ -73,6 +79,7 @@ public class RouteController : ControllerBase return Ok(result.routes); } + [Authorize(Policy = "DriverAccess")] [HttpGet("{id}")] public async Task GetRoute(int id, [FromQuery] string? fields) { @@ -91,6 +98,7 @@ public class RouteController : ControllerBase return Ok(result.route); } + [Authorize(Policy = "DriverAccess")] [HttpGet("withAddresses/{id}")] public async Task GetRouteWithAddresses(int id, [FromQuery] string? fields) { @@ -109,6 +117,7 @@ public class RouteController : ControllerBase return Ok(result.route); } + [Authorize(Policy = "CompanyAccess")] [HttpPut("{id}")] public async Task UpdateRoute(int id, UpdateRouteDto route) { @@ -127,6 +136,7 @@ public class RouteController : ControllerBase return Ok(result.route); } + [Authorize(Policy = "CompanyAccess")] [HttpDelete("{id}")] public async Task DeleteRoute(int id) { diff --git a/Server/Controllers/StatisticsController.cs b/Server/Controllers/StatisticsController.cs index 74dcfba..b424d8b 100644 --- a/Server/Controllers/StatisticsController.cs +++ b/Server/Controllers/StatisticsController.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Server.Services; @@ -5,6 +6,7 @@ using SharedModels.QueryParameters.Statistics; namespace Server.Controllers; +[Authorize] [Route("api/[controller]")] [ApiController] public class StatisticsController : ControllerBase @@ -16,6 +18,7 @@ public class StatisticsController : ControllerBase _statisticsService = statisticsService; } + [Authorize(Policy = "CompanyAccess")] [HttpGet("routes")] public async Task GetPopularRoutes([FromQuery] PopularRoutesParameters parameters) { @@ -31,6 +34,7 @@ public class StatisticsController : ControllerBase return Ok(result.route); } + [Authorize(Policy = "AdministratorAccess")] [HttpGet("users")] public async Task GetEngagedUsers([FromQuery] EngagedUserParameters parameters) @@ -47,6 +51,7 @@ public class StatisticsController : ControllerBase return Ok(result.users); } + [Authorize(Policy = "AdministratorAccess")] [HttpGet("companies")] public async Task GetPopularCompanies([FromQuery] PopularCompanyParameters parameters) { diff --git a/Server/Controllers/TicketGroupController.cs b/Server/Controllers/TicketGroupController.cs index 2e9b8a8..60ac118 100644 --- a/Server/Controllers/TicketGroupController.cs +++ b/Server/Controllers/TicketGroupController.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Server.Services; @@ -6,6 +7,7 @@ using SharedModels.QueryParameters.Objects; namespace Server.Controllers; +[Authorize] [Route("api/ticketGroups")] [ApiController] public class TicketGroupController : ControllerBase @@ -17,6 +19,7 @@ public class TicketGroupController : ControllerBase _ticketGroupManagementService = ticketGroupManagementService; } + [Authorize(Policy = "AdministratorAccess")] [HttpPost] public async Task AddTicketGroup(CreateTicketGroupDto ticketGroup) { @@ -30,6 +33,7 @@ public class TicketGroupController : ControllerBase return CreatedAtAction(nameof(GetTicketGroup), new {id = result.ticketGroup.Id}, result.ticketGroup); } + [Authorize(Policy = "AdministratorAccess")] [HttpPost("withTickets")] public async Task AddTicketGroupWithTickets(CreateTicketGroupWithTicketsDto ticketGroup) { @@ -99,6 +103,7 @@ public class TicketGroupController : ControllerBase return Ok(result.ticketGroup); } + [Authorize(Policy = "AdministratorAccess")] [HttpPut("{id}")] public async Task UpdateTicketGroup(int id, UpdateTicketGroupDto ticketGroup) { @@ -117,6 +122,7 @@ public class TicketGroupController : ControllerBase return Ok(result.ticketGroup); } + [Authorize(Policy = "AdministratorAccess")] [HttpDelete("{id}")] public async Task DeleteTicketGroup(int id) { @@ -129,5 +135,4 @@ public class TicketGroupController : ControllerBase return NoContent(); } -} - +} \ No newline at end of file diff --git a/Server/Controllers/VehicleController.cs b/Server/Controllers/VehicleController.cs index 3e93887..59a5f9e 100644 --- a/Server/Controllers/VehicleController.cs +++ b/Server/Controllers/VehicleController.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Server.Services; @@ -17,6 +18,7 @@ public class VehicleController : ControllerBase _vehicleManagementService = vehicleManagementService; } + [Authorize(Policy = "CompanyAccess")] [HttpPost] public async Task AddVehicle(CreateVehicleDto vehicle) { @@ -30,6 +32,7 @@ public class VehicleController : ControllerBase return CreatedAtAction(nameof(GetVehicle), new {id = result.vehicle.Id}, result.vehicle); } + [Authorize(Policy = "CompanyAccess")] [HttpGet] public async Task GetVehicles([FromQuery] VehicleParameters parameters) { @@ -45,6 +48,7 @@ public class VehicleController : ControllerBase return Ok(result.vehicles); } + [Authorize(Policy = "DriverAccess")] [HttpGet("{id}")] public async Task GetVehicle(int id, [FromQuery] string? fields) { @@ -58,6 +62,7 @@ public class VehicleController : ControllerBase return Ok(result.vehicle); } + [Authorize(Policy = "CompanyAccess")] [HttpPut("{id}")] public async Task UpdateVehicle(int id, UpdateVehicleDto vehicle) { @@ -71,6 +76,7 @@ public class VehicleController : ControllerBase return Ok(result.vehicle); } + [Authorize(Policy = "CompanyAccess")] [HttpDelete("{id}")] public async Task DeleteVehicle(int id) { diff --git a/Server/Controllers/VehicleEnrollmentController.cs b/Server/Controllers/VehicleEnrollmentController.cs index 0b3765e..b3da24d 100644 --- a/Server/Controllers/VehicleEnrollmentController.cs +++ b/Server/Controllers/VehicleEnrollmentController.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Server.Services; @@ -6,7 +7,7 @@ using SharedModels.QueryParameters.Objects; namespace Server.Controllers; - +[Authorize] [Route("api/vehicleEnrollments")] [ApiController] public class VehicleEnrollmentController : ControllerBase @@ -18,6 +19,7 @@ public class VehicleEnrollmentController : ControllerBase _vehicleEnrollmentManagementService = vehicleEnrollmentManagementService; } + [Authorize(Policy = "CompanyAccess")] [HttpPost] public async Task AddEnrollment(CreateVehicleEnrollmentDto enrollment) { @@ -31,6 +33,7 @@ public class VehicleEnrollmentController : ControllerBase return CreatedAtAction(nameof(GetEnrollment), new {id = result.enrollment.Id}, result.enrollment); } + [Authorize(Policy = "CompanyAccess")] [HttpPost("withDetails")] public async Task AddEnrollmentWithDetails(CreateVehicleEnrollmentWithDetailsDto enrollment) { @@ -44,6 +47,7 @@ public class VehicleEnrollmentController : ControllerBase return CreatedAtAction(nameof(GetEnrollment), new {id = result.enrollment.Id}, result.enrollment); } + [Authorize(Policy = "DriverAccess")] [HttpGet] public async Task GetEnrollments([FromQuery] VehicleEnrollmentParameters parameters) { @@ -59,6 +63,7 @@ public class VehicleEnrollmentController : ControllerBase return Ok(result.enrollments); } + [Authorize(Policy = "DriverAccess")] [HttpGet("withDetails")] public async Task GetEnrollments([FromQuery] VehicleEnrollmentWithDetailsParameters parameters) { @@ -74,6 +79,7 @@ public class VehicleEnrollmentController : ControllerBase return Ok(result.enrollments); } + [Authorize(Policy = "DriverAccess")] [HttpGet("{id}")] public async Task GetEnrollment(int id, [FromQuery] string? fields) { @@ -87,6 +93,7 @@ public class VehicleEnrollmentController : ControllerBase return Ok(result.enrollment); } + [Authorize(Policy = "CompanyAccess")] [HttpGet("withDetails/{id}")] public async Task GetEnrollmentWithDetails(int id, [FromQuery] string? fields) { @@ -100,6 +107,7 @@ public class VehicleEnrollmentController : ControllerBase return Ok(result.enrollment); } + [Authorize(Policy = "CompanyAccess")] [HttpPut("{id}")] public async Task UpdateVehicle(int id, UpdateVehicleEnrollmentDto enrollment) { @@ -113,6 +121,7 @@ public class VehicleEnrollmentController : ControllerBase return Ok(result.enrollment); } + [Authorize(Policy = "CompanyAccess")] [HttpDelete("{id}")] public async Task DeleteEnrollment(int id) { diff --git a/Server/Program.cs b/Server/Program.cs index 4c879c1..cc3e3d8 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -108,6 +108,8 @@ services.AddAutoMapper(typeof(MapperInitializer)); services.AddScoped(); services.AddScoped(); +services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/Server/Services/DriverManagementService.cs b/Server/Services/DriverManagementService.cs index fc0ee58..466f662 100644 --- a/Server/Services/DriverManagementService.cs +++ b/Server/Services/DriverManagementService.cs @@ -9,6 +9,7 @@ using Server.Models; using SharedModels.DataTransferObjects; using SharedModels.QueryParameters; using SharedModels.QueryParameters.Objects; +using Utils; namespace Server.Services; @@ -21,11 +22,12 @@ public class DriverManagementService : IDriverManagementService private readonly ISortHelper _userSortHelper; private readonly IDataShaper _userDataShaper; private readonly IPager _pager; + private readonly ISessionUserService _sessionUserService; public DriverManagementService(IUserManagementService userManagementService, IMapper mapper, UserManager userManager, ApplicationDbContext dbContext, ISortHelper userSortHelper, IDataShaper userDataShaper, - IPager pager) + IPager pager, ISessionUserService sessionUserService) { _userManagementService = userManagementService; _userManager = userManager; @@ -33,11 +35,30 @@ public class DriverManagementService : IDriverManagementService _userSortHelper = userSortHelper; _userDataShaper = userDataShaper; _pager = pager; + _sessionUserService = sessionUserService; _mapper = mapper; } public async Task<(bool isSucceeded, IActionResult? actionResult, DriverDto driver)> AddDriver(CreateDriverDto createDriverDto) { + + if (_sessionUserService.GetAuthUserRole() == Identity.Roles.Administrator.ToString()) + { + if (createDriverDto.CompanyId == null) + { + return (false, new BadRequestObjectResult("CompanyId must have a value"), null!); + } + } + else + { + var isAuthUserCompanyOwnerResult = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!isAuthUserCompanyOwnerResult.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!); + } + createDriverDto.CompanyId = isAuthUserCompanyOwnerResult.companyId; + } + var createUserDto = _mapper.Map(createDriverDto); createUserDto.Roles = new List { "Driver" }; @@ -50,8 +71,8 @@ public class DriverManagementService : IDriverManagementService return (false, result.actionResult, null); } - var driverDto = _mapper.Map(createUserDto); - _dbContext.CompanyDrivers.Add(new CompanyDriver { CompanyId = createDriverDto.CompanyId, DriverId = driverDto.Id }); + var driverDto = _mapper.Map(result.user); + _dbContext.CompanyDrivers.Add(new CompanyDriver { CompanyId = (int) createDriverDto.CompanyId, DriverId = driverDto.Id }); await _dbContext.SaveChangesAsync(); driverDto.Roles = result.user.Roles; @@ -63,6 +84,22 @@ public class DriverManagementService : IDriverManagementService { var dbUsers = _userManager.Users.Include(u => u.Employer) .Where(u => u.Employer != null).AsQueryable(); + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!, null!); + } + + dbUsers = dbUsers.Where(u => u.Employer.CompanyId == result.companyId); + } + + if (!dbUsers.Any()) + { + return (false, new NotFoundResult(), null!, null!); + } FilterByCompanyId(ref dbUsers, parameters.CompanyId); SearchByAllUserFields(ref dbUsers, parameters.Search); @@ -111,6 +148,14 @@ public class DriverManagementService : IDriverManagementService public async Task<(bool isSucceeded, IActionResult? actionResult, ExpandoObject driver)> GetDriver(string id, string? fields) { + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!await _sessionUserService.IsAuthUserCompanyDriver(id)) + { + return (false, new UnauthorizedResult(), null!); + } + } + var dbUser = await _userManager.Users.Include(u => u.Employer). FirstOrDefaultAsync(u => u.Id == id); @@ -132,6 +177,15 @@ public class DriverManagementService : IDriverManagementService public async Task<(bool isSucceeded, IActionResult? actionResult, DriverDto driver)> UpdateDriver(string id, UpdateDriverDto updateDriverDto) { + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!(await _sessionUserService.IsAuthUserCompanyOwner()).isCompanyOwner && + !await _sessionUserService.IsAuthUserCompanyDriver(id)) + { + return (false, new UnauthorizedResult(), null!); + } + } + var updateUserDto = _mapper.Map(updateDriverDto); var result = await _userManagementService.UpdateUser(id, updateUserDto); @@ -140,6 +194,14 @@ public class DriverManagementService : IDriverManagementService public async Task<(bool isSucceed, IActionResult? actionResult)> DeleteDriver(string id) { + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!await _sessionUserService.IsAuthUserCompanyDriver(id)) + { + return (false, new UnauthorizedResult()); + } + } + return await _userManagementService.DeleteUser(id); } } \ No newline at end of file diff --git a/Server/Services/IReportService.cs b/Server/Services/IReportService.cs index e7e2c11..aa65136 100644 --- a/Server/Services/IReportService.cs +++ b/Server/Services/IReportService.cs @@ -9,10 +9,10 @@ public interface IReportService GetTicket(int ticketGroupId); Task<(bool isSucceed, IActionResult? actionResult, Stream reportPdf)> - GetCompanyReportPdf(int companyId, DateTime fromDate, DateTime toDate); + GetCompanyReportPdf(int? companyId, DateTime fromDate, DateTime toDate); Task<(bool isSucceed, IActionResult? actionResult, StatisticsResponse statistics)> - GetCompanyReportRaw(int companyId, DateTime fromDate, DateTime toDate); + GetCompanyReportRaw(int? companyId, DateTime fromDate, DateTime toDate); Task<(bool isSucceed, IActionResult? actionResult, StatisticsResponse statistics)> GetAdminReportRaw(DateTime fromDate, DateTime toDate); diff --git a/Server/Services/ISessionUserService.cs b/Server/Services/ISessionUserService.cs new file mode 100644 index 0000000..2738df7 --- /dev/null +++ b/Server/Services/ISessionUserService.cs @@ -0,0 +1,15 @@ +namespace Server.Services; + +public interface ISessionUserService +{ + public string GetAuthUserId(); + public string GetAuthUserRole(); + + public Task<(bool isCompanyOwner, int companyId)> IsAuthUserCompanyOwner(); + public Task IsAuthUserCompanyVehicle(int vehicleId); + public Task IsAuthUserCompanyVehicleEnrollment(int enrollmentId); + public Task IsAuthUserCompanyDriver(string driverId); + + + public Task IsAuthUserReview(int reviewId); +} \ No newline at end of file diff --git a/Server/Services/ReportService.cs b/Server/Services/ReportService.cs index bb78b97..6dcdc83 100644 --- a/Server/Services/ReportService.cs +++ b/Server/Services/ReportService.cs @@ -9,6 +9,7 @@ using PdfSharpCore.Pdf; using Server.Data; using Server.Models; using SharedModels.Responses; +using Utils; using Route = Server.Models.Route; namespace Server.Services; @@ -16,10 +17,12 @@ namespace Server.Services; public class ReportService : IReportService { private readonly ApplicationDbContext _dbContext; + private readonly ISessionUserService _sessionUserService; - public ReportService(ApplicationDbContext dbContext) + public ReportService(ApplicationDbContext dbContext, ISessionUserService sessionUserService) { _dbContext = dbContext; + _sessionUserService = sessionUserService; } public async Task<(bool IsSucceed, IActionResult? actionResult, Stream ticketPdf)> GetTicket(int ticketGroupId) @@ -28,6 +31,15 @@ public class ReportService : IReportService { return (false, new NotFoundResult(), null!); } + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if ((await _dbContext.TicketGroups.FirstAsync(tg => tg.Id == ticketGroupId)).UserId != + _sessionUserService.GetAuthUserId()) + { + return (false, new UnauthorizedResult(), null!); + } + } var dbTicketGroup = await _dbContext.TicketGroups .Include(tg => tg.User) @@ -373,9 +385,26 @@ public class ReportService : IReportService } public async Task<(bool isSucceed, IActionResult? actionResult, Stream reportPdf)> - GetCompanyReportPdf(int companyId, DateTime fromDate, DateTime toDate) + GetCompanyReportPdf(int? companyId, DateTime fromDate, DateTime toDate) { - if (!await DoesCompanyExist(companyId)) + if (_sessionUserService.GetAuthUserRole() == Identity.Roles.Administrator.ToString()) + { + if (companyId == null) + { + return (false, new BadRequestObjectResult("CompanyId must have a value"), null!); + } + } + else + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!); + } + companyId = result.companyId; + } + + if (!await DoesCompanyExist((int)companyId)) { return (false, new NotFoundResult(), null!); } @@ -613,22 +642,22 @@ public class ReportService : IReportService row.Shading.Color = Color.FromRgbColor(25, Colors.Black); row.Cells[0].MergeRight = 1; - row.Cells[0].AddParagraph($"{route.GetCompanyEnrollmentCount(fromDate, toDate, companyId)}"); + row.Cells[0].AddParagraph($"{route.GetCompanyEnrollmentCount(fromDate, toDate, (int) companyId)}"); row.Cells[2].MergeRight = 1; - row.Cells[2].AddParagraph($"{route.GetCompanyCanceledEnrollmentCount(fromDate, toDate, companyId)}"); + row.Cells[2].AddParagraph($"{route.GetCompanyCanceledEnrollmentCount(fromDate, toDate, (int) companyId)}"); row.Cells[4].MergeRight = 1; - row.Cells[4].AddParagraph($"{route.GetCompanySoldTicketCount(fromDate, toDate, companyId)}"); + row.Cells[4].AddParagraph($"{route.GetCompanySoldTicketCount(fromDate, toDate, (int) companyId)}"); row.Cells[6].MergeRight = 1; - row.Cells[6].AddParagraph($"{route.GetCompanyIndirectTicketCount(fromDate, toDate, companyId)}"); + row.Cells[6].AddParagraph($"{route.GetCompanyIndirectTicketCount(fromDate, toDate, (int) companyId)}"); row.Cells[8].MergeRight = 1; - row.Cells[8].AddParagraph($"{route.GetCompanyTotalRevenue(fromDate, toDate, companyId)}"); + row.Cells[8].AddParagraph($"{route.GetCompanyTotalRevenue(fromDate, toDate, (int) companyId)}"); row.Cells[10].MergeRight = 1; - var routeAverageRating = route.GetCompanyAverageRating(fromDate, toDate, companyId); + var routeAverageRating = route.GetCompanyAverageRating(fromDate, toDate, (int) companyId); row.Cells[10].AddParagraph($"{(routeAverageRating == 0 ? "-" : routeAverageRating)}"); row = table.AddRow(); @@ -716,9 +745,26 @@ public class ReportService : IReportService } public async Task<(bool isSucceed, IActionResult? actionResult, StatisticsResponse statistics)> - GetCompanyReportRaw(int companyId, DateTime fromDate, DateTime toDate) + GetCompanyReportRaw(int? companyId, DateTime fromDate, DateTime toDate) { - if (!await DoesCompanyExist(companyId)) + if (_sessionUserService.GetAuthUserRole() == Identity.Roles.Administrator.ToString()) + { + if (companyId == null) + { + return (false, new BadRequestObjectResult("Query parameter CompanyId must have a value"), null!); + } + } + else + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!); + } + companyId = result.companyId; + } + + if (!await DoesCompanyExist((int)companyId)) { return (false, new NotFoundResult(), null!); } diff --git a/Server/Services/ReviewManagementService.cs b/Server/Services/ReviewManagementService.cs index 6f03b97..faba1c2 100644 --- a/Server/Services/ReviewManagementService.cs +++ b/Server/Services/ReviewManagementService.cs @@ -8,6 +8,7 @@ using Server.Models; using SharedModels.DataTransferObjects; using SharedModels.QueryParameters; using SharedModels.QueryParameters.Objects; +using Utils; namespace Server.Services; @@ -18,21 +19,32 @@ public class ReviewManagementService : IReviewManagementService private readonly ISortHelper _reviewSortHelper; private readonly IDataShaper _reviewDataShaper; private readonly IPager _pager; + private readonly ISessionUserService _sessionUserService; public ReviewManagementService(ApplicationDbContext dbContext, IMapper mapper, ISortHelper reviewSortHelper, - IDataShaper reviewDataShaper, IPager pager) + IDataShaper reviewDataShaper, IPager pager, + ISessionUserService sessionUserService) { _dbContext = dbContext; _mapper = mapper; _reviewSortHelper = reviewSortHelper; _reviewDataShaper = reviewDataShaper; _pager = pager; + _sessionUserService = sessionUserService; } public async Task<(bool isSucceed, IActionResult? actionResult, ReviewDto review)> AddReview(CreateReviewDto createReviewDto) { var review = _mapper.Map(createReviewDto); + + var hasTicketToEnrollment = await _dbContext.TicketGroups.AnyAsync(tg => + tg.UserId == _sessionUserService.GetAuthUserId() && tg.Tickets.Any(t => t.VehicleEnrollmentId == review.VehicleEnrollmentId)); + + if (!hasTicketToEnrollment && _sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + return (false, new UnauthorizedResult(), null!); + } await _dbContext.Reviews.AddAsync(review); await _dbContext.SaveChangesAsync(); @@ -47,6 +59,16 @@ public class ReviewManagementService : IReviewManagementService .Include(r => r.VehicleEnrollment).ThenInclude(ve => ve.Vehicle) .ThenInclude(v => v.Company).Include(r => r.User) .AsQueryable(); + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + dbReviews = dbReviews.Where(r => r.UserId == _sessionUserService.GetAuthUserId()); + } + + if (!dbReviews.Any()) + { + return (false, new NotFoundResult(), null!, null!); + } FilterByReviewRating(ref dbReviews, parameters.FromRating, parameters.ToRating); FilterByReviewComment(ref dbReviews, parameters.Comment); @@ -129,6 +151,12 @@ public class ReviewManagementService : IReviewManagementService .Include(r => r.VehicleEnrollment).ThenInclude(ve => ve.Vehicle) .ThenInclude(v => v.Company).Include(r => r.User) .FirstAsync(); + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString() && + dbReview.UserId != _sessionUserService.GetAuthUserId()) + { + return (false, new UnauthorizedResult(), null!); + } if (String.IsNullOrWhiteSpace(fields)) { @@ -146,6 +174,12 @@ public class ReviewManagementService : IReviewManagementService var review = _mapper.Map(updateReviewDto); _dbContext.Entry(review).State = EntityState.Modified; + if (!await _sessionUserService.IsAuthUserReview(updateReviewDto.Id) && + _sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + return (false, new UnauthorizedResult(), null!); + } + try { await _dbContext.SaveChangesAsync(); @@ -165,12 +199,17 @@ public class ReviewManagementService : IReviewManagementService public async Task<(bool isSucceed, IActionResult? actionResult)> DeleteReview(int id) { - var dbReview = await _dbContext.Reviews.FirstOrDefaultAsync(r => r.Id == id); - - if (dbReview == null) + if (!await IsReviewExists(id)) { - return (false,new NotFoundResult()); + return (false, new NotFoundResult()); } + + if (!await _sessionUserService.IsAuthUserReview(id)) + { + return (false, new UnauthorizedResult()); + } + + var dbReview = await _dbContext.Reviews.FirstAsync(r => r.Id == id); _dbContext.Reviews.Remove(dbReview); await _dbContext.SaveChangesAsync(); diff --git a/Server/Services/SessionUserService.cs b/Server/Services/SessionUserService.cs new file mode 100644 index 0000000..156d90a --- /dev/null +++ b/Server/Services/SessionUserService.cs @@ -0,0 +1,98 @@ +using System.Security.Claims; +using Microsoft.EntityFrameworkCore; +using Server.Constants; +using Server.Data; + +namespace Server.Services; + +public class SessionUserService : ISessionUserService +{ + private readonly ApplicationDbContext _dbContext; + private readonly ClaimsPrincipal _userClaimsPrincipal; + + public SessionUserService(IHttpContextAccessor httpContextAccessor, ApplicationDbContext dbContext) + { + _dbContext = dbContext; + _userClaimsPrincipal = httpContextAccessor.HttpContext.User; + } + + public string GetAuthUserId() + { + return _userClaimsPrincipal.Claims.FirstOrDefault(c => c.Properties.Values.Any(v => v == JwtStandardClaimNames.Sub))?.Value!; + } + + public string GetAuthUserRole() + { + return _userClaimsPrincipal.Claims.FirstOrDefault(c => c.Properties.Values.Any(v => v == "roles"))?.Value!; + } + + public async Task<(bool isCompanyOwner, int companyId)> IsAuthUserCompanyOwner() + { + var companyId = (await _dbContext.Companies.FirstOrDefaultAsync(c => c.OwnerId == GetAuthUserId()))?.Id; + + if (companyId == null) + { + return (false, -1); + } + + return (true, (int) companyId); + } + + public async Task IsAuthUserCompanyVehicle(int vehicleId) + { + var result = await IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return false; + } + + if (!await _dbContext.Vehicles.AnyAsync(v => v.Id == vehicleId)) + { + return true; + } + + return (await _dbContext.Vehicles.FirstOrDefaultAsync(v => v.Id == vehicleId))?.CompanyId == result.companyId; + } + + public async Task IsAuthUserCompanyVehicleEnrollment(int enrollmentId) + { + var result = await IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return false; + } + + if (!await _dbContext.VehicleEnrollments.AnyAsync(e => e.Id == enrollmentId)) + { + return true; + } + + return (await _dbContext.VehicleEnrollments + .Include(e => e.Vehicle) + .FirstAsync(e => e.Id == enrollmentId)) + .Vehicle.CompanyId == result.companyId; + } + + public async Task IsAuthUserCompanyDriver(string driverId) + { + var result = await IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return false; + } + + if (!await _dbContext.CompanyDrivers.AnyAsync(d => d.DriverId == driverId)) + { + return true; + } + + return (await _dbContext.CompanyDrivers + .FirstAsync(d => d.DriverId == driverId)) + .CompanyId == result.companyId; + } + + public async Task IsAuthUserReview(int reviewId) + { + return (await _dbContext.Reviews.FirstAsync(r => r.Id == reviewId)).UserId == GetAuthUserId(); + } +} \ No newline at end of file diff --git a/Server/Services/TicketGroupManagementService.cs b/Server/Services/TicketGroupManagementService.cs index 9c7c7ea..7b75b13 100644 --- a/Server/Services/TicketGroupManagementService.cs +++ b/Server/Services/TicketGroupManagementService.cs @@ -8,6 +8,7 @@ using Server.Models; using SharedModels.DataTransferObjects; using SharedModels.QueryParameters; using SharedModels.QueryParameters.Objects; +using Utils; namespace Server.Services; @@ -19,10 +20,12 @@ public class TicketGroupManagementService : ITicketGroupManagementService private readonly IDataShaper _ticketGroupDataShaper; private readonly IDataShaper _ticketGroupWithTicketsDataShaper; private readonly IPager _pager; + private readonly ISessionUserService _sessionUserService; public TicketGroupManagementService(ApplicationDbContext dbContext, IMapper mapper, ISortHelper ticketGroupSortHelper, IDataShaper ticketGroupDataShaper, - IDataShaper ticketGroupWithTicketsDataShaper, IPager pager) + IDataShaper ticketGroupWithTicketsDataShaper, IPager pager, + ISessionUserService sessionUserService) { _dbContext = dbContext; _mapper = mapper; @@ -30,6 +33,7 @@ public class TicketGroupManagementService : ITicketGroupManagementService _ticketGroupDataShaper = ticketGroupDataShaper; _ticketGroupWithTicketsDataShaper = ticketGroupWithTicketsDataShaper; _pager = pager; + _sessionUserService = sessionUserService; } public async Task<(bool isSucceed, IActionResult? actionResult, TicketGroupDto ticketGroup)> AddTicketGroup(CreateTicketGroupDto createTicketGroupDto) @@ -63,6 +67,16 @@ public class TicketGroupManagementService : ITicketGroupManagementService { var dbTicketGroups = _dbContext.TicketGroups.AsQueryable(); + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + dbTicketGroups = dbTicketGroups.Where(tg => tg.UserId == _sessionUserService.GetAuthUserId()); + } + + if (!dbTicketGroups.Any()) + { + return (false, new NotFoundResult(), null!, null!); + } + FilterTicketGroupsByUserId(ref dbTicketGroups, parameters.UserId); var ticketGroupDtos = _mapper.ProjectTo(dbTicketGroups); @@ -103,6 +117,16 @@ public class TicketGroupManagementService : ITicketGroupManagementService .ThenInclude(t => t.VehicleEnrollment) .AsQueryable(); + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + dbTicketGroups = dbTicketGroups.Where(tg => tg.UserId == _sessionUserService.GetAuthUserId()); + } + + if (!dbTicketGroups.Any()) + { + return (false, new NotFoundResult(), null!, null!); + } + FilterTicketGroupsByUserId(ref dbTicketGroups, parameters.UserId); var ticketGroupDtos = _mapper.ProjectTo(dbTicketGroups); @@ -143,10 +167,16 @@ public class TicketGroupManagementService : ITicketGroupManagementService var dbTicketGroup = await _dbContext.TicketGroups.Where(tg => tg.Id == id) .FirstAsync(); + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString() && + dbTicketGroup.UserId != _sessionUserService.GetAuthUserId()) + { + return (false, new UnauthorizedResult(), null!); + } if (String.IsNullOrWhiteSpace(fields)) { - fields = RouteParameters.DefaultFields; + fields = TicketGroupParameters.DefaultFields; } var ticketGroupDto = _mapper.Map(dbTicketGroup); @@ -165,10 +195,16 @@ public class TicketGroupManagementService : ITicketGroupManagementService var dbTicketGroup = await _dbContext.TicketGroups.Where(tg => tg.Id == id) .Include(tg => tg.Tickets) .FirstAsync(); + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString() && + dbTicketGroup.UserId != _sessionUserService.GetAuthUserId()) + { + return (false, new UnauthorizedResult(), null!); + } if (String.IsNullOrWhiteSpace(fields)) { - fields = RouteParameters.DefaultFields; + fields = TicketGroupParameters.DefaultFields; } var ticketGroupDto = _mapper.Map(dbTicketGroup); diff --git a/Server/Services/VehicleEnrollmentManagementService.cs b/Server/Services/VehicleEnrollmentManagementService.cs index b28104a..cd4b24d 100644 --- a/Server/Services/VehicleEnrollmentManagementService.cs +++ b/Server/Services/VehicleEnrollmentManagementService.cs @@ -8,6 +8,7 @@ using Server.Models; using SharedModels.DataTransferObjects; using SharedModels.QueryParameters; using SharedModels.QueryParameters.Objects; +using Utils; namespace Server.Services; @@ -19,11 +20,13 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe private readonly IDataShaper _enrollmentDataShaper; private readonly IDataShaper _enrollmentWithDetailsDataShaper; private readonly IPager _pager; + private readonly ISessionUserService _sessionUserService; public VehicleEnrollmentManagementService(ApplicationDbContext dbContext, IMapper mapper, ISortHelper enrollmentSortHelper, IDataShaper enrollmentDataShaper, IPager pager, - IDataShaper enrollmentWithDetailsDataShaper) + IDataShaper enrollmentWithDetailsDataShaper, + ISessionUserService sessionUserService) { _dbContext = dbContext; _mapper = mapper; @@ -31,10 +34,20 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe _enrollmentDataShaper = enrollmentDataShaper; _pager = pager; _enrollmentWithDetailsDataShaper = enrollmentWithDetailsDataShaper; + _sessionUserService = sessionUserService; } public async Task<(bool isSucceed, IActionResult? actionResult, VehicleEnrollmentDto enrollment)> AddEnrollment(CreateVehicleEnrollmentDto createEnrollmentDto) { + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!(await _sessionUserService.IsAuthUserCompanyOwner()).isCompanyOwner && + !await _sessionUserService.IsAuthUserCompanyVehicle(createEnrollmentDto.VehicleId)) + { + return (false, new UnauthorizedResult(), null!); + } + } + var enrollment = _mapper.Map(createEnrollmentDto); await _dbContext.VehicleEnrollments.AddAsync(enrollment); @@ -45,6 +58,15 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe public async Task<(bool isSucceed, IActionResult? actionResult, VehicleEnrollmentWithDetailsDto enrollment)> AddEnrollmentWithDetails(CreateVehicleEnrollmentWithDetailsDto createEnrollmentDto) { + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!(await _sessionUserService.IsAuthUserCompanyOwner()).isCompanyOwner && + !await _sessionUserService.IsAuthUserCompanyVehicle(createEnrollmentDto.VehicleId)) + { + return (false, new UnauthorizedResult(), null!); + } + } + var enrollment = _mapper.Map(createEnrollmentDto); await _dbContext.VehicleEnrollments.AddAsync(enrollment); @@ -62,6 +84,18 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe { var dbEnrollments = _dbContext.VehicleEnrollments .AsQueryable(); + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!, null!); + } + + dbEnrollments = dbEnrollments.Include(e => e.Vehicle) + .Where(e => e.Vehicle.CompanyId == result.companyId); + } SearchByAllEnrollmentFields(ref dbEnrollments, parameters.Search); FilterByEnrollmentVehicleId(ref dbEnrollments, parameters.VehicleId); @@ -166,6 +200,18 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe var dbEnrollments = _dbContext.VehicleEnrollments .Include(ve => ve.RouteAddressDetails) .AsQueryable(); + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!, null!); + } + + dbEnrollments = dbEnrollments.Include(e => e.Vehicle) + .Where(e => e.Vehicle.CompanyId == result.companyId); + } SearchByAllEnrollmentFields(ref dbEnrollments, parameters.Search); FilterByEnrollmentVehicleId(ref dbEnrollments, parameters.VehicleId); @@ -335,6 +381,14 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe return (false, new NotFoundResult(), null!); } + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!await _sessionUserService.IsAuthUserCompanyVehicleEnrollment(id)) + { + return (false, new UnauthorizedResult(), null!); + } + } + var dbEnrollment = await _dbContext.VehicleEnrollments.Where(e => e.Id == id) .FirstAsync(); @@ -355,6 +409,14 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe { return (false, new NotFoundResult(), null!); } + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!await _sessionUserService.IsAuthUserCompanyVehicleEnrollment(id)) + { + return (false, new UnauthorizedResult(), null!); + } + } var dbEnrollment = await _dbContext.VehicleEnrollments .Include(ve => ve.RouteAddressDetails) @@ -376,6 +438,15 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe var enrollment = _mapper.Map(updateEnrollmentDto); _dbContext.Entry(enrollment).State = EntityState.Modified; + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!(await _sessionUserService.IsAuthUserCompanyOwner()).isCompanyOwner && + !await _sessionUserService.IsAuthUserCompanyVehicle(updateEnrollmentDto.VehicleId)) + { + return (false, new UnauthorizedResult(), null!); + } + } + try { await _dbContext.SaveChangesAsync(); @@ -397,13 +468,21 @@ public class VehicleEnrollmentManagementService : IVehicleEnrollmentManagementSe public async Task<(bool isSucceed, IActionResult? actionResult)> DeleteEnrollment(int id) { - var dbEnrollment = await _dbContext.VehicleEnrollments.FirstOrDefaultAsync(e => e.Id == id); - - if (dbEnrollment == null) + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!await _sessionUserService.IsAuthUserCompanyVehicleEnrollment(id)) + { + return (false, new UnauthorizedResult()); + } + } + + if (!await IsEnrollmentExists(id)) { return (false, new NotFoundResult()); } + var dbEnrollment = await _dbContext.VehicleEnrollments.FirstAsync(e => e.Id == id); + _dbContext.VehicleEnrollments.Remove(dbEnrollment); await _dbContext.SaveChangesAsync(); diff --git a/Server/Services/VehicleManagementService.cs b/Server/Services/VehicleManagementService.cs index 59d28f9..cfabe9f 100644 --- a/Server/Services/VehicleManagementService.cs +++ b/Server/Services/VehicleManagementService.cs @@ -8,6 +8,7 @@ using Server.Models; using SharedModels.DataTransferObjects; using SharedModels.QueryParameters; using SharedModels.QueryParameters.Objects; +using Utils; namespace Server.Services; @@ -18,20 +19,40 @@ public class VehicleManagementService : IVehicleManagementService private readonly ISortHelper _vehicleSortHelper; private readonly IDataShaper _vehicleDataShaper; private readonly IPager _pager; + private readonly ISessionUserService _sessionUserService; public VehicleManagementService(ApplicationDbContext dbContext, IMapper mapper, ISortHelper vehicleSortHelper, - IDataShaper vehicleDataShaper, IPager pager) + IDataShaper vehicleDataShaper, IPager pager, + ISessionUserService sessionUserService) { _dbContext = dbContext; _mapper = mapper; _vehicleSortHelper = vehicleSortHelper; _vehicleDataShaper = vehicleDataShaper; _pager = pager; + _sessionUserService = sessionUserService; } public async Task<(bool isSucceed, IActionResult? actionResult, VehicleDto vehicle)> AddVehicle(CreateVehicleDto createVehicleDto) { + if (_sessionUserService.GetAuthUserRole() == Identity.Roles.Administrator.ToString()) + { + if (createVehicleDto.CompanyId == null) + { + return (false, new BadRequestObjectResult("CompanyId must have a value"), null!); + } + } + else + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!); + } + createVehicleDto.CompanyId = result.companyId; + } + var vehicle = _mapper.Map(createVehicleDto); await _dbContext.Vehicles.AddAsync(vehicle); @@ -47,6 +68,22 @@ public class VehicleManagementService : IVehicleManagementService .Include(t => t.Company) .AsQueryable(); + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!, null!); + } + + dbVehicles = dbVehicles.Where(v => v.CompanyId == result.companyId); + } + + if (!dbVehicles.Any()) + { + return (false, new NotFoundResult(), null!, null!); + } + var vehicleDtos = _mapper.ProjectTo(dbVehicles); var shapedData = _vehicleDataShaper.ShapeData(vehicleDtos, parameters.Fields).AsQueryable(); @@ -207,6 +244,14 @@ public class VehicleManagementService : IVehicleManagementService { return (false, new NotFoundResult(), null!); } + + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!await _sessionUserService.IsAuthUserCompanyVehicle(id)) + { + return (false, new UnauthorizedResult(), null!); + } + } var dbVehicle = await _dbContext.Vehicles.Where(v => v.Id == id) .Include(t => t.Company) @@ -228,6 +273,23 @@ public class VehicleManagementService : IVehicleManagementService var vehicle = _mapper.Map(updateVehicleDto); _dbContext.Entry(vehicle).State = EntityState.Modified; + if (_sessionUserService.GetAuthUserRole() == Identity.Roles.Administrator.ToString()) + { + if (updateVehicleDto.CompanyId == null) + { + return (false, new BadRequestObjectResult("CompanyId must have a value"), null!); + } + } + else + { + var result = await _sessionUserService.IsAuthUserCompanyOwner(); + if (!result.isCompanyOwner) + { + return (false, new UnauthorizedResult(), null!); + } + vehicle.CompanyId = result.companyId; + } + try { await _dbContext.SaveChangesAsync(); @@ -249,13 +311,21 @@ public class VehicleManagementService : IVehicleManagementService public async Task<(bool isSucceed, IActionResult? actionResult)> DeleteVehicle(int id) { - var dbVehicle = await _dbContext.Vehicles.FirstOrDefaultAsync(v => v.Id == id); - - if (dbVehicle == null) + if (_sessionUserService.GetAuthUserRole() != Identity.Roles.Administrator.ToString()) + { + if (!await _sessionUserService.IsAuthUserCompanyVehicle(id)) + { + return (false, new UnauthorizedResult()); + } + } + + if (!await IsVehicleExists(id)) { return (false, new NotFoundResult()); } - + + var dbVehicle = await _dbContext.Vehicles.FirstAsync(v => v.Id == id); + _dbContext.Vehicles.Remove(dbVehicle); await _dbContext.SaveChangesAsync(); @@ -266,4 +336,5 @@ public class VehicleManagementService : IVehicleManagementService { return await _dbContext.Vehicles.AnyAsync(v => v.Id == id); } + } \ No newline at end of file diff --git a/SharedModels/DataTransferObjects/DriverDto.cs b/SharedModels/DataTransferObjects/DriverDto.cs index ad27339..98d45db 100644 --- a/SharedModels/DataTransferObjects/DriverDto.cs +++ b/SharedModels/DataTransferObjects/DriverDto.cs @@ -7,7 +7,7 @@ public class DriverDto : UserDto public class CreateDriverDto : CreateUserDto { - public int CompanyId { get; set; } + public int? CompanyId { get; set; } public override IList? Roles { get; set; } } diff --git a/SharedModels/DataTransferObjects/ReviewDto.cs b/SharedModels/DataTransferObjects/ReviewDto.cs index d456cc0..ae3277a 100644 --- a/SharedModels/DataTransferObjects/ReviewDto.cs +++ b/SharedModels/DataTransferObjects/ReviewDto.cs @@ -7,7 +7,7 @@ public class ReviewDto : CreateReviewDto public int Id { get; set; } [DataType(DataType.DateTime)] - public DateTime PostDateTimeUtc { get; set; } + public DateTime PostDateTime { get; set; } public StrippedUserDto User { get; set; } = null!; public InReviewVehicleEnrollmentDto VehicleEnrollment { get; set; } = null!; diff --git a/SharedModels/DataTransferObjects/VehicleDto.cs b/SharedModels/DataTransferObjects/VehicleDto.cs index 3699ce9..a7a901c 100644 --- a/SharedModels/DataTransferObjects/VehicleDto.cs +++ b/SharedModels/DataTransferObjects/VehicleDto.cs @@ -43,8 +43,7 @@ public class CreateVehicleDto [Required] public bool HasBelts { get; set; } = false; - [Required] - public int CompanyId { get; set; } + public int? CompanyId { get; set; } } public class UpdateVehicleDto : CreateVehicleDto diff --git a/SharedModels/DataTransferObjects/VehicleEnrollmentDto.cs b/SharedModels/DataTransferObjects/VehicleEnrollmentDto.cs index e1eea19..347fa4b 100644 --- a/SharedModels/DataTransferObjects/VehicleEnrollmentDto.cs +++ b/SharedModels/DataTransferObjects/VehicleEnrollmentDto.cs @@ -8,17 +8,20 @@ public class VehicleEnrollmentDto : CreateVehicleEnrollmentDto public IList Tickets { get; set; } = null!; public IList Reviews { get; set; } = null!; + + public bool IsCanceled { get; set; } + public string? CancelationComment { get; set; } } public class CreateVehicleEnrollmentDto { [Required] public int VehicleId { get; set; } - public VehicleDto Vehicle { get; set; } = null!; + public VehicleDto? Vehicle { get; set; } = null!; [Required] public int RouteId { get; set; } - public RouteDto Route { get; set; } = null!; + public RouteDto? Route { get; set; } = null!; [Required] [DataType(DataType.DateTime)] @@ -31,9 +34,9 @@ public class UpdateVehicleEnrollmentDto : CreateVehicleEnrollmentDto public int Id { get; set; } public TimeSpan DelayTimeSpan { get; set; } = TimeSpan.Zero; - - public bool IsCanceled { get; set; } = false; - public string CancelationComment { get; set; } = null!; + + public bool? IsCanceled { get; set; } = false; + public string? CancelationComment { get; set; } } public class CreateVehicleEnrollmentWithDetailsDto : CreateVehicleEnrollmentDto diff --git a/SharedModels/QueryParameters/Objects/VehicleEnrollmentParameters.cs b/SharedModels/QueryParameters/Objects/VehicleEnrollmentParameters.cs index c8a2b51..b6899e9 100644 --- a/SharedModels/QueryParameters/Objects/VehicleEnrollmentParameters.cs +++ b/SharedModels/QueryParameters/Objects/VehicleEnrollmentParameters.cs @@ -2,8 +2,8 @@ namespace SharedModels.QueryParameters.Objects; public class VehicleEnrollmentParameters : ParametersBase { - public const string DefaultFields = "id,vehicleId,vehicle,routeId,route,departureDateTimeUtc," + - "tickets,reviews,delayTimeSpan,isCancelled,cancellationComment"; + public const string DefaultFields = "id,vehicleId,vehicle,routeId,route,departureDateTime," + + "tickets,reviews,delayTimeSpan,isCanceled,cancelationComment"; public VehicleEnrollmentParameters() {