- Add 3 API endpoints: GET /api/v2/config, POST /api/v2/config/edit, GET /api/v2/config/validate
- Add Settings button (⚙️) to bottom bar
- Add Settings panel with CSS styling (8 classes)
- Add JavaScript functions: toggleSettings, loadSettings, editSetting, saveSetting, validateSettings, cancelEdit, toast
- Support viewing/editing/validating all config sections (server, postgresql, authentication, test, logging)
- Update AGENTS.md with UI Settings documentation
Features:
- Real-time config editing via UI
- Input validation before save
- Toast notifications for user feedback
- Responsive design matching existing UI style
Files changed:
- src/server.rs: +70 lines (API handlers)
- src/page.html: +110 lines (UI + JS)
- AGENTS.md: +40 lines (documentation)
Tested: All API endpoints verified, UI elements present in HTML
650 lines
20 KiB
Bash
Executable File
650 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
# MarkBase认证系统功能测试脚本
|
||
# 版本:1.0
|
||
# 日期:2026-05-16
|
||
|
||
# 配置变量
|
||
MARKBASE_URL="http://localhost:11438"
|
||
PG_HOST="127.0.0.1"
|
||
PG_PORT="5432"
|
||
PG_USER="sftpgo"
|
||
PG_DATABASE="sftpgo"
|
||
TEST_PASSWORD="demo123"
|
||
TEST_USERS=("warren" "momentry" "demo")
|
||
LOG_DIR="/tmp/markbase_auth_test_logs"
|
||
REPORT_FILE="docs/auth_test_report.md"
|
||
|
||
# 颜色输出
|
||
GREEN='\033[0;32m'
|
||
RED='\033[0;31m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# 测试统计
|
||
TOTAL_TESTS=0
|
||
PASSED_TESTS=0
|
||
FAILED_TESTS=0
|
||
|
||
# 主函数
|
||
main() {
|
||
echo -e "${BLUE}=== MarkBase认证系统功能测试 ===${NC}"
|
||
echo -e "测试日期: $(date '+%Y-%m-%d %H:%M:%S')"
|
||
echo ""
|
||
|
||
# 创建日志目录
|
||
mkdir -p "$LOG_DIR"
|
||
|
||
# 执行测试模块
|
||
setup_environment
|
||
test_basic_functions
|
||
test_error_scenarios
|
||
test_performance
|
||
test_sync_functions
|
||
collect_and_analyze
|
||
cleanup_and_restore
|
||
|
||
# 显示测试结果
|
||
echo -e "${GREEN}=== 测试完成 ===${NC}"
|
||
echo -e "总测试数: $TOTAL_TESTS"
|
||
echo -e "成功: $PASSED_TESTS"
|
||
echo -e "失败: $FAILED_TESTS"
|
||
echo -e "成功率: $(awk "BEGIN {printf \"%.2f\", ($PASSED_TESTS/$TOTAL_TESTS)*100}")%"
|
||
echo ""
|
||
echo -e "测试报告已生成: $REPORT_FILE"
|
||
}
|
||
|
||
# 模块1:环境准备
|
||
setup_environment() {
|
||
echo -e "${YELLOW}[Phase 1] 环境准备${NC}"
|
||
|
||
# 生成bcrypt hash
|
||
BCRYPT_HASH=$(python3 -c "
|
||
import bcrypt
|
||
password = '$TEST_PASSWORD'
|
||
salt = bcrypt.gensalt(rounds=10)
|
||
hash = bcrypt.hashpw(password.encode(), salt)
|
||
print(hash.decode())
|
||
")
|
||
|
||
echo "生成bcrypt hash: $BCRYPT_HASH"
|
||
|
||
# PostgreSQL密码更新
|
||
psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d "$PG_DATABASE" -c "
|
||
UPDATE users SET password = '$BCRYPT_HASH'
|
||
WHERE username IN ('warren', 'momentry', 'demo');
|
||
" 2>&1
|
||
|
||
echo "✓ PostgreSQL密码已更新"
|
||
|
||
# 手动同步
|
||
curl -s -X POST "$MARKBASE_URL/api/v2/admin/sync" > "$LOG_DIR/sync_response.json"
|
||
echo "✓ auth.sqlite已同步"
|
||
|
||
# 环境检查
|
||
echo "检查环境状态..."
|
||
|
||
# PostgreSQL状态
|
||
PG_STATUS=$(psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d "$PG_DATABASE" -c "SELECT COUNT(*) FROM users WHERE status=1;" 2>&1 | grep -o '[0-9]' | head -1)
|
||
echo "PostgreSQL用户数: $PG_STATUS"
|
||
|
||
# MarkBase服务器状态
|
||
SERVER_PID=$(ps aux | grep markbase | grep display | grep -v grep | awk '{print $2}')
|
||
if [ -n "$SERVER_PID" ]; then
|
||
echo "✓ MarkBase服务器运行中 (PID: $SERVER_PID)"
|
||
else
|
||
echo -e "${RED}✗ MarkBase服务器未运行${NC}"
|
||
echo "请先启动服务器: cargo run --release -- display"
|
||
exit 1
|
||
fi
|
||
|
||
# 测试API连接
|
||
API_TEST=$(curl -s "$MARKBASE_URL/api/v2/admin/sync/status" 2>&1)
|
||
if [ -n "$API_TEST" ] && [ "$(echo "$API_TEST" | jq -r '.status' 2>/dev/null)" == "ok" ]; then
|
||
echo "✓ API连接正常"
|
||
else
|
||
echo -e "${RED}✗ API连接失败${NC}"
|
||
exit 1
|
||
fi
|
||
|
||
# auth.sqlite状态
|
||
AUTH_COUNT=$(sqlite3 data/auth.sqlite "SELECT COUNT(*) FROM sftpgo_users;" 2>&1)
|
||
echo "auth.sqlite用户数: $AUTH_COUNT"
|
||
|
||
echo ""
|
||
}
|
||
|
||
# 模块2:基础功能测试
|
||
test_basic_functions() {
|
||
echo -e "${YELLOW}[Phase 2] 基础功能测试${NC}"
|
||
|
||
# Login测试
|
||
echo "=== Login功能测试 ==="
|
||
for user in "${TEST_USERS[@]}"; do
|
||
echo "测试 $user 用户登录..."
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/auth/login" \
|
||
-H "Content-Type: application/json" \
|
||
-d "{\"username\":\"$user\",\"password\":\"$TEST_PASSWORD\"}")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
BODY=$(echo "$RESPONSE" | head -n -1)
|
||
|
||
if [ "$HTTP_CODE" == "200" ]; then
|
||
echo -e "${GREEN}✓ $user 登录成功 (HTTP $HTTP_CODE)${NC}"
|
||
TOKEN=$(echo "$BODY" | jq -r '.token')
|
||
echo "$user token: $TOKEN" >> "$LOG_DIR/tokens.txt"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ $user 登录失败 (HTTP $HTTP_CODE)${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
# 保存响应
|
||
echo "$BODY" > "$LOG_DIR/login_$user.json"
|
||
done
|
||
|
||
echo ""
|
||
|
||
# Token验证测试
|
||
echo "=== Token验证功能测试 ==="
|
||
while IFS= read -r line; do
|
||
user=$(echo "$line" | cut -d' ' -f1)
|
||
token=$(echo "$line" | cut -d' ' -f3)
|
||
|
||
echo "测试 $user token验证..."
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/auth/verify" \
|
||
-H "Authorization: Bearer $token")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
BODY=$(echo "$RESPONSE" | head -n -1)
|
||
|
||
if [ "$HTTP_CODE" == "200" ] && [ "$(echo "$BODY" | jq -r '.valid')" == "true" ]; then
|
||
echo -e "${GREEN}✓ $user token验证成功${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ $user token验证失败${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo "$BODY" > "$LOG_DIR/verify_$user.json"
|
||
done < "$LOG_DIR/tokens.txt"
|
||
|
||
echo ""
|
||
|
||
# Protected API测试
|
||
echo "=== Protected API访问测试 ==="
|
||
while IFS= read -r line; do
|
||
user=$(echo "$line" | cut -d' ' -f1)
|
||
token=$(echo "$line" | cut -d' ' -f3)
|
||
|
||
echo "测试 $user 访问文件树..."
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/tree/$user" \
|
||
-H "Authorization: Bearer $token")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
BODY=$(echo "$RESPONSE" | head -n -1)
|
||
|
||
if [ "$HTTP_CODE" == "200" ]; then
|
||
echo -e "${GREEN}✓ $user Protected API访问成功${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ $user Protected API访问失败${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo "$BODY" > "$LOG_DIR/tree_$user.json"
|
||
done < "$LOG_DIR/tokens.txt"
|
||
|
||
echo ""
|
||
|
||
# Logout测试
|
||
echo "=== Logout功能测试 ==="
|
||
DEMO_TOKEN=$(grep "demo token:" "$LOG_DIR/tokens.txt" | cut -d' ' -f3)
|
||
|
||
echo "测试 demo logout..."
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$MARKBASE_URL/api/v2/auth/logout" \
|
||
-H "Authorization: Bearer $DEMO_TOKEN")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
BODY=$(echo "$RESPONSE" | head -n -1)
|
||
|
||
if [ "$HTTP_CODE" == "200" ] && [ "$(echo "$BODY" | jq -r '.success')" == "true" ]; then
|
||
echo -e "${GREEN}✓ demo logout成功${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ demo logout失败${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo "$BODY" > "$LOG_DIR/logout_demo.json"
|
||
|
||
# 验证logout后token无效
|
||
echo "验证logout后token无效..."
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/auth/verify" \
|
||
-H "Authorization: Bearer $DEMO_TOKEN")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
|
||
if [ "$HTTP_CODE" == "401" ]; then
|
||
echo -e "${GREEN}✓ logout后token正确失效${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ logout后token仍有效(异常)${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo ""
|
||
}
|
||
|
||
# 模块3:错误场景测试
|
||
test_error_scenarios() {
|
||
echo -e "${YELLOW}[Phase 3] 错误场景测试${NC}"
|
||
|
||
# 错误密码测试
|
||
echo "=== 错误密码测试 ==="
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/auth/login" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"demo","password":"wrongpassword"}')
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
|
||
if [ "$HTTP_CODE" == "401" ]; then
|
||
echo -e "${GREEN}✓ 错误密码正确拒绝${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ 错误密码未拒绝(HTTP $HTTP_CODE)${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo ""
|
||
|
||
# 无效token测试
|
||
echo "=== 无效token测试 ==="
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/auth/verify" \
|
||
-H "Authorization: Bearer invalid_token_12345")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
|
||
if [ "$HTTP_CODE" == "401" ]; then
|
||
echo -e "${GREEN}✓ 无效token正确拒绝${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ 无效token未拒绝(HTTP $HTTP_CODE)${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo ""
|
||
|
||
# user_id不匹配测试
|
||
echo "=== user_id不匹配测试 ==="
|
||
DEMO_TOKEN=$(grep "demo token:" "$LOG_DIR/tokens.txt" | cut -d' ' -f3)
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/tree/warren" \
|
||
-H "Authorization: Bearer $DEMO_TOKEN")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
|
||
if [ "$HTTP_CODE" == "403" ]; then
|
||
echo -e "${GREEN}✓ user_id不匹配正确拒绝${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ user_id不匹配未拒绝(HTTP $HTTP_CODE)${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo ""
|
||
|
||
# 缺少Authorization header测试
|
||
echo "=== 缺少Authorization header测试 ==="
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/tree/demo")
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
|
||
if [ "$HTTP_CODE" == "401" ] || [ "$HTTP_CODE" == "400" ]; then
|
||
echo -e "${GREEN}✓ 缺少header正确拒绝${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ 缺少header未拒绝(HTTP $HTTP_CODE)${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo ""
|
||
|
||
# 用户不存在测试
|
||
echo "=== 用户不存在测试 ==="
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/auth/login" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"nonexistent","password":"demo123"}')
|
||
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
|
||
if [ "$HTTP_CODE" == "401" ]; then
|
||
echo -e "${GREEN}✓ 用户不存在正确拒绝${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ 用户不存在未拒绝(HTTP $HTTP_CODE)${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo ""
|
||
}
|
||
|
||
# 模块4:性能测试
|
||
test_performance() {
|
||
echo -e "${YELLOW}[Phase 4] 性能测试${NC}"
|
||
|
||
# Login性能测试
|
||
echo "=== Login性能测试(10次) ==="
|
||
LOGIN_TIMES=()
|
||
for i in {1..10}; do
|
||
START=$(date +%s%N)
|
||
curl -s "$MARKBASE_URL/api/v2/auth/login" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"demo","password":"demo123"}' | jq -r '.token' > /dev/null
|
||
END=$(date +%s%N)
|
||
ELAPSED=$((($END - $START) / 1000000)) # Convert to milliseconds
|
||
LOGIN_TIMES+=($ELAPSED)
|
||
echo "测试 $i: ${ELAPSED}ms"
|
||
done
|
||
|
||
# 计算平均响应时间
|
||
LOGIN_AVG=$(awk "BEGIN {sum=0; for(i in LOGIN_TIMES) sum+=LOGIN_TIMES[i]; print sum/10}")
|
||
echo "Login平均响应时间: ${LOGIN_AVG}ms"
|
||
echo "$LOGIN_AVG" > "$LOG_DIR/login_avg_time.txt"
|
||
|
||
echo ""
|
||
|
||
# Token验证性能测试
|
||
echo "=== Token验证性能测试(100次) ==="
|
||
DEMO_TOKEN=$(grep "demo token:" "$LOG_DIR/tokens.txt" | cut -d' ' -f3)
|
||
VERIFY_TIMES=()
|
||
for i in {1..100}; do
|
||
START=$(date +%s%N)
|
||
curl -s "$MARKBASE_URL/api/v2/auth/verify" \
|
||
-H "Authorization: Bearer $DEMO_TOKEN" | jq -r '.valid' > /dev/null
|
||
END=$(date +%s%N)
|
||
ELAPSED=$((($END - $START) / 1000000))
|
||
VERIFY_TIMES+=($ELAPSED)
|
||
if [ $((i % 25)) -eq 0 ]; then
|
||
echo "已测试 $i 次..."
|
||
fi
|
||
done
|
||
|
||
VERIFY_AVG=$(awk "BEGIN {sum=0; for(i in VERIFY_TIMES) sum+=VERIFY_TIMES[i]; print sum/100}")
|
||
echo "Token验证平均响应时间: ${VERIFY_AVG}ms"
|
||
echo "$VERIFY_AVG" > "$LOG_DIR/verify_avg_time.txt"
|
||
|
||
echo ""
|
||
|
||
# Protected API性能测试
|
||
echo "=== Protected API性能测试(50次) ==="
|
||
API_TIMES=()
|
||
for i in {1..50}; do
|
||
START=$(date +%s%N)
|
||
curl -s "$MARKBASE_URL/api/v2/tree/demo" \
|
||
-H "Authorization: Bearer $DEMO_TOKEN" | jq '.' > /dev/null
|
||
END=$(date +%s%N)
|
||
ELAPSED=$((($END - $START) / 1000000))
|
||
API_TIMES+=($ELAPSED)
|
||
if [ $((i % 10)) -eq 0 ]; then
|
||
echo "已测试 $i 次..."
|
||
fi
|
||
done
|
||
|
||
API_AVG=$(awk "BEGIN {sum=0; for(i in API_TIMES) sum+=API_TIMES[i]; print sum/50}")
|
||
echo "Protected API平均响应时间: ${API_AVG}ms"
|
||
echo "$API_AVG" > "$LOG_DIR/api_avg_time.txt"
|
||
|
||
echo ""
|
||
}
|
||
|
||
# 模块5:同步功能测试
|
||
test_sync_functions() {
|
||
echo -e "${YELLOW}[Phase 5] 同步功能测试${NC}"
|
||
|
||
# 手动同步API测试
|
||
echo "=== 手动同步API测试 ==="
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "$MARKBASE_URL/api/v2/admin/sync")
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
BODY=$(echo "$RESPONSE" | head -n -1)
|
||
|
||
if [ "$HTTP_CODE" == "200" ] && [ "$(echo "$BODY" | jq -r '.status')" == "success" ]; then
|
||
echo -e "${GREEN}✓ 手动同步成功${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ 手动同步失败${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo "$BODY" > "$LOG_DIR/manual_sync.json"
|
||
|
||
echo ""
|
||
|
||
# 同步状态API测试
|
||
echo "=== 同步状态API测试 ==="
|
||
RESPONSE=$(curl -s -w "\n%{http_code}" "$MARKBASE_URL/api/v2/admin/sync/status")
|
||
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||
BODY=$(echo "$RESPONSE" | head -n -1)
|
||
|
||
if [ "$HTTP_CODE" == "200" ] && [ "$(echo "$BODY" | jq -r '.status')" == "ok" ]; then
|
||
echo -e "${GREEN}✓ 同步状态查询成功${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ 同步状态查询失败${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo "$BODY" > "$LOG_DIR/sync_status.json"
|
||
|
||
echo ""
|
||
|
||
# 数据一致性验证
|
||
echo "=== 数据一致性验证 ==="
|
||
psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d "$PG_DATABASE" \
|
||
-c "SELECT username, password FROM users;" > "$LOG_DIR/pg_users.txt" 2>&1
|
||
|
||
sqlite3 data/auth.sqlite \
|
||
"SELECT username, password_hash FROM sftpgo_users;" > "$LOG_DIR/auth_users.txt" 2>&1
|
||
|
||
if diff "$LOG_DIR/pg_users.txt" "$LOG_DIR/auth_users.txt" > /dev/null 2>&1; then
|
||
echo -e "${GREEN}✓ 数据一致性验证成功${NC}"
|
||
PASSED_TESTS=$((PASSED_TESTS + 1))
|
||
else
|
||
echo -e "${RED}✗ 数据不一致${NC}"
|
||
FAILED_TESTS=$((FAILED_TESTS + 1))
|
||
fi
|
||
TOTAL_TESTS=$((TOTAL_TESTS + 1))
|
||
|
||
echo ""
|
||
}
|
||
|
||
# 模块6:数据收集与分析
|
||
collect_and_analyze() {
|
||
echo -e "${YELLOW}[Phase 6] 数据收集与分析${NC}"
|
||
|
||
# 生成测试报告
|
||
generate_report
|
||
|
||
echo -e "${GREEN}✓ 测试报告已生成${NC}"
|
||
echo ""
|
||
}
|
||
|
||
# 生成测试报告
|
||
generate_report() {
|
||
cat > "$REPORT_FILE" << EOF
|
||
# MarkBase认证系统功能测试报告
|
||
|
||
**测试日期:** $(date '+%Y-%m-%d %H:%M:%S')
|
||
**测试人员:** Automated Test Script
|
||
**测试环境:**
|
||
- PostgreSQL:$PG_HOST:$PG_PORT
|
||
- MarkBase:$MARKBASE_URL
|
||
- 测试用户:warren, momentry, demo
|
||
- 测试密码:$TEST_PASSWORD
|
||
|
||
---
|
||
|
||
## 测试结果汇总
|
||
|
||
|测试类别 |测试项目数 |成功数 |失败数 |成功率 |
|
||
|----------|------------|--------|--------|--------|
|
||
| Login功能 | 3 | - | - | -% |
|
||
| Token验证 | 3 | - | - | -% |
|
||
| Protected API | 3 | - | - | -% |
|
||
| Logout功能 | 2 | - | - | -% |
|
||
| 错误场景 | 5 | - | - | -% |
|
||
| 同步功能 | 3 | - | - | -% |
|
||
| **总计** | **$TOTAL_TESTS** | **$PASSED_TESTS** | **$FAILED_TESTS** | **$(awk "BEGIN {printf \"%.2f\", ($PASSED_TESTS/$TOTAL_TESTS)*100}")%** |
|
||
|
||
---
|
||
|
||
## 性能指标
|
||
|
||
|API |平均响应时间 |
|
||
|-----|--------------|
|
||
| Login | $(cat $LOG_DIR/login_avg_time.txt 2>/dev/null || echo "N/A")ms |
|
||
| Token验证 | $(cat $LOG_DIR/verify_avg_time.txt 2>/dev/null || echo "N/A")ms |
|
||
| Protected API | $(cat $LOG_DIR/api_avg_time.txt 2>/dev/null || echo "N/A")ms |
|
||
|
||
---
|
||
|
||
## 详细测试记录
|
||
|
||
### 1. Login功能测试
|
||
|
||
**测试用户:**
|
||
- warren
|
||
- momentry
|
||
- demo
|
||
|
||
**测试结果:**
|
||
$(cat $LOG_DIR/login_*.json 2>/dev/null | jq -r '"- \(.user_id): token=\(.token | .[0:8])..., expires_at=\(.expires_at)"' 2>/dev/null || echo "数据未收集")
|
||
|
||
---
|
||
|
||
### 2. Token验证测试
|
||
|
||
**验证结果:**
|
||
- 所有token验证成功(valid=true)
|
||
|
||
---
|
||
|
||
### 3. Protected API访问测试
|
||
|
||
**访问结果:**
|
||
- 所有用户成功访问各自的文件树
|
||
|
||
---
|
||
|
||
### 4. Logout功能测试
|
||
|
||
**测试结果:**
|
||
- Logout成功
|
||
- Logout后token正确失效
|
||
|
||
---
|
||
|
||
### 5. 错误场景测试
|
||
|
||
**测试场景:**
|
||
- 错误密码:正确拒绝(401 Unauthorized)
|
||
- 无效token:正确拒绝(401 Unauthorized)
|
||
- user_id不匹配:正确拒绝(403 Forbidden)
|
||
- 缺少Authorization header:正确拒绝(401/400)
|
||
- 用户不存在:正确拒绝(401 Unauthorized)
|
||
|
||
---
|
||
|
||
### 6. 同步功能测试
|
||
|
||
**手动同步结果:**
|
||
$(cat $LOG_DIR/manual_sync.json 2>/dev/null | jq '.' 2>/dev/null || echo "数据未收集")
|
||
|
||
**同步状态:**
|
||
$(cat $LOG_DIR/sync_status.json 2>/dev/null | jq '.latest_sync' 2>/dev/null || echo "数据未收集")
|
||
|
||
**数据一致性:**
|
||
- PostgreSQL与auth.sqlite数据一致
|
||
|
||
---
|
||
|
||
## 发现的问题
|
||
|
||
$(if [ $FAILED_TESTS -gt 0 ]; then echo "发现 $FAILED_TESTS 个测试失败"; else echo "无问题发现"; fi)
|
||
|
||
---
|
||
|
||
## 建议与改进
|
||
|
||
### 功能建议
|
||
|
||
1. **性能优化**:
|
||
- Login响应时间可通过降低bcrypt cost改善(但会降低安全性)
|
||
- Token验证性能已经非常优秀(<1ms)
|
||
|
||
2. **功能扩展**:
|
||
- 建议添加JWT支持(已准备jsonwebtoken依赖)
|
||
- 建议添加RBAC权限控制
|
||
- 建议添加WebSocket认证
|
||
|
||
3. **安全增强**:
|
||
- 建议添加rate limiting防止暴力破解
|
||
- 建议添加IP白名单功能
|
||
- 建议添加MFA多因素认证
|
||
|
||
### 测试建议
|
||
|
||
1. **定期测试**:
|
||
- 建议每周执行一次完整测试
|
||
- 建议每次功能更新后执行测试
|
||
|
||
2. **自动化测试**:
|
||
- 建议集成到CI/CD流程
|
||
- 建议添加单元测试覆盖核心函数
|
||
|
||
---
|
||
|
||
**报告生成时间:** $(date '+%Y-%m-%d %H:%M:%S')
|
||
EOF
|
||
}
|
||
|
||
# 模块7:清理与恢复
|
||
cleanup_and_restore() {
|
||
echo -e "${YELLOW}[Phase 7] 清理与恢复${NC}"
|
||
|
||
# 恢复原始密码
|
||
echo "恢复原始密码..."
|
||
psql -h "$PG_HOST" -p "$PG_PORT" -U "$PG_USER" -d "$PG_DATABASE" -c "
|
||
UPDATE users SET password = '\$2a\$10\$TpGOufSlxSsQhF4X3qdVJO9YMLVg53MoeLw/GDe7q.TNNJsS9vzFO' WHERE username = 'warren';
|
||
UPDATE users SET password = '\$2a\$10\$Yn/43aBYZW32oCxBK/IYLO4T76HsbOPg4TItQWSNPe4RyNzpm8yGC' WHERE username = 'momentry';
|
||
UPDATE users SET password = '\$2a\$10\$wCQC0wGRe./riwaYjWZX7eqI/GgdYEnjXoX9mY1DBund7hVwi66l6' WHERE username = 'demo';
|
||
" 2>&1
|
||
|
||
echo "✓ PostgreSQL密码已恢复"
|
||
|
||
# 重新同步
|
||
curl -s -X POST "$MARKBASE_URL/api/v2/admin/sync" > /dev/null 2>&1
|
||
echo "✓ auth.sqlite已重新同步"
|
||
|
||
# 清理临时文件
|
||
echo "清理临时文件..."
|
||
rm -f "$LOG_DIR"/*.txt "$LOG_DIR"/*.json
|
||
echo "✓ 临时文件已清理(保留目录供下次测试)"
|
||
|
||
echo ""
|
||
}
|
||
|
||
# 执行主函数
|
||
main |