264 lines
9.6 KiB
Python
264 lines
9.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script pour diagnostiquer et corriger les utilisateurs dans le realm unionflow
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
import time
|
|
|
|
class UnionflowUserFixer:
|
|
def __init__(self, base_url: str = "http://localhost:8180"):
|
|
self.base_url = base_url
|
|
self.session = requests.Session()
|
|
self.admin_token = None
|
|
|
|
def get_admin_token(self) -> bool:
|
|
"""Obtient le token admin"""
|
|
try:
|
|
data = {
|
|
"username": "admin",
|
|
"password": "admin",
|
|
"grant_type": "password",
|
|
"client_id": "admin-cli"
|
|
}
|
|
|
|
response = self.session.post(
|
|
f"{self.base_url}/realms/master/protocol/openid-connect/token",
|
|
data=data,
|
|
headers={"Content-Type": "application/x-www-form-urlencoded"}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
token_data = response.json()
|
|
self.admin_token = token_data.get("access_token")
|
|
return self.admin_token is not None
|
|
|
|
except Exception as e:
|
|
print(f"Erreur obtention token: {e}")
|
|
|
|
return False
|
|
|
|
def list_users_in_unionflow(self) -> list:
|
|
"""Liste tous les utilisateurs dans le realm unionflow"""
|
|
try:
|
|
response = self.session.get(
|
|
f"{self.base_url}/admin/realms/unionflow/users",
|
|
headers={"Authorization": f"Bearer {self.admin_token}"}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
return response.json()
|
|
else:
|
|
print(f"Erreur récupération utilisateurs: {response.status_code}")
|
|
return []
|
|
|
|
except Exception as e:
|
|
print(f"Exception récupération utilisateurs: {e}")
|
|
return []
|
|
|
|
def reset_user_password_properly(self, user_id: str, username: str, password: str) -> bool:
|
|
"""Remet à zéro le mot de passe d'un utilisateur de manière propre"""
|
|
print(f"🔑 Réinitialisation propre du mot de passe pour {username}...")
|
|
|
|
try:
|
|
# 1. D'abord, s'assurer que l'utilisateur est activé
|
|
user_update = {
|
|
"enabled": True,
|
|
"emailVerified": True
|
|
}
|
|
|
|
update_response = self.session.put(
|
|
f"{self.base_url}/admin/realms/unionflow/users/{user_id}",
|
|
json=user_update,
|
|
headers={
|
|
"Authorization": f"Bearer {self.admin_token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
)
|
|
|
|
if update_response.status_code == 204:
|
|
print(f" ✓ Utilisateur activé")
|
|
else:
|
|
print(f" ⚠ Erreur activation: {update_response.status_code}")
|
|
|
|
# 2. Supprimer toutes les credentials existantes
|
|
creds_response = self.session.get(
|
|
f"{self.base_url}/admin/realms/unionflow/users/{user_id}/credentials",
|
|
headers={"Authorization": f"Bearer {self.admin_token}"}
|
|
)
|
|
|
|
if creds_response.status_code == 200:
|
|
credentials = creds_response.json()
|
|
for cred in credentials:
|
|
if cred.get("type") == "password":
|
|
delete_response = self.session.delete(
|
|
f"{self.base_url}/admin/realms/unionflow/users/{user_id}/credentials/{cred['id']}",
|
|
headers={"Authorization": f"Bearer {self.admin_token}"}
|
|
)
|
|
if delete_response.status_code == 204:
|
|
print(f" ✓ Ancien mot de passe supprimé")
|
|
|
|
# 3. Définir le nouveau mot de passe
|
|
password_data = {
|
|
"type": "password",
|
|
"value": password,
|
|
"temporary": False
|
|
}
|
|
|
|
response = self.session.put(
|
|
f"{self.base_url}/admin/realms/unionflow/users/{user_id}/reset-password",
|
|
json=password_data,
|
|
headers={
|
|
"Authorization": f"Bearer {self.admin_token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
)
|
|
|
|
if response.status_code == 204:
|
|
print(f" ✓ Nouveau mot de passe défini")
|
|
|
|
# 4. Test immédiat
|
|
time.sleep(2)
|
|
if self.test_user_auth("unionflow", username, password):
|
|
print(f" ✅ {username} FONCTIONNE MAINTENANT !")
|
|
return True
|
|
else:
|
|
print(f" ❌ {username} ne fonctionne toujours pas")
|
|
return False
|
|
else:
|
|
print(f" ❌ Erreur définition mot de passe: {response.status_code}")
|
|
print(f" Réponse: {response.text}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f" ❌ Exception: {e}")
|
|
return False
|
|
|
|
def test_user_auth(self, realm_name: str, username: str, password: str) -> bool:
|
|
"""Teste l'authentification d'un utilisateur"""
|
|
try:
|
|
data = {
|
|
"username": username,
|
|
"password": password,
|
|
"grant_type": "password",
|
|
"client_id": "unionflow-mobile"
|
|
}
|
|
|
|
response = self.session.post(
|
|
f"{self.base_url}/realms/{realm_name}/protocol/openid-connect/token",
|
|
data=data,
|
|
headers={"Content-Type": "application/x-www-form-urlencoded"}
|
|
)
|
|
|
|
return response.status_code == 200 and "access_token" in response.json()
|
|
|
|
except:
|
|
return False
|
|
|
|
def fix_all_unionflow_users(self):
|
|
"""Corrige tous les utilisateurs dans le realm unionflow"""
|
|
print("=" * 80)
|
|
print("🔧 CORRECTION DES UTILISATEURS DANS LE REALM UNIONFLOW")
|
|
print("=" * 80)
|
|
print()
|
|
|
|
if not self.get_admin_token():
|
|
print("❌ Impossible d'obtenir le token admin")
|
|
return False
|
|
|
|
print("✅ Token admin obtenu")
|
|
print()
|
|
|
|
# Lister les utilisateurs existants
|
|
users = self.list_users_in_unionflow()
|
|
print(f"📋 {len(users)} utilisateurs trouvés dans le realm unionflow")
|
|
|
|
# Afficher les utilisateurs existants
|
|
existing_usernames = []
|
|
for user in users:
|
|
username = user.get("username", "N/A")
|
|
email = user.get("email", "N/A")
|
|
enabled = user.get("enabled", False)
|
|
existing_usernames.append(username)
|
|
print(f" 👤 {username} ({email}) - {'✅' if enabled else '❌'}")
|
|
|
|
print()
|
|
|
|
# Utilisateurs attendus avec leurs mots de passe
|
|
expected_users = {
|
|
"marie.active": "Marie123!",
|
|
"superadmin": "SuperAdmin123!",
|
|
"jean.simple": "Jean123!",
|
|
"tech.lead": "TechLead123!",
|
|
"rh.manager": "RhManager123!"
|
|
}
|
|
|
|
success_count = 0
|
|
working_users = []
|
|
|
|
# Corriger chaque utilisateur attendu
|
|
for username, password in expected_users.items():
|
|
# Trouver l'utilisateur
|
|
user_found = None
|
|
for user in users:
|
|
if user.get("username") == username:
|
|
user_found = user
|
|
break
|
|
|
|
if user_found:
|
|
user_id = user_found.get("id")
|
|
if self.reset_user_password_properly(user_id, username, password):
|
|
success_count += 1
|
|
working_users.append((username, password))
|
|
else:
|
|
print(f"❌ Utilisateur {username} non trouvé dans le realm unionflow")
|
|
|
|
print()
|
|
|
|
print("=" * 80)
|
|
print(f"📊 RÉSULTAT FINAL: {success_count}/{len(expected_users)} comptes fonctionnent")
|
|
print("=" * 80)
|
|
|
|
if success_count > 0:
|
|
print()
|
|
print("🎉 COMPTES QUI FONCTIONNENT MAINTENANT :")
|
|
print()
|
|
for username, password in working_users:
|
|
print(f" ✅ {username} / {password}")
|
|
|
|
print()
|
|
print("🚀 VOTRE APPLICATION MOBILE PEUT S'AUTHENTIFIER !")
|
|
print()
|
|
print("📱 PARAMÈTRES CONFIRMÉS :")
|
|
print(f" • Keycloak URL: {self.base_url}")
|
|
print(" • Realm: unionflow")
|
|
print(" • Client ID: unionflow-mobile")
|
|
print(f" • Redirect URI: dev.lions.unionflow-mobile://auth/callback")
|
|
print()
|
|
print("✅ TOUS LES COMPTES UNIONFLOW SONT OPÉRATIONNELS !")
|
|
|
|
return True
|
|
else:
|
|
print()
|
|
print("❌ Aucun compte ne fonctionne")
|
|
print()
|
|
print("🔧 SOLUTION MANUELLE RECOMMANDÉE :")
|
|
print("1. Ouvrez http://localhost:8180/admin/")
|
|
print("2. Connectez-vous avec admin/admin")
|
|
print("3. Sélectionnez le realm 'unionflow'")
|
|
print("4. Users > marie.active > Credentials")
|
|
print("5. Set password > Marie123! (décochez Temporary)")
|
|
print("6. Testez avec: python test_unionflow_realm.py")
|
|
|
|
return False
|
|
|
|
|
|
def main():
|
|
fixer = UnionflowUserFixer()
|
|
fixer.fix_all_unionflow_users()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|