feat: 审计库名改用 ServerEnv().get_module_dbname 适配多宿主 + 增加 customer_recharge 审计动作 + build.sh
This commit is contained in:
parent
d5feff2042
commit
48cc7fca82
@ -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",
|
||||
}
|
||||
|
||||
|
||||
@ -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
30
build.sh
Executable 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 注册。"
|
||||
@ -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.audit(superuser 也不行)
|
||||
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:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user