Optimize the get list of basic project for both infra and service
This commit is contained in:
parent
0395b46610
commit
c820b973a8
@ -174,7 +174,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
var hasTeamAttendancePermission = await _permission.HasPermission(PermissionsMaster.TeamAttendance, loggedInEmployee.Id);
|
var hasTeamAttendancePermission = await _permission.HasPermission(PermissionsMaster.TeamAttendance, loggedInEmployee.Id);
|
||||||
var hasSelfAttendancePermission = await _permission.HasPermission(PermissionsMaster.SelfAttendance, loggedInEmployee.Id);
|
var hasSelfAttendancePermission = await _permission.HasPermission(PermissionsMaster.SelfAttendance, loggedInEmployee.Id);
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
|
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
@ -353,7 +353,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return NotFound(ApiResponse<object>.ErrorResponse("Project not found."));
|
return NotFound(ApiResponse<object>.ErrorResponse("Project not found."));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!await _permission.HasProjectPermission(loggedInEmployee, projectId))
|
if (!await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId))
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Unauthorized access attempt by EmployeeId: {EmployeeId} for ProjectId: {ProjectId}", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("Unauthorized access attempt by EmployeeId: {EmployeeId} for ProjectId: {ProjectId}", loggedInEmployee.Id, projectId);
|
||||||
return Unauthorized(ApiResponse<object>.ErrorResponse("You do not have permission to access this project."));
|
return Unauthorized(ApiResponse<object>.ErrorResponse("You do not have permission to access this project."));
|
||||||
@ -399,7 +399,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
|
|
||||||
Employee LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
Employee LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync();
|
||||||
var result = new List<EmployeeAttendanceVM>();
|
var result = new List<EmployeeAttendanceVM>();
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(LoggedInEmployee, projectId);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(LoggedInEmployee.Id, projectId);
|
||||||
|
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -269,7 +269,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
using var scope = _serviceScopeFactory.CreateScope();
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
// Security Check: Ensure the requested project is in the user's accessible list.
|
// Security Check: Ensure the requested project is in the user's accessible list.
|
||||||
var hasPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId.Value);
|
var hasPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId.Value);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} on project {ProjectId} (not active or not accessible).", loggedInEmployee.Id, projectId.Value);
|
_logger.LogWarning("Access DENIED for user {UserId} on project {ProjectId} (not active or not accessible).", loggedInEmployee.Id, projectId.Value);
|
||||||
@ -358,7 +358,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
|
|
||||||
// 2a. Security Check: Verify permission for the specific project.
|
// 2a. Security Check: Verify permission for the specific project.
|
||||||
var hasPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId.Value);
|
var hasPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId.Value);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} on project {ProjectId}.", loggedInEmployee.Id, projectId.Value);
|
_logger.LogWarning("Access DENIED for user {UserId} on project {ProjectId}.", loggedInEmployee.Id, projectId.Value);
|
||||||
@ -689,7 +689,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
using var scope = _serviceScopeFactory.CreateScope();
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
|
|
||||||
bool hasPermission = await _permission.HasProjectPermission(loggedInEmployee!, projectId);
|
bool hasPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Unauthorized access by EmployeeId: {EmployeeId} to ProjectId: {ProjectId}", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("Unauthorized access by EmployeeId: {EmployeeId} to ProjectId: {ProjectId}", loggedInEmployee.Id, projectId);
|
||||||
|
|||||||
@ -96,7 +96,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
// Project permission check
|
// Project permission check
|
||||||
if (ProjectEntity == entityTypeId)
|
if (ProjectEntity == entityTypeId)
|
||||||
{
|
{
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, entityId);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, entityId);
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Employee {EmployeeId} does not have project access for ProjectId {ProjectId}", loggedInEmployee.Id, entityId);
|
_logger.LogWarning("Employee {EmployeeId} does not have project access for ProjectId {ProjectId}", loggedInEmployee.Id, entityId);
|
||||||
@ -1085,7 +1085,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
entityExists = await _context.Projects.AnyAsync(p => p.Id == oldAttachment.EntityId && p.TenantId == tenantId);
|
entityExists = await _context.Projects.AnyAsync(p => p.Id == oldAttachment.EntityId && p.TenantId == tenantId);
|
||||||
if (entityExists)
|
if (entityExists)
|
||||||
{
|
{
|
||||||
entityExists = await _permission.HasProjectPermission(loggedInEmployee, oldAttachment.EntityId);
|
entityExists = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, oldAttachment.EntityId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -153,7 +153,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
return NotFound(ApiResponse<object>.ErrorResponse("Project not found", "Project not found", 404));
|
return NotFound(ApiResponse<object>.ErrorResponse("Project not found", "Project not found", 404));
|
||||||
}
|
}
|
||||||
// Check if the logged-in employee has permission for the requested project
|
// Check if the logged-in employee has permission for the requested project
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("User {EmployeeId} attempts to get employees for project {ProjectId} without permission", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("User {EmployeeId} attempts to get employees for project {ProjectId} without permission", loggedInEmployee.Id, projectId);
|
||||||
@ -333,7 +333,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
var employeeQuery = _context.Employees.Where(e => e.IsActive);
|
var employeeQuery = _context.Employees.Where(e => e.IsActive);
|
||||||
if (projectId != null && projectId != Guid.Empty)
|
if (projectId != null && projectId != Guid.Empty)
|
||||||
{
|
{
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId.Value);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId.Value);
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("User {EmployeeId} attempts to get employee for project {ProjectId}, but not have access to the project", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("User {EmployeeId} attempts to get employee for project {ProjectId}, but not have access to the project", loggedInEmployee.Id, projectId);
|
||||||
@ -401,7 +401,7 @@ namespace MarcoBMS.Services.Controllers
|
|||||||
loggedInEmployee.Id, projectId);
|
loggedInEmployee.Id, projectId);
|
||||||
|
|
||||||
// Validate project access permission
|
// Validate project access permission
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId.Value);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId.Value);
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} does not have permission for ProjectId: {ProjectId}",
|
_logger.LogWarning("Access denied. EmployeeId: {EmployeeId} does not have permission for ProjectId: {ProjectId}",
|
||||||
|
|||||||
@ -63,7 +63,7 @@ namespace Marco.Pms.Services.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Check project access permission
|
// Step 2: Check project access permission
|
||||||
var hasPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var hasPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("[GetImageList] Access denied for EmployeeId: {EmployeeId} on ProjectId: {ProjectId}", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("[GetImageList] Access denied for EmployeeId: {EmployeeId} on ProjectId: {ProjectId}", loggedInEmployee.Id, projectId);
|
||||||
|
|||||||
@ -594,90 +594,6 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Helper Methods (Private)
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Fetches the list of possible next statuses based on current status.
|
|
||||||
/// </summary>
|
|
||||||
private async Task<List<ExpensesStatusMaster>> GetNextStatusesAsync(Guid? currentStatusId, Guid tenantId)
|
|
||||||
{
|
|
||||||
if (!currentStatusId.HasValue) return new List<ExpensesStatusMaster>();
|
|
||||||
|
|
||||||
return await _context.ExpensesStatusMapping
|
|
||||||
.AsNoTracking()
|
|
||||||
.Include(esm => esm.NextStatus).ThenInclude(s => s!.StatusPermissionMappings)
|
|
||||||
.Where(esm => esm.StatusId == currentStatusId && esm.Status != null)
|
|
||||||
.Select(esm => esm.NextStatus!) // Select only the NextStatus entity
|
|
||||||
.ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Filters statuses by permission and reorders specific actions (e.g., Reject).
|
|
||||||
/// </summary>
|
|
||||||
private List<ExpensesStatusMasterVM> ProcessNextStatuses(List<ExpensesStatusMaster> nextStatuses, Guid createdById, Guid loggedInEmployeeId, List<Guid> userPermissionIds)
|
|
||||||
{
|
|
||||||
if (nextStatuses == null || !nextStatuses.Any()) return new List<ExpensesStatusMasterVM>();
|
|
||||||
|
|
||||||
// Business Logic: Move "Reject" to the top
|
|
||||||
var rejectStatus = nextStatuses.FirstOrDefault(ns => ns.DisplayName == "Reject");
|
|
||||||
if (rejectStatus != null)
|
|
||||||
{
|
|
||||||
nextStatuses.Remove(rejectStatus);
|
|
||||||
nextStatuses.Insert(0, rejectStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultVMs = new List<ExpensesStatusMasterVM>();
|
|
||||||
|
|
||||||
foreach (var item in nextStatuses)
|
|
||||||
{
|
|
||||||
var vm = _mapper.Map<ExpensesStatusMasterVM>(item);
|
|
||||||
|
|
||||||
// Case 1: If Creator is viewing and status is Review (Assuming Review is a constant GUID or Enum)
|
|
||||||
if (item.Id == Review && createdById == loggedInEmployeeId)
|
|
||||||
{
|
|
||||||
resultVMs.Add(vm);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case 2: Standard Permission Check
|
|
||||||
bool hasPermission = vm.PermissionIds.Any(pid => userPermissionIds.Contains(pid));
|
|
||||||
|
|
||||||
// Exclude "Done" status (Assuming Done is a constant GUID)
|
|
||||||
if (hasPermission && item.Id != Done)
|
|
||||||
{
|
|
||||||
resultVMs.Add(vm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return resultVMs.Distinct().ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Attempts to fetch project details from Projects table, falling back to ServiceProjects.
|
|
||||||
/// </summary>
|
|
||||||
private async Task<BasicProjectVM?> GetProjectDetailsAsync(Guid? projectId, Guid tenantId)
|
|
||||||
{
|
|
||||||
if (!projectId.HasValue) return null;
|
|
||||||
|
|
||||||
// Check Infrastructure Projects
|
|
||||||
var infraProject = await _context.Projects
|
|
||||||
.AsNoTracking()
|
|
||||||
.Where(p => p.Id == projectId && p.TenantId == tenantId)
|
|
||||||
.ProjectTo<BasicProjectVM>(_mapper.ConfigurationProvider) // Optimized: Project directly to VM inside SQL
|
|
||||||
.FirstOrDefaultAsync();
|
|
||||||
|
|
||||||
if (infraProject != null) return infraProject;
|
|
||||||
|
|
||||||
// Fallback to Service Projects
|
|
||||||
return await _context.ServiceProjects
|
|
||||||
.AsNoTracking()
|
|
||||||
.Where(sp => sp.Id == projectId && sp.TenantId == tenantId)
|
|
||||||
.ProjectTo<BasicProjectVM>(_mapper.ConfigurationProvider)
|
|
||||||
.FirstOrDefaultAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public async Task<ApiResponse<object>> GetSupplerNameListAsync(Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> GetSupplerNameListAsync(Employee loggedInEmployee, Guid tenantId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -4367,6 +4283,85 @@ namespace Marco.Pms.Services.Service
|
|||||||
return CreateExpenseAttachmentEntities(batchId, expense.Id, employeeId, tenantId, objectKey, attachment);
|
return CreateExpenseAttachmentEntities(batchId, expense.Id, employeeId, tenantId, objectKey, attachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetches the list of possible next statuses based on current status.
|
||||||
|
/// </summary>
|
||||||
|
private async Task<List<ExpensesStatusMaster>> GetNextStatusesAsync(Guid? currentStatusId, Guid tenantId)
|
||||||
|
{
|
||||||
|
if (!currentStatusId.HasValue) return new List<ExpensesStatusMaster>();
|
||||||
|
|
||||||
|
return await _context.ExpensesStatusMapping
|
||||||
|
.AsNoTracking()
|
||||||
|
.Include(esm => esm.NextStatus).ThenInclude(s => s!.StatusPermissionMappings)
|
||||||
|
.Where(esm => esm.StatusId == currentStatusId && esm.Status != null)
|
||||||
|
.Select(esm => esm.NextStatus!) // Select only the NextStatus entity
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Filters statuses by permission and reorders specific actions (e.g., Reject).
|
||||||
|
/// </summary>
|
||||||
|
private List<ExpensesStatusMasterVM> ProcessNextStatuses(List<ExpensesStatusMaster> nextStatuses, Guid createdById, Guid loggedInEmployeeId, List<Guid> userPermissionIds)
|
||||||
|
{
|
||||||
|
if (nextStatuses == null || !nextStatuses.Any()) return new List<ExpensesStatusMasterVM>();
|
||||||
|
|
||||||
|
// Business Logic: Move "Reject" to the top
|
||||||
|
var rejectStatus = nextStatuses.FirstOrDefault(ns => ns.DisplayName == "Reject");
|
||||||
|
if (rejectStatus != null)
|
||||||
|
{
|
||||||
|
nextStatuses.Remove(rejectStatus);
|
||||||
|
nextStatuses.Insert(0, rejectStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
var resultVMs = new List<ExpensesStatusMasterVM>();
|
||||||
|
|
||||||
|
foreach (var item in nextStatuses)
|
||||||
|
{
|
||||||
|
var vm = _mapper.Map<ExpensesStatusMasterVM>(item);
|
||||||
|
|
||||||
|
// Case 1: If Creator is viewing and status is Review (Assuming Review is a constant GUID or Enum)
|
||||||
|
if (item.Id == Review && createdById == loggedInEmployeeId)
|
||||||
|
{
|
||||||
|
resultVMs.Add(vm);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case 2: Standard Permission Check
|
||||||
|
bool hasPermission = vm.PermissionIds.Any(pid => userPermissionIds.Contains(pid));
|
||||||
|
|
||||||
|
// Exclude "Done" status (Assuming Done is a constant GUID)
|
||||||
|
if (hasPermission && item.Id != Done)
|
||||||
|
{
|
||||||
|
resultVMs.Add(vm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultVMs.Distinct().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to fetch project details from Projects table, falling back to ServiceProjects.
|
||||||
|
/// </summary>
|
||||||
|
private async Task<BasicProjectVM?> GetProjectDetailsAsync(Guid? projectId, Guid tenantId)
|
||||||
|
{
|
||||||
|
if (!projectId.HasValue) return null;
|
||||||
|
|
||||||
|
// Check Infrastructure Projects
|
||||||
|
var infraProject = await _context.Projects
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(p => p.Id == projectId && p.TenantId == tenantId)
|
||||||
|
.ProjectTo<BasicProjectVM>(_mapper.ConfigurationProvider) // Optimized: Project directly to VM inside SQL
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
|
||||||
|
if (infraProject != null) return infraProject;
|
||||||
|
|
||||||
|
// Fallback to Service Projects
|
||||||
|
return await _context.ServiceProjects
|
||||||
|
.AsNoTracking()
|
||||||
|
.Where(sp => sp.Id == projectId && sp.TenantId == tenantId)
|
||||||
|
.ProjectTo<BasicProjectVM>(_mapper.ConfigurationProvider)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A private static helper method to create Document and BillAttachment entities.
|
/// A private static helper method to create Document and BillAttachment entities.
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using Marco.Pms.DataAccess.Data;
|
using Marco.Pms.DataAccess.Data;
|
||||||
using Marco.Pms.Model.Employees;
|
|
||||||
using Marco.Pms.Model.Entitlements;
|
using Marco.Pms.Model.Entitlements;
|
||||||
using Marco.Pms.Services.Helpers;
|
using Marco.Pms.Services.Helpers;
|
||||||
using MarcoBMS.Services.Helpers;
|
using MarcoBMS.Services.Helpers;
|
||||||
@ -50,29 +49,28 @@ namespace Marco.Pms.Services.Service
|
|||||||
var hasPermission = toCheckPermissionIds.Any(f => realPermissionIds.Contains(f));
|
var hasPermission = toCheckPermissionIds.Any(f => realPermissionIds.Contains(f));
|
||||||
return hasPermission;
|
return hasPermission;
|
||||||
}
|
}
|
||||||
public async Task<bool> HasProjectPermission(Employee LoggedInEmployee, Guid projectId)
|
public async Task<bool> HasInfraProjectPermission(Guid loggedInEmployeeId, Guid projectId)
|
||||||
{
|
{
|
||||||
var employeeId = LoggedInEmployee.Id;
|
var projectIds = await _cache.GetProjects(loggedInEmployeeId, tenantId);
|
||||||
var projectIds = await _cache.GetProjects(employeeId, tenantId);
|
|
||||||
|
|
||||||
if (projectIds == null)
|
if (projectIds == null)
|
||||||
{
|
{
|
||||||
var hasPermission = await HasPermission(PermissionsMaster.ManageProject, employeeId);
|
var hasPermission = await HasPermission(PermissionsMaster.ManageProject, loggedInEmployeeId);
|
||||||
if (hasPermission)
|
if (hasPermission)
|
||||||
{
|
{
|
||||||
var projects = await _context.Projects.AsNoTracking().Where(c => c.TenantId == LoggedInEmployee.TenantId).ToListAsync();
|
var projects = await _context.Projects.AsNoTracking().Where(c => c.TenantId == tenantId).ToListAsync();
|
||||||
projectIds = projects.Select(p => p.Id).ToList();
|
projectIds = projects.Select(p => p.Id).ToList();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var allocation = await _context.ProjectAllocations.AsNoTracking().Where(c => c.EmployeeId == employeeId && c.IsActive).ToListAsync();
|
var allocation = await _context.ProjectAllocations.AsNoTracking().Where(c => c.EmployeeId == loggedInEmployeeId && c.IsActive).ToListAsync();
|
||||||
if (!allocation.Any())
|
if (!allocation.Any())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList();
|
projectIds = allocation.Select(c => c.ProjectId).Distinct().ToList();
|
||||||
}
|
}
|
||||||
await _cache.AddProjects(LoggedInEmployee.Id, projectIds, tenantId);
|
await _cache.AddProjects(loggedInEmployeeId, projectIds, tenantId);
|
||||||
}
|
}
|
||||||
return projectIds.Contains(projectId);
|
return projectIds.Contains(projectId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,89 +54,144 @@ namespace Marco.Pms.Services.Service
|
|||||||
|
|
||||||
#region =================================================================== Project Get APIs ===================================================================\
|
#region =================================================================== Project Get APIs ===================================================================\
|
||||||
|
|
||||||
/// <summary>
|
public async Task<ApiResponse<List<BasicProjectVM>>> GetBothProjectBasicListAsync(Guid? id, string? searchString, Employee loggedInEmployee, Guid tenantId)
|
||||||
/// Retrieves a combined list of basic infrastructure and active service projects accessible by the logged-in employee within a tenant.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="searchString">Optional search term to filter projects by name (if implemented).</param>
|
|
||||||
/// <param name="loggedInEmployee">Authenticated employee requesting the data.</param>
|
|
||||||
/// <param name="tenantId">Tenant identifier to ensure multi-tenant data isolation.</param>
|
|
||||||
/// <returns>Returns an ApiResponse containing the distinct combined list of basic project view models or an error response.</returns>
|
|
||||||
public async Task<ApiResponse<object>> GetBothProjectBasicListAsync(Guid? id, string? searchString, Employee loggedInEmployee, Guid tenantId)
|
|
||||||
{
|
{
|
||||||
|
// 1. Validation and Context Checks
|
||||||
if (tenantId == Guid.Empty)
|
if (tenantId == Guid.Empty)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("GetBothProjectBasicListAsync called with invalid tenant context by EmployeeId {EmployeeId}", loggedInEmployee.Id);
|
_logger.LogWarning("Security Alert: GetBothProjectBasicListAsync called with empty TenantId by Employee: {EmployeeId}", loggedInEmployee.Id);
|
||||||
return ApiResponse<object>.ErrorResponse("Access Denied", "Invalid tenant context.", 403);
|
return ApiResponse<List<BasicProjectVM>>.ErrorResponse("Access Denied", "Invalid tenant context provided.", 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Retrieve list of project IDs accessible by the employee for tenant isolation and security
|
_logger.LogInfo("Initiating project fetch for Tenant: {TenantId}, User: {UserId}. Search: {Search}", tenantId, loggedInEmployee.Id, searchString ?? "None");
|
||||||
var accessibleProjectIds = await GetMyProjects(loggedInEmployee, tenantId);
|
|
||||||
|
|
||||||
// Fetch infrastructure projects concurrently filtered by accessible IDs and tenant
|
// 2. Check Permissions (Global check, do not block parallel tasks if possible, but needed for logic)
|
||||||
var infraProjectTask = Task.Run(async () =>
|
// usage of scoped service for permission check
|
||||||
|
using var scope = _serviceScopeFactory.CreateScope();
|
||||||
|
var permissionService = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
|
bool hasManagePermission = await permissionService.HasPermission(PermissionsMaster.ManageProject, loggedInEmployee.Id);
|
||||||
|
|
||||||
|
// 3. Define Parallel Tasks
|
||||||
|
// We use DbContextFactory to create short-lived contexts for safe parallel execution.
|
||||||
|
|
||||||
|
// --- TASK A: Infrastructure Projects ---
|
||||||
|
var infraTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
var infraProjectsQuery = context.Projects
|
|
||||||
.Where(p => accessibleProjectIds.Contains(p.Id) && p.TenantId == tenantId);
|
// Base Query
|
||||||
|
var query = context.Projects.AsNoTracking()
|
||||||
|
.Where(p => p.TenantId == tenantId);
|
||||||
|
|
||||||
|
// Apply Filters
|
||||||
|
if (id.HasValue)
|
||||||
|
{
|
||||||
|
query = query.Where(p => p.Id == id.Value);
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(searchString))
|
if (!string.IsNullOrWhiteSpace(searchString))
|
||||||
{
|
{
|
||||||
var normalized = searchString.Trim().ToLowerInvariant();
|
// Normalize search term. NOTE: Check if your DB Collation is already Case Insensitive (CI).
|
||||||
infraProjectsQuery = infraProjectsQuery
|
// If DB is CI, you don't need ToLower(). Assuming standard needed:
|
||||||
.Where(p => p.Name.ToLower().Contains(normalized) ||
|
string normalized = searchString.Trim();
|
||||||
(!string.IsNullOrWhiteSpace(p.ShortName) && p.ShortName.ToLower().Contains(normalized)));
|
query = query.Where(p => p.Name.Contains(normalized) ||
|
||||||
}
|
(p.ShortName != null && p.ShortName.Contains(normalized)));
|
||||||
if (id.HasValue)
|
|
||||||
{
|
|
||||||
infraProjectsQuery = infraProjectsQuery.Where(p => p.Id == id.Value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var infraProjects = await infraProjectsQuery.ToListAsync();
|
// Apply Security (Row Level Access)
|
||||||
return infraProjects.Select(p => _mapper.Map<BasicProjectVM>(p)).ToList();
|
if (!hasManagePermission)
|
||||||
|
{
|
||||||
|
// Optimization: Use Any() to create an EXISTS clause in SQL rather than fetching IDs to memory
|
||||||
|
query = query.Where(p => context.ProjectAllocations.Any(pa =>
|
||||||
|
pa.ProjectId == p.Id &&
|
||||||
|
pa.EmployeeId == loggedInEmployee.Id &&
|
||||||
|
pa.IsActive &&
|
||||||
|
pa.TenantId == tenantId));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Projection: Select only what is needed before hitting DB
|
||||||
|
return await query
|
||||||
|
.ProjectTo<BasicProjectVM>(_mapper.ConfigurationProvider)
|
||||||
|
.ToListAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch active service projects concurrently with tenant isolation
|
|
||||||
var serviceProjectTask = Task.Run(async () =>
|
// --- TASK B: Service Projects ---
|
||||||
|
var serviceTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await using var context = await _dbContextFactory.CreateDbContextAsync();
|
using var context = await _dbContextFactory.CreateDbContextAsync();
|
||||||
var serviceProjectsQuery = context.ServiceProjects
|
|
||||||
|
var query = context.ServiceProjects.AsNoTracking()
|
||||||
.Where(sp => sp.TenantId == tenantId && sp.IsActive);
|
.Where(sp => sp.TenantId == tenantId && sp.IsActive);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(searchString))
|
|
||||||
{
|
|
||||||
var normalized = searchString.Trim().ToLowerInvariant();
|
|
||||||
serviceProjectsQuery = serviceProjectsQuery
|
|
||||||
.Where(sp => sp.Name.ToLower().Contains(normalized) ||
|
|
||||||
(!string.IsNullOrWhiteSpace(sp.ShortName) && sp.ShortName.ToLower().Contains(normalized)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id.HasValue)
|
if (id.HasValue)
|
||||||
{
|
{
|
||||||
serviceProjectsQuery = serviceProjectsQuery.Where(sp => sp.Id == id.Value);
|
query = query.Where(sp => sp.Id == id.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceProjects = await serviceProjectsQuery.ToListAsync();
|
if (!string.IsNullOrWhiteSpace(searchString))
|
||||||
return serviceProjects.Select(sp => _mapper.Map<BasicProjectVM>(sp)).ToList();
|
{
|
||||||
|
string normalized = searchString.Trim();
|
||||||
|
query = query.Where(sp => sp.Name.Contains(normalized) ||
|
||||||
|
(sp.ShortName != null && sp.ShortName.Contains(normalized)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasManagePermission)
|
||||||
|
{
|
||||||
|
// Optimization: Complex security filter pushed to DB
|
||||||
|
// User has access if: Allocated directly OR Mapped via JobTicket
|
||||||
|
query = query.Where(sp =>
|
||||||
|
// Condition 1: Direct Allocation
|
||||||
|
context.ServiceProjectAllocations.Any(spa =>
|
||||||
|
spa.ProjectId == sp.Id &&
|
||||||
|
spa.EmployeeId == loggedInEmployee.Id &&
|
||||||
|
spa.TenantId == tenantId &&
|
||||||
|
spa.IsActive)
|
||||||
|
||
|
||||||
|
// Condition 2: Job Ticket Mapping
|
||||||
|
context.JobEmployeeMappings.Any(jem =>
|
||||||
|
jem.JobTicket != null &&
|
||||||
|
jem.JobTicket.ProjectId == sp.Id &&
|
||||||
|
jem.AssigneeId == loggedInEmployee.Id &&
|
||||||
|
jem.TenantId == tenantId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await query
|
||||||
|
.ProjectTo<BasicProjectVM>(_mapper.ConfigurationProvider)
|
||||||
|
.ToListAsync();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for both concurrent tasks to complete
|
// 4. Await Completion
|
||||||
await Task.WhenAll(infraProjectTask, serviceProjectTask);
|
await Task.WhenAll(infraTask, serviceTask);
|
||||||
|
|
||||||
// Combine, remove duplicates, and prepare response list
|
// 5. Aggregate Results
|
||||||
var combinedProjects = infraProjectTask.Result.Concat(serviceProjectTask.Result).OrderBy(p => p.Name).Distinct().ToList();
|
// DistinctBy is available in .NET 6+. If older, use GroupBy or distinct comparer.
|
||||||
|
var infraResults = await infraTask;
|
||||||
|
var serviceResults = await serviceTask;
|
||||||
|
|
||||||
_logger.LogInfo("GetBothProjectBasicListAsync returning {Count} projects for tenant {TenantId} by EmployeeId {EmployeeId}",
|
var combinedProjects = infraResults
|
||||||
combinedProjects.Count, tenantId, loggedInEmployee.Id);
|
.Concat(serviceResults)
|
||||||
|
.DistinctBy(p => p.Id) // Ensure no duplicate IDs if cross-contamination exists
|
||||||
|
.OrderBy(p => p.Name)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
return ApiResponse<object>.SuccessResponse(combinedProjects, "Service and infrastructure projects fetched successfully.", 200);
|
_logger.LogInfo("Successfully fetched {Count} projects ({InfraCount} Infra, {ServiceCount} Service) for User {UserId}.",
|
||||||
|
combinedProjects.Count, infraResults.Count, serviceResults.Count, loggedInEmployee.Id);
|
||||||
|
|
||||||
|
return ApiResponse<List<BasicProjectVM>>.SuccessResponse(combinedProjects, "Projects retrieved successfully.", 200);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("Project fetch operation was canceled by the client.");
|
||||||
|
return ApiResponse<List<BasicProjectVM>>.ErrorResponse("Request Canceled", "The operation was canceled.", 499);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, "Unexpected error in GetBothProjectBasicListAsync for tenant {TenantId} by EmployeeId {EmployeeId}",
|
_logger.LogError(ex, "CRITICAL: Failed to fetch projects for Tenant {TenantId}. Error: {Message}", tenantId, ex.Message);
|
||||||
tenantId, loggedInEmployee.Id);
|
return ApiResponse<List<BasicProjectVM>>.ErrorResponse("Internal Server Error", "An unexpected error occurred while processing your request.", 500);
|
||||||
return ApiResponse<object>.ErrorResponse("Internal Server Error", "An error occurred while fetching projects.", 500);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public async Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Employee loggedInEmployee, Guid tenantId)
|
public async Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Employee loggedInEmployee, Guid tenantId)
|
||||||
@ -278,7 +333,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
// --- Step 1: Run independent operations in PARALLEL ---
|
// --- Step 1: Run independent operations in PARALLEL ---
|
||||||
// We can check permissions and fetch data at the same time to reduce latency.
|
// We can check permissions and fetch data at the same time to reduce latency.
|
||||||
var permissionTask = _permission.HasProjectPermission(loggedInEmployee, id);
|
var permissionTask = _permission.HasInfraProjectPermission(loggedInEmployee.Id, id);
|
||||||
|
|
||||||
// This helper method encapsulates the "cache-first, then database" logic.
|
// This helper method encapsulates the "cache-first, then database" logic.
|
||||||
var projectDataTask = GetProjectDataAsync(id, tenantId);
|
var projectDataTask = GetProjectDataAsync(id, tenantId);
|
||||||
@ -333,7 +388,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Step 2: Check permission for this specific project
|
// Step 2: Check permission for this specific project
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, id);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, id);
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Project-specific access denied. EmployeeId: {EmployeeId}, ProjectId: {ProjectId}", loggedInEmployee.Id, id);
|
_logger.LogWarning("Project-specific access denied. EmployeeId: {EmployeeId}, ProjectId: {ProjectId}", loggedInEmployee.Id, id);
|
||||||
@ -649,7 +704,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1c. Security Check
|
// 1c. Security Check
|
||||||
var hasPermission = await _permission.HasProjectPermission(loggedInEmployee, id);
|
var hasPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, id);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} attempting to update project {ProjectId}.", loggedInEmployee.Id, id);
|
_logger.LogWarning("Access DENIED for user {UserId} attempting to update project {ProjectId}.", loggedInEmployee.Id, id);
|
||||||
@ -743,7 +798,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
// --- CRITICAL: Security Check ---
|
// --- CRITICAL: Security Check ---
|
||||||
// Before fetching data, you MUST verify the user has permission to see it.
|
// Before fetching data, you MUST verify the user has permission to see it.
|
||||||
// This is a placeholder for your actual permission logic.
|
// This is a placeholder for your actual permission logic.
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
var hasAllEmployeePermission = await _permission.HasPermission(PermissionsMaster.ViewAllEmployees, loggedInEmployee.Id);
|
var hasAllEmployeePermission = await _permission.HasPermission(PermissionsMaster.ViewAllEmployees, loggedInEmployee.Id);
|
||||||
var hasviewTeamPermission = await _permission.HasPermission(PermissionsMaster.ViewTeamMembers, loggedInEmployee.Id, projectId);
|
var hasviewTeamPermission = await _permission.HasPermission(PermissionsMaster.ViewTeamMembers, loggedInEmployee.Id, projectId);
|
||||||
|
|
||||||
@ -824,7 +879,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
// --- Step 2: Security and Existence Checks ---
|
// --- Step 2: Security and Existence Checks ---
|
||||||
// Before fetching data, you MUST verify the user has permission to see it.
|
// Before fetching data, you MUST verify the user has permission to see it.
|
||||||
// This is a placeholder for your actual permission logic.
|
// This is a placeholder for your actual permission logic.
|
||||||
var hasPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var hasPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} on project {ProjectId}.", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("Access DENIED for user {UserId} on project {ProjectId}.", loggedInEmployee.Id, projectId);
|
||||||
@ -1333,7 +1388,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the logged-in employee has permission for the requested project
|
// Check if the logged-in employee has permission for the requested project
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("User {EmployeeId} attempts to get employees for project {ProjectId} without permission", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("User {EmployeeId} attempts to get employees for project {ProjectId} without permission", loggedInEmployee.Id, projectId);
|
||||||
@ -1416,7 +1471,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check permission to view project team
|
// Check permission to view project team
|
||||||
var hasProjectPermission = await _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var hasProjectPermission = await _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasProjectPermission)
|
if (!hasProjectPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access denied: User {EmployeeId} tried to get team for Project {ProjectId}", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("Access denied: User {EmployeeId} tried to get team for Project {ProjectId}", loggedInEmployee.Id, projectId);
|
||||||
@ -1507,7 +1562,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
// --- Step 1: Run independent permission checks in PARALLEL ---
|
// --- Step 1: Run independent permission checks in PARALLEL ---
|
||||||
var projectPermissionTask = _permission.HasProjectPermission(loggedInEmployee, projectId);
|
var projectPermissionTask = _permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
var viewInfraPermissionTask = Task.Run(async () =>
|
var viewInfraPermissionTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
using var newScope = _serviceScopeFactory.CreateScope();
|
using var newScope = _serviceScopeFactory.CreateScope();
|
||||||
@ -1658,7 +1713,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
{
|
{
|
||||||
using var taskScope = _serviceScopeFactory.CreateScope();
|
using var taskScope = _serviceScopeFactory.CreateScope();
|
||||||
var permission = taskScope.ServiceProvider.GetRequiredService<PermissionServices>();
|
var permission = taskScope.ServiceProvider.GetRequiredService<PermissionServices>();
|
||||||
return await permission.HasProjectPermission(loggedInEmployee, projectId);
|
return await permission.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
});
|
});
|
||||||
var hasGenericViewInfraPermissionTask = Task.Run(async () =>
|
var hasGenericViewInfraPermissionTask = Task.Run(async () =>
|
||||||
{
|
{
|
||||||
@ -2511,7 +2566,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify logged-in employee has permission on the project
|
// Verify logged-in employee has permission on the project
|
||||||
var hasPermission = await permissionService.HasProjectPermission(loggedInEmployee, projectId);
|
var hasPermission = await permissionService.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} attempting to access project {ProjectId}.", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("Access DENIED for user {UserId} attempting to access project {ProjectId}.", loggedInEmployee.Id, projectId);
|
||||||
@ -2601,7 +2656,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate permission for logged-in employee to assign services to project
|
// Validate permission for logged-in employee to assign services to project
|
||||||
var hasPermission = await permissionService.HasProjectPermission(loggedInEmployee, model.ProjectId);
|
var hasPermission = await permissionService.HasInfraProjectPermission(loggedInEmployee.Id, model.ProjectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} attempting to assign services to project {ProjectId}.", loggedInEmployee.Id, model.ProjectId);
|
_logger.LogWarning("Access DENIED for user {UserId} attempting to assign services to project {ProjectId}.", loggedInEmployee.Id, model.ProjectId);
|
||||||
@ -2703,7 +2758,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify permission to update project
|
// Verify permission to update project
|
||||||
var hasPermission = await permissionService.HasProjectPermission(loggedInEmployee, model.ProjectId);
|
var hasPermission = await permissionService.HasInfraProjectPermission(loggedInEmployee.Id, model.ProjectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access DENIED for user {UserId} trying to deassign services from project {ProjectId}.", loggedInEmployee.Id, model.ProjectId);
|
_logger.LogWarning("Access DENIED for user {UserId} trying to deassign services from project {ProjectId}.", loggedInEmployee.Id, model.ProjectId);
|
||||||
@ -2801,7 +2856,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the logged in employee has permission to access the project
|
// Check if the logged in employee has permission to access the project
|
||||||
var hasPermission = await permissionService.HasProjectPermission(loggedInEmployee, projectId);
|
var hasPermission = await permissionService.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access denied for user {UserId} on project {ProjectId}", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("Access denied for user {UserId} on project {ProjectId}", loggedInEmployee.Id, projectId);
|
||||||
@ -2970,7 +3025,7 @@ namespace Marco.Pms.Services.Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if the logged in employee has permission to access the project
|
// Check if the logged in employee has permission to access the project
|
||||||
var hasPermission = await permissionService.HasProjectPermission(loggedInEmployee, projectId);
|
var hasPermission = await permissionService.HasInfraProjectPermission(loggedInEmployee.Id, projectId);
|
||||||
if (!hasPermission)
|
if (!hasPermission)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Access denied for user {UserId} on project {ProjectId}", loggedInEmployee.Id, projectId);
|
_logger.LogWarning("Access denied for user {UserId} on project {ProjectId}", loggedInEmployee.Id, projectId);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ namespace Marco.Pms.Services.Service.ServiceInterfaces
|
|||||||
{
|
{
|
||||||
public interface IProjectServices
|
public interface IProjectServices
|
||||||
{
|
{
|
||||||
Task<ApiResponse<object>> GetBothProjectBasicListAsync(Guid? id, string? searchString, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<List<BasicProjectVM>>> GetBothProjectBasicListAsync(Guid? id, string? searchString, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetAllProjectsBasicAsync(bool provideAll, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> GetAllProjectsAsync(string? searchString, int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetAllProjectsAsync(string? searchString, int pageNumber, int pageSize, Employee loggedInEmployee, Guid tenantId);
|
||||||
Task<ApiResponse<object>> GetProjectAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
Task<ApiResponse<object>> GetProjectAsync(Guid id, Employee loggedInEmployee, Guid tenantId);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user