Files
unionflow-server-api/test-mobile-auth.sh
2025-09-19 16:09:21 +00:00

309 lines
12 KiB
Bash

#!/bin/bash
# =============================================================================
# SCRIPT DE TEST D'AUTHENTIFICATION MOBILE UNIONFLOW
# =============================================================================
#
# Ce script teste l'authentification OAuth2/OIDC pour l'application mobile
# avec tous les comptes de test créés, simulant le flux WebView
#
# Usage : ./test-mobile-auth.sh [username]
# ./test-mobile-auth.sh (teste tous les comptes)
# =============================================================================
set -e
# Configuration
KEYCLOAK_URL="http://192.168.1.145:8180"
REALM="unionflow"
CLIENT_ID="unionflow-mobile"
REDIRECT_URI="dev.lions.unionflow-mobile://auth/callback"
# Couleurs
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
# Générer un code verifier PKCE
generate_code_verifier() {
echo $(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)
}
# Générer le code challenge PKCE
generate_code_challenge() {
local verifier="$1"
echo -n "$verifier" | openssl dgst -sha256 -binary | openssl base64 | tr -d "=+/" | cut -c1-43
}
# Générer un state aléatoire
generate_state() {
echo $(openssl rand -base64 32 | tr -d "=+/" | cut -c1-43)
}
# Tester l'authentification OAuth2 complète
test_oauth_flow() {
local username="$1"
local password="$2"
local role="$3"
log_info "🔐 Test OAuth2 pour $username ($role)"
# Générer les paramètres PKCE
local code_verifier=$(generate_code_verifier)
local code_challenge=$(generate_code_challenge "$code_verifier")
local state=$(generate_state)
echo " 📋 Paramètres OAuth2 :"
echo " • Code Verifier: ${code_verifier:0:20}..."
echo " • Code Challenge: ${code_challenge:0:20}..."
echo " • State: ${state:0:20}..."
# Étape 1: Construire l'URL d'autorisation
local auth_url="${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/auth"
auth_url="${auth_url}?response_type=code"
auth_url="${auth_url}&client_id=${CLIENT_ID}"
auth_url="${auth_url}&redirect_uri=${REDIRECT_URI}"
auth_url="${auth_url}&scope=openid%20profile%20email%20roles"
auth_url="${auth_url}&state=${state}"
auth_url="${auth_url}&code_challenge=${code_challenge}"
auth_url="${auth_url}&code_challenge_method=S256"
auth_url="${auth_url}&kc_locale=fr"
auth_url="${auth_url}&prompt=login"
echo " 🌐 URL d'autorisation générée"
# Étape 2: Simuler l'authentification (normalement fait via WebView)
log_info " 🔄 Simulation de l'authentification WebView..."
# Obtenir la page de login
local login_page=$(curl -s -c cookies.txt -b cookies.txt \
"$auth_url" \
-H "User-Agent: Mozilla/5.0 (Mobile)")
if echo "$login_page" | grep -q "kc-form-login"; then
log_success " ✓ Page de login Keycloak accessible"
# Extraire l'URL d'action du formulaire
local action_url=$(echo "$login_page" | grep -o 'action="[^"]*' | cut -d'"' -f2 | sed 's/&/\&/g')
if [ -n "$action_url" ]; then
# Soumettre les credentials
local auth_response=$(curl -s -c cookies.txt -b cookies.txt \
-X POST \
-L \
--max-redirs 5 \
"${KEYCLOAK_URL}${action_url}" \
-H "Content-Type: application/x-www-form-urlencoded" \
-H "User-Agent: Mozilla/5.0 (Mobile)" \
-d "username=${username}" \
-d "password=${password}")
# Chercher le code d'autorisation dans la réponse ou les redirections
local auth_code=""
# Vérifier si on a été redirigé vers l'URL de callback
if echo "$auth_response" | grep -q "$REDIRECT_URI"; then
auth_code=$(echo "$auth_response" | grep -o 'code=[^&]*' | cut -d'=' -f2 | head -1)
fi
if [ -n "$auth_code" ]; then
log_success " ✓ Code d'autorisation obtenu: ${auth_code:0:20}..."
# Étape 3: Échanger le code contre les tokens
log_info " 🔄 Échange du code contre les tokens..."
local token_response=$(curl -s -X POST \
"${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=${CLIENT_ID}" \
-d "code=${auth_code}" \
-d "redirect_uri=${REDIRECT_URI}" \
-d "code_verifier=${code_verifier}")
if echo "$token_response" | grep -q "access_token"; then
local access_token=$(echo "$token_response" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
local id_token=$(echo "$token_response" | grep -o '"id_token":"[^"]*' | cut -d'"' -f4)
log_success " ✓ Tokens obtenus avec succès"
echo " • Access Token: ${access_token:0:30}..."
echo " • ID Token: ${id_token:0:30}..."
# Étape 4: Vérifier les informations utilisateur
local user_info=$(curl -s -X GET \
"${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/userinfo" \
-H "Authorization: Bearer ${access_token}")
if echo "$user_info" | grep -q "email"; then
local email=$(echo "$user_info" | grep -o '"email":"[^"]*' | cut -d'"' -f4)
local name=$(echo "$user_info" | grep -o '"name":"[^"]*' | cut -d'"' -f4)
log_success " ✓ Informations utilisateur récupérées"
echo " • Nom: $name"
echo " • Email: $email"
# Décoder l'ID token pour voir les rôles (simulation)
log_info " 🔍 Vérification des rôles dans le token..."
# Test de décodage basique du JWT (partie payload)
local payload=$(echo "$id_token" | cut -d'.' -f2)
# Ajouter le padding si nécessaire
local padding=$((4 - ${#payload} % 4))
if [ $padding -ne 4 ]; then
payload="${payload}$(printf '=%.0s' $(seq 1 $padding))"
fi
local decoded=$(echo "$payload" | base64 -d 2>/dev/null || echo "{}")
if echo "$decoded" | grep -q "realm_access"; then
log_success " ✓ Rôles présents dans le token ID"
fi
log_success "🎉 Test OAuth2 complet réussi pour $username"
echo ""
return 0
else
log_error " ✗ Impossible de récupérer les informations utilisateur"
fi
else
log_error " ✗ Échec de l'échange code/tokens"
echo "Réponse: $token_response"
fi
else
log_error " ✗ Code d'autorisation non trouvé"
echo "Réponse: $auth_response"
fi
else
log_error " ✗ URL d'action du formulaire non trouvée"
fi
else
log_error " ✗ Page de login Keycloak inaccessible"
fi
# Nettoyer les cookies
rm -f cookies.txt
log_error "❌ Test OAuth2 échoué pour $username"
echo ""
return 1
}
# Test simplifié avec grant password (pour validation rapide)
test_password_grant() {
local username="$1"
local password="$2"
local role="$3"
log_info "🔑 Test Password Grant pour $username ($role)"
local response=$(curl -s -X POST \
"${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=${username}" \
-d "password=${password}" \
-d "grant_type=password" \
-d "client_id=${CLIENT_ID}")
if echo "$response" | grep -q "access_token"; then
local access_token=$(echo "$response" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
# Obtenir les infos utilisateur
local user_info=$(curl -s -X GET \
"${KEYCLOAK_URL}/realms/${REALM}/protocol/openid-connect/userinfo" \
-H "Authorization: Bearer ${access_token}")
if echo "$user_info" | grep -q "email"; then
local email=$(echo "$user_info" | grep -o '"email":"[^"]*' | cut -d'"' -f4)
log_success "$username ($email) - Authentification réussie"
return 0
fi
fi
log_error "$username - Échec de l'authentification"
return 1
}
# =============================================================================
# EXÉCUTION DES TESTS
# =============================================================================
echo "============================================================================="
echo "📱 TEST D'AUTHENTIFICATION MOBILE UNIONFLOW"
echo "============================================================================="
echo ""
# Comptes de test
declare -A test_accounts=(
["superadmin"]="SuperAdmin123!:SUPER_ADMINISTRATEUR"
["admin.org"]="AdminOrg123!:ADMINISTRATEUR_ORGANISATION"
["tech.lead"]="TechLead123!:RESPONSABLE_TECHNIQUE"
["tresorier"]="Tresorier123!:RESPONSABLE_FINANCIER"
["rh.manager"]="RhManager123!:RESPONSABLE_MEMBRES"
["marie.active"]="Marie123!:MEMBRE_ACTIF"
["jean.simple"]="Jean123!:MEMBRE_SIMPLE"
["visiteur"]="Visiteur123!:VISITEUR"
)
# Si un username spécifique est fourni
if [ $# -eq 1 ]; then
username="$1"
if [[ -n "${test_accounts[$username]}" ]]; then
IFS=':' read -r password role <<< "${test_accounts[$username]}"
echo "🎯 Test spécifique pour $username"
echo ""
test_password_grant "$username" "$password" "$role"
else
log_error "Utilisateur $username non trouvé dans les comptes de test"
echo ""
echo "Comptes disponibles :"
for user in "${!test_accounts[@]}"; do
echo "$user"
done
fi
else
# Tester tous les comptes
echo "🧪 Test de tous les comptes de test..."
echo ""
local success_count=0
local total_count=${#test_accounts[@]}
for username in "${!test_accounts[@]}"; do
IFS=':' read -r password role <<< "${test_accounts[$username]}"
if test_password_grant "$username" "$password" "$role"; then
((success_count++))
fi
echo ""
done
echo "============================================================================="
echo "📊 RÉSULTATS DES TESTS"
echo "============================================================================="
echo ""
echo "✅ Comptes fonctionnels : $success_count/$total_count"
echo ""
if [ $success_count -eq $total_count ]; then
log_success "🎉 Tous les comptes de test fonctionnent parfaitement !"
echo ""
echo "🚀 L'application mobile peut maintenant utiliser ces comptes :"
echo " • Authentification OAuth2/OIDC opérationnelle"
echo " • Tous les rôles configurés correctement"
echo " • Tokens JWT valides avec informations utilisateur"
else
log_warning "⚠️ Certains comptes nécessitent une vérification"
fi
fi
echo ""
echo "============================================================================="
echo "✅ TESTS TERMINÉS"
echo "============================================================================="