From b638e35b252bce0765c7834a9fde7fed3d29bde7 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Tue, 27 May 2025 12:24:41 +0530 Subject: [PATCH 1/6] Enhancement #375: Update "Get Contact" API to Enforce Feature Permissions --- .../Controllers/DirectoryController.cs | 5 ++++ Marco.Pms.Services/Helpers/DirectoryHelper.cs | 29 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index fcd82a7..de262fb 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -39,12 +39,17 @@ namespace Marco.Pms.Services.Controllers { return Ok(response); } + else if (response.StatusCode == 401) + { + return Unauthorized(response); + } else { return BadRequest(response); } } + [HttpGet("contact-bucket/{bucketId}")] public async Task GetContactsListByBucketId(Guid bucketId) { diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index 370e8fd..5cf83b1 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -18,13 +18,18 @@ namespace Marco.Pms.Services.Helpers private readonly ApplicationDbContext _context; private readonly ILoggingService _logger; private readonly UserHelper _userHelper; - + private readonly Guid directoryAdmin; + private readonly Guid directoryManager; + private readonly Guid directoryUser; public DirectoryHelper(ApplicationDbContext context, ILoggingService logger, UserHelper userHelper) { _context = context; _logger = logger; _userHelper = userHelper; + directoryAdmin = Guid.Parse("4286a13b-bb40-4879-8c6d-18e9e393beda"); + directoryManager = Guid.Parse("62668630-13ce-4f52-a0f0-db38af2230c5"); + directoryUser = Guid.Parse("0f919170-92d4-4337-abd3-49b66fc871bb"); } @@ -33,9 +38,29 @@ namespace Marco.Pms.Services.Helpers { Guid tenantId = _userHelper.GetTenantId(); var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); + var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); List? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync(); List bucketIds = employeeBuckets.Select(c => c.BucketId).ToList(); - List filterbucketIds = employeeBuckets.Select(c => c.BucketId).ToList(); + if (permissionIds.Contains(directoryAdmin)) + { + var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).ToListAsync(); + bucketIds = buckets.Select(b => b.Id).ToList(); + } + else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(directoryUser)) + { + var buckets = await _context.Buckets.Where(b => b.CreatedByID == LoggedInEmployee.Id).ToListAsync(); + var createdBucketIds = buckets.Select(b => b.Id).ToList(); + bucketIds.AddRange(createdBucketIds); + bucketIds = bucketIds.Distinct().ToList(); + } + else + { + _logger.LogError("Employee {EmployeeId} attemped to access a contacts, but do not have permission", LoggedInEmployee.Id); + return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); + } + + List filterbucketIds = bucketIds; if (filterDto != null && filterDto.BucketIds != null && filterDto.BucketIds.Count > 0) { filterbucketIds = filterDto.BucketIds; -- 2.43.0 From 9f53fb2df7dae3bfec5bea9bd3ffc09f58d9cc81 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Tue, 27 May 2025 12:27:04 +0530 Subject: [PATCH 2/6] Enhancement #376: Update "Get Contact by Bucket ID" API to Enforce Feature Permissions --- Marco.Pms.Services/Helpers/DirectoryHelper.cs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index 5cf83b1..898f43f 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -185,12 +185,37 @@ namespace Marco.Pms.Services.Helpers var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); if (id != Guid.Empty) { - EmployeeBucketMapping? employeeBucket = await _context.EmployeeBucketMappings.FirstOrDefaultAsync(em => em.BucketId == id && em.EmployeeId == LoggedInEmployee.Id); + Bucket? bucket = await _context.Buckets.FirstOrDefaultAsync(b => b.Id == id && b.TenantId == tenantId); + if (bucket == null) + { + _logger.LogInfo("Employee ID {EmployeeId} attempted access to bucket ID {BucketId}, but not found in database", LoggedInEmployee.Id); + return ApiResponse.ErrorResponse("Bucket not found", "Bucket not found", 404); + } + List? employeeBuckets = await _context.EmployeeBucketMappings.Where(em => em.BucketId == id).ToListAsync(); + var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); + var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); + + EmployeeBucketMapping? employeeBucket = null; + if (permissionIds.Contains(directoryAdmin)) + { + employeeBucket = employeeBuckets.FirstOrDefault(); + } + else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(directoryUser)) + { + employeeBucket = employeeBuckets.FirstOrDefault(eb => eb.EmployeeId == LoggedInEmployee.Id); + } + else + { + _logger.LogError("Employee {EmployeeId} attemped to access a contacts with in bucket {BucketId}, but do not have permission", LoggedInEmployee.Id, id); + return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); + } + if (employeeBucket == null) { _logger.LogInfo("Employee ID {EmployeeId} does not have access to bucket ID {BucketId}", LoggedInEmployee.Id); return ApiResponse.ErrorResponse("You do not have access to this bucket.", "You do not have access to this bucket.", 401); } + List contactBucket = await _context.ContactBucketMappings.Where(cb => cb.BucketId == id).ToListAsync() ?? new List(); List contactVMs = new List(); if (contactBucket.Count > 0) -- 2.43.0 From db25c25b9b1d9e94a9deadc2f00dd9eb1d1ba687 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Tue, 27 May 2025 12:28:22 +0530 Subject: [PATCH 3/6] Enhancement #377: Update "Update Contact" API to Enforce Feature --- .../Controllers/DirectoryController.cs | 4 +++ Marco.Pms.Services/Helpers/DirectoryHelper.cs | 30 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index de262fb..6b54891 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -103,6 +103,10 @@ namespace Marco.Pms.Services.Controllers { return NotFound(response); } + else if (response.StatusCode == 401) + { + return Unauthorized(response); + } else { return BadRequest(response); diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index 898f43f..f5a3e1c 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -476,6 +476,33 @@ namespace Marco.Pms.Services.Helpers return ApiResponse.ErrorResponse("Contact not found", "Contact not found", 404); } + var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); + var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); + List? employeeBuckets = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).ToListAsync(); + List bucketIds = employeeBuckets.Select(c => c.BucketId).ToList(); + if (permissionIds.Contains(directoryAdmin)) + { + var buckets = await _context.Buckets.Where(b => b.TenantId == tenantId).ToListAsync(); + bucketIds = buckets.Select(b => b.Id).ToList(); + } + else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(directoryUser)) + { + var buckets = await _context.Buckets.Where(b => b.CreatedByID == LoggedInEmployee.Id).ToListAsync(); + var createdBucketIds = buckets.Select(b => b.Id).ToList(); + bucketIds.AddRange(createdBucketIds); + bucketIds = bucketIds.Distinct().ToList(); + } + else + { + _logger.LogError("Employee {EmployeeId} attemped to update a contact, but do not have permission", LoggedInEmployee.Id); + return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); + } + + List contactBuckets = await _context.ContactBucketMappings.AsNoTracking().Where(m => m.ContactId == contact.Id && bucketIds.Contains(m.BucketId)).ToListAsync(); + bucketIds = contactBuckets.Select(b => b.BucketId).Distinct().ToList(); + + + var newContact = updateContact.ToContactFromUpdateContactDto(tenantId, contact); _context.Contacts.Update(newContact); await _context.SaveChangesAsync(); @@ -485,8 +512,7 @@ namespace Marco.Pms.Services.Helpers List emails = await _context.ContactsEmails.AsNoTracking().Where(p => p.ContactId == contact.Id).ToListAsync(); var emailIds = emails.Select(p => p.Id).ToList(); - List contactBuckets = await _context.ContactBucketMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync(); - var bucketIds = contactBuckets.Select(b => b.BucketId).Distinct().ToList(); + List contactTags = await _context.ContactTagMappings.AsNoTracking().Where(m => m.ContactId == contact.Id).ToListAsync(); var tagIds = contactTags.Select(t => t.ContactTagId).Distinct().ToList(); -- 2.43.0 From 1e6b2d7527192227e2d46c23185645b0d08ee9f0 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Tue, 27 May 2025 12:32:51 +0530 Subject: [PATCH 4/6] Enhancement #378: Update "Get Bucket List" API to Enforce Feature --- .../Controllers/DirectoryController.cs | 13 ++++++++- Marco.Pms.Services/Helpers/DirectoryHelper.cs | 28 +++++++++++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index 6b54891..d25c7e8 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -226,7 +226,18 @@ namespace Marco.Pms.Services.Controllers public async Task GetBucketList() { var response = await _directoryHelper.GetBucketList(); - return Ok(response); + if (response.StatusCode == 200) + { + return Ok(response); + } + else if (response.StatusCode == 401) + { + return Unauthorized(response); + } + else + { + return BadRequest(response); + } } [HttpPost("bucket")] diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index f5a3e1c..3d27b73 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -1002,20 +1002,38 @@ namespace Marco.Pms.Services.Helpers { Guid tenantId = _userHelper.GetTenantId(); var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); + var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); + var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); List employeeBuckets = await _context.EmployeeBucketMappings.Where(b => b.EmployeeId == LoggedInEmployee.Id).ToListAsync(); var bucketIds = employeeBuckets.Select(b => b.BucketId).ToList(); - List bucketList = await _context.Buckets.Where(b => bucketIds.Contains(b.Id)).ToListAsync(); + List bucketList = new List(); + if (permissionIds.Contains(directoryAdmin)) + { + bucketList = await _context.Buckets.Where(b => b.TenantId == tenantId).ToListAsync(); + } + else if (permissionIds.Contains(directoryManager) || permissionIds.Contains(directoryUser)) + { + bucketList = await _context.Buckets.Where(b => bucketIds.Contains(b.Id) || b.CreatedByID == LoggedInEmployee.Id).ToListAsync(); + } + else + { + _logger.LogError("Employee {EmployeeId} attemped to access a buckets list, but do not have permission", LoggedInEmployee.Id); + return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); + } List bucketVMs = new List(); - foreach (var bucket in bucketList) + if (bucketList.Any()) { - BucketVM bucketVM = bucket.ToBucketVMFromBucket(); - bucketVMs.Add(bucketVM); + foreach (var bucket in bucketList) + { + BucketVM bucketVM = bucket.ToBucketVMFromBucket(); + bucketVMs.Add(bucketVM); + } } _logger.LogInfo("{count} Buckets are fetched by Employee with ID {LoggedInEmployeeId}", bucketVMs.Count, LoggedInEmployee.Id); - return ApiResponse.SuccessResponse(bucketVMs, System.String.Format("{0} buckets fetched successfully", bucketVMs.Count), 200); + return ApiResponse.SuccessResponse(bucketVMs, $"{bucketVMs.Count} buckets fetched successfully", 200); } public async Task> CreateBucket(CreateBucketDto bucketDto) { -- 2.43.0 From 1490cfc1959b8dc88ac52ee49c1f86538b4d171d Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Tue, 27 May 2025 12:35:09 +0530 Subject: [PATCH 5/6] Enhancement #380: Update "Create Bucket" API to Enforce Feature --- Marco.Pms.Services/Controllers/DirectoryController.cs | 4 ++++ Marco.Pms.Services/Helpers/DirectoryHelper.cs | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index d25c7e8..680a708 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -261,6 +261,10 @@ namespace Marco.Pms.Services.Controllers { return Conflict(response); } + else if (response.StatusCode == 401) + { + return Unauthorized(response); + } else { return BadRequest(response); diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index 3d27b73..2b1604d 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -1041,6 +1041,15 @@ namespace Marco.Pms.Services.Helpers var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); if (bucketDto != null) { + var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); + var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); + var demo = !permissionIds.Contains(directoryUser); + if (!permissionIds.Contains(directoryAdmin) && !permissionIds.Contains(directoryManager) && !permissionIds.Contains(directoryUser)) + { + _logger.LogError("Employee {EmployeeId} attemped to create a bucket, but do not have permission", LoggedInEmployee.Id); + return ApiResponse.ErrorResponse("You don't have permission", "You don't have permission", 401); + } + var existingBucket = await _context.Buckets.FirstOrDefaultAsync(b => b.Name == bucketDto.Name); if (existingBucket != null) { -- 2.43.0 From fb3932fe25318ee1ceb3664ee7eb7d986bd0fcb9 Mon Sep 17 00:00:00 2001 From: "ashutosh.nehete" Date: Tue, 27 May 2025 12:37:24 +0530 Subject: [PATCH 6/6] Enhancement #381: Update "Update Bucket" API to Enforce Feature --- .../Controllers/DirectoryController.cs | 4 +++ Marco.Pms.Services/Helpers/DirectoryHelper.cs | 29 ++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Marco.Pms.Services/Controllers/DirectoryController.cs b/Marco.Pms.Services/Controllers/DirectoryController.cs index 680a708..cfc9ed8 100644 --- a/Marco.Pms.Services/Controllers/DirectoryController.cs +++ b/Marco.Pms.Services/Controllers/DirectoryController.cs @@ -284,6 +284,10 @@ namespace Marco.Pms.Services.Controllers { return NotFound(response); } + else if (response.StatusCode == 401) + { + return Unauthorized(response); + } else { return BadRequest(response); diff --git a/Marco.Pms.Services/Helpers/DirectoryHelper.cs b/Marco.Pms.Services/Helpers/DirectoryHelper.cs index 2b1604d..760ae61 100644 --- a/Marco.Pms.Services/Helpers/DirectoryHelper.cs +++ b/Marco.Pms.Services/Helpers/DirectoryHelper.cs @@ -1088,12 +1088,39 @@ namespace Marco.Pms.Services.Helpers var LoggedInEmployee = await _userHelper.GetCurrentEmployeeAsync(); if (bucketDto != null && id == bucketDto.Id) { - var bucket = await _context.Buckets.FirstOrDefaultAsync(b => b.Id == bucketDto.Id && b.TenantId == tenantId); + var assignedRoleIds = await _context.EmployeeRoleMappings.Where(r => r.EmployeeId == LoggedInEmployee.Id).Select(r => r.RoleId).ToListAsync(); + var permissionIds = await _context.RolePermissionMappings.Where(rp => assignedRoleIds.Contains(rp.ApplicationRoleId)).Select(rp => rp.FeaturePermissionId).Distinct().ToListAsync(); + var bucketIds = await _context.EmployeeBucketMappings.Where(eb => eb.EmployeeId == LoggedInEmployee.Id).Select(eb => eb.BucketId).ToListAsync(); + Bucket? bucket = await _context.Buckets.FirstOrDefaultAsync(b => b.Id == bucketDto.Id && b.TenantId == tenantId); + if (bucket == null) { _logger.LogWarning("Employee ID {LoggedInEmployeeId} attempted to update a bucket but not found in database.", LoggedInEmployee.Id); return ApiResponse.ErrorResponse("Bucket not found", "Bucket not found", 404); } + + Bucket? accessableBucket = null; + if (permissionIds.Contains(directoryAdmin)) + { + accessableBucket = bucket; + } + else if (permissionIds.Contains(directoryManager) && bucketIds.Contains(id)) + { + accessableBucket = bucket; + } + else if (permissionIds.Contains(directoryUser)) + { + if (bucket.CreatedByID == LoggedInEmployee.Id) + { + accessableBucket = bucket; + } + } + if (accessableBucket == null) + { + _logger.LogError("Employee {EmployeeId} attempted to access bucket {BucketId} without the necessary permissions.", LoggedInEmployee.Id, bucket.Id); + return ApiResponse.ErrorResponse("You don't have permission to access this bucket", "You don't have permission to access this bucket", 401); + } + bucket.Name = bucketDto.Name ?? ""; bucket.Description = bucketDto.Description ?? ""; -- 2.43.0