% ============================================================================= % CHAPITRE : MÉTHODE 2 — CONNEXION DIRECTE % ============================================================================= \chapter{Méthode 2 : Connexion directe (identifiant / mot de passe + ENT)} \label{ch:method2} \section{Principe général} Connexion via le protocole propriétaire de Pronote (JSON sur HTTPS), avec \textbf{chiffrement AES-CBC utilisant une clé dérivée par MD5 (16 octets, soit AES-128)} comme implémenté dans pronotepy 2.15.7 et mécanisme de défi-réponse. Utilisé par l'interface web. \begin{infobox} \textbf{Statut} : {\emojiinfo\ Observé dans le code local} (délégable à pronotepy via \texttt{ParentClient} ou \texttt{Client}). \end{infobox} \section{Flux d'authentification} \begin{enumerate} \item \textbf{Initialisation} : Requête GET vers \texttt{/pronote/\{espace\}.html} (ex. \texttt{parent.html}). \begin{itemize} \item Récupère \texttt{h} (ID de session), \texttt{a} (ID espace), \texttt{sCrA}/\texttt{sCoA} (drapeaux chiffrement/compression). \end{itemize} \item \textbf{Échange de clés} : Requête POST vers \texttt{/pronote/appelfonction/\{a\}/\{h\}/\{numeroOrdre\}}. \item \textbf{Identification} : Soumission de \texttt{identifiant}, \texttt{genreConnexion=0}, \texttt{genreEspace=\{a\}}. \item \textbf{Résolution du défi} : \begin{itemize} \item Calcul de \texttt{mtp = MAJUSCULE(HEX(SHA256(alea + mot\_de\_passe)))}. \item Dérivation de \texttt{key\_challenge = MD5(nom\_utilisateur + mtp)}. \item Déchiffrement du \texttt{challenge} avec \textbf{AES-CBC utilisant une clé dérivée par MD5 (16 octets, soit AES-128)}. \end{itemize} \item \textbf{Authentification} : Soumission de la réponse au défi. \end{enumerate} \begin{infobox} \textbf{Source} : {\emojiinfo\ Observé dans le code local de \texttt{pronotepy} 2.15.7} (module \texttt{clients.py} et \texttt{pronoteAPI.py}, vérifié le 2026-09-12). \end{infobox} \section{Intégration dans \texttt{pronote-sync}} \begin{itemize} \item \textbf{Paramètres} : \begin{itemize} \item \texttt{PRONOTE\_URL} (ex. \texttt{.env.example} ligne 3). \item \texttt{PRONOTE\_USERNAME}, \texttt{PRONOTE\_PASSWORD}. \item \texttt{PRONOTE\_ENT} (slug dans \texttt{\_ENT\_NAMES}). \item \texttt{PRONOTE\_ACCOUNT\_TYPE} (ex. \texttt{parent}). \end{itemize} \item \textbf{Comportement} : \begin{itemize} \item Utilise \texttt{pronotepy.ParentClient} pour les comptes parents. \item \textbf{Repli} : Si iCal échoue en mode \texttt{auto}, \texttt{pronotepy} est utilisé. \item \textbf{Pas de repli} si \texttt{PRONOTE\_AGENDA\_SOURCE=pronotepy} (échec explicite). \end{itemize} \end{itemize} \begin{infobox} \textbf{Source} : {\emojiinfo\ \texttt{pronote\_sync/sources/pronote/client.py}} (méthode \texttt{\_connect\_password}). \end{infobox} \section{ENT supportés} Liste \textbf{fermée} des \textbf{30 ENT} résolubles (lignes 52–83 de \texttt{pronote\_sync/sources/pronote/client.py}) : \begin{lstlisting}[language=Python, caption=Liste des ENT supportés, label=lst:ent-list] _monbureaunumerique, ent_elyco, bordeaux, ent_creuse, occitanie_montpellier, ... \end{lstlisting} \begin{warningbox} \textbf{Hypothèse à valider} : Les ENT non listés nécessitent une contribution à \texttt{pronotepy}. \end{warningbox} \begin{infobox} \textbf{Source} : {\emojiinfo\ Code source local de \texttt{pronote-sync}} (2026-09-12). \end{infobox} % ============================================================================= % FIN DU CHAPITRE % =============================================================================