203 lines
7.6 KiB
Bash
Executable File
203 lines
7.6 KiB
Bash
Executable File
#!/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 94基线..."
|
||
CANONICAL_FILE="$PROJECT_DIR/src/test/resources/permission/canonical-permissions-94.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 |