Removed the permission check from project details API

This commit is contained in:
ashutosh.nehete 2025-10-01 10:32:04 +05:30
parent 0066e20c43
commit 040e7df32b
2 changed files with 28 additions and 21 deletions

View File

@ -27,7 +27,7 @@ namespace Marco.Pms.Model.Dtos.Project
[DisplayName("Project Status")] [DisplayName("Project Status")]
[Required(ErrorMessage = "Project Status is required!")] [Required(ErrorMessage = "Project Status is required!")]
public required Guid ProjectStatusId { get; set; } public required Guid ProjectStatusId { get; set; }
public required Guid PromoterId { get; set; } public Guid? PromoterId { get; set; }
public required Guid PMCId { get; set; } public Guid? PMCId { get; set; }
} }
} }

View File

@ -201,21 +201,21 @@ namespace Marco.Pms.Services.Service
using var scope = _serviceScopeFactory.CreateScope(); using var scope = _serviceScopeFactory.CreateScope();
var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>(); var _permission = scope.ServiceProvider.GetRequiredService<PermissionServices>();
// Step 1: Check global view project permission //// Step 1: Check global view project permission
var hasViewProjectPermission = await _permission.HasPermission(PermissionsMaster.ViewProject, loggedInEmployee.Id, id); //var hasViewProjectPermission = await _permission.HasPermission(PermissionsMaster.ViewProject, loggedInEmployee.Id, id);
if (!hasViewProjectPermission) //if (!hasViewProjectPermission)
{ //{
_logger.LogWarning("ViewProjects permission denied for EmployeeId: {EmployeeId}", loggedInEmployee.Id); // _logger.LogWarning("ViewProjects permission denied for EmployeeId: {EmployeeId}", loggedInEmployee.Id);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to view projects", 403); // return ApiResponse<object>.ErrorResponse("Access denied", "You don't have permission to view projects", 403);
} //}
// 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.HasProjectPermission(loggedInEmployee, 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);
return ApiResponse<object>.ErrorResponse("Access denied", "You don't have access to this project", 403); // return ApiResponse<object>.ErrorResponse("Access denied", "You don't have access to this project", 403);
} //}
// Step 3: Fetch project with status // Step 3: Fetch project with status
var projectDetails = await _cache.GetProjectDetails(id); var projectDetails = await _cache.GetProjectDetails(id);
@ -481,6 +481,7 @@ namespace Marco.Pms.Services.Service
// --- Step 1: Fetch the Existing Entity from the Database --- // --- Step 1: Fetch the Existing Entity from the Database ---
// This is crucial to avoid the data loss bug. We only want to modify an existing record. // This is crucial to avoid the data loss bug. We only want to modify an existing record.
var existingProject = await _context.Projects var existingProject = await _context.Projects
.AsNoTracking()
.Where(p => p.Id == id && p.TenantId == tenantId) .Where(p => p.Id == id && p.TenantId == tenantId)
.SingleOrDefaultAsync(); .SingleOrDefaultAsync();
@ -501,17 +502,20 @@ namespace Marco.Pms.Services.Service
return ApiResponse<object>.ErrorResponse("Access Denied", "You do not have permission to update a project for this tenant.", 403); return ApiResponse<object>.ErrorResponse("Access Denied", "You do not have permission to update a project for this tenant.", 403);
} }
var promoterId = model.PromoterId ?? loggedInEmployee.OrganizationId;
var pmcId = model.PMCId ?? loggedInEmployee.OrganizationId;
// 1bb. Concurrent validation for Promoter and PMC organization existence. // 1bb. Concurrent validation for Promoter and PMC organization existence.
// Run database queries in parallel for better performance. // Run database queries in parallel for better performance.
var promoterTask = Task.Run(async () => var promoterTask = Task.Run(async () =>
{ {
await using var context = await _dbContextFactory.CreateDbContextAsync(); await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.Organizations.FirstOrDefaultAsync(o => o.Id == model.PromoterId); return await context.Organizations.FirstOrDefaultAsync(o => o.Id == promoterId);
}); });
var pmcTask = Task.Run(async () => var pmcTask = Task.Run(async () =>
{ {
await using var context = await _dbContextFactory.CreateDbContextAsync(); await using var context = await _dbContextFactory.CreateDbContextAsync();
return await context.Organizations.FirstOrDefaultAsync(o => o.Id == model.PMCId); return await context.Organizations.FirstOrDefaultAsync(o => o.Id == pmcId);
}); });
await Task.WhenAll(promoterTask, pmcTask); await Task.WhenAll(promoterTask, pmcTask);
@ -521,12 +525,12 @@ namespace Marco.Pms.Services.Service
if (promoter == null) if (promoter == null)
{ {
_logger.LogWarning("Promoter check failed. PromoterId={PromoterId} not found.", model.PromoterId); _logger.LogWarning("Promoter check failed. PromoterId={PromoterId} not found.", promoterId);
return ApiResponse<object>.ErrorResponse("Promoter not found", "Promoter not found in database.", 404); return ApiResponse<object>.ErrorResponse("Promoter not found", "Promoter not found in database.", 404);
} }
if (pmc == null) if (pmc == null)
{ {
_logger.LogWarning("PMC check failed. PMCId={PMCId} not found.", model.PMCId); _logger.LogWarning("PMC check failed. PMCId={PMCId} not found.", pmcId);
return ApiResponse<object>.ErrorResponse("PMC not found", "PMC not found in database.", 404); return ApiResponse<object>.ErrorResponse("PMC not found", "PMC not found in database.", 404);
} }
@ -543,8 +547,11 @@ namespace Marco.Pms.Services.Service
// This only modifies the properties defined in the mapping, preventing data loss. // This only modifies the properties defined in the mapping, preventing data loss.
_mapper.Map(model, existingProject); _mapper.Map(model, existingProject);
existingProject.PromoterId = promoterId;
existingProject.PMCId = pmcId;
// Mark the entity as modified (if your mapping doesn't do it automatically). // Mark the entity as modified (if your mapping doesn't do it automatically).
_context.Entry(existingProject).State = EntityState.Modified; _context.Projects.Update(existingProject);
try try
{ {