Fix user delete flow 11

This commit is contained in:
Urtzi Alfaro
2025-08-03 00:16:31 +02:00
parent a65386e138
commit b35eb7c875
5 changed files with 985 additions and 30 deletions

436
tests/debug_admin_role.sh Executable file
View File

@@ -0,0 +1,436 @@
#!/bin/bash
# =================================================================
# COMPREHENSIVE ADMIN ROLE DEBUG SCRIPT
# =================================================================
# This script will trace the entire flow of admin role assignment
# from registration through JWT token creation to API calls
# Configuration
API_BASE="http://localhost:8000"
AUTH_BASE="http://localhost:8001"
TEST_EMAIL="debug.admin.test.$(date +%s)@bakery.com"
TEST_PASSWORD="DebugPassword123!"
TEST_NAME="Debug Admin User"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
echo -e "${CYAN}🔍 COMPREHENSIVE ADMIN ROLE DEBUG${NC}"
echo -e "${CYAN}=================================${NC}"
echo "Test Email: $TEST_EMAIL"
echo "API Base: $API_BASE"
echo "Auth Base: $AUTH_BASE"
echo ""
# Utility functions
log_step() {
echo -e "${BLUE}📋 $1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
log_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
log_debug() {
echo -e "${PURPLE}🐛 DEBUG: $1${NC}"
}
# Function to decode JWT token (requires jq and base64)
decode_jwt() {
local token="$1"
local part="$2" # header=0, payload=1, signature=2
if [ -z "$token" ]; then
echo "No token provided"
return 1
fi
# Split token by dots
IFS='.' read -ra PARTS <<< "$token"
if [ ${#PARTS[@]} -ne 3 ]; then
echo "Invalid JWT format"
return 1
fi
# Decode the specified part (default to payload)
local part_index=${part:-1}
local encoded_part="${PARTS[$part_index]}"
# Add padding if needed
local padding=$(( 4 - ${#encoded_part} % 4 ))
if [ $padding -ne 4 ]; then
encoded_part="${encoded_part}$(printf '%*s' $padding | tr ' ' '=')"
fi
# Decode and format as JSON
echo "$encoded_part" | base64 -d 2>/dev/null | jq '.' 2>/dev/null || echo "Failed to decode JWT part"
}
# Function to extract JSON field
extract_json_field() {
local json="$1"
local field="$2"
echo "$json" | python3 -c "
import json, sys
try:
data = json.load(sys.stdin)
print(data.get('$field', ''))
except:
print('')
" 2>/dev/null
}
# =================================================================
# STEP 1: VERIFY SERVICES ARE RUNNING
# =================================================================
log_step "Step 1: Verifying services are running"
# Check API Gateway
if ! curl -s "$API_BASE/health" > /dev/null; then
log_error "API Gateway is not responding at $API_BASE"
echo "Please ensure services are running: docker-compose up -d"
exit 1
fi
log_success "API Gateway is responding"
# Check Auth Service directly
if ! curl -s "$AUTH_BASE/health" > /dev/null; then
log_error "Auth Service is not responding at $AUTH_BASE"
exit 1
fi
log_success "Auth Service is responding"
echo ""
# =================================================================
# STEP 2: USER REGISTRATION WITH DETAILED DEBUGGING
# =================================================================
log_step "Step 2: User Registration with Admin Role"
echo "Email: $TEST_EMAIL"
echo "Role: admin (explicitly set)"
echo ""
log_debug "Sending registration request..."
# Registration request with explicit role
REGISTER_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X POST "$API_BASE/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d "{
\"email\": \"$TEST_EMAIL\",
\"password\": \"$TEST_PASSWORD\",
\"full_name\": \"$TEST_NAME\",
\"role\": \"admin\"
}")
# Extract HTTP code and response
HTTP_CODE=$(echo "$REGISTER_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
REGISTER_RESPONSE=$(echo "$REGISTER_RESPONSE" | sed '/HTTP_CODE:/d')
echo "Registration HTTP Status: $HTTP_CODE"
echo "Registration Response:"
echo "$REGISTER_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$REGISTER_RESPONSE"
if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ]; then
log_error "Registration failed with HTTP $HTTP_CODE"
exit 1
fi
# Extract user information from registration response
USER_ID=$(extract_json_field "$REGISTER_RESPONSE" "user_id")
if [ -z "$USER_ID" ]; then
# Try alternative field names
USER_ID=$(echo "$REGISTER_RESPONSE" | python3 -c "
import json, sys
try:
data = json.load(sys.stdin)
user = data.get('user', {})
print(user.get('id', data.get('id', '')))
except:
print('')
" 2>/dev/null)
fi
ACCESS_TOKEN=$(extract_json_field "$REGISTER_RESPONSE" "access_token")
REFRESH_TOKEN=$(extract_json_field "$REGISTER_RESPONSE" "refresh_token")
log_debug "Extracted from registration:"
echo " User ID: $USER_ID"
echo " Access Token: ${ACCESS_TOKEN:0:50}..."
echo " Refresh Token: ${REFRESH_TOKEN:0:50}..."
echo ""
# =================================================================
# STEP 3: DECODE AND ANALYZE JWT TOKEN
# =================================================================
log_step "Step 3: JWT Token Analysis"
if [ -n "$ACCESS_TOKEN" ]; then
log_debug "Decoding JWT Header:"
JWT_HEADER=$(decode_jwt "$ACCESS_TOKEN" 0)
echo "$JWT_HEADER"
echo ""
log_debug "Decoding JWT Payload:"
JWT_PAYLOAD=$(decode_jwt "$ACCESS_TOKEN" 1)
echo "$JWT_PAYLOAD"
# Extract role from JWT payload
JWT_ROLE=$(echo "$JWT_PAYLOAD" | jq -r '.role // "NOT_FOUND"' 2>/dev/null)
JWT_USER_ID=$(echo "$JWT_PAYLOAD" | jq -r '.user_id // "NOT_FOUND"' 2>/dev/null)
JWT_EMAIL=$(echo "$JWT_PAYLOAD" | jq -r '.email // "NOT_FOUND"' 2>/dev/null)
echo ""
log_debug "JWT Payload Analysis:"
echo " Role in JWT: $JWT_ROLE"
echo " User ID in JWT: $JWT_USER_ID"
echo " Email in JWT: $JWT_EMAIL"
if [ "$JWT_ROLE" = "admin" ]; then
log_success "JWT contains admin role correctly"
else
log_error "JWT role is '$JWT_ROLE', expected 'admin'"
fi
else
log_error "No access token received in registration response"
echo "Cannot analyze JWT"
fi
echo ""
# =================================================================
# STEP 4: VERIFY USER PROFILE ENDPOINT
# =================================================================
log_step "Step 4: User Profile Verification"
if [ -n "$ACCESS_TOKEN" ]; then
log_debug "Calling /users/me endpoint..."
USER_PROFILE_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X GET "$API_BASE/api/v1/users/me" \
-H "Authorization: Bearer $ACCESS_TOKEN")
# Extract HTTP code and response
HTTP_CODE=$(echo "$USER_PROFILE_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
USER_PROFILE_RESPONSE=$(echo "$USER_PROFILE_RESPONSE" | sed '/HTTP_CODE:/d')
echo "User Profile HTTP Status: $HTTP_CODE"
echo "User Profile Response:"
echo "$USER_PROFILE_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$USER_PROFILE_RESPONSE"
if [ "$HTTP_CODE" = "200" ]; then
PROFILE_ROLE=$(extract_json_field "$USER_PROFILE_RESPONSE" "role")
PROFILE_EMAIL=$(extract_json_field "$USER_PROFILE_RESPONSE" "email")
PROFILE_USER_ID=$(extract_json_field "$USER_PROFILE_RESPONSE" "id")
echo ""
log_debug "Profile endpoint analysis:"
echo " Role from profile: $PROFILE_ROLE"
echo " Email from profile: $PROFILE_EMAIL"
echo " User ID from profile: $PROFILE_USER_ID"
if [ "$PROFILE_ROLE" = "admin" ]; then
log_success "Profile endpoint shows admin role correctly"
else
log_error "Profile endpoint shows role '$PROFILE_ROLE', expected 'admin'"
fi
else
log_error "Failed to get user profile (HTTP $HTTP_CODE)"
fi
else
log_error "No access token available for profile verification"
fi
echo ""
# =================================================================
# STEP 5: DIRECT DATABASE VERIFICATION (if possible)
# =================================================================
log_step "Step 5: Database Verification"
log_debug "Attempting to verify user role in database..."
# Try to connect to the auth database directly
DB_QUERY_RESULT=$(docker exec bakery-auth-db psql -U auth_user -d auth_db -t -c "SELECT id, email, role, created_at FROM users WHERE email='$TEST_EMAIL';" 2>/dev/null || echo "DB_ACCESS_FAILED")
if [ "$DB_QUERY_RESULT" != "DB_ACCESS_FAILED" ]; then
echo "Database Query Result:"
echo "$DB_QUERY_RESULT"
# Parse the database result
DB_ROLE=$(echo "$DB_QUERY_RESULT" | awk -F'|' '{print $3}' | tr -d ' ')
log_debug "Role in database: '$DB_ROLE'"
if [ "$DB_ROLE" = "admin" ]; then
log_success "Database shows admin role correctly"
else
log_error "Database shows role '$DB_ROLE', expected 'admin'"
fi
else
log_warning "Cannot access database directly (this is normal in some setups)"
echo "You can manually check with:"
echo " docker exec bakery-auth-db psql -U auth_user -d auth_db -c \"SELECT id, email, role FROM users WHERE email='$TEST_EMAIL';\""
fi
echo ""
# =================================================================
# STEP 6: TEST ADMIN ENDPOINT ACCESS
# =================================================================
log_step "Step 6: Testing Admin Endpoint Access"
if [ -n "$ACCESS_TOKEN" ] && [ -n "$USER_ID" ]; then
log_debug "Attempting to call admin deletion preview endpoint..."
ADMIN_TEST_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X GET "$API_BASE/api/v1/users/delete/$USER_ID/deletion-preview" \
-H "Authorization: Bearer $ACCESS_TOKEN")
# Extract HTTP code and response
HTTP_CODE=$(echo "$ADMIN_TEST_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
ADMIN_TEST_RESPONSE=$(echo "$ADMIN_TEST_RESPONSE" | sed '/HTTP_CODE:/d')
echo "Admin Endpoint HTTP Status: $HTTP_CODE"
echo "Admin Endpoint Response:"
echo "$ADMIN_TEST_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$ADMIN_TEST_RESPONSE"
case "$HTTP_CODE" in
"200")
log_success "Admin endpoint access successful!"
;;
"403")
log_error "Access denied - user does not have admin privileges"
echo "This confirms the role issue!"
;;
"401")
log_error "Authentication failed - token may be invalid"
;;
*)
log_warning "Unexpected response from admin endpoint (HTTP $HTTP_CODE)"
;;
esac
else
log_error "Cannot test admin endpoint - missing access token or user ID"
fi
echo ""
# =================================================================
# STEP 7: AUTH SERVICE LOGS ANALYSIS
# =================================================================
log_step "Step 7: Auth Service Logs Analysis"
log_debug "Checking recent auth service logs..."
AUTH_LOGS=$(docker logs --tail 50 bakery-auth-service 2>/dev/null | grep -E "(register|role|admin|$TEST_EMAIL)" || echo "NO_LOGS_FOUND")
if [ "$AUTH_LOGS" != "NO_LOGS_FOUND" ]; then
echo "Recent Auth Service Logs (filtered):"
echo "$AUTH_LOGS"
else
log_warning "Cannot access auth service logs"
echo "You can check manually with:"
echo " docker logs bakery-auth-service | grep -E \"(register|role|admin)\""
fi
echo ""
# =================================================================
# STEP 8: SUMMARY AND RECOMMENDATIONS
# =================================================================
log_step "Step 8: Debug Summary and Recommendations"
echo -e "${CYAN}🔍 DEBUG SUMMARY${NC}"
echo -e "${CYAN}===============${NC}"
echo ""
echo "Test User Details:"
echo " Email: $TEST_EMAIL"
echo " Expected Role: admin"
echo " User ID: ${USER_ID:-'NOT_EXTRACTED'}"
echo ""
echo "Token Analysis:"
echo " Access Token Received: $([ -n "$ACCESS_TOKEN" ] && echo 'YES' || echo 'NO')"
echo " Role in JWT: ${JWT_ROLE:-'NOT_FOUND'}"
echo " JWT User ID: ${JWT_USER_ID:-'NOT_FOUND'}"
echo ""
echo "API Responses:"
echo " Registration HTTP: ${HTTP_CODE:-'UNKNOWN'}"
echo " Profile Role: ${PROFILE_ROLE:-'NOT_CHECKED'}"
echo " Admin Endpoint Access: $([ -n "$ADMIN_TEST_RESPONSE" ] && echo "TESTED" || echo "NOT_TESTED")"
echo ""
echo "Database Verification:"
echo " DB Role: ${DB_ROLE:-'NOT_CHECKED'}"
echo ""
log_debug "Potential Issues:"
# Issue 1: Role not in JWT
if [ "$JWT_ROLE" != "admin" ]; then
echo " ❌ Role not correctly encoded in JWT token"
echo " → Check auth service JWT creation logic"
echo " → Verify SecurityManager.create_access_token includes role"
fi
# Issue 2: Registration not setting role
if [ "$PROFILE_ROLE" != "admin" ]; then
echo " ❌ User profile doesn't show admin role"
echo " → Check user registration saves role correctly"
echo " → Verify database schema allows role field"
fi
# Issue 3: Admin endpoint still denies access
if [ "$HTTP_CODE" = "403" ]; then
echo " ❌ Admin endpoint denies access despite admin role"
echo " → Check require_admin_role_dep implementation"
echo " → Verify role extraction from token in auth decorators"
fi
echo ""
echo -e "${YELLOW}🔧 RECOMMENDED NEXT STEPS:${NC}"
echo "1. Check the auth service logs during registration"
echo "2. Verify the database schema has a 'role' column"
echo "3. Check if the JWT creation includes the role field"
echo "4. Verify the role extraction in get_current_user_dep"
echo "5. Test with a direct database role update if needed"
echo ""
echo -e "${CYAN}🧪 Manual Verification Commands:${NC}"
echo "# Check database directly:"
echo "docker exec bakery-auth-db psql -U auth_user -d auth_db -c \"SELECT id, email, role FROM users WHERE email='$TEST_EMAIL';\""
echo ""
echo "# Check auth service logs:"
echo "docker logs bakery-auth-service | grep -A5 -B5 '$TEST_EMAIL'"
echo ""
echo "# Decode JWT manually:"
echo "echo '$ACCESS_TOKEN' | cut -d. -f2 | base64 -d | jq ."
echo ""
log_success "Debug script completed!"
echo -e "${YELLOW}Review the analysis above to identify the root cause.${NC}"

361
tests/debug_onboarding_flow.sh Executable file
View File

@@ -0,0 +1,361 @@
#!/bin/bash
# =================================================================
# ONBOARDING FLOW DEBUG SCRIPT
# =================================================================
# This script replicates the exact onboarding flow to debug the 403 issue
# Configuration
API_BASE="http://localhost:8000"
TEST_EMAIL="onboarding.debug.$(date +%s)@bakery.com"
TEST_PASSWORD="OnboardingDebug123!"
TEST_NAME="Onboarding Debug User"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m'
echo -e "${CYAN}🔍 ONBOARDING FLOW DEBUG - EXACT REPLICATION${NC}"
echo -e "${CYAN}=============================================${NC}"
echo "Test Email: $TEST_EMAIL"
echo "API Base: $API_BASE"
echo ""
# Utility functions
log_step() {
echo -e "${BLUE}📋 $1${NC}"
}
log_success() {
echo -e "${GREEN}$1${NC}"
}
log_error() {
echo -e "${RED}$1${NC}"
}
log_debug() {
echo -e "${PURPLE}🐛 DEBUG: $1${NC}"
}
extract_json_field() {
local json="$1"
local field="$2"
echo "$json" | python3 -c "
import json, sys
try:
data = json.load(sys.stdin)
user = data.get('user', {})
print(user.get('$field', data.get('$field', '')))
except:
print('')
" 2>/dev/null
}
# =================================================================
# STEP 1: REGISTER USER (EXACTLY LIKE ONBOARDING SCRIPT)
# =================================================================
log_step "Step 1: User Registration (Onboarding Style)"
echo "Email: $TEST_EMAIL"
echo "Role: admin (explicitly set)"
echo ""
log_debug "Registering via API Gateway (same as onboarding script)..."
REGISTER_RESPONSE=$(curl -s -X POST "$API_BASE/api/v1/auth/register" \
-H "Content-Type: application/json" \
-d "{
\"email\": \"$TEST_EMAIL\",
\"password\": \"$TEST_PASSWORD\",
\"full_name\": \"$TEST_NAME\",
\"role\": \"admin\"
}")
echo "Registration Response:"
echo "$REGISTER_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$REGISTER_RESPONSE"
# Extract user ID exactly like onboarding script
USER_ID=$(echo "$REGISTER_RESPONSE" | python3 -c "
import json, sys
try:
data = json.load(sys.stdin)
user = data.get('user', {})
print(user.get('id', ''))
except:
print('')
")
if [ -n "$USER_ID" ]; then
log_success "User ID extracted: $USER_ID"
else
log_error "Failed to extract user ID"
exit 1
fi
echo ""
# =================================================================
# STEP 2: LOGIN (EXACTLY LIKE ONBOARDING SCRIPT)
# =================================================================
log_step "Step 2: User Login (Onboarding Style)"
LOGIN_RESPONSE=$(curl -s -X POST "$API_BASE/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d "{
\"email\": \"$TEST_EMAIL\",
\"password\": \"$TEST_PASSWORD\"
}")
echo "Login Response:"
echo "$LOGIN_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$LOGIN_RESPONSE"
ACCESS_TOKEN=$(extract_json_field "$LOGIN_RESPONSE" "access_token")
if [ -n "$ACCESS_TOKEN" ]; then
log_success "Access token obtained: ${ACCESS_TOKEN:0:50}..."
else
log_error "Failed to extract access token"
exit 1
fi
echo ""
# =================================================================
# STEP 3: CHECK PROFILE ENDPOINT
# =================================================================
log_step "Step 3: Check Profile Endpoint"
PROFILE_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X GET "$API_BASE/api/v1/users/me" \
-H "Authorization: Bearer $ACCESS_TOKEN")
HTTP_CODE=$(echo "$PROFILE_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
PROFILE_RESPONSE=$(echo "$PROFILE_RESPONSE" | sed '/HTTP_CODE:/d')
echo "Profile HTTP Status: $HTTP_CODE"
echo "Profile Response:"
echo "$PROFILE_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$PROFILE_RESPONSE"
PROFILE_ROLE=$(extract_json_field "$PROFILE_RESPONSE" "role")
echo ""
log_debug "Profile role: $PROFILE_ROLE"
if [ "$PROFILE_ROLE" = "admin" ]; then
log_success "Profile shows admin role correctly"
else
log_error "Profile shows role '$PROFILE_ROLE', expected 'admin'"
fi
echo ""
# =================================================================
# STEP 4: TEST ADMIN DELETION PREVIEW (EXACTLY LIKE ONBOARDING)
# =================================================================
log_step "Step 4: Admin Deletion Preview (Onboarding Style)"
log_debug "Calling deletion preview endpoint..."
DELETION_PREVIEW_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X GET "$API_BASE/api/v1/users/delete/$USER_ID/deletion-preview" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json")
HTTP_CODE=$(echo "$DELETION_PREVIEW_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
DELETION_PREVIEW_RESPONSE=$(echo "$DELETION_PREVIEW_RESPONSE" | sed '/HTTP_CODE:/d')
echo "Deletion Preview HTTP Status: $HTTP_CODE"
echo "Deletion Preview Response:"
echo "$DELETION_PREVIEW_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$DELETION_PREVIEW_RESPONSE"
case "$HTTP_CODE" in
"200")
log_success "Deletion preview successful!"
;;
"403")
log_error "403 Forbidden - Admin access denied!"
echo "This is the same error as in onboarding script"
;;
"401")
log_error "401 Unauthorized - Token issue"
;;
*)
log_error "Unexpected HTTP status: $HTTP_CODE"
;;
esac
echo ""
# =================================================================
# STEP 5: TEST ACTUAL DELETION (EXACTLY LIKE ONBOARDING)
# =================================================================
log_step "Step 5: Admin User Deletion (Onboarding Style)"
if [ "$HTTP_CODE" = "200" ]; then
log_debug "Attempting actual deletion..."
DELETION_RESPONSE=$(curl -s -w "\nHTTP_CODE:%{http_code}" -X DELETE "$API_BASE/api/v1/users/delete/$USER_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN")
HTTP_CODE=$(echo "$DELETION_RESPONSE" | grep "HTTP_CODE:" | cut -d: -f2)
DELETION_RESPONSE=$(echo "$DELETION_RESPONSE" | sed '/HTTP_CODE:/d')
echo "Deletion HTTP Status: $HTTP_CODE"
echo "Deletion Response:"
echo "$DELETION_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$DELETION_RESPONSE"
case "$HTTP_CODE" in
"200")
log_success "Admin deletion successful!"
;;
"403")
log_error "403 Forbidden - Admin deletion denied!"
;;
*)
log_error "Deletion failed with HTTP $HTTP_CODE"
;;
esac
else
log_error "Skipping deletion test due to preview failure"
fi
echo ""
# =================================================================
# STEP 6: DETAILED TOKEN ANALYSIS
# =================================================================
log_step "Step 6: Detailed Token Analysis"
log_debug "Decoding access token from login..."
if [ -n "$ACCESS_TOKEN" ]; then
# Decode JWT payload
JWT_PAYLOAD=$(echo "$ACCESS_TOKEN" | cut -d. -f2)
# Add padding if needed
JWT_PAYLOAD="${JWT_PAYLOAD}$(printf '%*s' $((4 - ${#JWT_PAYLOAD} % 4)) | tr ' ' '=')"
echo "JWT Payload:"
echo "$JWT_PAYLOAD" | base64 -d 2>/dev/null | python3 -m json.tool 2>/dev/null || echo "Failed to decode"
JWT_ROLE=$(echo "$JWT_PAYLOAD" | base64 -d 2>/dev/null | python3 -c "
import json, sys
try:
data = json.load(sys.stdin)
print(data.get('role', 'NOT_FOUND'))
except:
print('DECODE_ERROR')
" 2>/dev/null)
echo ""
log_debug "JWT token role: $JWT_ROLE"
else
log_error "No access token available for analysis"
fi
echo ""
# =================================================================
# STEP 7: CHECK GATEWAY VS DIRECT AUTH
# =================================================================
log_step "Step 7: Gateway vs Direct Auth Comparison"
log_debug "Testing direct auth service call..."
DIRECT_PROFILE=$(curl -s -X GET "http://localhost:8001/me" \
-H "Authorization: Bearer $ACCESS_TOKEN" 2>/dev/null || echo "DIRECT_FAILED")
if [ "$DIRECT_PROFILE" != "DIRECT_FAILED" ]; then
echo "Direct Auth Service Profile:"
echo "$DIRECT_PROFILE" | python3 -m json.tool 2>/dev/null || echo "$DIRECT_PROFILE"
DIRECT_ROLE=$(extract_json_field "$DIRECT_PROFILE" "role")
log_debug "Direct auth service role: $DIRECT_ROLE"
else
log_debug "Direct auth service call failed (expected in some setups)"
fi
echo ""
# =================================================================
# STEP 8: CHECK AUTH SERVICE LOGS
# =================================================================
log_step "Step 8: Auth Service Logs for This Session"
log_debug "Checking auth service logs for this user..."
AUTH_LOGS=$(docker logs --tail 50 bakery-auth-service 2>/dev/null | grep -E "($TEST_EMAIL|$USER_ID)" || echo "NO_LOGS_FOUND")
if [ "$AUTH_LOGS" != "NO_LOGS_FOUND" ]; then
echo "Auth Service Logs (filtered for this user):"
echo "$AUTH_LOGS"
else
log_debug "No specific logs found for this user"
fi
echo ""
# =================================================================
# STEP 9: SUMMARY AND COMPARISON
# =================================================================
log_step "Step 9: Onboarding Flow Analysis Summary"
echo -e "${CYAN}🔍 ONBOARDING FLOW ANALYSIS${NC}"
echo -e "${CYAN}===========================${NC}"
echo ""
echo "Registration Results:"
echo " User ID: $USER_ID"
echo " Access Token: $([ -n "$ACCESS_TOKEN" ] && echo 'YES' || echo 'NO')"
echo ""
echo "Authentication Flow:"
echo " Profile Role: $PROFILE_ROLE"
echo " JWT Role: $JWT_ROLE"
echo " Direct Auth Role: ${DIRECT_ROLE:-'NOT_TESTED'}"
echo ""
echo "Admin Endpoint Tests:"
echo " Deletion Preview: HTTP $HTTP_CODE"
echo " Admin Access: $([ "$HTTP_CODE" = "200" ] && echo 'SUCCESS' || echo 'FAILED')"
echo ""
if [ "$HTTP_CODE" != "200" ]; then
echo -e "${RED}🚨 ISSUE IDENTIFIED:${NC}"
echo "The onboarding flow is still getting 403 errors"
echo ""
echo -e "${YELLOW}Possible causes:${NC}"
echo "1. Token from login different from registration token"
echo "2. Gateway headers not set correctly"
echo "3. Role being overridden somewhere in the flow"
echo "4. Cache or session issue"
echo ""
echo -e "${YELLOW}Next steps:${NC}"
echo "1. Compare JWT tokens from registration vs login"
echo "2. Check gateway request headers"
echo "3. Verify auth service restart picked up the fix"
echo "4. Check if there are multiple auth service instances"
else
log_success "Onboarding flow working correctly!"
fi
echo ""
echo -e "${CYAN}Manual commands to investigate:${NC}"
echo "# Check user in database:"
echo "docker exec bakery-auth-db psql -U auth_user -d auth_db -c \"SELECT id, email, role FROM users WHERE email='$TEST_EMAIL';\""
echo ""
echo "# Restart auth service:"
echo "docker-compose restart auth-service"
echo ""
echo "# Check auth service status:"
echo "docker-compose ps auth-service"

157
tests/verify_db_schema.sh Executable file
View File

@@ -0,0 +1,157 @@
#!/bin/bash
# =================================================================
# DATABASE SCHEMA AND DATA VERIFICATION SCRIPT
# =================================================================
# This script checks the auth database schema and data
echo "🔍 DATABASE VERIFICATION"
echo "========================"
# Colors
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Check if auth database container is running
if ! docker ps | grep -q "bakery-auth-db"; then
echo -e "${RED}❌ Auth database container is not running${NC}"
echo "Start with: docker-compose up -d auth-db"
exit 1
fi
echo -e "${GREEN}✅ Auth database container is running${NC}"
echo ""
# 1. Check database schema
echo "📋 1. CHECKING DATABASE SCHEMA"
echo "=============================="
echo "Users table structure:"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "\d users;" 2>/dev/null || {
echo -e "${RED}❌ Cannot access database or users table doesn't exist${NC}"
exit 1
}
echo ""
echo "Checking if 'role' column exists:"
ROLE_COLUMN=$(docker exec bakery-auth-db psql -U auth_user -d auth_db -t -c "SELECT column_name FROM information_schema.columns WHERE table_name='users' AND column_name='role';" 2>/dev/null | tr -d ' ')
if [ "$ROLE_COLUMN" = "role" ]; then
echo -e "${GREEN}✅ 'role' column exists in users table${NC}"
else
echo -e "${RED}❌ 'role' column is missing from users table${NC}"
echo "This is likely the root cause!"
echo ""
echo "Available columns in users table:"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "SELECT column_name, data_type FROM information_schema.columns WHERE table_name='users';"
exit 1
fi
echo ""
# 2. Check existing users and their roles
echo "📋 2. CHECKING EXISTING USERS"
echo "============================="
echo "All users in database:"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "SELECT id, email, role, is_active, created_at FROM users ORDER BY created_at DESC LIMIT 10;"
echo ""
# 3. Check for test users
echo "📋 3. CHECKING FOR TEST USERS"
echo "============================="
echo "Test users (containing 'test' in email):"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "SELECT id, email, role, is_active, created_at FROM users WHERE email LIKE '%test%' ORDER BY created_at DESC;"
echo ""
# 4. Check database constraints and defaults
echo "📋 4. CHECKING ROLE CONSTRAINTS"
echo "==============================="
echo "Role column details:"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_name='users' AND column_name='role';"
echo ""
echo "Role check constraints (if any):"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "SELECT conname, consrc FROM pg_constraint WHERE conrelid = 'users'::regclass AND consrc LIKE '%role%';" 2>/dev/null || echo "No role constraints found"
echo ""
# 5. Test role insertion
echo "📋 5. TESTING ROLE INSERTION"
echo "============================"
TEST_EMAIL="schema.test.$(date +%s)@example.com"
echo "Creating test user with admin role:"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "
INSERT INTO users (id, email, full_name, hashed_password, role, is_active, is_verified, created_at, updated_at)
VALUES (gen_random_uuid(), '$TEST_EMAIL', 'Schema Test', 'dummy_hash', 'admin', true, false, NOW(), NOW());
" 2>/dev/null
if [ $? -eq 0 ]; then
echo -e "${GREEN}✅ Successfully inserted user with admin role${NC}"
echo "Verifying insertion:"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "SELECT id, email, role FROM users WHERE email='$TEST_EMAIL';"
echo "Cleaning up test user:"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "DELETE FROM users WHERE email='$TEST_EMAIL';" 2>/dev/null
else
echo -e "${RED}❌ Failed to insert user with admin role${NC}"
echo "This indicates a database constraint or permission issue"
fi
echo ""
# 6. Check for migration history
echo "📋 6. CHECKING MIGRATION HISTORY"
echo "================================="
echo "Alembic version table (if exists):"
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "SELECT * FROM alembic_version;" 2>/dev/null || echo "No alembic_version table found"
echo ""
echo "📋 SUMMARY AND RECOMMENDATIONS"
echo "==============================="
# Check if we found any obvious issues
ISSUES_FOUND=0
# Check if role column exists
if [ "$ROLE_COLUMN" != "role" ]; then
echo -e "${RED}❌ CRITICAL: 'role' column missing from users table${NC}"
echo " → Run database migrations: alembic upgrade head"
echo " → Or add the column manually"
ISSUES_FOUND=1
fi
# Check if we can insert admin roles
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "INSERT INTO users (id, email, full_name, hashed_password, role, is_active, is_verified, created_at, updated_at) VALUES (gen_random_uuid(), 'temp.test@example.com', 'Test', 'hash', 'admin', true, false, NOW(), NOW());" 2>/dev/null
if [ $? -eq 0 ]; then
docker exec bakery-auth-db psql -U auth_user -d auth_db -c "DELETE FROM users WHERE email='temp.test@example.com';" 2>/dev/null
else
echo -e "${RED}❌ ISSUE: Cannot insert users with admin role${NC}"
echo " → Check database constraints or permissions"
ISSUES_FOUND=1
fi
if [ $ISSUES_FOUND -eq 0 ]; then
echo -e "${GREEN}✅ Database schema appears correct${NC}"
echo " → The issue is likely in the application code, not the database"
echo " → Check JWT token creation and role extraction logic"
else
echo -e "${YELLOW}⚠️ Database issues found - fix these first${NC}"
fi
echo ""
echo -e "${YELLOW}🔧 Next steps:${NC}"
echo "1. If role column is missing: Run 'alembic upgrade head' in auth service"
echo "2. If schema is OK: Run the main debug script to check application logic"
echo "3. Check auth service logs during user registration"