group-operations-access.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. 'use strict';
  2. const ROLE_CAPABILITIES = Object.freeze({
  3. headquarters_admin: ['*'],
  4. regional_manager: ['read', 'manage_plans', 'execute_items', 'manage_findings', 'manage_tasks', 'manage_quality'],
  5. store_manager: ['read', 'manage_plans', 'execute_items', 'manage_findings', 'manage_tasks'],
  6. executor: ['read', 'manage_plans', 'execute_items', 'manage_findings'],
  7. auditor: ['read']
  8. });
  9. function hasCapability(binding, capability) {
  10. const capabilities = ROLE_CAPABILITIES[binding?.role] || [];
  11. return capabilities.includes('*') || capabilities.includes(capability);
  12. }
  13. function resolveTargetStore(store, accountKey, input = {}) {
  14. if (input.storeId) return String(input.storeId);
  15. if (input.roomId) return String(store.getGroup(accountKey, input.roomId)?.store_id || '');
  16. if (input.itemId) return String(store.getPlanItemWithContext(accountKey, input.itemId)?.store_id || '');
  17. if (input.findingId) {
  18. const finding = store.db.prepare('SELECT room_id FROM group_ops_findings WHERE id=? AND account_key=?').get(input.findingId, accountKey);
  19. return String(finding?.room_id ? store.getGroup(accountKey, finding.room_id)?.store_id || '' : '');
  20. }
  21. if (input.taskId) return String(store.getTask(accountKey, input.taskId)?.room_id ? store.getGroup(accountKey, store.getTask(accountKey, input.taskId).room_id)?.store_id || '' : '');
  22. return '';
  23. }
  24. function authorizeGroupOps(store, accountKey, principal, capability, input = {}) {
  25. const bindings = store.listRoleBindings(accountKey);
  26. if (!bindings.length) return { allowed: true, mode: 'bootstrap', warning: '当前账号尚未配置角色绑定,沿用兼容模式。' };
  27. const binding = store.getRoleBinding(accountKey, principal);
  28. if (!binding) return { allowed: false, reason: '当前身份未被授予社群运营角色' };
  29. if (!hasCapability(binding, capability)) return { allowed: false, reason: `角色 ${binding.role} 没有 ${capability} 权限` };
  30. if (binding.role === 'headquarters_admin' || capability === 'read' && binding.role === 'auditor') return { allowed: true, binding };
  31. const targetStore = resolveTargetStore(store, accountKey, input);
  32. if (!targetStore) return { allowed: capability === 'read', binding, reason: capability === 'read' ? '' : '该操作缺少可校验的门店范围' };
  33. if (!binding.storeScope.includes(targetStore)) return { allowed: false, reason: `无权操作门店 ${targetStore}` };
  34. return { allowed: true, binding, targetStore };
  35. }
  36. module.exports = { ROLE_CAPABILITIES, authorizeGroupOps };