using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using PSTW_CentralSystem.DBContext; using PSTW_CentralSystem.Models; using Newtonsoft.Json; using System.Text.Json; using System.Data; namespace PSTW_CentralSystem.CustomPolicy { public class RoleModulePolicy : IAuthorizationRequirement { } public class RoleModuleHandler : AuthorizationHandler { private readonly CentralSystemContext _authDBContext; private readonly UserManager _userManager; private readonly RoleManager _roleManager; private readonly IHttpContextAccessor _httpContextAccessor; public RoleModuleHandler( CentralSystemContext authDBContext, UserManager userManager, RoleManager roleManager, IHttpContextAccessor httpContextAccessor) { _authDBContext = authDBContext; _userManager = userManager; _roleManager = roleManager; _httpContextAccessor = httpContextAccessor; } protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleModulePolicy requirement) { // Get the current user var currentUser = await _userManager.GetUserAsync(context.User); var userRole = await _userManager.GetRolesAsync(currentUser ?? new UserModel()); var moduleName = _httpContextAccessor.HttpContext?.GetRouteData().Values["controller"]?.ToString(); var pageName = _httpContextAccessor.HttpContext?.GetRouteData().Values["action"]?.ToString(); var registeredModule = _authDBContext.ModuleSettings.FirstOrDefault(x => x.ModuleName == moduleName); if (checkIfSuperAdmin()) { context.Succeed(requirement); return; } else { checkModuleExistOrNot(); checkModuleHaveRoleOrNot(); } bool checkIfSuperAdmin() { var superAdminRole = _authDBContext.Roles.Where(r => r.Name == "SuperAdmin").FirstOrDefault(); var sysAdminRole = _authDBContext.Roles.Where(r => r.Name == "SystemAdmin").FirstOrDefault(); if (userRole.ToString() != null && userRole.Contains("SuperAdmin") && superAdminRole?.Id == 1) { return true; } else if (userRole.ToString() != null && userRole.Contains("SystemAdmin") && sysAdminRole?.Id == 2) { return true; } else { return false; } } void checkModuleExistOrNot() { if ( moduleName == "Admin") { context.Fail(); return; } else if (registeredModule == null) { context.Fail(); return; } else { checkModuleActiveOrNot(); } } void checkModuleActiveOrNot() { if (registeredModule.ModuleStatus == 0) { context.Fail(); return; } } void checkModuleHaveRoleOrNot() { var allowedUserTypes = registeredModule?.AllowedUserType ?? ""; if (allowedUserTypes == "Public" || userRole.Any(role => allowedUserTypes.Contains(role))) { context.Succeed(requirement); return; } else if (currentUser != null && allowedUserTypes == "Registered User" ) { checkMethodAndRole(); } else { context.Fail(); return; } } void checkMethodAndRole() { // Load all ModuleSettings and process them in memory var moduleSettings = _authDBContext.ModuleSettings.AsEnumerable(); // Check if the method exists in the module settings var isMethodExist = moduleSettings.FirstOrDefault(m => m.MethodAllowedUserType?.Any(mt => mt.MethodName == pageName) == true); if (isMethodExist != null) // Check if the method exists which means method is registered { var registeredMethod = moduleSettings.Where(m => m.MethodAllowedUserType != null && m.MethodAllowedUserType.Any(mt => mt.MethodName == pageName)).FirstOrDefault(); var allowedUserTypes = registeredMethod?.MethodAllowedUserType?.Where(mt => mt.MethodName == pageName).Select(mt => mt.AllowedUserTypesArray).FirstOrDefault() ?? Array.Empty(); if (userRole.Any(role => allowedUserTypes.Contains(role)) || allowedUserTypes.Contains("All")) // Check if the user role is allowed, allowing only registered user to access. { context.Succeed(requirement); return; } else { context.Fail(); return; } } else // No method is registered to allow all method to be accessed { context.Succeed(requirement); return; } } } } }