using System.Diagnostics; using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using bitforum.Models; using bitforum.Models.Views; using bitforum.Constants; namespace bitforum.Controllers.Director { [Authorize] [Route("Director")] public class RoleController : Controller { private readonly ILogger _logger; private readonly string _RoleViewPath = "~/Views/Director/Role.cshtml"; private readonly string _PermissionViewPath = "~/Views/Director/Permission.cshtml"; private readonly RoleManager _roleManager; public RoleController(ILogger logger, RoleManager roleManager) { _logger = logger; _roleManager = roleManager; } [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); } [HttpGet("Role")] public async Task Index() { var roles = await _roleManager.Roles.ToListAsync(); var roleClaimsCount = new Dictionary(); if (roles.Count > 0) { foreach (var role in roles) { var claims = await _roleManager.GetClaimsAsync(role); roleClaimsCount[role.Name] = claims.Count; } } ViewBag.RoleClaimsCount = roleClaimsCount; return View(_RoleViewPath, roles); } [HttpPost("Role")] public async Task Add([FromForm(Name = "role_name")] string name) { try { // 수동 유효성 검사 if (string.IsNullOrWhiteSpace(name)) { ModelState.AddModelError("Role:", "역할 이름은 필수입니다."); } else if (name.Length > 256) { ModelState.AddModelError("Role:", "역할 이름은 256자를 초과할 수 없습니다."); } if (!ModelState.IsValid) { throw new Exception("역할 추가에 실패하였습니다."); } if (await _roleManager.RoleExistsAsync(name)) { ModelState.AddModelError("Role:", $"{name} 은 이미 존재합니다."); throw new Exception("역할 중복 오류"); } } catch (Exception e) { var roles = await _roleManager.Roles.ToListAsync(); _logger.LogError(e, e.Message); TempData["ErrorMessages"] = "역할 추가가 정상적으로 완료되었습니다."; return View(_RoleViewPath, roles); } await _roleManager.CreateAsync(new IdentityRole(name.Trim())); var message = $"{name}이 정상적으로 추가되었습니다."; TempData["SuccessMessage"] = message; _logger.LogInformation(message); return RedirectToAction("index", "Role"); } [HttpGet("ManagePermissions")] public async Task ManagePermissions(string roleID) { var role = await _roleManager.FindByIdAsync(roleID); if (role == null) { return NotFound(); } // 역할에 따른 권한들 조회 var roleClaims = _roleManager.GetClaimsAsync(role).Result.Select(c => c.Value).ToList(); // 권한 생성 var allClaims = Permissions.GeneratePermissions(); // 모든 권한 목록 생성 var allPermissions = allClaims.Select(p => new CheckBoxViewModel { DisplayValue = p, IsSelected = roleClaims.Contains(p) }).ToList(); var viewModel = new PermissionsFormViewModel { RoleID = roleID, RoleName = role.Name, RoleClaims = allPermissions }; return View(_PermissionViewPath, viewModel); } [HttpPost("ManagePermissions")] public async Task ManagePermissions(PermissionsFormViewModel request) { var role = await _roleManager.FindByIdAsync(request.RoleID); if (role == null) { return NotFound(); } var roleClaims = await _roleManager.GetClaimsAsync(role); foreach (var claim in roleClaims) { await _roleManager.RemoveClaimAsync(role, claim); } var selectedClaims = request.RoleClaims.Where(c => c.IsSelected).ToList(); foreach (var claim in selectedClaims) { await _roleManager.AddClaimAsync(role, new Claim("Permission", claim.DisplayValue)); } var message = "권한이 정상적으로 적용되었습니다."; TempData["SuccessMessage"] = message; _logger.LogInformation(message); return RedirectToAction("ManagePermissions", "Role", new { request.RoleID }); } } }