You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
364 lines
12 KiB
364 lines
12 KiB
#!/bin/bash
|
|
# RBAC E2E 测试脚本
|
|
# 测试:超级管理员登录、角色字段持久化、权限策略执行
|
|
|
|
BASE_URL="http://localhost:8888/api/v1"
|
|
TIMESTAMP=$(date +%s)
|
|
PASS=0
|
|
FAIL=0
|
|
|
|
log_step() {
|
|
echo -e "\n\033[36m--- Step $1: $2 ---\033[0m"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "\033[32m[PASS]\033[0m $1"
|
|
PASS=$((PASS + 1))
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "\033[31m[FAIL]\033[0m $1"
|
|
FAIL=$((FAIL + 1))
|
|
}
|
|
|
|
extract_value() {
|
|
echo "$1" | grep -o "\"$2\":\"[^\"]*\"" | head -1 | sed 's/"'"$2"'"://' | sed 's/^"//' | sed 's/"$//'
|
|
}
|
|
|
|
extract_int() {
|
|
echo "$1" | grep -o "\"$2\":[^,}]*" | head -1 | sed 's/"'"$2"'"://' | tr -d ' '
|
|
}
|
|
|
|
# ============================
|
|
# Part 1: 超级管理员登录
|
|
# ============================
|
|
|
|
log_step "1" "Super admin login (admin@system.local / admin123)"
|
|
LOGIN_RESULT=$(curl -s -X POST ${BASE_URL}/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email":"admin@system.local","password":"admin123"}')
|
|
ADMIN_TOKEN=$(extract_value "$LOGIN_RESULT" "token")
|
|
LOGIN_CODE=$(extract_int "$LOGIN_RESULT" "code")
|
|
|
|
if [ "$LOGIN_CODE" = "200" ] && [ -n "$ADMIN_TOKEN" ]; then
|
|
log_success "Super admin login success"
|
|
else
|
|
log_error "Super admin login failed: $LOGIN_RESULT"
|
|
echo "=== RESULT: $PASS passed, $FAIL failed ==="
|
|
exit 1
|
|
fi
|
|
|
|
# ============================
|
|
# Part 2: 验证 JWT 包含 role claim
|
|
# ============================
|
|
|
|
log_step "2" "Verify JWT contains role claim"
|
|
JWT_PAYLOAD=$(echo "$ADMIN_TOKEN" | cut -d. -f2 | base64 -d 2>/dev/null)
|
|
JWT_ROLE=$(echo "$JWT_PAYLOAD" | grep -o '"role":"[^"]*"' | head -1 | sed 's/"role":"//' | sed 's/"$//')
|
|
|
|
if [ "$JWT_ROLE" = "super_admin" ]; then
|
|
log_success "JWT role claim = super_admin"
|
|
else
|
|
log_error "JWT role claim expected 'super_admin', got '$JWT_ROLE'"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 3: 创建带角色的用户(admin 管理员用户)
|
|
# ============================
|
|
|
|
log_step "3" "Create user with role=admin via super_admin"
|
|
CREATE_ADMIN_RESULT=$(curl -s -X POST ${BASE_URL}/user \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
|
-d "{\"username\":\"rbac_admin_${TIMESTAMP}\",\"email\":\"rbac_admin_${TIMESTAMP}@test.com\",\"password\":\"password123\",\"role\":\"admin\",\"remark\":\"RBAC test admin\"}")
|
|
ADMIN_USER_ID=$(extract_int "$CREATE_ADMIN_RESULT" "id")
|
|
CREATED_ROLE=$(extract_value "$CREATE_ADMIN_RESULT" "role")
|
|
CREATED_SOURCE=$(extract_value "$CREATE_ADMIN_RESULT" "source")
|
|
CREATED_REMARK=$(extract_value "$CREATE_ADMIN_RESULT" "remark")
|
|
|
|
if [ -n "$ADMIN_USER_ID" ] && [ "$CREATED_ROLE" = "admin" ]; then
|
|
log_success "Created admin user (id=$ADMIN_USER_ID, role=$CREATED_ROLE)"
|
|
else
|
|
log_error "Create admin user failed: $CREATE_ADMIN_RESULT"
|
|
fi
|
|
|
|
if [ "$CREATED_SOURCE" = "manual" ]; then
|
|
log_success "Source = manual (correct for admin-created user)"
|
|
else
|
|
log_error "Source expected 'manual', got '$CREATED_SOURCE'"
|
|
fi
|
|
|
|
if [ "$CREATED_REMARK" = "RBAC test admin" ]; then
|
|
log_success "Remark preserved correctly"
|
|
else
|
|
log_error "Remark expected 'RBAC test admin', got '$CREATED_REMARK'"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 4: 创建普通用户
|
|
# ============================
|
|
|
|
log_step "4" "Create user with default role (user)"
|
|
CREATE_USER_RESULT=$(curl -s -X POST ${BASE_URL}/user \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
|
-d "{\"username\":\"rbac_user_${TIMESTAMP}\",\"email\":\"rbac_user_${TIMESTAMP}@test.com\",\"password\":\"password123\"}")
|
|
NORMAL_USER_ID=$(extract_int "$CREATE_USER_RESULT" "id")
|
|
NORMAL_ROLE=$(extract_value "$CREATE_USER_RESULT" "role")
|
|
|
|
if [ -n "$NORMAL_USER_ID" ] && [ "$NORMAL_ROLE" = "user" ]; then
|
|
log_success "Created normal user (id=$NORMAL_USER_ID, role=user)"
|
|
else
|
|
log_error "Create normal user failed: $CREATE_USER_RESULT"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 5: 注册用户验证默认 role 和 source
|
|
# ============================
|
|
|
|
log_step "5" "Register new user — verify role=user, source=register"
|
|
REGISTER_RESULT=$(curl -s -X POST ${BASE_URL}/register \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"username\":\"rbac_reg_${TIMESTAMP}\",\"email\":\"rbac_reg_${TIMESTAMP}@test.com\",\"password\":\"password123\"}")
|
|
REG_ROLE=$(extract_value "$REGISTER_RESULT" "role")
|
|
REG_SOURCE=$(extract_value "$REGISTER_RESULT" "source")
|
|
|
|
if [ "$REG_ROLE" = "user" ]; then
|
|
log_success "Registered user role = user"
|
|
else
|
|
log_error "Registered user role expected 'user', got '$REG_ROLE'"
|
|
fi
|
|
|
|
if [ "$REG_SOURCE" = "register" ]; then
|
|
log_success "Registered user source = register"
|
|
else
|
|
log_error "Registered user source expected 'register', got '$REG_SOURCE'"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 6: 普通用户登录 — 验证受限访问
|
|
# ============================
|
|
|
|
log_step "6" "Normal user login"
|
|
NORMAL_LOGIN=$(curl -s -X POST ${BASE_URL}/login \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"email\":\"rbac_user_${TIMESTAMP}@test.com\",\"password\":\"password123\"}")
|
|
USER_TOKEN=$(extract_value "$NORMAL_LOGIN" "token")
|
|
NORMAL_LOGIN_CODE=$(extract_int "$NORMAL_LOGIN" "code")
|
|
|
|
if [ "$NORMAL_LOGIN_CODE" = "200" ] && [ -n "$USER_TOKEN" ]; then
|
|
log_success "Normal user login success"
|
|
else
|
|
log_error "Normal user login failed: $NORMAL_LOGIN"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 7: 普通用户 GET /users — 应该 403
|
|
# ============================
|
|
|
|
log_step "7" "Normal user GET /users — expect 403"
|
|
USER_LIST_RESULT=$(curl -s -o /dev/null -w "%{http_code}" -X GET "${BASE_URL}/users?page=1&pageSize=10" \
|
|
-H "Authorization: Bearer ${USER_TOKEN}")
|
|
|
|
if [ "$USER_LIST_RESULT" = "403" ]; then
|
|
log_success "GET /users returned 403 for role=user"
|
|
else
|
|
log_error "GET /users expected 403, got $USER_LIST_RESULT"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 8: 普通用户 POST /user — 应该 403
|
|
# ============================
|
|
|
|
log_step "8" "Normal user POST /user — expect 403"
|
|
USER_CREATE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X POST ${BASE_URL}/user \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer ${USER_TOKEN}" \
|
|
-d '{"username":"hacker","email":"hacker@test.com","password":"password123"}')
|
|
|
|
if [ "$USER_CREATE_CODE" = "403" ]; then
|
|
log_success "POST /user returned 403 for role=user"
|
|
else
|
|
log_error "POST /user expected 403, got $USER_CREATE_CODE"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 9: 普通用户 DELETE /user/:id — 应该 403
|
|
# ============================
|
|
|
|
log_step "9" "Normal user DELETE /user/:id — expect 403"
|
|
USER_DELETE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE "${BASE_URL}/user/${NORMAL_USER_ID}" \
|
|
-H "Authorization: Bearer ${USER_TOKEN}")
|
|
|
|
if [ "$USER_DELETE_CODE" = "403" ]; then
|
|
log_success "DELETE /user/:id returned 403 for role=user"
|
|
else
|
|
log_error "DELETE /user/:id expected 403, got $USER_DELETE_CODE"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 10: 普通用户 GET /profile/me — 应该 200
|
|
# ============================
|
|
|
|
log_step "10" "Normal user GET /profile/me — expect 200"
|
|
PROFILE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET "${BASE_URL}/profile/me" \
|
|
-H "Authorization: Bearer ${USER_TOKEN}")
|
|
|
|
if [ "$PROFILE_CODE" = "200" ]; then
|
|
log_success "GET /profile/me returned 200 for role=user"
|
|
else
|
|
log_error "GET /profile/me expected 200, got $PROFILE_CODE"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 11: 普通用户 GET /dashboard/stats — 应该 200
|
|
# ============================
|
|
|
|
log_step "11" "Normal user GET /dashboard/stats — expect 200"
|
|
DASHBOARD_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET "${BASE_URL}/dashboard/stats" \
|
|
-H "Authorization: Bearer ${USER_TOKEN}")
|
|
|
|
if [ "$DASHBOARD_CODE" = "200" ]; then
|
|
log_success "GET /dashboard/stats returned 200 for role=user (inherits guest)"
|
|
else
|
|
log_error "GET /dashboard/stats expected 200, got $DASHBOARD_CODE"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 12: admin 用户登录 — 验证管理权限
|
|
# ============================
|
|
|
|
log_step "12" "Admin user login"
|
|
ADMIN_USER_LOGIN=$(curl -s -X POST ${BASE_URL}/login \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"email\":\"rbac_admin_${TIMESTAMP}@test.com\",\"password\":\"password123\"}")
|
|
ADMIN_USER_TOKEN=$(extract_value "$ADMIN_USER_LOGIN" "token")
|
|
|
|
if [ -n "$ADMIN_USER_TOKEN" ]; then
|
|
log_success "Admin user login success"
|
|
else
|
|
log_error "Admin user login failed"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 13: admin 用户 GET /users — 应该 200
|
|
# ============================
|
|
|
|
log_step "13" "Admin user GET /users — expect 200"
|
|
ADMIN_LIST_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X GET "${BASE_URL}/users?page=1&pageSize=10" \
|
|
-H "Authorization: Bearer ${ADMIN_USER_TOKEN}")
|
|
|
|
if [ "$ADMIN_LIST_CODE" = "200" ]; then
|
|
log_success "GET /users returned 200 for role=admin"
|
|
else
|
|
log_error "GET /users expected 200, got $ADMIN_LIST_CODE"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 14: admin 用户 DELETE /user/:id — 应该 403 (仅 super_admin 可删除)
|
|
# ============================
|
|
|
|
log_step "14" "Admin user DELETE /user/:id — expect 403"
|
|
ADMIN_DELETE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE "${BASE_URL}/user/${NORMAL_USER_ID}" \
|
|
-H "Authorization: Bearer ${ADMIN_USER_TOKEN}")
|
|
|
|
if [ "$ADMIN_DELETE_CODE" = "403" ]; then
|
|
log_success "DELETE /user/:id returned 403 for role=admin"
|
|
else
|
|
log_error "DELETE /user/:id expected 403, got $ADMIN_DELETE_CODE"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 15: 更新用户角色 (super_admin 修改 role)
|
|
# ============================
|
|
|
|
log_step "15" "Super admin update user role"
|
|
UPDATE_ROLE_RESULT=$(curl -s -X PUT "${BASE_URL}/user/${NORMAL_USER_ID}" \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}" \
|
|
-d '{"role":"admin","remark":"promoted to admin"}')
|
|
UPDATED_ROLE=$(extract_value "$UPDATE_ROLE_RESULT" "role")
|
|
UPDATED_REMARK=$(extract_value "$UPDATE_ROLE_RESULT" "remark")
|
|
|
|
if [ "$UPDATED_ROLE" = "admin" ]; then
|
|
log_success "User role updated to admin"
|
|
else
|
|
log_error "User role update failed, expected 'admin', got '$UPDATED_ROLE'"
|
|
fi
|
|
|
|
if [ "$UPDATED_REMARK" = "promoted to admin" ]; then
|
|
log_success "Remark updated correctly"
|
|
else
|
|
log_error "Remark expected 'promoted to admin', got '$UPDATED_REMARK'"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 16: super_admin 用户列表包含 role/source 字段
|
|
# ============================
|
|
|
|
log_step "16" "Verify user list returns role/source fields"
|
|
LIST_RESULT=$(curl -s -X GET "${BASE_URL}/users?page=1&pageSize=100" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}")
|
|
|
|
if echo "$LIST_RESULT" | grep -q '"role"'; then
|
|
log_success "User list contains 'role' field"
|
|
else
|
|
log_error "User list missing 'role' field"
|
|
fi
|
|
|
|
if echo "$LIST_RESULT" | grep -q '"source"'; then
|
|
log_success "User list contains 'source' field"
|
|
else
|
|
log_error "User list missing 'source' field"
|
|
fi
|
|
|
|
if echo "$LIST_RESULT" | grep -q '"remark"'; then
|
|
log_success "User list contains 'remark' field"
|
|
else
|
|
log_error "User list missing 'remark' field"
|
|
fi
|
|
|
|
# ============================
|
|
# Part 17: super_admin DELETE — 应该 200
|
|
# ============================
|
|
|
|
log_step "17" "Super admin DELETE /user/:id — expect 200"
|
|
SA_DELETE_CODE=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE "${BASE_URL}/user/${NORMAL_USER_ID}" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}")
|
|
|
|
if [ "$SA_DELETE_CODE" = "200" ]; then
|
|
log_success "DELETE /user/:id returned 200 for super_admin"
|
|
else
|
|
log_error "DELETE /user/:id expected 200 for super_admin, got $SA_DELETE_CODE"
|
|
fi
|
|
|
|
# ============================
|
|
# Cleanup: 删除测试创建的 admin 用户
|
|
# ============================
|
|
|
|
log_step "18" "Cleanup — delete test admin user"
|
|
curl -s -o /dev/null -X DELETE "${BASE_URL}/user/${ADMIN_USER_ID}" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}"
|
|
log_success "Cleanup complete"
|
|
|
|
# 删除注册的测试用户
|
|
REG_USER=$(curl -s -X GET "${BASE_URL}/users?page=1&pageSize=100&keyword=rbac_reg_${TIMESTAMP}" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}")
|
|
REG_USER_ID=$(extract_int "$REG_USER" "id")
|
|
if [ -n "$REG_USER_ID" ]; then
|
|
curl -s -o /dev/null -X DELETE "${BASE_URL}/user/${REG_USER_ID}" \
|
|
-H "Authorization: Bearer ${ADMIN_TOKEN}"
|
|
fi
|
|
|
|
# ============================
|
|
# 结果汇总
|
|
# ============================
|
|
echo ""
|
|
echo "========================================="
|
|
echo -e " RBAC E2E Test Results"
|
|
echo -e " \033[32mPassed: $PASS\033[0m | \033[31mFailed: $FAIL\033[0m"
|
|
echo "========================================="
|
|
|
|
if [ "$FAIL" -gt 0 ]; then
|
|
exit 1
|
|
fi
|
|
|