Paillasse/portail/public/js/contenus-2.js
Adam Belkacemi 30e14b1c54 ajoute le portail Laravel : connexion prof/élève, session unique, gestion de classe, salle d'attente
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-08 02:01:58 +02:00

90 lines
18 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Cours complets · lot 2 : tubes, réseaux (OSI), SQL
window.CONTENUS_PRO = (window.CONTENUS_PRO || []).concat([
{ id: 'tubes', match: /redirection|tubes|grep|filtres|sed|awk/i,
titre: 'Redirections, tubes et filtres de texte', duree: '4 h (CM 1 h · TD 1 h 30 · TP 1 h 30)', niveau: 'BTS SIO · BTS CIEL · BUT R&T · TSSR',
prerequis: ['Le terminal Linux'],
competences: ['BTS SIO · Bloc 1 · Exploiter des journaux', 'BUT R&T · Compétence « Administrer » · automatiser'],
intro: 'Un administrateur passe beaucoup de temps à lire des journaux de plusieurs milliers de lignes. Plutôt que de les lire à l’œil, on enchaîne de petites commandes spécialisées. C’est la philosophie Unix : chaque outil fait une chose, et bien.',
cm: [
{ t: 'Les trois flux standard', d: '10 min', html: 'Chaque processus dispose de trois flux : <b>stdin (0)</b> l’entrée, <b>stdout (1)</b> la sortie normale, <b>stderr (2)</b> les erreurs. Les séparer permet de garder les résultats propres et d’isoler les erreurs.' },
{ t: 'Rediriger', d: '15 min', html: 'On envoie un flux vers un fichier ou on lit un fichier comme entrée.', table: [['Opérateur', 'Effet'], ['>', 'stdout vers un fichier (écrase)'], ['>>', 'stdout ajouté à la fin'], ['2>', 'stderr vers un fichier'], ['&> ou > f 2>&1', 'les deux flux dans le même fichier'], ['<', 'le fichier devient stdin'], ['> /dev/null', 'jeter la sortie']], exemple: 'find / -name "*.conf" > resultats.txt 2> /dev/null' },
{ t: 'Le tube', d: '10 min', html: 'Le tube <code>|</code> branche la sortie d’une commande sur l’entrée de la suivante, sans fichier intermédiaire. On construit une chaîne de traitement de gauche à droite.', exemple: 'cat /var/log/auth.log | grep "Failed password" | wc -l' },
{ t: 'La boîte à outils', d: '20 min', html: '', table: [['Commande', 'Rôle', 'Exemple'], ['grep', 'garder les lignes qui correspondent', 'grep -i erreur syslog'], ['cut', 'extraire des colonnes', 'cut -d: -f1,7 /etc/passwd'], ['sort', 'trier', 'sort -n, sort -rn'], ['uniq -c', 'compter les lignes identiques consécutives', 'sort | uniq -c'], ['wc -l', 'compter les lignes', ''], ['head / tail', 'début / fin', 'tail -f pour suivre en direct'], ['awk', 'traiter par colonnes', "awk '{print $1}'"], ['sed', 'remplacer', "sed 's/http/https/g'"]], attention: 'uniq ne regroupe que les lignes consécutives : il faut presque toujours trier avant avec sort.' },
{ t: 'Un cas réel : repérer une attaque SSH', d: '15 min', html: 'Objectif : trouver les adresses IP qui ont le plus échoué à se connecter.', exemple: "grep 'Failed password' /var/log/auth.log \\\n | awk '{print $(NF-3)}' \\\n | sort | uniq -c | sort -rn | head -5\n\n 412 203.0.113.42\n 87 198.51.100.7\n 12 192.0.2.19" }],
synthese: ['> écrase, >> ajoute, 2> capture les erreurs', '| enchaîne les traitements', 'sort | uniq -c | sort -rn : le classement le plus utile de l’administrateur', 'tail -f pour suivre un journal en direct'],
qcm: [
['Où va l’erreur de ls /inexistant > sortie.txt ?', ['Dans sortie.txt', 'À l’écran', 'Nulle part', 'Dans /dev/null'], 1, '> ne redirige que stdout ; stderr s’affiche.'],
['Comment jeter à la fois la sortie et les erreurs ?', ['> /dev/null', '2> /dev/null', '&> /dev/null', '| null'], 2, '&> redirige les deux flux.'],
['Que fait cut -d: -f1 /etc/passwd ?', ['Supprime la ligne 1', 'Affiche la 1re colonne séparée par :', 'Compte les lignes', 'Trie'], 1, '-d = séparateur, -f = champ.'],
['Pourquoi trier avant uniq -c ?', ['Pour aller plus vite', 'uniq ne regroupe que les lignes consécutives', 'Ce n’est pas utile', 'Pour supprimer les doublons'], 1, 'Sans tri, les doublons dispersés ne sont pas regroupés.'],
['Quelle commande suit un journal en temps réel ?', ['head -f', 'tail -f', 'cat -f', 'less -r'], 1, 'tail -f affiche les nouvelles lignes au fil de l’eau.'],
['Que fait sed "s/a/b/g" f.txt ?', ['Supprime a', 'Remplace tous les a par b à l’affichage', 'Modifie le fichier sur disque', 'Compte les a'], 1, 'Sans -i, sed ne modifie pas le fichier.']],
td: [
{ n: 'Échauffement', c: 'Enregistrer la liste de /etc dans liste.txt, puis y ajouter celle de /var.', r: 'ls /etc > liste.txt && ls /var >> liste.txt' },
{ n: 'Application', c: 'Afficher les comptes qui utilisent /bin/bash, avec seulement leur nom.', r: 'grep "/bin/bash$" /etc/passwd | cut -d: -f1' },
{ n: 'Application', c: 'Dans acces.log (format Apache), classer les 10 pages les plus demandées.', r: "awk '{print $7}' acces.log | sort | uniq -c | sort -rn | head -10" },
{ n: 'Approfondissement', c: 'Compter les erreurs 404 par heure dans acces.log.', r: "awk '$9 == 404 {print substr($4, 14, 2)}' acces.log | sort | uniq -c" }],
tp: { type: 'IDE Bash', url: 'apercu-ide.html?ex=bash-tp', desc: 'Scripts Bash sur de vrais journaux, vérifiés par des tests.', etapes: ['Compter les connexions échouées', 'Classer les IP suspectes', 'Écrire un rapport dans un fichier', 'Bonus : alerte si plus de 100 échecs'] },
plusLoin: [['Le jeu OverTheWire Bandit (niveaux 10 à 20)', 'https://overthewire.org/wargames/bandit/'], ['Défis « Linux Shell » sur HackerRank', 'https://www.hackerrank.com/domains/shell']] },
{ id: 'osi', match: /OSI|TCP\/IP|modèle en couches|encapsulation|Internet : IP/i,
titre: 'Modèles OSI et TCP/IP, encapsulation', duree: '4 h (CM 1 h 30 · TD 1 h · TP 1 h 30)', niveau: 'SNT · BTS SIO · BTS CIEL · BUT R&T S1',
prerequis: ['Binaire et hexadécimal'],
competences: ['BTS SIO · Bloc 1 · Exploiter les éléments d’un réseau', 'BTS CIEL · C03 · Analyser un réseau', 'BUT R&T · Compétence « Connecter »'],
intro: 'Quand un réseau tombe en panne, l’administrateur raisonne couche par couche : le câble est-il branché ? le switch voit-il la carte ? l’adresse IP est-elle bonne ? le service écoute-t-il ? Le modèle en couches est d’abord une méthode de diagnostic.',
cm: [
{ t: 'Pourquoi un modèle en couches', d: '10 min', html: 'Communiquer suppose de régler beaucoup de problèmes : transmettre des bits, les adresser, les acheminer, les remettre en ordre, les présenter à l’application. Chaque couche règle un problème et offre un service à la couche du dessus, sans connaître le détail des autres.' },
{ t: 'Les 7 couches OSI', d: '20 min', html: '', table: [['N°', 'Couche', 'Rôle', 'Unité', 'Exemples'], ['7', 'Application', 'service rendu à l’utilisateur', 'données', 'HTTP, DNS, SSH, SMTP'], ['6', 'Présentation', 'format, chiffrement', 'données', 'TLS, UTF-8'], ['5', 'Session', 'dialogue', 'données', 'RPC'], ['4', 'Transport', 'bout en bout, ports', 'segment', 'TCP, UDP'], ['3', 'Réseau', 'adressage logique, routage', 'paquet', 'IP, ICMP'], ['2', 'Liaison', 'accès au support, MAC', 'trame', 'Ethernet, Wi-Fi'], ['1', 'Physique', 'signal', 'bit', 'RJ45, fibre, radio']] },
{ t: 'Le modèle TCP/IP', d: '10 min', html: 'Le modèle réellement implémenté compte 4 couches : <b>Accès réseau</b> (OSI 1-2), <b>Internet</b> (3), <b>Transport</b> (4), <b>Application</b> (5-7).' },
{ t: 'L’encapsulation', d: '20 min', html: 'À l’émission, chaque couche ajoute son en-tête aux données reçues de la couche supérieure. À la réception, chaque couche lit et retire le sien.', exemple: '[ HTTP : GET /index.html ]\n[ TCP : port src 51234 → dst 443 ][ HTTP … ]\n[ IP : 192.168.10.65 → 93.184.216.34 ][ TCP … ][ HTTP … ]\n[ Eth : MAC src → MAC passerelle ][ IP … ][ TCP … ][ HTTP … ][ FCS ]' },
{ t: 'Les équipements par couche', d: '10 min', html: '<b>Hub</b> : couche 1, répète le signal. <b>Switch</b> : couche 2, commute selon les adresses MAC. <b>Routeur</b> : couche 3, achemine selon les adresses IP. <b>Pare-feu</b> : couches 3-4, filtre IP et ports (voire 7 pour un pare-feu applicatif).' },
{ t: 'Diagnostiquer couche par couche', d: '15 min', html: 'On part du bas : <code>ip link</code> (lien actif ?), <code>ip addr</code> (adresse ?), <code>ping</code> la passerelle (couche 3), <code>ss -tlnp</code> (le service écoute-t-il ?), <code>curl</code> (l’application répond-elle ?).', attention: 'Un ping qui échoue ne prouve pas que la machine est éteinte : ICMP est souvent filtré par les pare-feux.' }],
synthese: ['OSI 7 couches, TCP/IP 4 couches', 'bit → trame → paquet → segment → données', 'MAC couche 2, IP couche 3, port couche 4', 'On diagnostique toujours de bas en haut'],
qcm: [
['À quelle couche travaille un switch classique ?', ['1', '2', '3', '4'], 1, 'Il commute selon les adresses MAC.'],
['Quelle est l’unité de la couche Transport ?', ['Trame', 'Paquet', 'Segment', 'Bit'], 2, 'TCP et UDP manipulent des segments (datagrammes pour UDP).'],
['Le port 443 est une information de couche :', ['2', '3', '4', '7'], 2, 'Les ports sont gérés par la couche Transport.'],
['Quel protocole n’est PAS de couche application ?', ['DNS', 'SSH', 'ICMP', 'SMTP'], 2, 'ICMP accompagne IP, couche 3.'],
['Dans une trame Ethernet, l’adresse MAC de destination est celle :', ['du serveur web distant', 'de la passerelle ou du voisin direct', 'du DNS', 'du switch'], 1, 'La MAC change à chaque saut, l’IP de destination reste la même.'],
['Combien de couches compte le modèle TCP/IP ?', ['3', '4', '5', '7'], 1, 'Accès réseau, Internet, Transport, Application.'],
['Un poste a une IP mais n’accède pas à Internet. Première vérification ?', ['Réinstaller', 'ping la passerelle', 'Changer le câble', 'Vider le cache DNS'], 1, 'On teste la couche 3 vers la passerelle avant d’aller plus haut.']],
td: [
{ n: 'Échauffement', c: 'Classer par couche OSI : HTTP, IP, switch, TCP, câble RJ45, routeur, TLS, Wi-Fi.', r: '7 · 3 · 2 · 4 · 1 · 3 · 6 · 1-2' },
{ n: 'Application', c: 'Dessiner l’encapsulation d’une requête DNS du poste 192.168.1.20 vers 1.1.1.1.', r: 'DNS (requête) → UDP (port src aléatoire → 53) → IP (192.168.1.20 → 1.1.1.1) → Ethernet (MAC poste → MAC box)' },
{ n: 'Application', c: 'Un utilisateur ne peut pas ouvrir intranet.lycee.fr. Proposer une démarche de diagnostic en 5 commandes, de bas en haut.', r: 'ip link · ip addr · ping passerelle · nslookup intranet.lycee.fr · curl -I https://intranet.lycee.fr' },
{ n: 'Approfondissement', c: 'Expliquer pourquoi l’adresse MAC de destination change à chaque routeur traversé alors que l’adresse IP de destination reste la même.', r: 'La couche 2 ne sert qu’à atteindre le voisin direct ; chaque routeur ré-encapsule dans une nouvelle trame. La couche 3 porte l’adresse finale.' }],
tp: { type: 'Lab VM', url: 'apercu-labs.html', desc: 'Capturer du trafic avec tcpdump et reconnaître chaque en-tête.', etapes: ['Lancer tcpdump sur eth0', 'Faire un curl vers un site', 'Identifier Ethernet, IP, TCP, HTTP', 'Comparer avec une requête DNS en UDP'] },
plusLoin: [['Cisco Networking Academy · cours gratuits', 'https://www.netacad.com/'], ['RFC 1122 (Requirements for Internet Hosts)', 'https://www.rfc-editor.org/rfc/rfc1122']] },
{ id: 'sql', match: /SQL|SELECT|requête|bases de données relationnelles|jointure/i,
titre: 'SQL : interroger une base de données relationnelle', duree: '6 h (CM 2 h · TD 2 h · TP 2 h)', niveau: 'NSI Terminale · BTS SIO SLAM · BUT Informatique · MIAGE',
prerequis: ['Notion de tableau de données'],
competences: ['NSI Tle · Bases de données : langage SQL', 'BTS SIO SLAM · Bloc 2 · Concevoir et exploiter une base de données', 'BUT Info · Compétence « Gérer des données »'],
intro: 'Presque toutes les applications stockent leurs données dans une base relationnelle : un ENT, un site marchand, Syllabus elle-même. SQL est le langage standard pour les interroger. Il se lit presque comme une phrase.',
cm: [
{ t: 'Le modèle relationnel', d: '20 min', html: 'Une base est un ensemble de <b>tables</b> (relations). Chaque ligne est un enregistrement, chaque colonne un attribut typé. La <b>clé primaire</b> identifie une ligne de façon unique ; une <b>clé étrangère</b> référence la clé primaire d’une autre table.', table: [['eleves', 'id (PK)', 'nom', 'prenom', 'classe_id (FK)'], ['', '1', 'Martin', 'Léa', '3'], ['', '2', 'Kaci', 'Inès', '3']] },
{ t: 'Sélectionner : SELECT … FROM', d: '15 min', html: 'On choisit les colonnes, puis la table. <code>*</code> sélectionne toutes les colonnes, <code>DISTINCT</code> supprime les doublons, <code>AS</code> renomme.', exemple: 'SELECT nom, prenom FROM eleves;\nSELECT DISTINCT ville FROM eleves;\nSELECT nom AS "Nom de famille" FROM eleves;' },
{ t: 'Filtrer et trier', d: '20 min', html: '<code>WHERE</code> filtre avec =, <>, <, >, BETWEEN, IN, LIKE (% = n’importe quelle suite), IS NULL, combinés par AND, OR, NOT. <code>ORDER BY</code> trie (ASC, DESC), <code>LIMIT</code> restreint.', exemple: "SELECT nom, moyenne FROM eleves\nWHERE classe_id = 3 AND moyenne >= 10\nORDER BY moyenne DESC\nLIMIT 5;" },
{ t: 'Agréger : COUNT, AVG, GROUP BY', d: '20 min', html: 'Les fonctions d’agrégat calculent sur un ensemble de lignes : COUNT, SUM, AVG, MIN, MAX. <code>GROUP BY</code> forme des groupes, <code>HAVING</code> filtre les groupes (WHERE filtre les lignes avant).', exemple: 'SELECT classe_id, COUNT(*) AS effectif, AVG(moyenne) AS moy\nFROM eleves\nGROUP BY classe_id\nHAVING COUNT(*) > 20;', attention: 'Toute colonne du SELECT qui n’est pas agrégée doit figurer dans le GROUP BY.' },
{ t: 'Joindre des tables', d: '25 min', html: 'La jointure relie deux tables par leurs clés. <b>INNER JOIN</b> garde les lignes qui ont une correspondance des deux côtés ; <b>LEFT JOIN</b> garde toutes les lignes de gauche, avec NULL s’il n’y a pas de correspondance.', exemple: 'SELECT e.nom, c.libelle\nFROM eleves e\nJOIN classes c ON e.classe_id = c.id;\n\n-- Classes sans aucun élève :\nSELECT c.libelle FROM classes c\nLEFT JOIN eleves e ON e.classe_id = c.id\nWHERE e.id IS NULL;' },
{ t: 'Modifier les données', d: '15 min', html: '<code>INSERT INTO</code> ajoute, <code>UPDATE … SET … WHERE</code> modifie, <code>DELETE FROM … WHERE</code> supprime.', attention: 'Un UPDATE ou un DELETE sans WHERE touche toutes les lignes. On teste toujours d’abord le WHERE avec un SELECT.' },
{ t: 'Sécurité : l’injection SQL', d: '10 min', html: 'Construire une requête en collant du texte saisi par l’utilisateur permet de détourner la requête (<code>\' OR 1=1 --</code>). On utilise toujours des <b>requêtes préparées</b> avec paramètres.' }],
synthese: ['SELECT colonnes FROM table WHERE condition ORDER BY tri', 'WHERE filtre les lignes, HAVING filtre les groupes', 'JOIN … ON relie clé étrangère et clé primaire', 'Jamais de DELETE ni d’UPDATE sans WHERE', 'Requêtes préparées contre l’injection'],
qcm: [
['Quelle clause filtre les groupes après un GROUP BY ?', ['WHERE', 'HAVING', 'ORDER BY', 'LIMIT'], 1, 'HAVING s’applique aux groupes.'],
['Que renvoie SELECT COUNT(*) FROM eleves WHERE moyenne IS NULL ?', ['Les élèves sans moyenne', 'Le nombre d’élèves sans moyenne', 'Une erreur', '0 toujours'], 1, 'COUNT compte les lignes retenues.'],
['Quelle jointure garde les classes sans élève ?', ['INNER JOIN', 'LEFT JOIN depuis classes', 'CROSS JOIN', 'Aucune'], 1, 'LEFT JOIN conserve toutes les lignes de la table de gauche.'],
['LIKE "Ma%" correspond à :', ['Ma exactement', 'tout texte commençant par Ma', 'tout texte finissant par Ma', 'tout texte contenant %'], 1, '% remplace n’importe quelle suite de caractères.'],
['Que se passe-t-il avec DELETE FROM eleves; ?', ['Rien', 'Toutes les lignes sont supprimées', 'La table est supprimée', 'Erreur de syntaxe'], 1, 'Sans WHERE, toutes les lignes partent. La table reste.'],
['Quel est le rôle d’une clé étrangère ?', ['Chiffrer', 'Référencer une ligne d’une autre table', 'Accélérer les tris', 'Rendre une colonne unique'], 1, 'Elle garantit l’intégrité référentielle.'],
['Comment se protéger de l’injection SQL ?', ['Masquer les erreurs', 'Requêtes préparées', 'Mettre des guillemets', 'Utiliser HTTPS'], 1, 'Les paramètres ne sont jamais interprétés comme du SQL.'],
['Classer les élèves du meilleur au moins bon :', ['ORDER BY moyenne', 'ORDER BY moyenne DESC', 'SORT BY moyenne', 'GROUP BY moyenne'], 1, 'DESC = décroissant.']],
td: [
{ n: 'Échauffement', c: 'Afficher nom et prénom des élèves de la classe 3, triés par nom.', r: 'SELECT nom, prenom FROM eleves WHERE classe_id = 3 ORDER BY nom;' },
{ n: 'Application', c: 'Afficher l’effectif et la moyenne de chaque classe, avec son libellé.', r: 'SELECT c.libelle, COUNT(e.id), AVG(e.moyenne)\nFROM classes c LEFT JOIN eleves e ON e.classe_id = c.id\nGROUP BY c.libelle;' },
{ n: 'Application', c: 'Lister les élèves qui n’ont rendu aucun devoir (tables eleves, rendus).', r: 'SELECT e.nom FROM eleves e\nLEFT JOIN rendus r ON r.eleve_id = e.id\nWHERE r.id IS NULL;' },
{ n: 'Approfondissement', c: 'Afficher les classes dont la moyenne est supérieure à la moyenne générale.', r: 'SELECT classe_id, AVG(moyenne) FROM eleves GROUP BY classe_id\nHAVING AVG(moyenne) > (SELECT AVG(moyenne) FROM eleves);' },
{ n: 'Approfondissement', c: 'Réécrire en requête préparée (PHP PDO) : "SELECT * FROM users WHERE login = \'" . $login . "\'"', r: '$st = $pdo->prepare("SELECT * FROM users WHERE login = ?");\n$st->execute([$login]);' }],
tp: { type: 'IDE SQL', url: 'apercu-ide.html?ex=sql-select', desc: 'Une base SQLite dans le navigateur, requêtes vérifiées automatiquement.', etapes: ['Explorer les tables', '8 requêtes SELECT progressives', '3 jointures', '2 requêtes d’agrégat', 'Défi : le palmarès par classe'] },
plusLoin: [['SQLBolt · exercices interactifs', 'https://sqlbolt.com/'], ['Défis SQL sur HackerRank', 'https://www.hackerrank.com/domains/sql'], ['DataCamp · Introduction to SQL', 'https://www.datacamp.com/courses/introduction-to-sql']] }
]);