Files
unionflow-server-impl-quarkus/fix_client_redirect.py

280 lines
11 KiB
Python

#!/usr/bin/env python3
"""
Script pour corriger la configuration du client unionflow-mobile
Spécifiquement les redirect_uri pour l'application mobile
"""
import requests
import json
class ClientRedirectFixer:
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 get_client_internal_id(self, realm_name: str, client_id: str) -> str:
"""Obtient l'ID interne du client"""
try:
response = self.session.get(
f"{self.base_url}/admin/realms/{realm_name}/clients",
headers={"Authorization": f"Bearer {self.admin_token}"}
)
if response.status_code == 200:
clients = response.json()
for client in clients:
if client.get("clientId") == client_id:
return client.get("id")
except Exception as e:
print(f"Erreur récupération client ID: {e}")
return None
def fix_client_configuration(self, realm_name: str = "unionflow", client_id: str = "unionflow-mobile") -> bool:
"""Corrige la configuration du client pour mobile"""
print(f"🔧 Correction de la configuration du client {client_id}...")
# 1. Obtenir l'ID interne du client
internal_id = self.get_client_internal_id(realm_name, client_id)
if not internal_id:
print(f" ❌ Client {client_id} non trouvé")
return False
print(f" ✓ Client trouvé (ID interne: {internal_id})")
# 2. Configuration correcte pour une application mobile
client_config = {
"id": internal_id,
"clientId": client_id,
"name": "UnionFlow Mobile App",
"description": "Client pour l'application mobile UnionFlow",
"enabled": True,
"clientAuthenticatorType": "client-secret",
"secret": "",
"redirectUris": [
"http://localhost:*",
"http://127.0.0.1:*",
"http://192.168.1.11:*",
"unionflow://oauth/callback",
"unionflow://login",
"com.unionflow.mobile://oauth",
"urn:ietf:wg:oauth:2.0:oob"
],
"webOrigins": [
"http://localhost",
"http://127.0.0.1",
"http://192.168.1.11",
"+"
],
"notBefore": 0,
"bearerOnly": False,
"consentRequired": False,
"standardFlowEnabled": True,
"implicitFlowEnabled": False,
"directAccessGrantsEnabled": True,
"serviceAccountsEnabled": False,
"publicClient": True,
"frontchannelLogout": False,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false",
"access.token.lifespan": "300",
"client_credentials.use_refresh_token": "false",
"oauth2.device.authorization.grant.enabled": "false",
"oidc.ciba.grant.enabled": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": True,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": ["web-origins", "role_list", "profile", "roles", "email"],
"optionalClientScopes": ["address", "phone", "offline_access", "microprofile-jwt"]
}
try:
# 3. Mettre à jour la configuration
response = self.session.put(
f"{self.base_url}/admin/realms/{realm_name}/clients/{internal_id}",
json=client_config,
headers={
"Authorization": f"Bearer {self.admin_token}",
"Content-Type": "application/json"
}
)
if response.status_code == 204:
print(f" ✅ Configuration du client mise à jour")
# 4. Vérifier la configuration
verify_response = self.session.get(
f"{self.base_url}/admin/realms/{realm_name}/clients/{internal_id}",
headers={"Authorization": f"Bearer {self.admin_token}"}
)
if verify_response.status_code == 200:
config = verify_response.json()
print(f" ✓ Configuration vérifiée:")
print(f" - Public Client: {config.get('publicClient')}")
print(f" - Direct Access Grants: {config.get('directAccessGrantsEnabled')}")
print(f" - Standard Flow: {config.get('standardFlowEnabled')}")
print(f" - Redirect URIs: {len(config.get('redirectUris', []))} configurées")
print(f" - Web Origins: {len(config.get('webOrigins', []))} configurées")
# Afficher les redirect URIs
print(f" ✓ Redirect URIs configurées:")
for uri in config.get('redirectUris', []):
print(f" - {uri}")
return True
else:
print(f" ❌ Erreur mise à jour: {response.status_code}")
print(f" Réponse: {response.text}")
return False
except Exception as e:
print(f" ❌ Exception: {e}")
return False
def test_client_after_fix(self, realm_name: str = "unionflow", client_id: str = "unionflow-mobile") -> bool:
"""Teste le client après correction"""
print(f"🧪 Test du client après correction...")
# Test d'authentification simple (Resource Owner Password Credentials)
test_data = {
"username": "marie.active",
"password": "Marie123!",
"grant_type": "password",
"client_id": client_id
}
try:
response = self.session.post(
f"{self.base_url}/realms/{realm_name}/protocol/openid-connect/token",
data=test_data,
headers={"Content-Type": "application/x-www-form-urlencoded"}
)
print(f" Status: {response.status_code}")
if response.status_code == 200:
token_data = response.json()
if "access_token" in token_data:
print(f" ✅ AUTHENTIFICATION RÉUSSIE !")
print(f" ✓ Token reçu")
return True
else:
print(f" ❌ Token manquant")
else:
print(f" ❌ Authentification échouée")
print(f" Réponse: {response.text}")
except Exception as e:
print(f" ❌ Exception: {e}")
return False
def fix_complete(self):
"""Correction complète du client"""
print("=" * 80)
print("🔧 CORRECTION DU CLIENT UNIONFLOW-MOBILE")
print("=" * 80)
print()
if not self.get_admin_token():
print("❌ Impossible d'obtenir le token admin")
return False
print("✅ Token admin obtenu")
print()
# Corriger la configuration
if not self.fix_client_configuration():
print("❌ Échec de la correction du client")
return False
print()
# Tester le client
if self.test_client_after_fix():
print()
print("=" * 80)
print("🎉 CLIENT CORRIGÉ AVEC SUCCÈS !")
print("=" * 80)
print()
print("🚀 Le client unionflow-mobile est maintenant correctement configuré")
print(" pour votre application mobile avec les redirect URIs appropriées.")
print()
print("📱 REDIRECT URIs CONFIGURÉES :")
print(" • http://localhost:* (pour tests locaux)")
print(" • http://127.0.0.1:* (pour tests locaux)")
print(" • http://192.168.1.11:* (pour votre réseau)")
print(" • unionflow://oauth/callback (pour l'app mobile)")
print(" • unionflow://login (pour l'app mobile)")
print(" • com.unionflow.mobile://oauth (pour l'app mobile)")
print(" • urn:ietf:wg:oauth:2.0:oob (pour OAuth out-of-band)")
print()
print("✅ Votre application mobile peut maintenant s'authentifier !")
return True
else:
print()
print("=" * 80)
print("⚠️ CLIENT CORRIGÉ MAIS PROBLÈME D'AUTHENTIFICATION")
print("=" * 80)
print()
print("Le client a été reconfiguré mais l'authentification échoue encore.")
print("Cela peut être dû aux utilisateurs. Essayez la configuration manuelle :")
print()
print("1. Ouvrez http://localhost:8180/admin/")
print("2. Connectez-vous avec admin/admin")
print("3. Realm 'unionflow' > Users > marie.active")
print("4. Credentials > Set password > Marie123! (non temporaire)")
return False
def main():
fixer = ClientRedirectFixer()
fixer.fix_complete()
if __name__ == "__main__":
main()