Improve the design of the frontend
This commit is contained in:
@@ -1,436 +0,0 @@
|
||||
#!/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}"
|
||||
@@ -1,361 +0,0 @@
|
||||
#!/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"
|
||||
@@ -1,157 +0,0 @@
|
||||
#!/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"
|
||||
Reference in New Issue
Block a user