Files
wenzi/scripts/check_permission_consistency.sh

203 lines
7.6 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# 权限码一致性校验脚本
# 校验后端/数据库/前端/canonical基线四维权限码差异
# 支持多段权限码(如 approval.index.batch.transfer.ALL和连字符如 system.api-key.create.ALL
set -e
echo "=== 权限码一致性校验 ==="
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
BACKEND_PERMS="$SCRIPT_DIR/.permission_check_backend.txt"
FRONTEND_PERMS="$SCRIPT_DIR/.permission_check_frontend.txt"
DB_PERMS="$SCRIPT_DIR/.permission_check_db.txt"
CANONICAL_PERMS="$SCRIPT_DIR/.permission_check_canonical.txt"
DIFF_REPORT="$SCRIPT_DIR/permission_diff_report.md"
# 清理旧文件
rm -f "$BACKEND_PERMS" "$FRONTEND_PERMS" "$DB_PERMS" "$CANONICAL_PERMS" "$DIFF_REPORT"
echo "0. 加载Canonical 90基线..."
CANONICAL_FILE="$PROJECT_DIR/src/test/resources/permission/canonical-permissions-90.txt"
if [ -f "$CANONICAL_FILE" ]; then
grep -v '^#' "$CANONICAL_FILE" | grep -v '^$' | sort -u > "$CANONICAL_PERMS" || true
fi
CANONICAL_COUNT=$(wc -l < "$CANONICAL_PERMS")
echo " Canonical基线权限码数量: $CANONICAL_COUNT"
echo "1. 提取前端权限码..."
# 提取前端权限码从roles.ts
# 支持多段格式: module.resource[.subresource].operation[.suboperation].dataScope
# 例如: approval.index.batch.transfer.ALL (5段), dashboard.chart.realtime.ALL (4段)
grep -oE "'[a-z]+(-[a-z]+)*\.[a-z]+(-[a-z]+)*(\.[a-z]+(-[a-z]+)*)*\.[A-Z]+'" "$PROJECT_DIR/frontend/admin/src/auth/roles.ts" 2>/dev/null | \
sed "s/'//g" | sort -u > "$FRONTEND_PERMS" || true
# 也支持双引号
grep -oE '"[a-z]+(-[a-z]+)*\.[a-z]+(-[a-z]+)*(\.[a-z]+(-[a-z]+)*)*\.[A-Z]+"' "$PROJECT_DIR/frontend/admin/src/auth/roles.ts" 2>/dev/null | \
sed 's/"//g' >> "$FRONTEND_PERMS" || true
sort -u "$FRONTEND_PERMS" -o "$FRONTEND_PERMS"
FRONTEND_COUNT=$(wc -l < "$FRONTEND_PERMS")
echo " 前端权限码数量: $FRONTEND_COUNT"
echo "2. 提取数据库权限码..."
# 提取数据库权限码从SQL迁移脚本
# 支持多段格式: module.resource[.subresource].operation[.suboperation].dataScope
grep -oE "'[a-z]+(-[a-z]+)*\.[a-z]+(-[a-z]+)*(\.[a-z]+(-[a-z]+)*)*\.[A-Z]+'" "$PROJECT_DIR/src/main/resources/db/migration/V26__Seed_roles_permissions.sql" 2>/dev/null | \
sed "s/'//g" > "$DB_PERMS" || true
# 从其他迁移脚本补充
for sql in "$PROJECT_DIR/src/main/resources/db/migration"/V*.sql; do
grep -oE "'[a-z]+(-[a-z]+)*\.[a-z]+(-[a-z]+)*(\.[a-z]+(-[a-z]+)*)*\.[A-Z]+'" "$sql" 2>/dev/null | sed "s/'//g" >> "$DB_PERMS" || true
done
sort -u "$DB_PERMS" -o "$DB_PERMS"
DB_COUNT=$(wc -l < "$DB_PERMS")
echo " 数据库权限码总数: $DB_COUNT"
echo "3. 提取后端权限码..."
# 提取后端权限码从RequirePermission注解
# 支持直接字符串: @RequirePermission("approval.index.view.ALL")
# 支持多段格式: module.resource[.subresource].operation[.suboperation].dataScope
grep -r "RequirePermission" "$PROJECT_DIR/src/main/java" --include="*.java" 2>/dev/null | \
grep -oE '"[a-z]+(-[a-z]+)*\.[a-z]+(-[a-z]+)*(\.[a-z]+(-[a-z]+)*)*\.[A-Z]+"' | sed 's/"//g' >> "$BACKEND_PERMS" || true
# 支持常量引用: @RequirePermission(PERM_XXX) - 需要进一步处理常量定义
# 找出所有常量定义
grep -r "private static final String PERM_" "$PROJECT_DIR/src/main/java" --include="*.java" 2>/dev/null | \
grep -oE 'PERM_[A-Z_]+ = "[a-z]+(-[a-z]+)*\.[a-z]+(-[a-z]+)*(\.[a-z]+(-[a-z]+)*)*\.[A-Z]+"' | \
sed 's/.*= *"/"/g' | sed 's/"//g' >> "$BACKEND_PERMS" || true
sort -u "$BACKEND_PERMS" -o "$BACKEND_PERMS"
BACKEND_COUNT=$(wc -l < "$BACKEND_PERMS")
echo " 后端权限码数量: $BACKEND_COUNT"
echo ""
echo "4. 生成差异报告..."
# 计算差异
comm -23 "$FRONTEND_PERMS" "$CANONICAL_PERMS" > "$SCRIPT_DIR/.frontend_only.txt" || true
comm -23 "$DB_PERMS" "$CANONICAL_PERMS" > "$SCRIPT_DIR/.db_only.txt" || true
comm -23 "$BACKEND_PERMS" "$CANONICAL_PERMS" > "$SCRIPT_DIR/.backend_only.txt" || true
comm -23 "$CANONICAL_PERMS" "$FRONTEND_PERMS" > "$SCRIPT_DIR/.canonical_not_in_frontend.txt" || true
comm -23 "$CANONICAL_PERMS" "$DB_PERMS" > "$SCRIPT_DIR/.canonical_not_in_db.txt" || true
comm -23 "$CANONICAL_PERMS" "$BACKEND_PERMS" > "$SCRIPT_DIR/.canonical_not_in_backend.txt" || true
FRONTEND_ONLY=$(wc -l < "$SCRIPT_DIR/.frontend_only.txt")
DB_ONLY=$(wc -l < "$SCRIPT_DIR/.db_only.txt")
BACKEND_ONLY=$(wc -l < "$SCRIPT_DIR/.backend_only.txt")
CANONICAL_NOT_IN_FRONTEND=$(wc -l < "$SCRIPT_DIR/.canonical_not_in_frontend.txt")
CANONICAL_NOT_IN_DB=$(wc -l < "$SCRIPT_DIR/.canonical_not_in_db.txt")
CANONICAL_NOT_IN_BACKEND=$(wc -l < "$SCRIPT_DIR/.canonical_not_in_backend.txt")
# 写入报告
cat > "$DIFF_REPORT" << EOF
# 权限码一致性校验报告
生成时间: $(date '+%Y-%m-%d %H:%M:%S')
## 四维统计
| 来源 | 权限码数量 |
|------|------------|
| Canonical基线 | $CANONICAL_COUNT |
| 前端 | $FRONTEND_COUNT |
| 数据库 | $DB_COUNT |
| 后端 | $BACKEND_COUNT |
## Canonical基线覆盖率
| 维度 | 缺失数量 | 说明 |
|------|----------|------|
| 前端缺失 | $CANONICAL_NOT_IN_FRONTEND | Canonical基线在前端未定义 |
| 数据库缺失 | $CANONICAL_NOT_IN_DB | Canonical基线在数据库未导入 |
| 后端缺失 | $CANONICAL_NOT_IN_BACKEND | Canonical基线在后端未使用 |
## 额外权限码分析不在Canonical基线中
### 前端独有权限码 (不在Canonical基线中): $FRONTEND_ONLY
EOF
if [ $FRONTEND_ONLY -gt 0 ]; then
echo "" >> "$DIFF_REPORT"
cat "$SCRIPT_DIR/.frontend_only.txt" >> "$DIFF_REPORT"
echo "" >> "$DIFF_REPORT"
fi
cat >> "$DIFF_REPORT" << EOF
### 数据库独有权限码 (不在Canonical基线中): $DB_ONLY
EOF
if [ $DB_ONLY -gt 0 ]; then
echo "" >> "$DIFF_REPORT"
cat "$SCRIPT_DIR/.db_only.txt" >> "$DIFF_REPORT"
echo "" >> "$DIFF_REPORT"
fi
cat >> "$DIFF_REPORT" << EOF
### 后端独有权限码 (不在Canonical基线中): $BACKEND_ONLY
EOF
if [ $BACKEND_ONLY -gt 0 ]; then
echo "" >> "$DIFF_REPORT"
cat "$SCRIPT_DIR/.backend_only.txt" >> "$DIFF_REPORT"
echo "" >> "$DIFF_REPORT"
fi
cat >> "$DIFF_REPORT" << EOF
## Canonical基线缺失项
### 前端未覆盖Canonical基线 ($CANONICAL_NOT_IN_FRONTEND)
EOF
if [ $CANONICAL_NOT_IN_FRONTEND -gt 0 ]; then
echo "" >> "$DIFF_REPORT"
cat "$SCRIPT_DIR/.canonical_not_in_frontend.txt" >> "$DIFF_REPORT"
echo "" >> "$DIFF_REPORT"
fi
cat >> "$DIFF_REPORT" << EOF
### 数据库未导入Canonical基线 ($CANONICAL_NOT_IN_DB)
EOF
if [ $CANONICAL_NOT_IN_DB -gt 0 ]; then
echo "" >> "$DIFF_REPORT"
cat "$SCRIPT_DIR/.canonical_not_in_db.txt" >> "$DIFF_REPORT"
echo "" >> "$DIFF_REPORT"
fi
cat >> "$DIFF_REPORT" << EOF
### 后端未实现Canonical基线 ($CANONICAL_NOT_IN_BACKEND)
EOF
if [ $CANONICAL_NOT_IN_BACKEND -gt 0 ]; then
echo "" >> "$DIFF_REPORT"
cat "$SCRIPT_DIR/.canonical_not_in_backend.txt" >> "$DIFF_REPORT"
echo "" >> "$DIFF_REPORT"
fi
# 判断是否通过 - 以Canonical基线为基准
if [ $CANONICAL_NOT_IN_FRONTEND -eq 0 ] && [ $CANONICAL_NOT_IN_DB -eq 0 ] && [ $CANONICAL_NOT_IN_BACKEND -eq 0 ]; then
echo ""
echo "✅ 权限码一致性校验通过Canonical基线已完整覆盖。"
RESULT=0
else
echo ""
echo "❌ 权限码一致性校验未通过,请查看差异报告: $DIFF_REPORT"
echo " Canonical基线缺失 - 前端: $CANONICAL_NOT_IN_FRONTEND"
echo " Canonical基线缺失 - 数据库: $CANONICAL_NOT_IN_DB"
echo " Canonical基线缺失 - 后端: $CANONICAL_NOT_IN_BACKEND"
RESULT=1
fi
# 清理临时文件
rm -f "$SCRIPT_DIR/.frontend_only.txt" "$SCRIPT_DIR/.db_only.txt" "$SCRIPT_DIR/.backend_only.txt"
rm -f "$SCRIPT_DIR/.canonical_not_in_frontend.txt" "$SCRIPT_DIR/.canonical_not_in_db.txt" "$SCRIPT_DIR/.canonical_not_in_backend.txt"
exit $RESULT