From 40044819895e85c532253298ef76e9e687b33b37 Mon Sep 17 00:00:00 2001 From: pqhuy1987 Date: Tue, 16 Jun 2026 09:51:49 +0700 Subject: [PATCH] =?UTF-8?q?[CLAUDE]=20Auth:=20public=20module=20Nh=C3=A2n?= =?UTF-8?q?=20s=E1=BB=B1=20(H=E1=BB=93=20s=C6=A1=20NS)=20read-only=20cho?= =?UTF-8?q?=20m=E1=BB=8Di=20role?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Anh user yêu cầu public module Nhân sự cho user thường tra cứu hồ sơ. Thêm SeedAllRolesHrmProfileReadPermissionsAsync (DbInitializer) grant CanRead cho Hrm + Hrm_HoSo cho 13 role, chạy SAU RevokeTemporarilyHiddenModulesAsync (S58) để thắng revoke. Upgrade-only (nâng false→true trên row prod đã tồn tại, mirror Pe S57bis :2107) — không NO-OP im lặng. Read-only: chỉ CanRead; Create/Update/Delete vẫn khóa qua policy controller. Giữ ẩn Dashboard NS + Hrm_Config*. Migration-free, idempotent. Reviewer PASS 7/7. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../Persistence/DbInitializer.cs | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs b/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs index 97ddee1..b9d9d16 100644 --- a/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs +++ b/src/Backend/SolutionErp.Infrastructure/Persistence/DbInitializer.cs @@ -2038,6 +2038,12 @@ public static class DbInitializer // (GetMyMenuTree lọc CanRead). Chạy SAU grant seed để revoke thắng. // Mở lại sau golive: gỡ prefix khỏi revoke + thêm lại vào InReviewScope. await RevokeTemporarilyHiddenModulesAsync(db, roleManager, logger); + + // [S65 2026-06-16] CHẠY SAU revoke để THẮNG: mở lại quyền XEM "Hồ sơ Nhân sự" + // (+ root nhóm "Nhân sự") cho MỌI role — anh chốt public module Nhân sự cho + // user thường tra cứu hồ sơ. Dashboard NS (Hrm_Dashboard) + 6 catalog + // Hrm_Config* VẪN ẨN (revoke che). Read-only (chỉ CanRead). + await SeedAllRolesHrmProfileReadPermissionsAsync(db, roleManager, logger); } // [S57] Cấp CanRead (CHỈ xem) cho MỌI role trên menu HRM + Office + Master để mọi @@ -2183,6 +2189,66 @@ public static class DbInitializer } } + // [S65 2026-06-16] Mở quyền XEM (Read-only) "Hồ sơ Nhân sự" cho MỌI role: anh chốt + // public module Nhân sự (trọng tâm Hồ sơ NS) để user thường tra cứu hồ sơ nhân sự. + // CHẠY SAU RevokeTemporarilyHiddenModulesAsync (SeedAsync) để THẮNG revoke: revoke + // set mọi Hrm* = false cho non-Admin; method này nâng RIÊNG 2 key Hrm + Hrm_HoSo. + // - GIỮ ẨN: Dashboard NS (Hrm_Dashboard) + 6 catalog Hrm_Config* — vẫn bị revoke che. + // - Read-only: chỉ CanRead. Create/Update/Delete hồ sơ vẫn khóa qua policy + // Hrm_HoSo.{Create/Update/Delete} (EmployeesController) — non-Admin không có. + // - UPGRADE-ONLY (mirror Pe S57bis :2107): row đã tồn tại (revoke vừa set CanRead + // =false trên prod) → NÂNG CanRead=true. Row chưa có (DB mới) → tạo CanRead=true, + // cờ khác false. KHÔNG hạ + KHÔNG đụng Create/Update/Delete (không phá quyền admin). + // Flip ẩn lại khi cần: xóa call ở SeedAsync — revoke sẽ tự che lại lần seed kế. + private static async Task SeedAllRolesHrmProfileReadPermissionsAsync( + ApplicationDbContext db, RoleManager roleManager, ILogger logger) + { + // Root nhóm "Nhân sự" (để menu group hiện chắc chắn) + leaf "Hồ sơ Nhân sự". + // KHÔNG Hrm_Dashboard, KHÔNG Hrm_Config* (giữ ẩn theo scope anh chốt). + var hrmKeys = new[] { MenuKeys.Hrm, MenuKeys.HrmHoSo }; + var roles = await roleManager.Roles.ToListAsync(); + + var existingRows = (await db.Permissions + .Where(p => hrmKeys.Contains(p.MenuKey)) + .ToListAsync()) + .ToDictionary(p => (p.RoleId, p.MenuKey)); + + var added = 0; + var upgraded = 0; + foreach (var role in roles) + { + foreach (var key in hrmKeys) + { + if (existingRows.TryGetValue((role.Id, key), out var row)) + { + // Upgrade-only: nâng CanRead nếu đang false (revoke vừa set false). + if (!row.CanRead) { row.CanRead = true; upgraded++; } + continue; + } + + db.Permissions.Add(new Permission + { + RoleId = role.Id, + MenuKey = key, + CanRead = true, + CanCreate = false, + CanUpdate = false, + CanDelete = false, + }); + added++; + } + } + + if (added > 0 || upgraded > 0) + { + await db.SaveChangesAsync(); + logger.LogInformation( + "Seeded all-roles HRM profile read perms: {Added} added + {Upgraded} upgraded " + + "(Hrm + Hrm_HoSo CanRead — public Hồ sơ NS, S65)", + added, upgraded); + } + } + // [Plan CA S29 2026-05-22] Permission defaults cho role CatalogManager. // Strategy: full CRUD trên 9 menu key danh mục dùng chung: // - Master (root group) + Suppliers + Projects + Departments