- app/services/oauth_connectors.py : flow OAuth2 complet PKCE (S256) pour
2 fournisseurs décrits par 1 dict — Google (Drive/Gmail/Calendar en lecture
seule) et Microsoft 365 (Graph Files.Read / Mail.Read / Calendars.Read) ;
begin() = URL d'autorisation + state + code_verifier, complete() = échange du
code, access_token() = refresh automatique (60 s de marge, refresh_token
conservé si absent de la réponse), api_get() = path absolu refusé + validation
SSRF + borne 20 000 car.
- Tokens chiffrés Fernet en réutilisant calendar_sync._encrypt_tokens (zéro
dépendance) dans la table connector_tokens (migration 33, PK (kind, user_id)).
- 4 routes /api/agent/connectors/oauth/{kind}/… : status, authorize (cookies
d'état HttpOnly 10 min, retour same-origin validé), callback (GET safe, state
comparé en temps constant, tokens stockés puis cookies purgés, redirection
?oauth=connected / ?oauth_error=), disconnect. OpenAPI 523 chemins.
- Config + .env.example : GOOGLE_CLIENT_ID/SECRET, MS_CLIENT_ID/SECRET (vidés =
« non configuré »), redirect URI dérivé d'APP_BASE_URL.
- Catalogue : google/ms365 en natifs avec badge connecté/non connecté ;
connector_fetch et Tester passent par l'API du fournisseur avec le token de
l'utilisateur (user_id transmis par l'outil LLM).
- Menu + : « Se connecter » / « Déconnecter » sur la fiche, toast au retour du
flux (URL nettoyée par history.replaceState). État dans la fiche du menu
plutôt qu'une page dédiée.
- Tests : tests/test_v756_oauth_connectors.py (13), 0 appel réseau réel
(_post_form / _api_get monkeypatchés) — state forgé refusé sans échange,
tokens chiffrés en base, refresh, URL absolue refusée, 401/404, câblage menu ;
test_v755 adapté (5 natifs). Suite complète 1319 verts (-n auto), ruff 0,
eslint 0 erreur (19 warnings préexistants hors fichiers touchés).
111 lines
4.2 KiB
Bash
111 lines
4.2 KiB
Bash
# ── Gitea ──
|
|
GITEA_URL=https://git.dracodev.net
|
|
GITEA_TOKEN=change-me
|
|
# Laissez VIDES pour activer le login local seul : depuis v7.46.0 les valeurs de
|
|
# substitution (`test-id`, `test-secret`, `change-me`) comptent comme « provider
|
|
# non configuré » — avant, /auth/login redirigeait vers Gitea avec un client_id
|
|
# invalide (authentification OAuth impossible).
|
|
GITEA_OAUTH_CLIENT_ID=
|
|
GITEA_OAUTH_CLIENT_SECRET=
|
|
GITEA_WEBHOOK_SECRET=
|
|
|
|
# ── GitHub ──
|
|
GITHUB_OAUTH_CLIENT_ID=
|
|
GITHUB_OAUTH_CLIENT_SECRET=
|
|
|
|
# ── OAuth2 ──
|
|
# Laisser VIDE = redirect URI dynamique (dérivée du Host/X-Forwarded-* de la requête).
|
|
# Ne définir QUE si on veut forcer une URI exacte — elle DOIT être enregistrée
|
|
# dans l'application OAuth2 côté Gitea/GitHub (Settings → Applications).
|
|
# Exemple : OAUTH_REDIRECT_URI=https://flowdeck.dracodev.net/auth/callback
|
|
OAUTH_REDIRECT_URI=
|
|
|
|
# ── Connecteurs OAuth (v7.56.0) — Google / Microsoft 365 ──
|
|
# Vidés = connecteur « non configuré » (le menu + affiche la raison).
|
|
# Le redirect URI à enregistrer est dérivé d'APP_BASE_URL :
|
|
# {APP_BASE_URL}/api/agent/connectors/oauth/google/callback
|
|
# {APP_BASE_URL}/api/agent/connectors/oauth/ms365/callback
|
|
GOOGLE_CLIENT_ID=
|
|
GOOGLE_CLIENT_SECRET=
|
|
MS_CLIENT_ID=
|
|
MS_CLIENT_SECRET=
|
|
|
|
# ── App ──
|
|
APP_SECRET_KEY=change-me-to-random
|
|
APP_HOST=0.0.0.0
|
|
APP_PORT=8080
|
|
LOG_LEVEL=INFO
|
|
DEFAULT_LANG=fr
|
|
|
|
# ── Database ──
|
|
# SQLite UNIQUEMENT (le code ne lit que le préfixe sqlite:///, tout autre
|
|
# schéma retombe silencieusement sur /data/flowdeck.db).
|
|
DATABASE_URL=sqlite:////data/flowdeck.db
|
|
|
|
# ── Sync ──
|
|
SYNC_INTERVAL=60
|
|
GITEA_CACHE_TTL=30
|
|
|
|
# ── Backups (v5.2.0) ──
|
|
# Sauvegarde automatique quotidienne du fichier SQLite (fichiers datés).
|
|
BACKUP_ENABLED=true
|
|
BACKUP_DIR=/data/backups
|
|
BACKUP_INTERVAL_HOURS=24
|
|
BACKUP_KEEP=30
|
|
|
|
# ── Forge projects sync (v5.2.0) ──
|
|
# Rafraîchissement périodique de la table `projects` depuis les forges connectées.
|
|
PROJECT_SYNC_ENABLED=true
|
|
PROJECT_SYNC_INTERVAL_HOURS=1
|
|
|
|
# ── Public API v2 (v6.3.0) ──
|
|
# PUBLIC_API_INSECURE_OK=true autorise le token de dev fd-public-key (jamais en prod).
|
|
PUBLIC_API_INSECURE_OK=false
|
|
API_V2_RATE_LIMIT_PER_TOKEN=300
|
|
|
|
# ── Email notifications (v4.9.0) ──
|
|
# Laisser SMTP_HOST vide = pas d'envoi d'email (seulement les notifications in-app).
|
|
SMTP_HOST=
|
|
SMTP_PORT=587
|
|
SMTP_USER=
|
|
SMTP_PASSWORD=
|
|
SMTP_FROM=FlowDeck <[email protected]>
|
|
SMTP_USE_TLS=true
|
|
APP_BASE_URL=http://localhost:8080
|
|
|
|
# ── SSO / Enterprise (v6.7.0) ──
|
|
# Fallback de démarrage uniquement : dès qu'un admin enregistre une configuration
|
|
# dans Settings → Admin → SSO / Enterprise, la table `sso_config` prime sur le .env.
|
|
# Le bouton SSO n'apparaît sur la page de connexion que si une config est active.
|
|
# SSO_PROVIDER=saml # saml | oidc (vide = SSO désactivé)
|
|
# SSO_NAME=Company SSO # libellé du bouton
|
|
# SSO_ONLY=false # true = refuser le login local (les admins gardent le leur)
|
|
# SSO_AUTO_PROVISION=true # créer le compte au premier login SSO
|
|
# SAML :
|
|
# SSO_ENTITY_ID=https://idp.example.com/saml/metadata
|
|
# SSO_SSO_URL=https://idp.example.com/saml/sso
|
|
# SSO_SLO_URL=https://idp.example.com/saml/slo
|
|
# SSO_X509_CERTIFICATE=-----BEGIN CERTIFICATE-----
|
|
# SSO_SIGN_REQUESTS=false # signer les AuthnRequests / LogoutRequest
|
|
# OIDC :
|
|
# SSO_ISSUER_URL=https://auth.example.com/realms/flowdeck
|
|
# SSO_CLIENT_ID=
|
|
# SSO_CLIENT_SECRET=
|
|
# SSO_SCOPE=openid profile email
|
|
# Mapping (JSON) :
|
|
# SSO_ATTRIBUTE_MAPPING={"email":"email","full_name":"name","groups":"groups"}
|
|
# SSO_GROUPS_MAPPING=[{"sso_group":"FlowDeck Admins","workspace_role":"admin","workspace_id":1}]
|
|
# SSO_DEFAULT_WORKSPACE_ID=0
|
|
|
|
# ── Web tools de l'agent (v7.46.0) ──
|
|
# Skills « recherche-marche », « veille-techno », « debug-web ».
|
|
# web_search → EXA (recherche sémantique + extraits, ~10 $/mois offerts)
|
|
# fetch_url → aucune config : lecture d'une page, garde-fou SSRF actif
|
|
# search_code → GitHub public (10 req/min sans jeton, 30 avec)
|
|
# Sans EXA_API_KEY, web_search bascule sur DuckDuckGo (repli dégradé, sans
|
|
# compte mais parsé au HTML) : utilisable, moins fiable.
|
|
WEB_SEARCH_PROVIDER=exa
|
|
EXA_API_KEY=
|
|
GITHUB_TOKEN=
|
|
WEB_FETCH_MAX_CHARS=20000
|