|
|
4808a48594
|
refactor(audit): 审计架构清理——复活白名单监听器、停用噪声监听器、清除僵尸装饰器
一、统一为单一监听器实现
原先两套 SQLAlchemy 事件监听器并存:
· app/utils/audit_events.py —— 全局监听 db.Model、无白名单、无请求上下文守卫(实际在跑)
· app/core/audit_listener.py —— 白名单制、有守卫、有模型级开关(从未生效)
后者失效的根因:注册代码写在 extensions.py 的 init_extensions() 内,
而该函数全仓库只有定义、没有任何调用(create_app 直接内联调用 db.init_app 等)。
现统一由 app/core/audit_listener.py 承担,并在 create_app() 中显式注册。
extensions.py 的死函数 init_extensions 整体删除,避免后人误以为它是有效入口。
二、修复监听器三处致命缺陷(此前注册了也写不进数据)
1. 事件回调第二个参数是 Connection,原代码却调用 Connection.add()(不存在),
每次写日志都抛 AttributeError 并被 except 吞掉 → 改为 connection.execute()
2. register_audit_listeners 从 app.models 批量 import 多个未导出的模型,
ImportError 被上层 try/except 吞掉 → 改为按表名从 db.metadata 取模型
3. 本项目有 31 处函数体内延迟导入模型(如 scrap.py 内部才 import ScrapApproval),
一次性注册会静默漏表 → 增加 ensure_audit_listeners() 惰性补绑,
并在模型预加载段补全审批单/BOM/采购等模型
三、强约束
· WHITELIST_TABLES:仅 18 张核心业务表,系统表/草稿表/向量表不再自审
· has_request_context() 守卫:系统初始化与后台定时任务不再产生 username=system 噪声
· IGNORE_FIELDS 增加 password/password_hash/salt/token/secret/api_key(安全红线)
· created_at 显式写 beijing_time(),与全系统时间口径一致
四、清除僵尸装饰器
@audit_log 早已退化为直接透传的空壳(module/action 参数全被忽略,
数据库中零星的中文 action 即其历史遗留产物),却仍挂在 38 处路由上。
连同 13 个文件的 import 一并移除;audit_events.register_audit_events 改为空操作。
验证:应用上下文中的写操作不产生日志;HTTP 请求产生 5 条日志,
对象为业务单号(APR-SCRAP-... / SKU),模块中文,操作人真实,时间为北京时间。
|
2026-09-10 14:16:27 +08:00 |
|
|
|
67d3113fe1
|
fix(permission): 记录管理者视角仅超管/主管/仓库管理员,去掉入库员/出库员
- PRIVILEGED_VIEWER_ROLES 收敛为 SUPER_ADMIN/SUPERVISOR/WAREHOUSE_MGR
- 入库员(INBOUND)、出库员(OUTBOUND)按普通处理:借还/出库记录只看自己
|
2026-09-09 11:19:09 +08:00 |
|
|
|
9622baf76e
|
fix(borrow,outbound): 记录查看按角色收窄——普通只看自己,库管/主管/超管/跨域看全部
- decorators 新增 is_privileged_viewer(SUPER_ADMIN/SUPERVISOR/WAREHOUSE_MGR 或 crossDomain)
- 借库记录列表:非管理者强制 applicant_id=当前用户
- 出库记录列表+详情:非管理者强制只看自己/无权访问他人单(403)
|
2026-09-09 09:31:01 +08:00 |
|
|
|
347f20497c
|
feat: Redis幂等锁 + 关键端点防重复提交
## decorators.py
- 新增 @prevent_double_submit(lock_timeout=5) 装饰器
Redis key: idem:{user_id}:{path}:{MD5(body)}
锁存在→409, 不存在→setex→执行业务→delete
Redis不可用时fail-open降级放行
## purchase.py
- POST /purchase (创建): +@prevent_double_submit
- PATCH /purchase/<id>/approve (审批): +@prevent_double_submit
## outbound.py
- POST /outbound (出库): +@prevent_double_submit
## transactions.py
- POST /borrow/dispatch (借库扣减): +@prevent_double_submit
|
2026-07-16 13:08:37 +08:00 |
|
|
|
0b75740ae0
|
feat: 权限系统重构 — 操作权限双向展开 + 启动时自动补全默认权限
## permission_service.py
- init_all_menus: menu_defs 新增 inbound_purchase(采购申请) 菜单项
- init_all_menus: 创建 inbound_purchase:operation 操作元素
- 新增 ensure_default_permissions(): 启动时从 sys_user 提取活跃角色,
对空权限角色自动补全默认菜单(按角色类型分级)
- 自动迁移: 已有 inbound_buy 权限的角色 → 自动获得 inbound_purchase
- SUPERVISOR 启动时自动获得 inbound_purchase 菜单权限
## decorators.py
- _expand_operation_perms 改为双向桥接:
正向(inbound_buy:operation←inbound_buy:write)→通过
反向(inbound_buy←inbound_buy:operation)→通过(可编辑隐含可读)
- 新增详细诊断日志,记录展开路径和失败原因
## __init__.py
- 启动时调用 PermissionService.ensure_default_permissions()
|
2026-07-16 11:25:41 +08:00 |
|
|
|
e1417d740a
|
feat: 全模块公司隔离 + crossDomain权限码动态跨域控制
- get_current_company_filter: 新增_has_cross_domain_permission, 权限码替代硬编码
- 补全11个Service的get_current_company_filter调用(semi/product/service/outbound/bom/trans/scrap/summary)
- base/search修复: search_material此前无隔离, 已补全
- get_current_company_filter兜底: JWT缺company_name时返回__NO_COMPANY__防止放行
- permission.py: _get_operator_company补全返回值, 修复权限页保存逻辑
- 新增crossDomain迁移脚本, element_type=element挂system_mgmt下
|
2026-07-15 11:11:40 +08:00 |
|
|
|
9cae1cc44c
|
feat: 跨域访问从硬编码改为权限码crossDomain动态控制, 新增SQL迁移脚本
|
2026-07-15 09:22:58 +08:00 |
|
|
|
4f5965db02
|
feat: JWT多租户数据权限隔离 & 主管系统管理权限 & 含税单价补齐
## 多租户公司数据隔离
- 新增 get_current_company_filter() 工具函数 (decorators.py)
SUPER_ADMIN: 可传company_name参数过滤或传ALL看全量
其他角色: 强制隔离到JWT中的company_name
- 重构 base_service.py / buy_service.py: 用集中式函数替换内联公司过滤
- SysRolePermission 表新增 company_name 字段,支持同角色不同公司权限
- get_user_permissions() 新增 company_name 参数,查公司定制+全局模板权限
- permission.py API 新增 @permission_required 拦截 + 公司过滤
- 19个API/service文件传递 company_name 到权限查询
## 主管系统管理权限
- delete_user() 允许SUPERVISOR删除同公司用户 (原仅SUPER_ADMIN)
- get_all_users() 新增 company_name 参数过滤
- 用户列表/权限分配 API 应用 get_current_company_filter()
- 前端 UserCreate.vue: 超管可见公司下拉框,主管隐藏部门字段
## 前端多租户适配
- material/list.vue / buy.vue: 公司下拉框仅超管可见,默认ALL
- UserCreate.vue: 新增搜索栏公司筛选,部门字段按角色显隐
- auth.ts: getUserList() 支持 params 参数
## Bug修复: 含税单价字段补齐
- buy.vue: 表格列/高级筛选/排序/权限映射新增 post_tax_unit_price
- buy_service.py: allowed_fields/sort_field_map 新增 post_tax_unit_price
|
2026-07-13 15:12:22 +08:00 |
|
|
|
3cb31c2b67
|
fix: 修复 JWT 幽灵令牌漏洞,新增 Dify 权限过滤服务
|
2026-05-18 16:16:50 +08:00 |
|
|
|
f8f5b05d7d
|
refactor(audit): 废弃装饰器+分离架构,改为监听器单体直写入库
|
2026-04-20 16:04:01 +08:00 |
|
|
|
7e72c12f30
|
fix(audit): 修复 decorators.py 中缺失 has_request_context 导入导致的致命 NameError
|
2026-04-20 15:10:12 +08:00 |
|
|
|
decb7f5e1f
|
debug(audit): 添加X光调试-追踪断点
|
2026-04-20 15:01:20 +08:00 |
|
|
|
1c8def7e6f
|
refactor(audit): 分离架构-监听器计算装饰器入库
|
2026-04-20 14:41:40 +08:00 |
|
|
|
381d1fa675
|
feat(audit): 平滑升级-监听器+装饰器共存,装饰器自动检测并跳过已处理日志
|
2026-04-20 13:15:25 +08:00 |
|
|
|
a52ced0375
|
fix(backend): resolve DetachedInstanceError in audit_log, add pessimistic locks for stock adjustments, and eliminate N+1 queries with eager loading
|
2026-04-02 18:44:12 +08:00 |
|
|
|
46dd8f1c3a
|
fix(auth,audit): ensure display_name persists in token refresh and add fallback in audit log
|
2026-03-25 11:16:13 +08:00 |
|
|
|
032479fe38
|
fix: capture and persist target object names for delete, outbound, and borrow operations in audit logs
|
2026-03-20 15:47:13 +08:00 |
|
|
|
4223a95f10
|
feat: generate permission sql for stocktake modules and implement single-device login restriction
|
2026-03-20 09:11:54 +08:00 |
|
|
|
ac97c6066b
|
feat: 升级审计装饰器,支持自动抓取并记录 API 请求体作为变更明细
|
2026-03-10 17:36:02 +08:00 |
|
|
|
be6575344a
|
feat: 新增企业级操作审计日志闭环模块(包含底层模型、记录装饰器与前端看板)
|
2026-03-10 12:15:26 +08:00 |
|
|
|
c1e4acc1d8
|
fix: standardize role case handling in permission logic
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
|
2026-02-27 17:07:45 +08:00 |
|
|
|
a0993767fe
|
fix: make SUPER_ADMIN role checks case-insensitive across app
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
|
2026-02-27 17:04:22 +08:00 |
|
|
|
11fafde5e3
|
fix: remove temporary role whitelist and add permission denial logging
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
|
2026-02-27 10:29:15 +08:00 |
|
|
|
1f9a363545
|
chore: add debug logs and temp whitelist to permission decorator
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
|
2026-02-27 10:27:44 +08:00 |
|
|
|
b3e1ac6245
|
feat: implement permission checking and field-level data masking
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
|
2026-02-27 10:20:09 +08:00 |
|
|
|
73ee163352
|
feat: add MaterialBase permission control with field-level filtering
Co-authored-by: aider (openai/DeepSeek-V3.2-Thinking) <aider@aider.chat>
|
2026-02-27 10:16:43 +08:00 |
|
|
|
13590b1fac
|
超级管理员登录设置
|
2026-02-04 13:30:07 +08:00 |
|
|
|
ee9f4aed3e
|
修正git管理关系
|
2026-01-26 13:47:53 +08:00 |
|