docs(pronote-auth): reconstruire le source LaTeX et régénérer le PDF
Les fichiers de chapitres référencés par docs/pronote-auth.tex (preamble, frontmatter, ch-*, annex-*) n'avaient jamais été committés, rendant le PDF non reproductible. Reconstitution fidèle depuis docs/pronote-auth.md, correction des instructions de compilation (TEXINPUTS + -output-directory), ajout de l'Annexe C, du Glossaire et de l'Historique des révisions, PDF régénéré (27 pages).
This commit is contained in:
@@ -0,0 +1,212 @@
|
||||
% =============================================================================
|
||||
% CHAPITRE : MÉTHODE 3 — QR CODE + TOKEN MOBILE
|
||||
% =============================================================================
|
||||
|
||||
\chapter{Méthode 3 : QR Code + token mobile (pour \texttt{pronote-sync})}
|
||||
\label{ch:method3}
|
||||
|
||||
\section{Principe général}
|
||||
|
||||
Mécanisme d'appairage par QR code pour les appareils mobiles, \textbf{contournant
|
||||
l'authentification ENT/EduConnect}. Le QR code est généré \textbf{depuis l'interface web
|
||||
Pronote, espace parent \rightarrow paramètres \rightarrow QR code}, puis utilisé avec un
|
||||
\textbf{PIN à 4 chiffres} pour obtenir un token dont la durée dépend de l'instance/serveur.
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Statut} : {\emojicheck\ Pris en charge} par \texttt{pronote-sync} (mode
|
||||
\texttt{PRONOTE\_AUTH\_MODE=qr\_token}).
|
||||
\end{infobox}
|
||||
|
||||
\section{Procédure QR pour \texttt{pronote-sync}}
|
||||
\label{sec:procedure-qr}
|
||||
|
||||
\subsection{Étape 1 : Génération du QR code (interface web)}
|
||||
|
||||
\begin{enumerate}
|
||||
\item Se connecter à Pronote via un navigateur (espace \textbf{Parent}).
|
||||
\item Aller dans \textbf{Paramètres \rightarrow Accès mobile / Application mobile}.
|
||||
\item Définir un \textbf{PIN temporaire à 4 chiffres}.
|
||||
\item Pronote affiche un \textbf{QR code} contenant un JSON avec les clés :
|
||||
\begin{itemize}
|
||||
\item \texttt{login}, \texttt{jeton}, et \texttt{url} (ex.
|
||||
\texttt{https://[host]/pronote/mobile.parent.html}).
|
||||
\end{itemize}
|
||||
\textbf{Le fichier JSON réel contient des identifiants chiffrés et ne doit jamais être
|
||||
copié, partagé, ou committé.}
|
||||
\item \textbf{Exporter le QR code} :
|
||||
\begin{itemize}
|
||||
\item Sauvegardez le fichier JSON localement ou scannez-le avec un appareil.
|
||||
\item \textbf{Ne jamais partager} le JSON ou le PIN.
|
||||
\item \textbf{Le fichier JSON du QR code contient des identifiants chiffrés : ne jamais
|
||||
le coller dans la documentation ni le committer.}
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\emojiinfo\ Observé localement dans l'interface web Pronote} (version non
|
||||
spécifiée, hypothèse à valider).
|
||||
\end{infobox}
|
||||
|
||||
\subsection{Étape 2 : Configuration de \texttt{pronote-sync}}
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Enregistrer le QR code} :
|
||||
\begin{itemize}
|
||||
\item Sauvegarder le JSON dans un fichier (ex. \texttt{/path/to/qr\_code.json}).
|
||||
\item \textbf{Permissions} : \texttt{chmod 600 /path/to/qr\_code.json}.
|
||||
\end{itemize}
|
||||
\item \textbf{Configurer \texttt{.env}} :
|
||||
\begin{lstlisting}[language=bash, caption=Configuration QR Code dans .env, label=lst:qr-env]
|
||||
PRONOTE_AUTH_MODE=qr_token
|
||||
PRONOTE_QR_CODE_FILE=/path/to/qr_code.json
|
||||
PRONOTE_QR_PIN= # renseigner localement la valeur secrète du PIN (jamais committée)
|
||||
\end{lstlisting}
|
||||
\textbf{Note} : \texttt{.env.example} ne doit \textbf{jamais} contenir de PIN concret.
|
||||
\end{enumerate}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\emojiinfo\ Observé dans \texttt{.env.example}} (lignes 21–25) et
|
||||
\texttt{pronote\_sync/sources/pronote/client.py}.
|
||||
\end{infobox}
|
||||
|
||||
\subsection{Étape 3 : Premier login (enrôlement)}
|
||||
|
||||
\begin{enumerate}
|
||||
\item \texttt{pronote-sync} lit \texttt{PRONOTE\_QR\_CODE\_FILE} et \texttt{PRONOTE\_QR\_PIN}.
|
||||
\item Appel à \texttt{pronotepy.ParentClient.qrcode\_login(qr\_code, pin, uuid)} :
|
||||
\begin{itemize}
|
||||
\item \texttt{qr\_code} : JSON du fichier QR.
|
||||
\item \texttt{pin} : PIN à 4 chiffres.
|
||||
\item \texttt{uuid} : UUID permanent généré par \texttt{pronote-sync} (ex.
|
||||
\texttt{pronote-sync-\{uuid4()\}}).
|
||||
\end{itemize}
|
||||
\item \textbf{Déchiffrement} :
|
||||
\begin{itemize}
|
||||
\item Algorithme :
|
||||
\textbf{AES-CBC utilisant une clé dérivée par MD5 (16 octets, soit AES-128)}.
|
||||
\item Clé : \texttt{MD5(PIN)} (dérivée du PIN secret).
|
||||
\item IV : 16 octets nuls.
|
||||
\item Résultat : \texttt{login} et \texttt{jeton} en clair.
|
||||
\end{itemize}
|
||||
\item \textbf{Échange de token} : Pronote retourne un \texttt{jetonConnexionAppliMobile} (token
|
||||
dont la durée dépend de l'instance/serveur).
|
||||
\item \textbf{Persistance} : \texttt{pronote-sync} sauvegarde les credentials via
|
||||
\texttt{export\_credentials()} dans \texttt{.pronote\_auth\_state.json} (mode \texttt{0600}).
|
||||
\end{enumerate}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\emojiinfo\ Observé dans le code local de \texttt{pronotepy} 2.15.7}
|
||||
(\texttt{clients.py} lignes 181–189) + \texttt{pronote\_sync/sources/pronote/client.py} (méthode
|
||||
\texttt{\_enroll\_qr\_code}).
|
||||
\end{infobox}
|
||||
|
||||
\subsection{Étape 4 : Connexions ultérieures (auto-login)}
|
||||
|
||||
\begin{enumerate}
|
||||
\item \texttt{pronote-sync} charge \texttt{.pronote\_auth\_state.json}.
|
||||
\item Appel à \texttt{pronotepy.ParentClient.token\_login(**credentials)} :
|
||||
\begin{itemize}
|
||||
\item \texttt{pronote\_url}, \texttt{username}, \texttt{password} (token), \texttt{uuid}.
|
||||
\end{itemize}
|
||||
\item \textbf{Rotation du token} : Le token est \textbf{remplacé uniquement si le serveur
|
||||
renvoie \texttt{jetonConnexionAppliMobile}} (observé dans \texttt{pronotepy} 2.15.7,
|
||||
\texttt{clients.py:382–387}).
|
||||
\item \textbf{Persistance} : Les credentials sont sauvegardés dans
|
||||
\texttt{.pronote\_auth\_state.json} après chaque opération réussie.
|
||||
\end{enumerate}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\emojiinfo\ Observé dans le code local de \texttt{pronotepy} 2.15.7}
|
||||
(\texttt{clients.py} lignes 245–280) + \texttt{pronote\_sync/sources/pronote/client.py} (méthode
|
||||
\texttt{\_connect\_qr\_token}).
|
||||
\end{infobox}
|
||||
|
||||
\section{Cycle de vie des tokens}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{QR code} : Valide \textbf{~10 minutes} après génération
|
||||
({\warningicon\ \textbf{Hypothèse à valider}} : cette durée n'est attestée que par un
|
||||
message d'exception dans \texttt{pronotepy} et n'est pas une garantie officielle/indépendante
|
||||
de l'instance).
|
||||
\item \textbf{\texttt{jetonConnexionAppliMobile}} :
|
||||
\begin{itemize}
|
||||
\item Durée \textbf{dépendante de l'instance/serveur} (observation du 2026-09-12,
|
||||
hypothèse : peut persister jusqu'à la fin de l'année scolaire, non garanti).
|
||||
\item \textbf{Remplacé uniquement si le serveur renvoie
|
||||
\texttt{jetonConnexionAppliMobile}} (observé dans \texttt{pronotepy} 2.15.7,
|
||||
\texttt{clients.py:382–387}).
|
||||
\item \textbf{Révocable} manuellement dans Pronote (Paramètres \rightarrow Accès mobile).
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\warningicon\ Comportement variable selon les instances} (à tester localement).
|
||||
\end{infobox}
|
||||
|
||||
\section{Sécurité}
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Fichiers sensibles} :
|
||||
\begin{itemize}
|
||||
\item \texttt{.pronote\_auth\_state.json} : \textbf{Ne jamais versionner} (couvert par
|
||||
\texttt{.gitignore}).
|
||||
\item \texttt{PRONOTE\_QR\_CODE\_FILE} : \textbf{Ne jamais committer} (ex. dans Git).
|
||||
\end{itemize}
|
||||
\item \textbf{Secrets} :
|
||||
\begin{itemize}
|
||||
\item Le PIN et le contenu du QR code sont \textbf{masqués} dans les logs (via
|
||||
\texttt{redact\_secrets()}).
|
||||
\item Les exceptions sont \textbf{expurgées} (via \texttt{redact\_exception()}).
|
||||
\end{itemize}
|
||||
\item \textbf{Recommandations} :
|
||||
\begin{itemize}
|
||||
\item Utiliser un \textbf{PIN robuste} (éviter les codes simples comme \guillemotleft 0000 \guillemotright ou
|
||||
des séquences évidentes).
|
||||
\item \textbf{Révoquer} le token en cas de compromission (via Pronote web).
|
||||
\end{itemize}
|
||||
\end{enumerate}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\emojiinfo\ \texttt{pronote\_sync/utils/redaction.py} +
|
||||
\texttt{pronote\_sync/sources/pronote/client.py}} (méthode \texttt{\_collect\_auth\_secrets}).
|
||||
\end{infobox}
|
||||
|
||||
\section{Erreurs et repli}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{\texttt{PronoteAuthRotationError}} : Levée si :
|
||||
\begin{itemize}
|
||||
\item Le token persisté est \textbf{invalide/expiré}.
|
||||
\item Le fichier QR ou le PIN est \textbf{manquant/invalide}.
|
||||
\end{itemize}
|
||||
\item \textbf{Action requise} :
|
||||
\begin{enumerate}
|
||||
\item Supprimer \texttt{.pronote\_auth\_state.json}.
|
||||
\item Générer un \textbf{nouveau QR code depuis l'interface web Pronote, espace parent}.
|
||||
\item Relancer \texttt{pronote-sync}.
|
||||
\end{enumerate}
|
||||
\end{itemize}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\emojiinfo\ Observé dans \texttt{pronote\_sync/errors.py} +
|
||||
\texttt{pronote\_sync/sources/pronote/client.py}} (lignes 346–364).
|
||||
\end{infobox}
|
||||
|
||||
\section{Incompatibilités}
|
||||
|
||||
\begin{itemize}
|
||||
\item \textbf{Mode \texttt{dry-run}} : \textbf{Incompatible} avec
|
||||
\texttt{PRONOTE\_AUTH\_MODE=qr\_token} (risque de désynchronisation du token local).
|
||||
\begin{itemize}
|
||||
\item \texttt{pronote-sync --dry-run} \textbf{refuse} le mode \texttt{qr\_token} avant toute
|
||||
connexion.
|
||||
\end{itemize}
|
||||
\end{itemize}
|
||||
|
||||
\begin{infobox}
|
||||
\textbf{Source} : {\emojiinfo\ \texttt{docs/exploitation.md}} (ligne 65–66).
|
||||
\end{infobox}
|
||||
|
||||
% =============================================================================
|
||||
% FIN DU CHAPITRE
|
||||
% =============================================================================
|
||||
Reference in New Issue
Block a user