using adas_core.Application.Exceptions; using adas_core.Application.Repositories.Interfaces; using adas_core.Application.Services.Interfaces; using adas_core.Domain.Enums; using adas_core.Domain.Models.AppSettings; using adas_core.Domain.Models.MongoModels; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using MongoDB.Bson; namespace adas_core.Application.Services; public class PermissionService( IOptions permissionsConfig, ILogger logger, Lazy displayService, Lazy userRepository, Lazy authorityRepository) : IPermissionService { private readonly ILogger _logger = logger; private readonly PermissionSettings _permissionsConfig = permissionsConfig.Value; public async Task GetPermissionsForDisplay(Display display, User user) { var authorities = user.Authorization; if (authorities == null) { var a = await userRepository.Value.GetByUserAndAuthoritesName(user.UserName); authorities = a?.Authorization; user.Authorization = authorities; } if (authorities == null) throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission); foreach (var auth in authorities) if (display.Id.ToString().Equals(auth.DisplayId) || display.UnitId.ToString().Equals(auth.UnitId)) { _logger.LogInformation("User {user} has role {role} for display {displayId} or unit {unitId}", user.UserName, auth.Rol, auth.DisplayId, auth.UnitId); //var unitPerms = await GetPermissionsForUnit(display.UnitId.ToString(), user); switch ((PermissionEnum.RolesType?)Enum.Parse(typeof(PermissionEnum.RolesType), auth.Rol ?? string.Empty)) { case PermissionEnum.RolesType.AuthGuest: // return (await CheckPermissions(_permissionsConfig.Guest.Display, display.UnitId.ToString())); return _permissionsConfig.Guest.Display; case PermissionEnum.RolesType.AuthAdmin: // return await CheckPermissions(_permissionsConfig.Admin.Display, display.UnitId.ToString()); return _permissionsConfig.Admin.Display; case PermissionEnum.RolesType.AuthDeveloper: // return await CheckPermissions(_permissionsConfig.Developer.Display, display.UnitId.ToString()); return _permissionsConfig.Developer.Display; case PermissionEnum.RolesType.AuthDoctorchief: // return await CheckPermissions(_permissionsConfig.DoctorChief.Display, display.UnitId.ToString()); return _permissionsConfig.DoctorChief.Display; case PermissionEnum.RolesType.AuthDoctor: // return await CheckPermissions(_permissionsConfig.Doctor.Display, display.UnitId.ToString()); return _permissionsConfig.Doctor.Display; case PermissionEnum.RolesType.AuthNursesupervisor: // return await CheckPermissions(_permissionsConfig.NursingSupervisor.Display, display.UnitId.ToString()); return _permissionsConfig.NursingSupervisor.Display; case PermissionEnum.RolesType.AuthNurse: // return await CheckPermissions(_permissionsConfig.Nurse.Display, display.UnitId.ToString()); return _permissionsConfig.Nurse.Display; } } //return _permissionsConfig.NoPermissions.Display; throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission); } public Task GetPermissionsForUnit(string unitId, User user) { var authorities = user.Authorization; if (authorities == null) throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission); foreach (var auth in authorities) if (auth.UnitId != null && auth.UnitId.Equals(unitId)) { _logger.LogInformation("User {user} has role {role} for unit {unitId}", user.UserName, auth.Rol, auth.UnitId); switch ((PermissionEnum.RolesType?)Enum.Parse(typeof(PermissionEnum.RolesType), auth.Rol ?? string.Empty)) { case PermissionEnum.RolesType.AuthGuest: // return await CheckPermissions(_permissionsConfig.Guest.Unit, auth.UnitId); return Task.FromResult(_permissionsConfig.Guest.Unit); case PermissionEnum.RolesType.AuthAdmin: // return await CheckPermissions(_permissionsConfig.Admin.Unit, auth.UnitId); return Task.FromResult(_permissionsConfig.Admin.Unit); case PermissionEnum.RolesType.AuthDeveloper: // return await CheckPermissions(_permissionsConfig.Developer.Unit, auth.UnitId); return Task.FromResult(_permissionsConfig.Developer.Unit); case PermissionEnum.RolesType.AuthDoctorchief: // return await CheckPermissions(_permissionsConfig.DoctorChief.Unit, auth.UnitId); return Task.FromResult(_permissionsConfig.DoctorChief.Unit); case PermissionEnum.RolesType.AuthDoctor: // return await CheckPermissions(_permissionsConfig.Doctor.Unit, auth.UnitId); return Task.FromResult(_permissionsConfig.Doctor.Unit); case PermissionEnum.RolesType.AuthNursesupervisor: // return await CheckPermissions(_permissionsConfig.NursingSupervisor.Unit, auth.UnitId); return Task.FromResult(_permissionsConfig.NursingSupervisor.Unit); case PermissionEnum.RolesType.AuthNurse: // return await CheckPermissions(_permissionsConfig.Nurse.Unit, auth.UnitId); return Task.FromResult(_permissionsConfig.Nurse.Unit); } } throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission); } /* private async Task CheckPermissions(DisplayPermissionTypes guestUnit, string authUnitId) { var isParsed = ObjectId.TryParse(authUnitId, out var unitId); if(isParsed) { var unit = await uniService.Value.FindById(unitId); var unitConfiguration = unit?.Configuration; if (unitConfiguration != null) { guestUnit.Admissions.Execute = unitConfiguration.ManualAdmit; guestUnit.Discharges.Execute = unitConfiguration.ManualDischarge; guestUnit.DemographicData.Create = unitConfiguration.ManualEdit; guestUnit.DemographicData.Delete = unitConfiguration.ManualEdit; guestUnit.DemographicData.Update = unitConfiguration.ManualEdit; guestUnit.DemographicData.Execute = unitConfiguration.ManualEdit; } } _logger.LogInformation("Permissions for unit {unitId}: {@permissions}", authUnitId, guestUnit); return guestUnit; } */ public async Task GetPermissionsForPanel(string user) { var userFound = await userRepository.Value.GetByUserName(user); if(userFound == null) throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission); userFound.Authorization = await authorityRepository.Value.GetUserAuthorities(userFound.Id); return GetPermissionsForPanel(userFound); } public PanelPermissionTypes GetPermissionsForPanel(User user) { var authorities = user.Authorization; if (authorities == null) throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission); foreach (var auth in authorities) if (auth.PanelAuthorization) { _logger.LogInformation("User {user} has role {role} for panel", user.UserName, auth.Rol); switch ((PermissionEnum.RolesType?)Enum.Parse(typeof(PermissionEnum.RolesType), auth.Rol ?? string.Empty)) { case PermissionEnum.RolesType.AuthGuest: return _permissionsConfig.Guest.Panel; case PermissionEnum.RolesType.AuthAdmin: return _permissionsConfig.Admin.Panel; case PermissionEnum.RolesType.AuthDeveloper: return _permissionsConfig.Developer.Panel; case PermissionEnum.RolesType.AuthDoctorchief: return _permissionsConfig.DoctorChief.Panel; case PermissionEnum.RolesType.AuthDoctor: return _permissionsConfig.Doctor.Panel; case PermissionEnum.RolesType.AuthNursesupervisor: return _permissionsConfig.NursingSupervisor.Panel; case PermissionEnum.RolesType.AuthNurse: return _permissionsConfig.Nurse.Panel; } } throw new ForbbidenException(HttpEnum.ErrorMessage.ForbiddenNoPermission); } public async Task HasAccessToDisplay(string username, PermissionEnum.RolesType userRole, PermissionEnum.SourcePermissionsEnum source, string displayId) { if (!ObjectId.TryParse(displayId, out var displayObjectId)) return false; var display = await displayService.Value.GetById(displayObjectId); var user = await userRepository.Value.GetByUserName(username); if (user == null || display == null) return false; var authorities = await authorityRepository.Value.GetUserAuthorities(user.Id); user.Authorization = authorities; return SearchRoleInDisplay(display, authorities, userRole); } public async Task HasAccessToUnit(string username, PermissionEnum.RolesType userRole, PermissionEnum.SourcePermissionsEnum source, string unitId) { var user = await userRepository.Value.GetByUserName(username); if (user == null) return false; var authorities = await authorityRepository.Value.GetUserAuthorities(user.Id); user.Authorization = authorities; return SearchRoleInUnit(unitId, authorities, userRole); } public async Task HasAccessToPanel(string username, PermissionEnum.RolesType userRole, PermissionEnum.SourcePermissionsEnum source) { var user = await userRepository.Value.GetByUserName(username); if (user == null) return false; var authorities = await authorityRepository.Value.GetUserAuthorities(user.Id); user.Authorization = authorities; return SearchRoleInPanel(authorities, userRole); } private static bool SearchRoleInDisplay(Display display, List? authorities, PermissionEnum.RolesType role) { if (authorities is not { Count: > 0 }) return false; return ( from auth in authorities let authRole = (PermissionEnum.RolesType?)Enum.Parse(typeof(PermissionEnum.RolesType), auth.Rol ?? string.Empty) where display.Id.ToString().Equals(auth.DisplayId) || display.UnitId.ToString().Equals(auth.UnitId) let result = SearchRoleInUnit(display.UnitId.ToString(), authorities, role) where result || authRole == role select authRole ).Any(); } private static bool SearchRoleInUnit(string unitId, List? authorities, PermissionEnum.RolesType role) { if (authorities == null) return false; foreach (var auth in authorities) { var authRole = (PermissionEnum.RolesType?)Enum.Parse(typeof(PermissionEnum.RolesType), auth.Rol ?? string.Empty); if (auth.UnitId != null && auth.UnitId.Equals(unitId) && authRole == role) return true; } return false; } private static bool SearchRoleInPanel(List? authorities, PermissionEnum.RolesType role) { if (authorities == null) return false; return ( from auth in authorities let authRole = (PermissionEnum.RolesType?)Enum.Parse(typeof(PermissionEnum.RolesType), auth.Rol ?? string.Empty) where auth.PanelAuthorization && authRole == role select auth ).Any(); } }