feat: add imperative resource-based authorization

I decided not to make authorization requirements and handlers for each and every resource because the validation logic is pretty similar
This commit is contained in:
cuqmbr 2023-05-22 10:46:35 +03:00
parent 1575e56516
commit e9af067dfa
23 changed files with 552 additions and 53 deletions

View File

@ -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<IActionResult> 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<IActionResult> GetDrivers([FromQuery] CompanyDriverParameters parameters)
{
@ -45,6 +49,7 @@ public class DriverController : ControllerBase
return Ok(result.drivers);
}
[Authorize(Policy = "CompanyAccess")]
[HttpGet("{id}")]
public async Task<IActionResult> 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<IActionResult> 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<IActionResult> DeleteDriver(string id)
{

View File

@ -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<IActionResult> GetCompanyReportPdf(int companyId, DateTime fromDate, DateTime toDate)
public async Task<IActionResult> 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<IActionResult> GetCompanyReportRaw(int companyId, DateTime fromDate, DateTime toDate)
public async Task<IActionResult> 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<IActionResult> 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);

View File

@ -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

View File

@ -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<IActionResult> 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<IActionResult> 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<IActionResult> GetRoutes([FromQuery] RouteParameters parameters)
{
@ -58,6 +63,7 @@ public class RouteController : ControllerBase
return Ok(result.routes);
}
[Authorize(Policy = "DriverAccess")]
[HttpGet("withAddresses")]
public async Task<IActionResult> GetRouteWithAddresses([FromQuery] RouteWithAddressesParameters parameters)
{
@ -73,6 +79,7 @@ public class RouteController : ControllerBase
return Ok(result.routes);
}
[Authorize(Policy = "DriverAccess")]
[HttpGet("{id}")]
public async Task<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> DeleteRoute(int id)
{

View File

@ -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<IActionResult> GetPopularRoutes([FromQuery] PopularRoutesParameters parameters)
{
@ -31,6 +34,7 @@ public class StatisticsController : ControllerBase
return Ok(result.route);
}
[Authorize(Policy = "AdministratorAccess")]
[HttpGet("users")]
public async Task<IActionResult> GetEngagedUsers([FromQuery] EngagedUserParameters parameters)
@ -47,6 +51,7 @@ public class StatisticsController : ControllerBase
return Ok(result.users);
}
[Authorize(Policy = "AdministratorAccess")]
[HttpGet("companies")]
public async Task<IActionResult> GetPopularCompanies([FromQuery] PopularCompanyParameters parameters)
{

View File

@ -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<IActionResult> 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<IActionResult> AddTicketGroupWithTickets(CreateTicketGroupWithTicketsDto ticketGroup)
{
@ -99,6 +103,7 @@ public class TicketGroupController : ControllerBase
return Ok(result.ticketGroup);
}
[Authorize(Policy = "AdministratorAccess")]
[HttpPut("{id}")]
public async Task<IActionResult> 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<IActionResult> DeleteTicketGroup(int id)
{
@ -129,5 +135,4 @@ public class TicketGroupController : ControllerBase
return NoContent();
}
}
}

View File

@ -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<IActionResult> 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<IActionResult> GetVehicles([FromQuery] VehicleParameters parameters)
{
@ -45,6 +48,7 @@ public class VehicleController : ControllerBase
return Ok(result.vehicles);
}
[Authorize(Policy = "DriverAccess")]
[HttpGet("{id}")]
public async Task<IActionResult> 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<IActionResult> 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<IActionResult> DeleteVehicle(int id)
{

View File

@ -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<IActionResult> 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<IActionResult> 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<IActionResult> GetEnrollments([FromQuery] VehicleEnrollmentParameters parameters)
{
@ -59,6 +63,7 @@ public class VehicleEnrollmentController : ControllerBase
return Ok(result.enrollments);
}
[Authorize(Policy = "DriverAccess")]
[HttpGet("withDetails")]
public async Task<IActionResult> GetEnrollments([FromQuery] VehicleEnrollmentWithDetailsParameters parameters)
{
@ -74,6 +79,7 @@ public class VehicleEnrollmentController : ControllerBase
return Ok(result.enrollments);
}
[Authorize(Policy = "DriverAccess")]
[HttpGet("{id}")]
public async Task<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> DeleteEnrollment(int id)
{

View File

@ -108,6 +108,8 @@ services.AddAutoMapper(typeof(MapperInitializer));
services.AddScoped<IEmailSenderService, EmailSenderService>();
services.AddScoped<IAuthenticationService, AuthenticationService>();
services.AddScoped<ISessionUserService, SessionUserService>();
services.AddScoped<ICountryManagementService, CountryManagementService>();
services.AddScoped<IStateManagementService, StateManagementService>();
services.AddScoped<ICityManagementService, CityManagementService>();

View File

@ -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<ExpandoObject> _userSortHelper;
private readonly IDataShaper<DriverDto> _userDataShaper;
private readonly IPager<ExpandoObject> _pager;
private readonly ISessionUserService _sessionUserService;
public DriverManagementService(IUserManagementService userManagementService, IMapper mapper,
UserManager<User> userManager, ApplicationDbContext dbContext,
ISortHelper<ExpandoObject> userSortHelper, IDataShaper<DriverDto> userDataShaper,
IPager<ExpandoObject> pager)
IPager<ExpandoObject> 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<CreateUserDto>(createDriverDto);
createUserDto.Roles = new List<string> { "Driver" };
@ -50,8 +71,8 @@ public class DriverManagementService : IDriverManagementService
return (false, result.actionResult, null);
}
var driverDto = _mapper.Map<DriverDto>(createUserDto);
_dbContext.CompanyDrivers.Add(new CompanyDriver { CompanyId = createDriverDto.CompanyId, DriverId = driverDto.Id });
var driverDto = _mapper.Map<DriverDto>(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<UpdateUserDto>(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);
}
}

View File

@ -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);

View File

@ -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<bool> IsAuthUserCompanyVehicle(int vehicleId);
public Task<bool> IsAuthUserCompanyVehicleEnrollment(int enrollmentId);
public Task<bool> IsAuthUserCompanyDriver(string driverId);
public Task<bool> IsAuthUserReview(int reviewId);
}

View File

@ -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!);
}

View File

@ -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<ExpandoObject> _reviewSortHelper;
private readonly IDataShaper<ReviewDto> _reviewDataShaper;
private readonly IPager<ExpandoObject> _pager;
private readonly ISessionUserService _sessionUserService;
public ReviewManagementService(ApplicationDbContext dbContext,
IMapper mapper, ISortHelper<ExpandoObject> reviewSortHelper,
IDataShaper<ReviewDto> reviewDataShaper, IPager<ExpandoObject> pager)
IDataShaper<ReviewDto> reviewDataShaper, IPager<ExpandoObject> 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<Review>(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<Review>(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();

View File

@ -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<bool> 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<bool> 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<bool> 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<bool> IsAuthUserReview(int reviewId)
{
return (await _dbContext.Reviews.FirstAsync(r => r.Id == reviewId)).UserId == GetAuthUserId();
}
}

View File

@ -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<TicketGroupDto> _ticketGroupDataShaper;
private readonly IDataShaper<TicketGroupWithTicketsDto> _ticketGroupWithTicketsDataShaper;
private readonly IPager<ExpandoObject> _pager;
private readonly ISessionUserService _sessionUserService;
public TicketGroupManagementService(ApplicationDbContext dbContext, IMapper mapper,
ISortHelper<ExpandoObject> ticketGroupSortHelper, IDataShaper<TicketGroupDto> ticketGroupDataShaper,
IDataShaper<TicketGroupWithTicketsDto> ticketGroupWithTicketsDataShaper, IPager<ExpandoObject> pager)
IDataShaper<TicketGroupWithTicketsDto> ticketGroupWithTicketsDataShaper, IPager<ExpandoObject> 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<TicketGroupDto>(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<TicketGroupWithTicketsDto>(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<TicketGroupDto>(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<TicketGroupDto>(dbTicketGroup);

View File

@ -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<VehicleEnrollmentDto> _enrollmentDataShaper;
private readonly IDataShaper<VehicleEnrollmentWithDetailsDto> _enrollmentWithDetailsDataShaper;
private readonly IPager<ExpandoObject> _pager;
private readonly ISessionUserService _sessionUserService;
public VehicleEnrollmentManagementService(ApplicationDbContext dbContext,
IMapper mapper, ISortHelper<ExpandoObject> enrollmentSortHelper,
IDataShaper<VehicleEnrollmentDto> enrollmentDataShaper, IPager<ExpandoObject> pager,
IDataShaper<VehicleEnrollmentWithDetailsDto> enrollmentWithDetailsDataShaper)
IDataShaper<VehicleEnrollmentWithDetailsDto> 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<VehicleEnrollment>(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<VehicleEnrollment>(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<VehicleEnrollment>(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();

View File

@ -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<ExpandoObject> _vehicleSortHelper;
private readonly IDataShaper<VehicleDto> _vehicleDataShaper;
private readonly IPager<ExpandoObject> _pager;
private readonly ISessionUserService _sessionUserService;
public VehicleManagementService(ApplicationDbContext dbContext,
IMapper mapper, ISortHelper<ExpandoObject> vehicleSortHelper,
IDataShaper<VehicleDto> vehicleDataShaper, IPager<ExpandoObject> pager)
IDataShaper<VehicleDto> vehicleDataShaper, IPager<ExpandoObject> 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<Vehicle>(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<VehicleDto>(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<Vehicle>(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);
}
}

View File

@ -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<string>? Roles { get; set; }
}

View File

@ -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!;

View File

@ -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

View File

@ -8,17 +8,20 @@ public class VehicleEnrollmentDto : CreateVehicleEnrollmentDto
public IList<InVehicleEnrollmentTicketDto> Tickets { get; set; } = null!;
public IList<InVehicleEnrollmentReviewDto> 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

View File

@ -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()
{