using LCU.Library.Internal.IncentiveApiModels.Entities; using LCU.Library.Internal.IncentiveApiModels.Enums; using LCU.API.Internal.Operations.IncentiveApiLib.Repositories; using LCU.Library.Internal.IncentiveApiModels.Common; namespace LCU.API.Internal.Operations.IncentiveApi.Services; public class AuthorizationService : IAuthorizationService { private readonly IDepartmentRepository _departmentRepository; private readonly IUserAssignmentRepository _userAssignmentRepository; public AuthorizationService(IDepartmentRepository departmentRepository, IUserAssignmentRepository userAssignmentRepository) { _departmentRepository = departmentRepository; _userAssignmentRepository = userAssignmentRepository; } public async Task AppUserCanMakeStateChange(AppUser appUser, Activity activity, ActivityState targetState, int targetDepartmentId = 0) { if (appUser.HasRoleAnywhere(Role.Admin)) { return await Task.FromResult(true); } targetDepartmentId = targetDepartmentId == 0 ? activity.DepartmentId : targetDepartmentId; var targetDepartmentAppUserPermissions = appUser.ActiveDepartmentsForRange(new MonthRange()) .FirstOrDefault(x => x.DepartmentId == targetDepartmentId) ?.Role.Permissions.ToList(); if (appUser.AdditionalPermissions != null && targetDepartmentAppUserPermissions == null) { targetDepartmentAppUserPermissions = new List(); targetDepartmentAppUserPermissions.AddRange(appUser.AdditionalPermissions.Select(x => x.Permission)); } else if (appUser.AdditionalPermissions != null) { targetDepartmentAppUserPermissions.AddRange(appUser.AdditionalPermissions.Select(x => x.Permission)); } if (targetDepartmentAppUserPermissions == null || activity.State == targetState) { return await Task.FromResult(false); } var canExecuteChange = activity.State switch { ActivityState.Accepted => targetState switch { ActivityState.ManualReview => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToManualReviewFromAccepted), ActivityState.Rejected => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToRejectedFromAccepted), _ => false }, ActivityState.ManualReview => targetState switch { ActivityState.Accepted => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToAcceptedFromManualReview), ActivityState.Rejected => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToRejectedFromManualReview), _ => false }, ActivityState.PendingTransfer => targetState switch { ActivityState.Accepted => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToAcceptedFromPendingTransfer), ActivityState.Transferred => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToTransferredFromPendingTransfer), _ => false }, ActivityState.Rejected => targetState switch { ActivityState.Accepted => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToAcceptedFromRejected), ActivityState.ManualReview => targetDepartmentAppUserPermissions.Contains(Permission.SetActivityToManualReviewFromRejected), _ => false }, _ => false }; return canExecuteChange; } public async Task AppUserCanViewReport(AppUser appUser, string permissionCode) { if (appUser.HasRoleAnywhere(Role.Admin)) { return await Task.FromResult(true); } var requiredPermission = Permission.LookupPermissionFromCode(permissionCode); return appUser.UserHasPermission(requiredPermission); } public async Task ValidateHierarchicalDepartmentPermission( AppUser appUser, IReadOnlyCollection allowedDirectRoles, int departmentId ) { return appUser.HasRoleAnywhere(Role.Admin) || appUser.HasAnyRoleForActiveDepartment(departmentId, allowedDirectRoles.ToArray()) || await ValidateIsBusinessLineManager(appUser, departmentId) || await ValidateIsRegionalManager(appUser, departmentId); } public async Task ValidateIsBusinessLineManager(AppUser appUser, int departmentId) { var userDept = appUser.FindDepartmentForRole(Role.BusinessLineManager); if (userDept != null && userDept.Department != null) { var bl = BusinessLine.FindByCode(userDept.Department.BusinessLineCode); if (bl == null) { return userDept.Department.Id == departmentId; } var departments = await _departmentRepository.FindDepartmentsByBusinessLineAsync(bl); if (departments.Select(x => x.Id).Contains(departmentId)) { return true; } } return false; } public async Task ValidateIsRegionalManager(AppUser appUser, int departmentId) { var userDept = appUser.FindDepartmentForRole(Role.RegionalManager); if (userDept != null && userDept.Department != null) { var userAssign = await _userAssignmentRepository.IsUserAssigned(AssignmentType.RegionalManager, appUser); Region rc = null; if (userAssign != null) { rc = Region.FindByCode(userAssign.Key); } if (rc == null) { rc = Region.FindByCode(userDept.Department.RegionCode); if (rc == null) { return userDept.Department.Id == departmentId; } } var departments = await _departmentRepository.FindDepartmentsByRegionAsync(rc); if (departments.Select(x => x.Id).Contains(departmentId)) { return true; } } return false; } }