feat: 审计库名改用 ServerEnv().get_module_dbname 适配多宿主 + 增加 customer_recharge 审计动作 + build.sh

This commit is contained in:
yumoqing 2026-08-17 13:55:32 +08:00
parent d5feff2042
commit 48cc7fca82
4 changed files with 42 additions and 6 deletions

View File

@ -15,6 +15,7 @@ app_audit/audit_service.py - 审计日志全局模块
工作环境work_env_set / org_key_gen / remote_bwrap
部署账号account_create / account_remove / sandbox_run
用户机构user_create / user_disable / user_delete / org_change
财务customer_recharge
审计自身audit_delete / audit_backup
"""
@ -29,6 +30,7 @@ VALID_ACTIONS = {
"work_env_set", "org_key_gen", "remote_bwrap",
"account_create", "account_remove", "sandbox_run",
"user_create", "user_disable", "user_delete", "org_change",
"customer_recharge",
"audit_delete", "audit_backup",
}

View File

@ -16,9 +16,11 @@ def load_app_audit():
async def _init_audit(app):
from sqlor.dbpools import DBPools
from appPublic.log import debug
from ahserver.serverenv import ServerEnv
try:
db = DBPools()
async with db.sqlorContext("pipeline") as sor:
dbname = ServerEnv().get_module_dbname('app_audit')
async with db.sqlorContext(dbname) as sor:
# 审计日志表append-only全局
await sor.sqlExe(
"CREATE TABLE IF NOT EXISTS sd_audit_logs ("

30
build.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/bash
# app_audit module build script
# 链接 wwwroot 到宿主应用Sage 或 pipeline。审计表由 load_app_audit() 启动时自动建。
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 查找宿主应用根目录(含 wwwroot 目录)
APP_ROOT=""
for candidate in "$SCRIPT_DIR/../.." "$HOME/repos/sage" "$HOME/sage" "$HOME/work/repos/sage"; do
if [ -d "$candidate/wwwroot" ]; then
APP_ROOT="$(cd "$candidate" && pwd)"
break
fi
done
if [ -z "$APP_ROOT" ]; then
echo "ERROR: host app root not found"
exit 1
fi
echo "Host app root: $APP_ROOT"
# 链接 wwwroot 到宿主应用
rm -f "$APP_ROOT/wwwroot/app_audit"
ln -sf "$SCRIPT_DIR/wwwroot" "$APP_ROOT/wwwroot/app_audit"
echo "app_audit module build complete (wwwroot linked)."
echo "提示Python 包需 pip install . RBAC 权限用 scripts/load_path.py 注册。"

View File

@ -2,6 +2,8 @@
# 查看/备份/删除 仅 owner.audit 角色审计独立性superuser 也无权访问)
# action: list / backup / delete
_dbname = get_module_dbname('app_audit')
user_id = await get_user()
if not user_id:
return json.dumps({'ok': False, 'error': '未登录'}, ensure_ascii=False)
@ -15,7 +17,7 @@ from app_audit.audit_service import (
# 查 username 和 client_ip
username = user_id
try:
async with get_sor_context(request._run_ns, 'pipeline') as _sor:
async with get_sor_context(request._run_ns, _dbname) as _sor:
_u = await _sor.sqlExe("SELECT username FROM users WHERE id=${u}$", {'u': user_id})
if _u:
username = getattr(_u[0], 'username', user_id) or user_id
@ -29,7 +31,7 @@ except Exception:
pass
# 权限校验:所有 action 仅 owner.auditsuperuser 也不行)
async with get_sor_context(request._run_ns, 'pipeline') as _sor:
async with get_sor_context(request._run_ns, _dbname) as _sor:
if not await is_audit_role(_sor, user_id):
return json.dumps({'ok': False, 'error': '仅 owner.audit 角色可访问审计日志'}, ensure_ascii=False)
@ -44,7 +46,7 @@ if action == 'list':
page = (params_kw or {}).get('page', 1)
rows = (params_kw or {}).get('rows', 60)
try:
async with get_sor_context(request._run_ns, 'pipeline') as sor:
async with get_sor_context(request._run_ns, _dbname) as sor:
r = await list_audit_logs(sor, filters, page, rows)
return json.dumps(r, ensure_ascii=False)
except Exception as e:
@ -60,7 +62,7 @@ elif action == 'backup':
}
blimit = (params_kw or {}).get('limit', 10000)
try:
async with get_sor_context(request._run_ns, 'pipeline') as sor:
async with get_sor_context(request._run_ns, _dbname) as sor:
r = await backup_audit_logs(sor, user_id, username, bfilters, blimit, client_ip)
return json.dumps(r, ensure_ascii=False)
except Exception as e:
@ -69,7 +71,7 @@ elif action == 'backup':
elif action == 'delete':
before = (params_kw or {}).get('before', '')
try:
async with get_sor_context(request._run_ns, 'pipeline') as sor:
async with get_sor_context(request._run_ns, _dbname) as sor:
r = await delete_audit_logs(sor, user_id, username, before, client_ip)
return json.dumps(r, ensure_ascii=False)
except Exception as e: