Bỏ qua, đến nội dung

Engine ACL

Không trùng với plugin plugin-acl (đồng bộ DB) - đây là thư viện runtime thuần bộ nhớ.

1) Tổng quan kiến trúc

2) Các thành phần chi tiết

Thành phầnTrách nhiệm
rolesMap<string, ACLRole> - định nghĩa qua define({ role, strategy?, actions?, snippets? })
allowManagerĐăng ký ngoại lệ "cho phép" resource/action theo điều kiện
snippetManagerNhóm quyền theo snippet (pattern action path, hỗ trợ ! phủ định)
fixedParamsManagerGộp params cố định vào kết quả can (filter bổ sung)
availableActionsAction khả dụng từ plugin collection (export, import...)
actionAliasMapping alias → action thực
availableStrategyStrategy mặc định cho role
middlewaresPipeline ACL (topo sort) - allow-manager trước core

3) Luồng can() - kiểm tra quyền

  • can({ role, resource, action }) hoặc can({ roles, resource, action }).
  • Nếu có root trong roles → chỉ xét root (superadmin).
  • Role thường: kiểm tra action trên ACLRole; nếu không có config cụ thể → dùng strategy + snippet (minimatch trên resource:action).
  • fixedParamsManager.getParams(resource, action) merge vào params kết quả.

4) allow() / AllowManager - ngoại lệ cho phép

Tra cứu hỗ trợ wildcard * cho resource hoặc action.

Điều kiệnÝ nghĩaVí dụ
'public'Không cần đăng nhậpLogin page, health check
'loggedIn'Chỉ cần có currentUserProfile page
'allowConfigure'Role có allowConfigure trong strategyAdmin settings
functionCustom logicCheck IP, check feature flag

allow vs skip

Trong source code, allow còn có tên nội bộ skip (deprecated). Cả hai đều ủy quyền cho AllowManager. Dùng allow trong code mới.

5) Snippet - nhóm quyền theo pattern

  • registerSnippet({ name, actions }) - actions là glob pattern (minimatch) cho path dạng resource:action.
  • Role có thể được gán snippet; snippet quyết định mở API UI/plugin.
  • Ví dụ: ui.* match tất cả action liên quan UI, pm.* match tất cả plugin management.
  • Hỗ trợ ! phủ định: !pm.users từ chối action trên resource pm.users.

6) fixedParams - filter ẩn theo role

Fixed params cho phép inject filter vào mọi request cho resource/action cụ thể theo role:

Tình huốngFixed paramsHiệu ứng
"View own"{ filter: { createdById: currentUserId } }User chỉ thấy record mình tạo
"Department scope"{ filter: { departmentId: { $in: userDepts } } }User thấy record của department
"Field restriction"{ fields: ['name', 'email'] }Chỉ trả về một số field

Merge, không overwrite

Fixed params được merge vào can() result (dùng and-merge cho filter). Plugin hoặc client không thể bypass filter này vì nó được inject ở tầng ACL.

7) Middleware ACL

Pipeline middleware ACL gồm hai stage (topo):

  1. allow-manager - kiểm tra ngoại lệ trước.
  2. core - kiểm tra quyền thực tế qua can().

8) setAvailableAction / strategy resource

APIMô tả
setAvailableAction(name, config)Plugin đăng ký action trên collection (export, import...)
setStrategyResources(resources)Set danh sách collection áp dụng strategy mặc định
appendStrategyResource(resource)Thêm một collection vào strategy list

9) beforeGrantAction - hook phân quyền

Listener chuỗi beforeGrantAction:

  • Merge params.own với predicate (ví dụ: { createdById: currentUser.id }).
  • Chuyển fieldswhitelist cho action create/update.

10) Error handling

  • NoPermissionError và các export trong errors/ - dùng khi từ chối quyền có kiểm soát.
  • Client nhận HTTP 403 với error code rõ ràng.

11) Phân biệt ACL engine vs plugin-acl

ACL Engine (@digiforce-nc/acl)Plugin ACL (plugin-acl)
Vị trípackages/core/acl/packages/plugins/@digiforce-nc/plugin-acl/
Dữ liệuTrong bộ nhớ (Map)Đồng bộ từ DB
Trách nhiệmCheck quyền runtimeCRUD cấu hình quyền, sync → engine
APIacl.define(), acl.can()Admin UI, REST API quản lý roles

Đọc tiếp