309 lines
12 KiB
Bash
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.11: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 "============================================================================="
|