Cette page uniquementToutes les pages
Propulsé par GitBook
1 sur 27

SAE203

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

**anciennes pages ci-dessous**

CM2 : Introduction à GitHub

Cours de Minh Nhat Thaï

1MB
CM-GIT-Minh Nhat Thai.pdf
PDF
Ouvrir

CM1 : Présentation de la SAE

réalisation d'un site web dynamique en php + mysql

Introduction et démonstration

Comme en S1 vous allez ici réaliser un site individuellement présentant des données de votre choix. A la différence de la SAE de S1, ici les données seront stockées dans une base de données mysql pour être facilement manipulable. Il y aura un "back office" permettant à un administrateur de facilement gérer ces données (ajouter des données, modifier des données, supprimer des données). Les donnés à traiter que vous choisirez (cela peut être les mêmes que lors de la SAE de S1) devront être suffisamment complexes pour nécessiter la mise en place de 2 tables dans votre base de données:

par exemple, si vous choisissez la gestion de bandes dessinées vous devrez avoir des informations à gérer qui nécessitent 2 tables: par exemple, une table bandes dessinées et une table auteurs ou une table bandes dessinées et une table editeurs, ou une table bandes dessinées et une table genres ...

il devra aussi y avoir un champs avec une photo (du produit, du film, du chanteur...) pour chaque enregistrement. De plus il devra y avoir au moins 50 enregistrements sur une des tables et au moins 10 sur la deuxieme.

vous devrez avoir au moins 6 champs (sans compter l'id) dans une de vos tables et dans l'autre au minimum 3 champs (toujours sans compter l'id).

vous devrez bien sur déjà réaliser une analyse de vos données (dictionnaire/MCD/MLD).

Exemple :

Organisation des pages à développer

Planning de la semaine

Rendu fin de première semaine

voir

TP 03: débugage

DROITS SUR LE DOSSIER UPLOADS

Pour "Uploader" vos images dans le dossier /var/www/sae203/images/uploads Il est nécessaire que le processus apache puisse écrire dans ce dossier. Rappelez-vous que le processus apache est exécuté par l'utilisateur www-data, c'est donc à cet utilisateur qu'il faut donner les droits en écriture sur le dossier.

TD01 : intégration 1/2

Réalisation de la partie front du site

Partie 1 - Etude préalable des données

Créez tout d'abord votre MCD

Vous devez réfléchir à la structure de vos donnees: 2 tables (une de 6 champs minimum et une de 3 champs minimum sans compter les id. Cette étude vous permettra déjà de savoir combien de colonnes vous aurez à afficher dans les différentes pages.

TD05 : github

gérer son projet de développement avec github

Cours de Minh Nhat Thaï

241KB
git-td.pdf
PDF
Ouvrir

Réaliser ce TP avec les lignes de commandes, VSCode ou PHPStorm

Il faut :

  • Installer GIT sur sa machine

  • Créer un compte github

  • Finaliser le TD

  • Rajouter en collaborateur [email protected] à votre projet github

*************************

semaine 2

CM3 : Template et responsive

Template et responsive (Amine Haraoubia)

...

Il faut aussi que votre utilisateur MMI puisse aussi écrire dans le dossier (si vous voulez qu'il puisse mettre des fichiers via filezilla par exemple). C'est pourquoi on ne donne pas les permissions directement à l'utilisateur www-data, mais à son groupe (qui se nomme aussi www-data)

En tenant compte des contraintes évoquées ci-dessus, les commandes à utiliser sont:

Vous pouvez vérifier que les permissions sont correctes avec la commande:

Qui doit donc vous renvoyer l'information:

chown -R MMI:www-data /var/www/sae203/images/uploads
chmod -R 775 /var/www/sae203/images/uploads
ls -l /var/www/sae203/images | grep uploads
drwxrwxr-x 2 MMI www-data 4096 mars  23 08:07 uploads

Dans la plus grande table, il devra y avoir un champs "photo" pour illustrer l'enregistrement (ex: photo du chanteur, photo de l'affiche du film...) ce champ sera du texte (varChar) d'une taille de 30 caractères pour y stocker le nom de l'image (ex: "photoGarfield01.jpg") sachant que les fichiers photos seront eux stockées sur votre vps dans un dossier "images"

Faites vérifier votre MCD avant de passer à la suite

Partie 2 - Réalisation de la page d'accueil et catalogue

Réalisez la page d'accueil (index.php) et de la page d'affichage(listing.php) de toutes les données (version statique pour l'instant)

Exemple d'affichage "looké" pour vos datas (listing.php) n'utilisant pas une présentation type datatable: https://www.pokemon.com/fr/pokedex/

Les pages du front devront toutes être responsives (2 versions : version écran ordi et version téléphone, une seule bascule à 480px)

La page listing.php sera à terme en php (pour pouvoir afficher toutes les données de la base de données). Pour l'instant, vous la laisser avec l'extension ".php" mais vous n'y mettez pas de php dedans (à part pour gérer l'entete et le pied de page comme en S1) et vous affichez les données sous forme d'un tableau avec 2 ou 3 lignes de données fictives.

ToDo liste de la fin du TP :

page des rendus

TD02 : intégration 2/2

Réalisation de la partie front du site 2/2

en cours de rédaction...

ToDo liste de la seance précédente:

Mise en oeuvre des données sur un serveur MySql

Exemple de MLD + Fichier excel pour export .csv

Voici le MLD suivant : films(film_id, film_titre, film_annee, film_resume, film_duree, film_genre, film_photo, _real_id) realisateurs(real_id, real_nom, real_prenom, real_nationalite)

Les clés primaires sont en bleues, etrangères en rouges

Le fichier excel de données correspond sera le suivant. Une feuille par table. Bien stocker la clé étrangere de la table principales (ici dans film : _real_id avec un underscore au début pour indiquer que c'est une clé étrangère)

support de cours:

vous pouvez vous appuyer sur le cours de R214 dons le support est ici:

...

objectif

nous allons ici créer les tables nécessaires sur votre serveur mysql local (Docker)

dans notre exemple de présentation nous parlions de bandes dessinées reliées à une table d'auteurs.

...

TD03 : Formulaire et traitement

Réalisation de la page de formulaire de recherche et de la page de résultats

La page de formulaire est purement en html et la page de réponse est quand à elle en php. Pour l'instant, vous la laisser avec l'extension ".php" mais vous n'y mettez pas de php dedans (à part pour gérer l'entete et le pied de page comme en S1), et vous affichez les données sous forme d'un tableau avec 2 ou 3 lignes de données fictives. (comme pour "listing.php" de la séance précédente)

Avancée des travaux :

Après ce TD, vous avez 3h de projet tutoré pour finir ces 4 pages et préparer vos données : c'est à dire créer toutes vos données dans un fichier Excel (2 onglets si 2 tables) et préparer un dossier avec toutes les photos d'illustration de vos enregistrements.

Feuille réalisateur
Feuille films

TD06 : Eco-conception & accessibilité

Ce TD à pour objectif que le site soit accessible et intègre des critères et règles de bonnes pratiques pour l'éco-conception (au regard des enjeux du S1, et de vos compétences techniques)

Diagnostic général

Vérifiez votre site avec les outils vus en S1 :

  • Wave ou équivalent

  • (sur Chrome) ou équivalent

  • ou équivalent

A partir de ces analyses essayez d'améliorer votre site en terme d'accessibilité, de SEO, de performance et d'éco-conception.

Quelques éléments (liste non exhaustive) sont données dans parties suivantes

Vérifier les règles minimales d'accessibilité

N'oubliez pas de relire et prendre en compte les points vus au S1 :

Accessibilité des formulaires

  • Est-ce que tous les champs de vos formulaires ont le bon type, un label associé, un libellé clair, un texte d'aide si nécessaire ?

  • Est-ce que je peux naviguer dans le formulaire avec la touche tabulation ?

Accessibilité des images

  • Est-ce que les images ont une alternative textuelle adaptée ?

Tableau

  • Est-ce que les tableaux sont correctement structurés (en-tête, légende...)

Contrastes / couleurs

  • Est-ce que les contrastes sont au moins de 4.5 pour tous les éléments de votre site ?

  • Aucune information n'est passé uniquement par la couleur ?

Navigation

  • Le menu est identique sur toutes les pages

  • Je peux revenir à l'accueil (et si besoin à la page précédente) depuis toutes les pages, et sans utiliser le bouton précédent

  • Les pictos/icônes sont doublé d'un texte significatif

  • La langue et l'encodage de toutes les pages sont précisées

Intégrer l'eco-conception dans le projet

Les images

  • Est-ce que les images sont dans le format le plus approprié ?

    • SVG pour le logo par exemple

    • Webp ou png optimisé pour les autres images

  • Est-ce que la résolution des images est adaptée au web ?

CSS / JS

  • Ne garder que ce que vous utilisez

    • Supprimer le CSS inutile

    • Supprimer le JS non utilisé

    • Manuellement pour le moment

BILAN des rendus

Rendu fin de premiere semaine

GIT

Vendredi 3 mars à 15h30, mettre un fichier texte (sur votre VPS) "/root/MMI-git.txt" où MMI est votre identifiant (ex: mmi21xxx). A l'intérieur de ce fichier, mettez votre lien https vers votre github.

Dans ce fichier texte, il ne doit y avoir qu'une seule ligne du type:

""

Ce repository doit être privé (pour ne pas être visible d'autres étudiants) et par contre vous devez rajouter les contributeurs suivants (les enseignants du module) :

pgommery , Dannebicque , haraou01, meuzer01 , f-libbrecht

nous devons trouver sur votre github l'intégralité de vos pages de la partie "front" (index.php, listing.php, form_recherche.php, reponse_recherche.php...)

VPS

Sur votre VPS (http://MMI.sae203.ovh) vous devez avoir les 4 pages développées cette semaine accessibles (index, listing, form_recherche, reponse_recherche) .

Seule la page listing.php doit avoir le php fonctionnelle en terme d'affiche des informations.

La réponse au formulaire doit avoir la sécurisation des textes saisis ( pour éviter par exemple les injections de script). par contre l'affichage en php de la liste des 'articles' correspondants à la recherche n'est pas à faire pour l'instant.

  • index.php

  • listing.php (liée à votre BDD)

  • form_recherche.php

  • reponse_recherche.php (données d'exemples pour le moment)

CM4 : Eco-conception & accessibilité

Ressources utiles

Le livre "Eco-conception web / Les 115 bonnes pratiques" => . Librement telechargeable ici :

  • Très vite avec des outils automatiques (purifyCSS par exemple)

  • Mimifier vos fichiers CSS et JS

    • Avec des outils en lignes pour le moment,

      • exemple : https://www.websiteplanet.com/fr/webtools/jscssminifier/

      • Très vite de manière automatique (webpack par exemple)

  • Lighthouse
    Dareboost
    https://cours.davidannebicque.fr/accessibilite-numerique
    https://github.com/votrecomptegit/sae203
    471KB
    CM-Eco-conception.pptx
    Ouvrir
    Le support de cours
    https://www.eco-conception.fr/articles/h/eco-conception-web-les-115-bonnes-pratiques-3eme-edition.html
    https://collectif.greenit.fr/ecoconception-web/

    TP 02 : Recherche : autocomplétion du formulaire + résultats

    Modification du formulaire de recherche pour remplir automatiquement notre liste de proposition d’auteurs et affichage des résultats de recherche

    Préambule

    Nous avons vu lors du TD04 comment faire une liste de propositions dans le champs de recherche grace à <datalist>. Pour le moment cette liste est écrire à la main, nous avons nous même entré les propositions à donner à l'utilisateur. Nous allons automatiser la création de cette liste à partir des données stockées dans notre base.

    Partie 1 : Modification de la page du fomulaire de recherche

    Création de la fonction

    Création de la fonction de génération des <option> du <datalist> dans notre librairie de fonctions lib_crud.inc.php

    Modification du formulaire de recherche

    Modifier le code de votre page form_recherche.php afin de générer automatiquement la <datalist> à partir de la BDD

    Partie 2 : Création de la page des resultats de recherche : reponse_recherche.php

    Ecriture de la requête

    1. Ecrivez tout d'abord la requete

    2. Testez-la sur phpMyAdmin

    3. Créez ensuite la fonction qui génère les resultats

    Nous allons utiliser l'opérateur pour filtrer les résultats à afficher

    Par exemple :

    SELECT * FROM chiens WHERE nom_chiens LIKE 'bu%';

    Affichera tous les chiens dont le nom commence par "bu"

    Création de la fonction

    Création de la fonction d'affichage des resultats de recherche dans notre librairie de fonctions lib_crud.inc.php

    Création de la page de résultats

    Votre page reponse_recherche.php et très similaite à listing.php et devrait ressembler à cela :

    ancien TP01 : réalisation de la page listing.php

    connexion de la page listing.php à la base de données

    Pour pouvoir réaliser correctement l'exercice su votre VPS, vous devez avoir installé les paquets suivants sur votre serveur: php8.1-xml, php8.1-mysqli, php8.1-mbstring, php8.1-curl . Si vous avez un doute, avant de commencer, exécutez les commandes suivantes

    support de cours

    Bilan des rendus de la 2ieme semaine

    Sur votre VPS pour vendredi 17h

    Sur votre VPS (https://MMI.sae203.ovh) vous devez avoir l'ensemble du site fonctionnel Le certificat SSL pour HTTPS doit donc être installé et actif Le dossier admin doit être protégé par un fichier .htaccess qui reprend les options vues dans le TD13

    • La partie front

    :
    • Page d'accueil

    • Page de listing

    • Formulaire et résultats de recherche

  • La partie back-office : avec les gestions CRUD des 2 tables

    • Affichage de la liste,

    • Ajout

    • Modification,

    • Suppression

    attention: il doit y avoir cette gestion CRUD pour les 2 tables!

  • le tout pushé sur votre github

  • vous pouvez vous appuyer sur le cours de R213 dons le support est ici: http://149.91.83.164/lectio/p-R213-developpement-web_cm-02.html#1

    objectif

    nous allons ici relier la page listing.php (qui pour l'instant ne contient que 2 ou 3 'articles' fictives) à la base de données.

    dans notre exemple de présentation nous parlions de bandes dessinées reliées à une table d'auteurs.

    connexion à la base de données

    ouvrir votre fichier listing.php et commencer par inclure la ligne permettant la connexion à la base de données (à mettre au début, juste après body par exemple). attention changer monMotDePasse par votre propre mot de passe d'accès à votre base de données (celui du compte sae203)

    vous pouvez déjà tester votre page listing.php. En la testant, vous devez voir aucun changement, sauf si il y a un soucis de connexion à votre base de données et dans ce cas vous aurez un message d'erreur qu'il faudra résoudre (erreur de mot de passe, de nom de base de données, d'identifiant...)

    passer l'envois de vos requêtes en UTF8

    ajouter la ligne nécessaire

    préparation de la requete

    Après la connexion à la base de données, il est maintenant nécessaire de préparer et d'exécuter la requete SQL permettant de récupérer toutes les informations sur les albums avec le nom des auteurs (pour notre exemple ici! il faut bien sur adapter cela à vos propres données)

    affichage sommaire des informations

    ajouter les lignes suivantes (en les adaptant à vos données!)

    vous pouvez maintenant tester votre page 'listing.php' , et vous devez observer l'affichage (présentation sommaire) de toutes vos données

    amélioration de l'affichage des informations

    vous pouvez maintenant améliorer l'affichage des données en fonction de ce que vous aviez prévue en terme de html et css au début de la SAE.

    exemple:

    insertion des photos

    vous pouvez ajouter dans le foreach, l'affichage du champs photo. il faut bien sur que vos photos soient dans un dossier images dans votre dossier de votre projet.

    vous pouvez maintenant tester votre page 'listing.php' , et vous devez observer l'affichage de toutes vos données y compris la photo. Vérifiez aussi l'affichage en version mobile.

    votre page listing est maintenant opérationnelle, vous pouvez la peaufiner graphiquement.

    like

    ancien TD04 : vérification front

    Validation des données entrées dans les champs des formulaires

    Partie 1 - Validation des données

    Nous verrons ici comment obtenir nos données dans le format souhaité. Par exemple dans un champs prix, nous voulons que l'utilisateur rentre des chiffres

    Attention, la validation coté front ne remplace pas celle coté back. L'utilisateur peut désactiver le javascript ou utiliser la console du navigateur pour contourner très facilement vos vérifications.

    Afin de faciliter le développement, nous utiliserons ici le plugin javascript :

    Installation du plugin

    Téléchargez le javascript et le css du plugin

    Ce plugin necessite Jquery

    Importez le plugin

    Dans votre <head>, ajoutez les lignes suivantes :

    Activez le plugin sur votre formulaire

    Ajoutez l'attribut data-parsley-validate à votre formulaire

    Activez la vérification des champs

    Ici nous souhaitons valider des chiffres, nous allons donc utiliser l'option data-parsley-type="number" sur nos champs

    Testez

    Le plugin sait valider tous types de champs :

    • Nombre

    • Entier

    Partie 2 - Autocompletion

    Afin de faciliter l'usage du site à nos visiteurs, nous avons utiliser la completion automatique sur notre champ de recherche.

    L'autocompletion est le fait de proposer des résultats à l'utilisateur au fur et à mesure qu'il tape des caratères dans le champ du formulaire.

    Une nouvelle balise HTML5 à la rescousse

    La 5ème version d'HTML a apportée son lot de nouveautés, la prise en charge nativement d'une autocomplétion par les navigateurs en fait partie.

    Nous allons donc utiliser la balise <datalist>

    1) Créez votre liste de propositions

    Pour le moment cette liste est faite à la main, en 2ème partie de SAE vous aurez les compétences pour la générer automatiquement avec PHP. De fait, la liste sera toujours à jour. Si vous ajoutez un réalisateur dans votre BDD, il sera proposé dans cette liste.

    2) Lier la liste avec l'input

    Ajoutez l'attribut list afin de lier votre champ de texte à votre liste

    Exemple pour un formulaire de recherche de réalisateurs

    Bug avec l'autofill ou remplissage automatique des champs

    Si vous avez l'habitude d'enregistrer vos informations de formulaire (login, email,...), il peut se produire un effet particulier ou la navigateur vous propose en plus du datalist, le remplissage avec vos infos.

    Allez plus loin avec les plugins

    Si vous souhaitez aller plus loin des plugins d'autocomplétion plus performants et personnalisables existent :

    TD04 : filter_var et filtrage des données des formulaires en PHP

    Lorsque nous utilisons des formulaires sur une page web, leur traitement en PHP doit assurer la sécurité de leur contenu. Dans cette séance, on va essayer de comprendre ce qui peut mal se passer lors du traitement des informations par le code PHP.

    1) Sécurité des champs d'un formulaire de connexion :

    On donne le formulaire de connexion "form1.php" suivant :

    Dans ce formulaire, on demande à l'utilisateur de définir une adresse e-mail et un mot de passe pour sa connexion. Le champ "e-mail" est de type "text", le champ "mdp" est de type "password".

    On donne le fichier de traitement "t1.php" :

    TP01 : réalisation de la page listing.php

    connexion de la page listing.php à la base de données

    Pour pouvoir réaliser correctement l'exercice su votre VPS, vous devez avoir installé les paquets suivants sur votre serveur: php8.1-xml, php8.1-mysqli, php8.1-mbstring, php8.1-curl . Si vous avez un doute, avant de commencer, exécutez les commandes suivantes

    support de cours

    sudo -i
    apt update
    apt install php8.1-xml php8.1-mysqli php8.1-mbstring php8.1-curl 
    <?php
    $mabd = new PDO('mysql:host=localhost;dbname=sae203;charset=UTF8;', 'sae203', 'monMotDePasse');
    ?>
    <?php
    $mabd = new PDO('mysql:host=localhost;dbname=sae203;charset=UTF8;', 'sae203', 'monMotDePasse');
    
    $mabd->query('SET NAMES utf8;');
    ?>
    ...
    $req = "SELECT * FROM bandes_dessinees INNER JOIN auteurs ON bandes_dessinees._auteur_id = auteurs.auteur_id";
    $resultat = $mabd->query($req);
    ...
    foreach ($resultat as $value) {
        echo $value['bd_titre'] . ' , ' . $value['bd_prix'] . ' euro ';
        echo '<br> auteur: ' . $value['auteur_nom']. '<hr>';
    }
    ...
    foreach ($resultat as $value) {
        echo '<div class="album">' ;
        echo '<h3>'.$value['bd_titre'] . '</h3>';
        echo '<p>tarif: ' . $value['bd_prix'] . ' euro </p>';
        echo '<p class="page">' . $value['bd_page'] . ' pages </p>';
        echo '<p class="auteur"> auteur: ' . $value['auteur_nom'] . '</p>';
        echo '</div>';
    }
    ...
    foreach ($resultat as $value) {
        echo '<div class="album">' ;
        echo '<h3>'.$value['bd_titre'] . '</h3>';
        ...
        echo '<img class="image" src="images/'.$value['bd_photo'].'">';
        ...
        echo '<p>tarif: ' . $value['bd_prix'] . ' euro </p>';
        echo '<p class="page">' . $value['bd_nb_page'] . ' pages </p>';
        echo '<p>Résumé: ' . $value['bd_resume'] . ' </p>';
        echo '<p class="auteur"> de ' . $value['auteur_nom'] . '</p>';
        echo '</div>';
    }
    ...
    
    // Génération de la liste des auteurs dans le formulaire de recherche
    function genererDatalistAuteurs($mabd) {
        // on sélectionne le nom et prénom de tous les auteurs de la table auteurs
        $req = "SELECT auteur_nom FROM auteurs";
        try {
            $resultat = $mabd->query($req);
        } catch (PDOException $e) {
            // s'il y a une erreur, on l'affiche
            echo '<p>Erreur : ' . $e->getMessage() . '</p>';
            die();
        }
        // pour chaque auteur, on met son nom <option>
        foreach ($resultat as $value) {
            echo '<option value="'. ??? .'">'; 
        } 
    }
    ...
    
    <input type="search" id="real" list="auteurs" name="texte" autocomplete="off" />
    <datalist id="auteurs">
    <?php
        // On va afficher ici la datalist
        require 'lib_crud.inc.php';
        $co=connexionBD();
        genererDatalistAuteurs($co);
        deconnexionBD($co);
    ?>
    </datalist>
    // affichage des resultats de recherche
    function afficherResultatRecherche($mabd) {
        $req = "SELECT * FROM bandes_dessinees 
                INNER JOIN auteurs 
                ON bandes_dessinees._auteur_id = auteurs.auteur_id
                WHERE ???";
        try {
            $resultat = $mabd->query($req);
        } catch (PDOException $e) {
            // s'il y a une erreur, on l'affiche
            echo '<p>Erreur : ' . $e->getMessage() . '</p>';
            die();
        }
        // ICI VOTRE CODE POUR AFFICHER LES ALBUMS FILTRES
        // ...
        // ...
    }
    <h1>Nos albums</h1>
    <p>Résultats de votre recherche</p>
    <hr />
    <?php
        require 'lib_crud.inc.php';
        $co=connexionBD();
        afficherResultatRecherche($co);
        deconnexionBD($co);
    ?>
    Email
  • Url

  • Champs obligatoire

  • ...

  • Je vous renvoie à la documentation pour plus d'informations

    Dans ce cas on doit tricher et peut desactiver le remplissage automatique avec l'attribut, autocomplete ainsi que lui donner un name contenant le mot clé search Exemple :
    Parsley.js
    https://parsleyjs.org/dist/parsley.min.js
    https://parsleyjs.org/src/parsley.css
    https://tarekraafat.github.io/autoComplete.js
    https://bashooka.com/coding/autocomplete-autosuggest-javascript-libraries/
    Il est possible de traduire les erreurs en éditant le fichier parsley.js
    L'autocompletion de Google
    Dans ce fichier de traitement, on regarde si les deux champs ont bien été remplis correctement. S'il en manque un des deux, on retourne à la page du formulaire. Si les deux champs sont remplis, on affiche leur contenu (d'ailleurs en passant, ce n'est pas bien d'afficher le contenu d'un mot de passe...).
    • Envoyez ces deux fichiers sur votre VPS dans le dossier "public_html/travaux/sae203/td06/". Testez le code en entrant un e-mail "normal" et un mot de passe "bidon" : "toto1234" par exemple. Que se passe-t-il au niveau de l'affichage par la page de traitement (y a-t-il un problème) ?

    • Maintenant sur votre navigateur, retournez sur la page du formulaire et entrez : [email protected]<script>alert('script 1');</script> dans le champ "e-mail" et toto1234<script>alert('script 2');</script> dans le champ "mdp". Validez votre formulaire, que se passe-t-il sur la page de traitement ?

    Il y a donc possibilité d'injecter du code Javascript dans un champ de type "text" dans un formulaire (c'est de l'injection de code XSS). Cela donne un problème de sécurité, n'importe qui peut envoyer des scripts dans vos champs de formulaire. Ici, c'est juste un affichage mais on pourrait injecter un script qui redirige vers une autre page...

    Il faut donc, pour n'importe quelle donnée, respecter les trois étapes suivantes :

    1. Sanitize input (assainir les entrées)

    2. Validate data (valider les données)

    3. Escape output (échapper les sorties)

    En PHP, la fonction d'assainissement et de validation des données est filter_var() et la fonction d'échappement des caractères spéciaux dans les chaînes est htmlentities().

    Dans notre cas, le champ qui pose problème est le champ "email" car le champ "mdp" n'a pas besoin d'être affiché (et ne doit jamais l'être sur un site), même sa version cryptée ! Mettez en commentaire la ligne //echo '<p>'.$_POST['mdp'].'</p>'."\n"; dans votre page de traitement "t1.php".

    • Modifiez votre code pour "assainir", "valider" et "échapper" le champ email. Envoyez votre nouveau code sur votre VPS, testez ce qui se passe avec "[email protected]<script>alert('script 1');</script>" dans le champ "e-mail" et "toto1234<script>alert('script 2');</script>" dans le champ mot de passe. Normalement, votre code n'affichera plus les fenêtres pop-up "alert()".

    Pour éviter ce genre de problème, vous pouvez passer le champ "email" du type "text" au type "email" qui existe en HTML.

    2) Sécurité des champs d'un formulaire de renseignement :

    On donne le code du formulaire "form2.php" ici :

    • On donne le fichier de traitement "t2.php" :

    • Envoyez ces deux fichiers sur votre VPS dans le dossier "public_html/travaux/sae203/td06/". Testez le code en entrant Robert<script>alert('Prénom pas sûr !')</script> et 20<script>alert('Âge pas sûr non plus !')</script>. Que se passe-t-il au niveau de l'affichage par la page de traitement (y a-t-il un problème) ?

    • Appliquez l'assainissement, la validation et l'échappement dans le fichier de traitement "t2.php". Testez votre code avec Robert<script>alert('Prénom pas sûr !')</script> et 20<script>alert('Âge pas sûr non plus !')</script> jusqu'à ce qu'il n'y ait plus de problème d'injection de code Javascript dans vos champs de formulaire.

    • En résumé, pour garantir un premier niveau de sécurité, il faut mettre les types qui correspondent aux champs dans les champs de formulaire : <input type= "email"> pour un e-mail, "number" pour un nombre, "date" pour une date... Tout mettre en <input type="text" ...> n'est pas une bonne idée !

    On aurait pu aussi démarrer les sessions sur les pages de notre site et choisir, au lieu d'afficher des erreurs au niveau de la page de traitement, de les passer en session à la page du formulaire pour prévenir l'utilisateur qu'un champ n'est pas correctement rempli dans le formulaire (on l'a déjà fait en S1 en SAE105...).

    3) Sécurité de votre formulaire de recherche SAE203 :

    Afin de vérifier si vous avez bien compris la sécurisation de vos données de champs de formulaire, modifiez le code de votre formulaire de recherche et de votre page de traitement "reponse_recherche.php".

    Testez votre code en mettant un script dans le champ de recherche par nom/prénom d'un auteur, par exemple Albert Uderzo<script>alert('Danger !!!')</script>. Si votre protection fonctionne bien, vous ne devez pas voir la fenêtre pop-up qui affiche "Danger !!!" apparaître lors du traitement de votre formulaire.

    4) Pour aller plus loin :

    Quelques liens à lire pour comprendre un peu mieux les enjeux de la sécurité de vos pages web de traitement de formulaires avec PHP :

    • PHP good security practices

    • Sécurité PHP

    • Filtres de nettoyage PHP

    • Filtres de validation PHP

    vous pouvez vous appuyer sur le cours de R213 dons le support est ici: http://149.91.83.164/lectio/p-R213-developpement-web_cm-02.html#1

    objectif

    nous allons ici relier la page listing.php (qui pour l'instant ne contient que 2 ou 3 'articles' fictives) à la base de données.

    dans notre exemple de présentation nous parlions de bandes dessinées reliées à une table d'auteurs.

    connexion à la base de données

    ouvrir votre fichier listing.php et commencer par inclure la ligne permettant la connexion à la base de données (à mettre au début, juste après body par exemple). attention changer monMotDePasse par votre propre mot de passe d'accès à votre base de données (celui du compte sae203)

    vous pouvez déjà tester votre page listing.php. En la testant, vous devez voir aucun changement, sauf si il y a un soucis de connexion à votre base de données et dans ce cas vous aurez un message d'erreur qu'il faudra résoudre (erreur de mot de passe, de nom de base de données, d'identifiant...)

    passer l'envois de vos requêtes en UTF8

    ajouter la ligne nécessaire

    préparation de la requete

    Après la connexion à la base de données, il est maintenant nécessaire de préparer et d'exécuter la requete SQL permettant de récupérer toutes les informations sur les albums avec le nom des auteurs (pour notre exemple ici! il faut bien sur adapter cela à vos propres données)

    affichage sommaire des informations

    ajouter les lignes suivantes (en les adaptant à vos données!)

    vous pouvez maintenant tester votre page 'listing.php' , et vous devez observer l'affichage (présentation sommaire) de toutes vos données

    amélioration de l'affichage des informations

    vous pouvez maintenant améliorer l'affichage des données en fonction de ce que vous aviez prévue en terme de html et css au début de la SAE.

    exemple:

    insertion des photos

    vous pouvez ajouter dans le foreach, l'affichage du champs photo. il faut bien sur que vos photos soient dans un dossier images dans votre dossier de votre projet.

    vous pouvez maintenant tester votre page 'listing.php' , et vous devez observer l'affichage de toutes vos données y compris la photo. Vérifiez aussi l'affichage en version mobile.

    votre page listing est maintenant opérationnelle, vous pouvez la peaufiner graphiquement.

    TD07 : HEBERGEMENT SITE SAE203

    Hébergement

    OBJECTIF

    Votre site final devra être accessible par l'URL : https://MMI.sae203.ovh Les pages du site devront se trouver dans un dossier /var/www/sae203 de votre VPS

    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="parsley.min.js"></script>
    <link rel="stylesheet" href="parsley.css">
    <form action="reponse_recherche.php" data-parsley-validate>
    <p>
        <label for="duree_mini">Durée minimum (en minutes)</label>
        <input type="text" id="duree_mini" name="duree_mini" placeholder="10" data-parsley-type="number">
    </p>
    <datalist id="realisateurs">
        <option value="Allen">
        <option value="Donner">
        <option value="Kubrick">
        <option value="Nolan">
        <option value="Tarantino">
        <option value="Tessari">
    </datalist>
    <input type="search" list="realisateurs" id="real" name="real" />
     <form action="reponse_recherche.php">
        <label for="real">Entrez un nom de réalisateur :</label>
        <input type="search" list="realisateurs" id="real" name="real" />
        <datalist id="realisateurs">
            <option value="Allen">
            <option value="Donner">
            <option value="Kubrick">
            <option value="Nolan">
            <option value="Tarantino">
            <option value="Tessari">
        </datalist>
        <input class="btn btn-primary" type="submit" value="Rechercher" id="submit">
      </form>
    <input type="search" autocomplete="off" list="realisateurs" id="real" name="searchReal" />
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
        </head>
        <body>
            <h1>Connexion</h1>
            <form method="post" action="t1.php">
                <label for="email">e-mail : </label>
                <input type="text" name="email" id="email"><br />
                <label for="mdp">mot de passe : </label>
                <input type="password" name="mdp" id="mdp"><br />
                <input type="submit" value="Vérifier">
            </form>
        </body>
    </html>
    <?php
        if ( (empty($_POST['email'])) || (empty($_POST['mdp'])) ){
            header('Location: form1.php');
        }
    
        echo '<p>'.$_POST['email'].'</p>'."\n";
        echo '<p>'.$_POST['mdp'].'</p>'."\n";
    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8" />
        </head>
        <body>
            <h1>Connexion</h1>
            <form method="post" action="t2.php">
                <label for="prenom">Votre prénom : </label>
                <input type="text" name="prenom" id="prenom"><br />
                <label for="age">Votre âge : </label>
                <input type="text" name="age" id="age"> ans.<br />
                <input type="submit" value="Envoyer">
            </form>
        </body>
    </html>
    <?php
        if ( (empty($_POST['prenom'])) || (empty($_POST['age'])) ) {
            header('Location: form2.php');
        }
    
        echo '<p>Votre prénom : '.$_POST['prenom'].'</p>'."\n";
        echo '<p>Votre âge : '.$_POST['age'].'</p>'."\n";
    sudo -i
    apt update
    apt install php8.1-xml php8.1-mysqli php8.1-mbstring php8.1-curl 
    <?php
    $mabd = new PDO('mysql:host=localhost;dbname=sae203;charset=UTF8;', 'sae203', 'monMotDePasse');
    ?>
    <?php
    $mabd = new PDO('mysql:host=localhost;dbname=sae203;charset=UTF8;', 'sae203', 'monMotDePasse');
    
    $mabd->query('SET NAMES utf8;');
    ?>
    ...
    $req = "SELECT * FROM bandes_dessinees INNER JOIN auteurs ON bandes_dessinees._auteur_id = auteurs.auteur_id";
    $resultat = $mabd->query($req);
    ...
    foreach ($resultat as $value) {
        echo $value['bd_titre'] . ' , ' . $value['bd_prix'] . ' euro ';
        echo '<br> auteur: ' . $value['auteur_nom']. '<hr>';
    }
    ...
    foreach ($resultat as $value) {
        echo '<div class="album">' ;
        echo '<h3>'.$value['bd_titre'] . '</h3>';
        echo '<p>tarif: ' . $value['bd_prix'] . ' euro </p>';
        echo '<p class="page">' . $value['bd_page'] . ' pages </p>';
        echo '<p class="auteur"> auteur: ' . $value['auteur_nom'] . '</p>';
        echo '</div>';
    }
    ...
    foreach ($resultat as $value) {
        echo '<div class="album">' ;
        echo '<h3>'.$value['bd_titre'] . '</h3>';
        ...
        echo '<img class="image" src="images/'.$value['bd_photo'].'">';
        ...
        echo '<p>tarif: ' . $value['bd_prix'] . ' euro </p>';
        echo '<p class="page">' . $value['bd_nb_page'] . ' pages </p>';
        echo '<p>Résumé: ' . $value['bd_resume'] . ' </p>';
        echo '<p class="auteur"> de ' . $value['auteur_nom'] . '</p>';
        echo '</div>';
    }
    Fonction de nettoyage avant affichage
    PREAMBULE

    Dans tout le document, remplacez MMI par votre identifiant MMI personnel (mmi21Xxx). Testez l'enregistrement DNS de votre site : MMI.sae203.ovh avec la commande dig +shortMMI.sae203.ovh Le résultat retourné doit être l'adresse IP de votre VPS. Dans le cas contraire, signalez-le à l'enseignant pour qu'il vérifie.

    MISE EN PLACE DU SITE

    LE DOSSIER et les DROITS D'ACCES pour l'utilisateur MMI

    Pour commencer , ouvrez un terminal et connectez-vous en SSH sur votre VPS avec votre compte utilisateur MMI et le mot de passe associé. Une fois connecté, n'oubliez pas de saisir la commande sudo -i pour obtenir les autorisations root sur votre machine.

    Créez un dossier /var/www/sae203 (mkdir)

    Donnez les droits en écriture à votre utilisateur MMI sur le dossier sae203 (chown)

    Pour faire un premier test, dans le dossier sae203, créez une page index.php avec le contenu suivant : <?php phpinfo(); ?>

    LE FICHIER DE CONFIGURATION APACHE

    Placez vous dans le dossier /etc/apache2/sites-available (cd)

    Créez un fichier 003-sae203.conf avec le contenu suivant Remplacez les ?????? par les valeurs attendues

    <VirtualHost *:80> ServerName ?????? ServerAdmin prenom.nom@etudiant.univ-reims.fr DocumentRoot ?????? DirectoryIndex ?????? ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>

    Activez votre nouveau site (a2ensite)

    Rechargez la configuration d'Apache (systemctl reload)

    Testez votre configuration avec l'URL : http://MMI.sae203.ovh Vous devez voir afficher la configuration PHP de votre serveur :

    Ne tenez pas compte de la version pour l'instant

    Votre site étant maintenant correctement configuré, nous allons pouvoir passer à la suite

    MISE A JOUR DE PHP

    Pour continuer, nous allons maintenant mettre à jour PHP en version 8 afin de profiter au mieux de toutes les fonctionnalités du langage. Pour être plus précis, nous n'allons pas seulement mettre à jour notre version de PHP, mais voir comment faire cohabiter deux versions de PHP sous Apache.

    AJOUT (ou mise à jour) DU DEPOT SURY

    Comme nous l'avons déjà remarqué dans d'autres cours, notre distribution Debian ne dispose pas des versions les plus récentes de PHP dans ses dépôts. Nous allons donc commencer par ajouter un nouveau dépôt à notre installation pour pouvoir récupérer les paquets des dernières versions de PHP. Pour l'exercice, nous utiliserons les dépôts de Sury un des développeurs de la distribution Debian.

    1- Vérifiez que les paquets prérequis pour l'installation sont présents sur notre machine. Utilisez la commande suivante pour commencer :

    2- Récupérez la clé de vérification des paquets qui nous garantira que les données téléchargées ne sont pas altérées et sont bien celles publiées par Sury.

    3- Ajoutez le dépôt Sury :

    Si le fichier est vide, ajoutez les lignes suivantes. Si le fichier existe déjà, vérifiez simplement que le contenu est le suivant :

    4- Mettez à jour la liste des paquets avec la commande : apt update ATTENTION Si des messages d'erreurs s'affichent , ne continuez pas l'exercice, corrigez les erreurs !!!

    INSTALLATION DES VERSIONS DE PHP

    Voyons maintenant comment il est possible d'avoir plusieurs versions de php actives sur notre serveur web. C'est le module CGI (Common Gateway Interface) qui va permettre à Apache de passer des instructions à un autre processus et d'en récupérer le résultat.

    Pour que cela fonctionne, il faut juste que le processus externe puisse aussi être gérer à travers cette interface. Dans notre cas, nous utiliserons le module fast_cgi d'Apache (mod_fcgid) et les versions FPM (FastCGI Process Manager) de PHP.

    Le module FastCGI servira d'interface entre Apache et les versions de PHP que nous voulons installer

    1- Commencez par installer les paquets suivants :

    libapache2-mod-fcgid php7.4-fpm php8.1-fpm REMARQUE : En plus du module fcgid, nous installons ici les version FPM de php afin de pouvoir les utiliser simultanément avec Apache, nous verrons un peu plus loin comment choisir la version active pour un site ou une application précise.

    2- Activez les modules apache et les configurations de nos versions de php

    a2enconf php7.4-fpm a2enconf php8.1-fpm a2enmod proxy_fcgi a2enmod fcgid

    3- Relancez apache : service apache2 restart

    ATTENTION Si des messages d'erreurs s'affichent , ne continuez pas l'exercice, corrigez les erreurs !!!

    4- Vérifiez la version active de PHP en rappelant la page index.php crée en début de cours : http://MMI.sae203.ovh

    La version 8 de PHP est bien installée

    CHOISIR SA VERSION DE PHP

    Voyons maintenant comment indiquer à Apache la version de PHP qu'il doit utiliser. Avec le module FastCGI, le choix peut se faire au niveau d'un site, mais aussi au niveau d'un dossier. Il suffit simplement d'ajouter les lignes suivantes dans le contexte désiré :

    Par exemple, pour que votre site de travail reste en version 7 , ajoutez les lignes suivantes à votre fichier de configuration 001-MMI.conf , juste après la ligne <VirtualHost *:80> :

    <FilesMatch .php$> SetHandler "proxy:unix:/var/run/php/php7.4-fpm.sock|fcgi://localhost" </FilesMatch> ATTENTION si vous avez activé HTTPS sur votre site MMI.mmi-troyes.fr , il faut aussi ajouter ces lignes dans le fichier 001-MMI-le-ssl.conf après la ligne <VirtualHost *:443>

    Ensuite, relancez apache pour prendre en compte les modifications.

    Pour tester, créez une page info.php avec la fonction phpinfo() dans votre dossier public_html Appelez cette page dans votre navigateur et vérifiez que vous utilisez bien la version 7 de PHP.

    Votre site MMI.mmi-troyes.fr fonctionne toujours en PHP 7

    Pour terminer cette partie, modifiez le fichier de configuration de votre site sae203 pour qu'il ne prenne en compte que la version 8.1 de php

    CONFIGURATION DE PHP

    Vous avez pu voir avec phpinfo() un aperçu de la configuration de l'interpréteur php de votre serveur. Si vous observez le début de la page, vous pouvez voir que PHP utilise un fichier de configuration nommé php.ini . Ce fichier est unique pour chaque version de php .

    Le fichier de configuration de notre version 8.1 est donc : /etc/php/8.1/fpm/php.ini

    Rassurez-vous nous n'allons pas passer tous les paramètres en revue, mais seulement nous intéresser à quelques-uns d'entre eux :

    • display_errors : Affichage des Erreurs PHP

    • upload_max_filesize : Taille Maximum des fichiers téléchargés

    • post_max_size : Taille Maximum des données envoyées via la méthode POST

    Pour régler ces paramètres comme nous le désirons, il suffit d'éditer le fichier php.ini correspondant à notre version de PHP et de modifier les valeurs comme suit :

    display_errors = On upload_max_filesize = 25M post_max_size = 25M

    Pour vous simplifier le travail et éviter les erreurs, je mets à votre disposition un fichier php.ini correctement configuré. Utilisez les commandes suivantes pour le récupérer

    Exemple pour php8.1 : cd /etc/php/8.1/fpm rm php.ini wget http://demos4.mmi-troyes.fr/support/php.ini

    Une fois le fichier modifié (ou recopié), redémarrez les services php associés . Exemple pour php8.1 : service php8.1-fpm restart Vérifiez ensuite avec votre page info.php que les modifications ont bien été prises en compte. Pour terminer cette partie, modifiez le fichier php.ini des deux versions de PHP installées (7.4 et 8.1) , renommez la page index.php de votre site sae203 en info.php créez une nouvelle page index.php avec le contenu de votre choix. Cette page sera la page d'accueil de votre site http://MMI.sae203.ovh

    Il ne vous restera plus qu'à installer le certificat Let's Encrypt pour passer votre site en HTTPS. Pour cela saisissez simplement la commande certbot --apache comme nous l'avons fait pour la sae105 lors du premier semestre.

    REMARQUE : Rappelez-vous que le nombre de requête de certificat est limité à une cinquantaine par semaine, donc soyez patient. Si le nombre de requêtes est atteint aujourd'hui , réessayez la semaine prochaine.

    Guide de Dépannage Git

    Procédure rapide pour remettre le dépôt correctement

    Schéma de fonctionnement attendu

    OBJECTIFS

    L'objectif est d'obtenir le fonctionnement de déploiement ci-dessus avec

    • Un Dossier en LOCAL (Votre poste de Travail) qui contient votre code et sur lequel vous développez la SAE. Ce Dossier fait aussi de Dépôt Git LOCAL

    • Un Dépôt GitHUB qui est votre dépôt Git DISTANT

    • Un Dossier /var/www/sae203 sur votre VPS qui est le dépôt Git de PRODUCTION

    Pour simplifier le fonctionnement, vos dépôts Git ne doivent posséder qu'une seule branche : main (la branche principale)

    NETTOYAGE DE L'EXISTANT

    Pour corriger vos problèmes, il est surement plus simple de repartir de zéro, donc nous allons supprimer tous les dépôts et les récréer.

    IMPORTANT : Sur votre poste de travail faites une copie de tous le contenu de votre site sae203 dans un dossier autre que sae203 . Copiez les fichiers en les sélectionnant dans votre gestionnaire de fichiers, ne copiez pas le sous-dossier .git !!! Ne vous contentez pas de renommer le dossier ou d'en faire une copie !! Il faut copier son contenu uniquement (sauf .git qui est constitue le dépôt actuel)

    Ensuite:

    • Sur votre poste de travail, supprimez complétement le dossier de votre site sae203

    • Sur GitHub, supprimez le dépôt sae203 (pas seulement son contenu)

    Pour supprimer un dépôt GitHub, sélectionnez Settings dans le menu du dépôt

    Ensuite , allez en bas de la page et sélectionnez l'option : Delete This Repository

    RECONSTRUCTION DU DEPOT

    Attention, l'ordre de réalisation des différentes étapes est important.

    ETAPE 1 : DEPOT SAE203 sur GitHUB

    CREATION DU DEPOT

    1. Connectez-vous à GitHub

    2. Créez un nouveau dépôt privé nommé sae203. Ajoutez le fichier README Ajoutez le fichier .gitignore avec le template de votre choix.

    AJOUT DES COLLABORATEURS AU DEPOT

    Ensuite ajouter les collaborateurs suivants en cliquant sur Sur Settings, puis Collaborators

    Les collaborateurs à ajouter : jlandre72 , pgommery , Dannebicque , haraou01, meuzer01 , f-libbrecht

    RECUPERATION DU LIEN DE CLONAGE

    Pour terminer cette partie, récupérez le lien de stockage en déroulant le menu Code Faites une copie du lien avant de continuer.

    Si vous avez recopiez votre clé SSH sur GitHub, prenez le lien SSH Sinon, prenez le lien HTTPS

    ETAPE 2 : LE DEPOT LOCAL

    CREATION DU DEPOT

    Sur votre poste de travail, créez un dossier vide nommé sae203 Ce dossier contiendra les pages de votre site, mais ne les copier pas dedans pour l'instant.

    Ouvrez un terminal, positionnez-vous dans le répertoire parent de sae203 et saisissez la commande : git clone LIEN_GITHUB sae203

    ATTENTION : Vous ne devez pas être dans le dossier sae203, mais bien dans le dossier supérieur avant de saisir la commande.

    Remplacez LIEN_GITHUB par le lien de clonage que vous avez copié à l'étape précédente.

    Vous pouvez vérifier que tout est correct en ouvrant le dossier sae203

    PUSH DU PROJET SAE203

    Si tout est correct à l'étape précédente, recopiez les fichiers de votre site dans le dossier sae203

    Après recopié les fichiers dans le dossier, nous pouvons maintenant les inclures (add) dans le dépôt Git local (commit) et ensuite les envoyer sur le dépôt distant (push)

    Ouvrez un terminal et positionnez-vous dans le dossier sae203

    Vous pouvez vérifier sur GitHub que vos fichiers ont bien été envoyés dans le dépôt distant.

    MISE A JOUR DU DEPOT

    Lorsque vous voulez envoyez vos modifications vers le dépôt distant, il vous suffit de saisir les commandes (en se positionnant dans le dossier sae203 avant !)

    ETAPE 3 : LE DEPOT DE PRODUCTION

    Nous appelons le dépôt de production, le dépôt Git du dossier /var/www/sae203 Comme le montre le schéma au début de cette page, il est alimenté par le dépôt distant, pas directement par votre poste de travail. Il faut donc réaliser un pull du dépôt GitHub vers le dépôt de production (et pas l'inverse)

    Considérant que vous avez déjà installé Git sur votre VPS et recopier la clé publique de votre utilisateur MMI sur GitHub (TD07), nous ne reprenons ici que les étapes de création du dépôt de production.

    INITIALISATION du dépôt de Production sur le VPS

    Connectez-vous en SSH sur votre VPS

    Vous ne devez pas avoir fait sudo -i pour continuer. l'invite de commandes doit être MMI@MMI:~$ (et surtout pas #)

    Commençons par initialiser git pour avec votre compte github

    Ensuite dans GitHUB, récupérer le lien SSH de votre dépôt sae203

    Pour terminer , placez-vous dans le dossier /var/www et clonez le dépôt distant sur votre VPS avec les commandes suivantes

    Ne faites pas de copier/coller, remplacez MMI par vos identifiants et surtout le LIEN SSH GITHUB par celui de votre dépôt

    Normalement, vous devriez retrouver tous vos fichiers dans votre dossier sae203. Vérifiez que votre site fonctionne avec l'URL: MMI.sae203.ovh

    apt update
    apt-get -y install apt-transport-https lsb-release ca-certificates curl
    cd /root
    wget https://packages.sury.org/php/apt.gpg
    apt-key add apt.gpg
    rm apt.gpg
    cd /etc/apt/sources.list.d
    nano php.list
    deb https://packages.sury.org/php/ buster main
    Sélectionnez Settings dans le menu du dépôt
    Choisissez l'Option Delete this repository et confirmer comme demandé
    Création du dépôt sae203 en privé avec les fichiers README et .gitignore
    Ajoutez des collborateurs
    Copiez le lien SSH si vous avez créez votre clé publique sur GitHub
    Création et Clonage du dépôt en local
    Vérifier le présence du fichier README et du .gitignore
    Exemple de commit et de push vers le dépôt distant
    Les fichier ont bien été poussés sur le dépot distant
    Exemple : le lien ssh de mon dépôt sae203

    ancien TD05 : MYSQL en ligne de commandes

    OBJECTIF

    Créer une base de données et un utilisateur dédié pour le projet SAE203 Importer vos tables de données dans la base.

    PREAMBULE

    La base de données devra se nommée sae203 L'utilisateur sera nommée sae203 avec le mot de passe de votre choix La base doit contenir deux tables nommées selon le choix de votre sujet. Les deux tables doivent répondre au cahier des charges données en début de SAE

    PREREQUIS

    Vous devez avoir préparé vos tables ainsi que le contenu avant de commencer ce TD et de les exporter en .csv

    Exemple de MLD + Fichier excel pour export .csv

    Voici le MLD suivant : films(film_id, film_titre, film_annee, film_resume, film_duree, film_genre, film_photo, _real_id) realisateur(real_id, real_nom, real_prenom, real_nationalite)

    Les clés primaires sont en bleues, etrangères en rouges

    Le fichier Excel de données correspond sera le suivant. Une feuille par table. Bien stocker la clé étrangère de la table principales (ici dans film : _real_id avec un underscore au début pour indiquer que c'est une clé étrangère)

    EXPORTATION DES DONNEES

    Après avoir créé vos 2 feuilles de calcul dans Excel, exportez-les au format csv en utilisant enregistrer-sous et en choisissant le format .csv (séparateur ; de préférence)

    Attention, vérifiez que votre fichier est bien encodé en UTF8 (avec sublime-text par exemple) et que tout les accents ou caractères spéciaux sont bien présents.

    CREATION DE LA BASE sur le VPS

    Comme vous avez pu le constater, vous ne pouvez pas créer de nouvelle base en utilisant phpmyadmin et votre login étudiant. Ceci pour des raisons de sécurité , mais aussi de bonne pratique : 1 Projet = 1 Base = 1 Utilisateur . En ne stockant pas toutes les données dans la même base, vous améliorez les performances et vous évitez de tout perdre en cas de crash ou de compromission d'un compte utilisateur.

    Nous devons donc créer une nouvelle base et un nouvel utilisateur en utilisant la ligne de commande et le client mysql fournit sur vos VPS.

    CONNEXION AU VPS et lancement du client MYSQL

    1 - Connectez-vous a à votre VPS avec votre compte MMI 2 - Elevez vos privilèges en root 2 - Exécutez la commande mysql (sans aucun arguments)

    Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 1758 Server version: 10.3.29-MariaDB-0+deb10u1 Debian 10

    Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

    MariaDB [(none)]>

    Vous arrivez alors sur l'invite de commandes du client : MariaDB [(none)]>

    Vous remarquerez que ce n'est pas mysql qui est installé sur vos VPS, mais bien MariaDB , une réécriture OpenSource du Mysql d'origine qui est maintenant sur Licence Oracle. Même s'il existe des différences techniques entre les deux produits, cela ne change rien dans l'utilisation que nous faisons du moteur de base de données, et encore moins en ce qui concerne les commandes SQL que vous avez apprises en cours.

    CREATION D'UNE NOUVELLE BASE et d'un UTILISATEUR

    A partir de l'invite de commandes du client , saisissez les commandes suivantes

    1 - Création de la base de données sae203 2 - Création de l'utilisateur sae203 et son mot de passe (remplacez le mot de passe !!!) 3 - Attribution de tous les privilèges (all) à l'utilisateur sae203 sur toutes les tables (.*) de la base. 4 - On quitte (quit) le client mysql pour revenir à l'invite de commandes du shell (~#)

    A chaque commande, le serveur vous répond Query OK pour vous signaler que la syntaxe est correcte et que la commande a été exécutée .

    Pourquoi 'localhost' ? Tout simplement pour limiter l'accès à l'utilisateur à partir du serveur lui-même. En précisant ce paramètre, on empêche toute tentative de connexion à la base de données à partir d'une autre machine. On ne peut donc se connecter à la base qu'à partir d'une commande ou d'une page en php (par exemple) qu'en l'exécutant depuis le VPS

    IMPORTATION DES DONNEES

    Notre base et notre utilisateur étant créés , nous allons pouvoir importer nos données.

    ETAPE 1 : Connexion à phpmyadmin

    Laissez de coté votre terminal pour l'instant, nous y reviendrons en fin de TD pour découvrir quelques autres commandes. Pour continuer, ouvrez un navigateur avec l'URL: MMI.mmi-troyes.fr/adminsql

    ETAPE 2 : CREATION DES TABLES

    Sélectionnez la base sae203 et créez une nouvelle table avec le nom des champs que vous avez déterminés dans votre MLD.

    Répétez l'opération pour la seconde table.

    ETAPE 3 : IMPORTATION DES DONNEES

    Nos tables étant maintenant créées, nous allons pouvoir les remplir en utilisant l'onglet importer

    Jeu de caractères : UTF-8

    Importer à partir du début : 1 (pour omettre la ligne contenant le nom des champs)

    Désactiver la vérification des clés étrangères

    Choisissez le format du fichier à importer : CSV par défaut

    Choisissez votre séparateur de colonnes (dans l'exemple ; ) SI les colonnes (les champs) sont entourées de " , précisez-le (ce n'est pas le cas ici)

    En CSV, toutes lignes sont terminées par auto

    Cliquez sur Exécuter pour importer les données

    Vous pouvez vérifier les données importées en cliquant sur le nom de la table dans la liste et en sélectionnant l'onglet parcourir.

    Répétez l'opération avec la seconde table pour terminer l'importation des données L'importation des données est terminée

    RETOUR DANS LE TERMINAL

    Pour continuer ce TD, nous allons maintenant voir ensemble quelques commandes nous permettant de manipuler nos données et nos tables sans passer par phpmyadmin. Ouvrez de nouveau votre terminal, reconnectez-vous en ssh si nécessaire et relancez le client mysql

    PETITE VISITE DE VOS BASES DE DONNEES:

    1. show databases; pour voir la liste des bases de données sur votre serveur

    2. use sae203; pour utiliser la base sae203 (l'invite devient MariaDB [sae203]>)

    3. show tables; liste les tables de la base active

    QUELQUES AUTRES COMMANDES UTILES:

    Attention les commandes de suppression (drop) sont irréversibles

    1. drop database NomBase; Supprime une base de données et son contenu

    2. drop table NomTable; Supprime une table et son contenu

    3. drop user 'NomUser'@'localhost'; Supprime un utilisateur

    ET POUR METTRE UN NOUVEAU MOT DE PASSE à un utilisateur si vous l'avez oublié:

    SAUVEGARDE DE LA BASE DE DONNEES

    Pour terminer ce TD, quittez le client mysql avec la commande quit Et sauvegardons notre base de données dans le dossier /var/www/sae203 en saisissant simplement la commande :

    Si vous ouvrez le fichier sae203.sql, vous pouvez constatez qu'il ne contient que des commandes SQL(DROP TABLE, CREATE TABLE, INSERT INTO etc.). Pour restaurer la base en cas de Crash ou de pertes des données, il suffira simplement de faire la commande:

    Donc, conservez bien ce fichier précieusement (sur le dépôt GitHub de la sae203 par exemple)

    TD 13: Les secrets du htaccess

    Introduction aux fichiers .htaccess

    OBJECTIF

    Protéger l'accès à votre dossier admin et par extension aux pages d'administration de votre site et de votre base de données.

    PREAMBULE

    Comme nous l'avons déjà évoqué en cours d'hébergement, les fichiers .htaccess d'Apache fournissent des méthodes de configuration au niveau de chaque dossier de votre site. Ils peuvent servir à protéger l'accès à un dossier, mais aussi à modifier le comportement de votre site en remplaçant la configuration d'Apache dans le répertoire ou se trouve le fichier .htaccess

    IMPORTANT : N'oubliez pas le . devant .htaccess. Le . est l'équivalent de l'attribut caché sur les systèmes Linux.

    PARTIE 1 - PROTECTION DU DOSSIER admin

    CONFIGURATION APACHE

    Pour commencer, nous allons déjà vérifier que votre site est configuré pour prendre en compte les fichiers .htaccess. La directive AllowOverride doit être active dans la configuration de votre site . Editez votre fichier /etc/apache2/sites-available/003-sae203.conf et ajoutez le bloc <Directory> comme ci-dessous :

    ATTENTION : Si vous avez activé SSL (HTTPS),

    il faut aussi modifier le fichier 003-sae203-le-ssl.conf

    Ensuite relancez Apache avec la commande : systemctl reload apache2

    CREATION DU FICHIER .htaccess

    Nous pouvons maintenant, créer notre fichier .htaccess dans le dossier /var/www/sae203/admin

    Remarquez que nous utilisons ici le même fichier de mots de passe que votre site de travail : htpassword.mmi L' accès à votre dossier sera donc protégé par votre identifiant MMI et le mot de passe associé

    Quelques Explications sur le contenu du fichier :

    • AuthName : C'est le message qui sera affiché pour demander l'authentification

    • AuthType Basic : Authentification Simple par Login/MotDePasse

    • AuthUserFile : Fichier des Mots de Passe

    LE FICHIER htpassword.mmi

    Ce fichier se trouve dans le dossier de votre utilisateur /home/MMI Il contient les empreintes des mots de passe utilisés pour protéger votre dossier travaux, et donc maintenant votre dossier admin. Si vous l'ouvrez, vous devriez voir quelque chose qui ressemble à ceci :

    Ne tenez pas compte des valeurs, ce ne sont que des exemples

    Ces empreintes sont générées à l'aide de la commande : htpasswd Si vous voulez modifier un mot de passe , ou ajoutez un nouvel utilisateur, utilisez la syntaxe suivante :

    htpasswd -b /home/MMI/htpassword.mmi UTILISATEUR MOTDEPASSE

    ATTENTION : Ne changez pas et ne supprimez pas le mot de passe de l'utilisateur prof !! Vous empêcheriez les enseignants accéder à vos pages et seriez pénalisés

    ACCES A VOTRE PAGE D'ADMINISTRATION :

    Votre dossier étant maintenant protégé, vous devriez pouvoir y accéder avec l'URL : MMI.sae203.ovh/admin/admin.php et vous identifier avec MMI et le mot de passe associé.

    PARTIE 2 - COMPLEMENT du HTACCESS

    LA PAGE admin.php par défaut

    Comme indiqué au début de cours, le fichier .htaccess ne sert pas qu'à la protection des dossiers. Il peut aussi servir à reconfigurer le comportement d'Apache pour le dossier dans lequel il est présent.

    Vous avez du remarquer que vous êtes obliger de préciser la page à ouvrir (admin.php). Si vous n'indiquez que le dossier /admin, vous obtiendrez immédiatement un beau Forbidden du à la ligne Options -Indexes de votre fichier de configuration. Une sécurité supplémentaire qui évite que l'on puisse voir le nom de votre page d'administration, mais une contrainte pour vous et l'écriture de vos liens vers cette page.

    Pour régler ce petit souci, il suffit d'utiliser une Directive que vous connaissez déjà : DirectoryIndex Editez votre fichier .htaccess et ajoutez la ligne suivante :

    Ouvrez de nouveau votre navigateur avec l'URL : MMI.sae203.ovh/admin (sans préciser la page) Plus de Forbidden, mais directement votre page admin.php qui est donc reconnue comme la page par défaut pour le dossier /admin.

    DESACTIVATION DES ERREURS PHP

    Un autre usage des fichiers .htaccess est la reconfiguration de php. Prenons un exemple simple : L'affichage des erreurs PHP (Display_errors) . Si il est en effet très pratique d'afficher les erreurs pendant la phase de développement, cela peut devenir rapidement gênant sur un serveur en production.

    Vous avez du voir pendant la réalisation de votre site de nombreuses erreurs qui affichaient le nom des pages, des fonctions, voir même le nom de la base de données et de l'utilisateur associé ; autant d'informations qui pourraient être exploitées pour pirater votre site et vos données.

    Nous pourrions, bien sur, remettre à Off l'option Display_errors du fichier php.ini, mais il serait désactiver pour tous les sites, même quand vous voulez débugger votre premier déploiement. Encore une fois, le fichier .htaccess peut vous aider.

    DEMONSTRATION :

    A l'aide nano, éditez directement votre page admin.php sur votre serveur et ajoutez n'importe quoi derrière le premier <?php que vous trouvez pour provoquer une erreur. Rechargez la page pour constater qu'il y a bien une erreur PHP d'affichée. Par Exemple :

    Maintenant, éditez votre fichier .htaccess et ajouter la ligne suivante :

    Rechargez la page, les erreurs ne s'affichent plus. En fonction de votre navigateur vous obtiendrez une page blanche ou une erreur 500, mais plus aucune information confidentielle n'apparaitra ce qui est le plus important.

    Pour voir les erreurs PHP, vous devez donc regarder les logs d'apache Ouvrez le fichier /var/log/apache2/error.log Vous y trouverez votre erreur PHP comme elle s'affichait avant: [client 193.50.215.251:10401] AH01071: Got error 'PHP message: PHP Parse error: syntax error, unexpected token "echo" in /var/www/sae203/admin/admin.php on line 3'

    IMPORTANT : N'oubliez de corriger l'erreur dans votre page admin.php avant de continuer et vérifiez que votre page fonctionne de nouveau

    REECRITURE DES URLs

    Un autre usage du fichier .htaccess que vous rencontrerez souvent, surtout avec les frameworks ou les CMS comme Wordpress par exemple est la réécriture des URLs ; une autre façon de cacher le nom des pages et les arguments qui pourraient être passés dans l'URL. Par Exemple, au lieu d'écrire :

    • /admin/table1_gestion.php vous pourriez utiliser simplement /admin/albums

    • /admin/table2_gestion.php deviendrait alors /admin/auteurs

    Essayons de mettre cela en place dans notre fichier .htaccess. Il faut dans un premier temps activer le module rewrite d'Apache (qui est déjà installé sur vos VPS) Puis écrire une règle de réécriture pour chacune des URLs à rediriger. Avec notre exemple, cela donnerait :

    Ajoutez ces lignes à votre fichier .htaccess en les modifiant pour les adapter à votre site. Testez avec les URLs (en les adaptant):

    • MMI.sae203.ovh/admin/albums

    • MMI.sae203.ovh/admin/auteurs

    CONCLUSION

    Les autres possibilités d'usage du fichier .htaccess sont nombreuses et un cours entier ne suffirait pas à toutes les démontrer. Vous aurez surement l'occasion à de nombreuses reprises de revoir les concepts abordés dans ce cours.

    Toutefois avant de conclure, il est important de bien comprendre que l'usage des fichiers .htaccess n'est pas l'unique façon de protéger ou de configurer l'accès à un dossier. Ce n'est d'ailleurs pas non plus la meilleure, ni en terme de sécurité, ni en terme de performances.

    L'usage de ces fichiers , s'il est en effet incontournable sur des hébergements ou vous n'avez pas accès à la configuration d'Apache, ce n'est pas le cas sur un VPS ou un serveur dédié que vous pouvez administrer. Il est bien plus intéressant et sécurisant de mettre les directives du fichier .htaccess dans le fichier de configuration du site entre les balises et du dossier que l'on souhaite gérer, surtout sur un site de production.

    IMPORTANT : Pour les besoins de la sae et pour faciliter la notation de votre travail, nous vérifierons le fichier .htaccess, donc ne modifiez rien de plus dans votre fichier de configuration. Rien ne vous empéchera d'utiliser ces concepts dans un prochain projet.

    Gardez bien aussi à l'esprit que si vous n'activez pas HTTPS sur votre site, l'identifiant et le mot de passe utilisé pour l'authentification .htaccess passent en clair dans le flux réseau. N'oubliez donc pas de faire le nécessaire pour le site de la sae203

    CM5 : Présentation de la semaine 2

    Planning de la semaine

    semaine 2

    rappel sur votre base de données:

    vous devez avoir 2 tables liées entre elles, avec . Il devra y avoir un champs avec une photo (du produit, du film, du chanteur...) pour chaque enregistrement. De plus il devra y avoir au moins 50 enregistrements sur une des tables et au moins 10 sur la deuxieme.

    vous devrez avoir au moins 6 champs (sans compter l'id) dans une de vos tables et dans l'autre au minimum 3 champs (toujours sans compter l'id).

    rappelez vous, il vous faut aussi un dossier "images" dans votre dossier racine de votre site pour y stocker toutes vos photos car dans votre base de données vous ne stockez que le nom des fichiers photos.

    rappel sur le nommage des pages:

    vous devez suivre scrupuleusement le nommage des pages de ces illustrations:

    Rappel sur l'éco-conception

    une partie de la note sera sur l'éco-conception (css mimifié, js idem, images optimisées...)

    Bilan de la premiere semaine (demo en amphi)

    vérifiez bien vos nommages de fichiers! et leur accessibilité pour un visiteur extérieur

    Finalisation du front office

    pour la partie front, il reste à mettre en place la page de réponse au formulaire (reponse_recherche.php). Cette page admet un parametre envoyé depuis le formulaire, ici dans l'exemple c'est le nom d'un auteur mais cela peut etre aussi le prix d'un album (variable $texte passé dans l'URL)

    il faut déjà s'assurer dans form_recherche.php que le champs de recherche se nomme bien texte comme demandé ci-dessus (vous pouvez bien sur lui donner un autre nom, mais il faudra être cohérent dans la page reponse_recherche.php pour bien récupérer cette variable)

    extrait de form_recherche.php:

    on vérifie tout de suite que le formulaire envois bien dans l'url notre variable en testant le formulaire:

    maintenant il reste à faire la page reponse_recherche.php. Elle ressemble completement à la page listing.php sauf que l'affichage se limite à la liste des bandes dessinées correspondant au critère saisie dans le formulaire précédent.

    il faut déjà en début de fichier (reponse_recherche.php) récupérer dans l'url la valeur du parametre 'texte' (ou un autre nom de variable si vous en avez choisi un autre):

    il faut maintenant modifier la requete SQL utilisée au départ pour afficher toutes les bandes dessinées pour restreindre le nombre d'albums affichés:

    vous pouvez tester votre recherche.

    variante: si à la place de faire une recherche sur le prix nous le faisions sur le nom de l'auteur

    il faut déjà changer un peu le texte dans le formulaire:

    la requete dans la page reponse_recherche sera bien différente. Dans un premier temps, on peut juste changer la requete comme cela:

    si l'on ne fait que ce changement, cela ne marchera pas car le champ auteur_nom est de type CHAR: il faut donc entourer le texte (donc la variable $nom) avec des guillemets (')

    il faut donc écrire:

    attention aux enchainements de " et de ' ! (bien comprendre leur sens)

    Le resultat est maintenant fonctionnel: on peut faire une recherche sur le nom de l'auteur. Mais il faut taper le nom exact!

    Amélioration de la recherche:

    Améliorons la recherche en faisant une recherche approximative avec jsute quelques lettre du nom de l'auteur (par exemple si on tape dans la zone de recherche "tib" on doit trouver les albums créés par Bautiburg et Pantino. Pour cela nous allons utiliser en SQL la notion de LIKE ()

    une requete de recherche avec LIKE peut s'ecrire:

    SELECT * FROM table WHERE champs1 LIKE '%toto%' ;

    ce qui donnerais pour nous ici:

    on peut maintenant tester notre recherche approximative.

    Il est bien sur possible de compliquer la recherche en

    Rendu fin de deuxieme semaine

    voir

    https://www.aristys-web.com/eco-conception-webwww.aristys-web.com
    https://www.aristys-web.com/eco-conception-web
    C'est quoi l'éco-conception ? La réponse complète est ici.altermaker.fr
    https://altermaker.fr/eco-conception/
    Vers la sobriété numérique - François Zaninotto - Forum PHP 2021 / AFUP
    Éco-conception web : Coder un site écologique 🌱 – Alex so yesAlex so yes
    https://alexsoyes.com/eco-conception-web/
    Guide d'écoconception de services numériquesDesigners Éthiques
    Les bonnes pratiques pour éco-concevoir un site web - UsewebUseweb
    Green ITGreen IT
    git config --global user.name "NOM GITHUB"
    git config --global user.email "VOTRE ADRESSE MAIL de GITHUB"
    git add .
    git commit -m "Debut de la SAE203"
    git push origin main
    git add .
    git commit -m "ma modification"
    git push
    git config --global user.name NOM_GITHUB
    git config --global user.email EMAIL_UTILISEE_POUR_GITHUB
    cd /var/www
    sudo rm -Rf sae203    (si vous ne l'avez pas déjà supprimé)
    sudo mkdir sae203     (pour recréer le dossier vide, sans dépôt .git)
    sudo chown -R MMI:MMI sae203
    git clone LIEN_SSH_DU_DEPOT_GITHUB_SAE203 sae203
    cd sae203
    ls -l                  (pour vérifier que tout est là)
    describe NomTable; pour voir la structure d'une table
  • select * from NomTable ; pour voir les enregistrements d'une table

  • Deux tables avec une relation 1-N uniquement
    Feuille réalisateur
    Feuille filmsVo
    exemple d'export csv avec le ; comme séparateur
    Identifiez-vous avec le compte sae203 et le mot de passe que vous avez choisi.
    La base sae203 est bien crée et accessible par notre utilisateur
    Ici, on créait une table avec 8 champs (id compris)
    Déterminez bien le nombre et le type de vos champs avant l'importation Attention à bien déclarer le champ ID en clé primaire (PRIMARY) et à le mettre en incrémentation automatique (cochez la case A.I )
    Structure de la table films
    Choisissez le fichier .csv à importer et renseignez correctement les différentes options
    L'importation à réussie
    Contenu de la table film après l'import
    Require valid-user
    : Oblige l'utilisateur à s'authentifier pour accéder au dossier protégé
    Authentification htaccess
    doc
    page des rendus de fin de deuxieme semaine
    formulaire avec la valeur 45 de saisie
    on vois bien ici que la valeur '45' saisie dans le formulaire apparait bien dans l'url dans la variable 'texte'
    https://eco-conception.designersethiques.org/guide/fr/
    https://www.useweb.fr/blog/post/eco-conception-web-bonnes-pratiques/
    https://www.greenit.fr/
    Logo
    Comment sauver la planète en ne faisant rien - Hélène MAITRE-MARCHOIS - Forum PHP 2021 / AFUP
    create database sae203;
    create user 'sae203'@'localhost' identified by 'MotDePasseFortDeVotreChoix';
    grant all on sae203.* to 'sae203'@'localhost';
    quit
    UPDATE mysql.user SET password=PASSWORD("nouveau_mdp") where User="NomUser"; 
    flush privileges;
    mysqldump sae203 > /var/www/sae203/sae203.sql
    mysql sae203 < /var/www/sae203/sae203.sql
    <VirtualHost *:80>
    	<FilesMatch .php$>
       	SetHandler "proxy:unix:/var/run/php/php8.1-fpm.sock|fcgi://localhost"
       	</FilesMatch>
    
    	ServerName MMI.sae203.ovh
    	ServerAdmin [email protected]
    	DocumentRoot /var/www/sae203
    	DirectoryIndex index.php
    	
    	<Directory /var/www/sae203/admin>
    	Options -Indexes
       	AllowOverride All
    	</Directory>
    	
    	ErrorLog ${APACHE_LOG_DIR}/error.log
       	CustomLog ${APACHE_LOG_DIR}/access.log combined
     </VirtualHost>
    AuthName "Protection du CRUD sae203"
    AuthType Basic
    AuthUserFile "/home/MMI/htpassword.mmi"
    Require valid-user
    prof:$apd12$xkEugZrD$QLS9dnYE2IX7qXEgYvnKT0
    mmi21x43:$apd12$m1uR6Zeu$EDVIG6suKB0zZRuBS6R.18
    DirectoryIndex admin.php
    Parse error: syntax error, unexpected identifier "kkkk", expecting "," or ";" in /var/www/sae203/admin/admin.php on line 3
    SetEnv PHP_VALUE "display_errors = Off"
    RewriteEngine On
    RewriteRule albums /var/www/sae203/admin/table1_gestion.php
    RewriteRule auteurs /var/www/sae203/admin/table2_gestion.php
    ...
    recherche sur le prix (prix max):
    ...
     <form action="reponse_recherche.php" method="get">
    <input type="text" name="texte">
     <button type="submit" >Afficher les albums correspondants</button>
     </form>
     ...
    ...
    $prixmax = $_GET['texte'];
    ...
    ...
    <?php
    $prixmax = $_GET['texte'];
    $mabd = new PDO('mysql:host=localhost;dbname=sae203;charset=UTF8;', 'root', 'root');
    $mabd->query('SET NAMES utf8;');
    $req = "SELECT * FROM bandes_dessinees 
                INNER JOIN auteurs 
                ON bandes_dessinees._auteur_id = auteurs.auteur_id
                WHERE bd_prix < ". $prixmax ;
    $resultat = $mabd->query($req);
    foreach ($resultat as $value) {
        echo '<img class="vignette" src="images/'.$value['bd_photo'].'">';
        echo '<h3>'.$value['bd_titre'] . '</h3>';
        echo '<p>tarif: ' . $value['bd_prix'] . ' euro </p>';
        echo '<p class="page">' . $value['bd_nb_pages'] . ' pages </p>';
        echo '<p>Résumé: ' . $value['bd_resume'] . ' </p>';
        echo '<p class="auteur"> de ' . $value['auteur_nom'] . '</p>';
        echo '<hr>';
    }
    ?>
    ...
    ...
    recherche sur le nom de l'auteur:
    ...
     <form action="reponse_recherche.php" method="get">
    <input type="text" name="texte">
     <button type="submit" >Afficher les albums correspondants</button>
     </form>
     ...
    ...
    <?php
    $nom = $_GET['texte'];
    $mabd = new PDO('mysql:host=localhost;dbname=sae203;charset=UTF8;', 'root', 'root');
    $mabd->query('SET NAMES utf8;');
    $req = "SELECT * FROM bandes_dessinees 
                INNER JOIN auteurs 
                ON bandes_dessinees._auteur_id = auteurs.auteur_id
                WHERE auteur_nom = ". $nom ;
    $resultat = $mabd->query($req);
    ...
    ...
    $req = "SELECT * FROM bandes_dessinees 
                INNER JOIN auteurs 
                ON bandes_dessinees._auteur_id = auteurs.auteur_id
                WHERE auteur_nom = '" . $nom . "'" ;
    ...
    ...
    $req = "SELECT * FROM bandes_dessinees 
                INNER JOIN auteurs 
                ON bandes_dessinees._auteur_id = auteurs.auteur_id
                WHERE auteur_nom LIKE '%" . $nom . "%'" ;
    ...

    TD 11 et 12 : librairie CRUD en PHP (2/2)

    1. Suppression d'un album :

    • Pour effacer un album de la table, on va créer la page table1_delete.php qui va recevoir en méthode GET l'id de l'album à effacer dans la table grâce au lien d'effacement dans table1_gestion.php (fonction afficherListe() dans lib_crud.inc.php) :

    • La page table1_delete.php va contenir le code suivant :

    • Dans cette page, on récupère le numéro de l'album, on se connecte à la base de données, on appelle la fonction effacerBD()en lui passant deux paramètres : l'identifiant de connexion à la base de données ($co) et le numéro de l'album à effacer ($id).

    • Il faut donc ajouter le code de la fonction effacerBD() dans lib_crud.inc.php :

    • Dans le code précédent, il faut évidemment remplacer ??? par la requête d'effacement d'un album dans la table bandes_dessinees. Attention, avec une requête de type UPDATEou DELETE, il faut absolument mettre une clause WHERE dans la requête ! Sinon, on efface ou on modifie toutes les lignes de la table.

    • Dans l'exemple ci-dessous, j'avais ajouté l'album de titre "Jérôme", il apparaît bien dans la liste, j'appuie sur supprimer et il a effectivement disparu de la liste des albums.

    2. Modification des données :

    • Pour modifier les données, on va utiliser le même formulaire que pour la création mais il faut le pré-remplir avec la valeur actuelle des champs.

    • Le code incomplet de table1_update_form.php est donné ici, il manque le pré-remplissage des champs prix et nombre de pages :

    3. Fonction getBD() pour récupérer les informations d'un album :

    • Pour pré-remplir les champs, on va créer une fonction getBD() dans lib_crud.inc.php qui va prendre en paramètres la connexion à la base de données et l'id de l'album à modifier.

    • On va récupérer cet id et on va remplir une variable $album avec les informations pour cet album.

    • Ajoutez la fonction getBD()

    • Il manque la sélection du "bon" auteur pour notre album. On va donc créer une fonction afficherAuteursOptionsSelectionne() qui va générer, comme la fonction afficherAuteursOptions() les balises <option> du <select> mais cette fonction va en plus ajouter l'attribut selected="selected" dans la balise pour pré-sélectionner l'auteur de l'album dans la liste.

    • Le code de la fonction afficherAuteursOptionsSelectionne est donné ici, on remarque que l'on connaît le "bon" auteur car c'est le paramètre

    • Testez votre code et vérifiez que le "bon" auteur est pré-sélectionné dans la liste.

    4. Modification des données :

    • On donne le code de la page table1_update_valide.php :

    • Comme pour l'ajout, la page va récupérer les informations du formulaire de modification y compris la photo. On va ensuite appeler la fonction modifierBD() qui doit être créée dans lib_crud.inc.php et qui va réaliser la requête de modification des données dans la table.

    • Le code de la fonction modifierBD()est donné ici :

    • Dans le code ci-dessus, modifiez la requête pour réaliser la modification de l'album dans la table.

    • Remarque : N'oubliez pas que les champs de type chaînes de caractères doivent être entourés de " dans les requêtes !

    • Le résultat en images devrait ressembler à ceci :

    5. À la fin :

    • Nettoyez votre code en enlevant tous les affichages inutiles : les requêtes et les var_dump(). Vous pouvez les mettre en commentaires pour ne plus les exécuter.

    • N'oubliez pas de créer le CRUD complet pour la deuxième table (pour mon exemple, c'est la table auteurs mais pour vous cela dépend de ce que vous avez en deuxième table). Les deux CRUDs : pour la table 1 et la table 2 seront évalués pour votre note finale en SAE203.

    • Félicitations, vous avez réussi à créer un code CRUD en PHP pour la table 1, il vous faut faire la même chose (en plus simple car la table a normalement moins de champs) pour la table 2.

    dans
    lib_crud.inc.php
    , modifiez le code pour créer la "bonne" requête à la place de
    ???
    :
    $idAuteur
    qui le contient :
  • Si vous avez compris ce CRUD, vous saurez TOUS les faire, c'est toujours la même technique, ce qui change, c'est le nom de la table et le nom des champs.

  • Bon courage, portez-vous bien ! :)

  • Logo
    ...
    echo '<td><a href="table1_delete.php?num='
    	.$value['bd_id'].'">Supprimer</a></td>'."\n";
    ...
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>SAE203</title>
    	</head>
    	<body style="font-family:sans-serif;">
    	    <a href="../index.php">Accueil</a> | <a href="table1_gestion.php">Gestion</a>
    	    <hr />
    	    <h1>Supprimer une bande dessinée</h1>
    	    <hr />
    	    <?php
    	        require '../lib_crud.inc.php';
    	
    	        $id=$_GET['num'];
    	
    	        $co=connexionBD();
    	        effacerBD($co, $id);
    	        deconnexionBD($co);
    	    ?>
    	</body>
    </html>
    ...
        // fonction d'effacement d'une BD
        function effacerBD($mabd, $id) {
            $req = '???';
            echo '<p>'.$req.'</p>'."\n";
            try{
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            if ($resultat->rowCount()==1) {
                echo '<p>La bande dessinée '.$id.' a été supprimée du catalogue.</p>'."\n";
            } else {
                echo '<p>Erreur lors de la suppression.</p>'."\n";
                die();
            }
        }
    <!DOCTYPE html>
    <html>
    <head>
    	<title>SAE203</title>
    </head>
    <body style="font-family:sans-serif;">
        <a href="../index.php">Accueil</a> | <a href="table1_gestion.php">Gestion</a>
    	<hr>
        <h1>Modifier une bande dessinée</h1>
        <hr />
        <?php
            require '../lib_crud.inc.php';
    
            $id=$_GET['num'];
            $co=connexionBD();
            $album=getBD($co, $id);
            var_dump($album);
            deconnexionBD($co);
        ?>
        <form action="table1_update_valide.php" method="POST" enctype="multipart/form-data" >
            <input type="hidden" name="num" value="<?= $id; ?>" />
            Titre : <input type="text" name="titre" value="<?php echo $album['bd_titre']; ?>" required/><br />
            Année : <input type="number" name="annee" min="-5000" max="3000" value="<?= $album['bd_annee']; ?>" required /><br />
            Nb pages : <input type="number" name="pages" value="" required /><br />
            Prix : <input type="number" name="prix" min="0.00" max="10000.00" step="0.01" value="" required /><br />
            Résumé : <textarea name="resume" required><?= $album['bd_resume']; ?></textarea><br />
            Photo : <input type="file" name="photo" required /><br />
            Auteur : <select name="auteur" required>
            <?php
                $co=connexionBD();
                //afficherAuteursOptionsSelectionne($co, $album['_auteur_id']);
                deconnexionBD($co);
            ?>
            </select><br />
            <input type="submit" value="Modifier" />
        </form>
    </body>
    </html>
    ...
        // fonction de récupération des informations d'une BD
        function getBD($mabd, $idAlbum) {
            $req = '???='.$idAlbum;
            echo '<p>GetBD() : '.$req.'</p>'."\n";
            try {
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            // la fonction retourne le tableau associatif 
            // contenant les champs et leurs valeurs
            return $resultat->fetch();
        }
    ...
    	// afficher le "bon" auteur parmi les auteurs (prénom et nom)
       // dans les balises "<option>"
    	function afficherAuteursOptionsSelectionne($mabd, $idAuteur) {
            $req = "SELECT * FROM auteurs";
            try {
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            foreach ($resultat as $value) {
                echo '<option value="'.$value['auteur_id'].'"';
                if ($value['auteur_id']==???) {
                    echo ' selected="selected"';
                }
                echo '>';
                echo $value['auteur_prenom'].' '.$value['auteur_nom'];
                echo '</option>'."\n";
            }
        }
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>SAE203</title>
    	</head>
    	<body style="font-family:sans-serif;">
    	    <a href="../index.php">Accueil</a> | <a href="table1_gestion.php">Gestion</a>
    	    <hr />
    	    <h1>Modifier une bande dessinée</h1>
    	    <hr />
    	    <?php
    	        require '../lib_crud.inc.php';
    	
    	        $id=$_POST['num'];
    	        $titre=$_POST['titre'];
    	        $prix=$_POST['prix'];
    	        $annee=$_POST['annee'];
    	        $nbPages=$_POST['pages'];
    	        $resume=trim($_POST['resume']);
    	        $auteur=$_POST['auteur'];
    	        var_dump($_POST);
    	        var_dump($_FILES);
    	
    	        $imageType=$_FILES["photo"]["type"];
    	        if ( ($imageType != "image/png") &&
    	            ($imageType != "image/jpg") &&
    	            ($imageType != "image/jpeg") ) {
    	                echo '<p>Désolé, le type d\'image n\'est pas reconnu ! Seuls les formats PNG et JPEG sont autorisés.</p>'."\n";
    	                die();
    	        }
    	
    	        $nouvelleImage = date("Y_m_d_H_i_s")."---".$_FILES["photo"]["name"];
    	
    	        if(is_uploaded_file($_FILES["photo"]["tmp_name"])) {
    	            if(!move_uploaded_file($_FILES["photo"]["tmp_name"], "../images/uploads/".$nouvelleImage)) {
    	                echo '<p>Problème avec la sauvegarde de l\'image, désolé...</p>'."\n";
    	                die();
    	            }
    	        } else {
    	            echo '<p>Problème : image non chargée...</p>'."\n";
    	            die();
    	        }
    	
    	        $co=connexionBD();
    	        modifierBD($co, $id, $titre, $annee, $prix, $nouvelleImage, $nbPages, $resume, $auteur);
    	        deconnexionBD($co);
    	    ?>
    	</body>
    </html>
    ...
    	// fonction de modification d'une BD dans la table bande_dessinees
        function modifierBD($mabd, $id, $titre, $annee, $prix, $nouvelleImage, $nbPages, $resume, $auteur)
        {
            $req = 'UPDATE bandes_dessinees 
                    SET 
                        ??? 
                    WHERE bd_id='.$id;
            echo '<p>' . $req . '</p>' . "\n";
            try {
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            if ($resultat->rowCount() == 1) {
                echo '<p>La bande dessinée ' . $titre . ' a été modifiée.</p>' . "\n";
            } else {
                echo '<p>Erreur lors de la modification.</p>' . "\n";
                die();
            }
        }
    Logo

    TD 09 et 10 : librairie CRUD en PHP (1/2)

    Introduction

    • Dans ces séances consacrées au CRUD (Create Read Update Delete), on va créer une librairie de fonctions PHP. Ces fonctions vont nous permettre d'effectuer les opérations sur les données de la base de données. La librairie de fonctions sera à insérer dans toutes les pages de notre projet SAE203 à l'aide de l'instruction require.

    • Pour se connecter à la base de données, on va utiliser le constructeur de la classe PDO, la fonction PDO() qui prend trois paramètres : une chaîne de caractères contenant les données de connexion (adresse IP de l'hôte, port, nom de la (data)base et charset utilisé), le login et le mot de passe utilisateur.

    • Remarque sur la sécurité :

    Tous les fichiers que nous allons créer seront situés dans un sous-dossier de votre site nommé admin/. Ce dossier sera protégé par un fichier .htaccessdans lequel on demandera un login et un mot de passe pour accéder à cette partie privée de votre site. En effet, lorsque votre site sera en ligne, seul un administrateur du site doit avoir le droit de modifier les données de vos tables. Cette partie "sécurité" sera traitée dans une autre séance de la SAE203.

    • Remarque sur le dossier des images :

    Toutes les images des albums seront dans la suite de cete séance dans un dossier "images/uploads/" dans notre dossier de base de la SAE203. Ce dossier devra, lorsqu'il sera mis en ligne, pouvoir enregistrer les images téléchargées par les utilisateurs. Il faut donc mettre les DROITS D'ÉCRITURE sur ce dossier sur votre VPS et dans votre dossier de travail (si vous êtes en local sous WAMP/MAMP/LAMP). ATTENTION, les droits d'écriture sont à mettre sur le dossier "uploads" seulement, pas sur le dossier "images", ce qui rendrait modifiables TOUTES les images de votre site. Ici, on ne souhaite que pouvoir écrire les images des albums.

    • Remarque sur le rendu final :

    Dans ces deux séances, nous ne traiterons QUE la table 1 de votre SAE203, ce sera à VOUS de FAIRE la même chose pour la gestion de la table 2 dans le rendu final ! Votre code écrit PHP pour la gestion de la table 2 sera aussi évalué dans la note finale !

    1. Création de secretxyz123.inc.php :

    • Afin de cacher les informations login et mot de passe dans votre code PHP, on va les mettre dans un fichier spécial qui va définir des chaînes à remplacer par d'autres grâce à la fonction define().

    • Dans le dossier principal de votre SAE203, créez un fichier secretxyz123.inc.php.

    • Dans ce fichier, ajoutez les définitions de votre login et de votre mot de passe utilisateur pour la connexion à votre base de données MySQL :

    2. Création de la librairie lib_crud.inc.php :

    • Dans le dossier principal de votre SAE203, créez un fichier lib_crud.inc.php.

    • Dans ce fichier, ajoutez les fonctions de connexion et de déconnexion à la base de données MySQL :

    3. Test de la librairie lib_crud.inc.php :

    • Afin de tester le fonctionnement de la librairie lib_crud.inc.php, modifiez votre code de la page listing.php pour charger la librairie de fonctions et remplacez votre code de connexion et de déconnexion par les fonctions fournies connexionBD() et deconnexionBD().

    • Puis, placez votre code qui réalise l'affichage dans une fonction afficherCatalogue($mabd) dans lib_crud.inc.php.

    • Votre code simplifié dans listing.php devrait ressembler à quelque chose comme ça (c'est beaucoup plus court, non ?) :

    • Le résultat affiché devrait ressembler à quelque chose comme ça (évidemment, cet affichage dépend de vos données et de vos styles CSS) :

    4. Création de la page admin.php :

    • Dans votre dossier de travail "sae203", vous devez créer un dossier "admin" (qui sera protégé par un .htaccess plus tard).

    • Dans le menu général, le lien "Admin." va pointer vers "admin/admin.php" (la page d'administration des données de votre site).

    • Dans le dossier admin, on va créer un fichier admin.php dans lequel on va mettre le code :

    • Dans le dossier admin, on va créer un fichier table1_gestion.php dans lequel on va mettre le code :

    • Il faut donc créer une fonction afficherListe() dans lib_crud.inc.php qui va afficher une table HTML contenant les informations sur les bandes dessinées :

    • Attention, dans le code ci-dessus, ... n'est pas une instruction PHP valide, c'est juste pour indiquer que ce code est dans . De plus, il faut changer les ??? pour afficher le numéro de la bande dessinée afin de le passer à la page de modification et à la page de suppression.

    • Testez votre code, la page obtenue decrait ressembler à ceci (selon votre CSS évidemment) :

    5. Ajout d'une bande dessinée (liste des auteurs) :

    • Pour ajouter un bande dessinée à notre catalogue (pour insérer les données dans MySQL), on va créer un fichier table1_new_form.php dans lequel on va insérer le code suivant :

    • Attention, le formulaire est OBLIGATOIREMENT en méthode POST car on va passer une image à notre site, donc on va utiliser un champ de type file. On précise de plus l'encodage de notre image : multipart/form-data.

    • Pour afficher la liste des auteurs, il faut ajouter dans notre librairie lib_crud.inc.php le code qui va permettre de générer la liste des prénoms et noms des auteurs sous la forme de balises <option> dans une balise HTML <select>.

    • Testez votre code, vous devriez avoir quelque chose comme ceci (la liste déroulante contient bien TOUS les prénoms et noms des auteurs) :

    6. Ajout d'une bande dessinée (validation) :

    • On va maintenant valider les changements dans la table bandes_dessinees.

    • On va créer le fichier table1_new_valide.php qui va récupérer les informations de la nouvelle BD (avec l'image à télécharger) et qui va insérer les informations dans la table.

    • Le code de la page table1_new_valide.phpest donné ici :

    • Dans ce code, on récupère les informations passées par le formulaire de la page précédente, on vérifie ensuite le type de l'image, on la récupère sur le serveur (VPS ou local) dans le dossier "images/uploads/" (en la renommant en ajoutant la date) et on appelle la fonction ajouterBD() en lui passant les informations nécessaires pour insérer les données dans la table bandes_dessinees.

    • Le code (incomplet) de la fonction ajouterBD() à mettre dans lib_crud.inc.phpest :

    • Il faut remplacer les ??? par le code PHP qui va générer le "INSERT INTO" de façon correcte.

    • Testez votre code jusqu'à avoir la nouvelle bande dessinée qui apparait dans la liste des albums.

    7. Un peu de nettoyage :

    • Quand tout fonctionne, vous pouvez "nettoyer" votre code en enlevant TOUS les affichages qui ne servent plus : les requêtes, les print_r(), les var_dump()... Pour cela, mettez-les en commentaires dans tous les fichiers concernés :

    TD08 : Les Clés du DevOps

    Authentification SSH - Utilisation de SSH avec GIT

    OBJECTIF

    Comprendre le principe des clés SSH. Les utiliser pour se connecter en SSH sans saisir de mot de passe Les utiliser pour s'authentifier avec GIT et automatiser le déploiement de la sae203

    Le début du code de afficherCatalogue($mabd) devrait ressembler à ceci :

    Le code de la fonction afficherAuteursOptions($co) doit ressembler à ceci :

    <?php
      // FICHIER DE DÉFINITION de chaînes de remplacement
    	
      // Mettez VOTRE LOGIN ci-dessous (2ème paramètre de define)
      define('LUTILISATEUR', 'mmijlandre');
      // Mettez VOTRE MOT DE PASSE ci-dessous (2ème paramètre de define)
      define('LEMOTDEPASSE', 'toto@1234#');
    <?php
      // LIBRAIRIE "lib_crud.inc.php"
      // 2022 - BUT MMI - IUT Troyes - URCA
      // JL
    
      // insertion des dépendances
      require 'secretxyz123.inc.php';
    
      // connexion à la base de données
      function connexionBD()
      {
        // on initialise la variable de connexion à null
        $mabd = null;
        try {
          // on essaie de se connecter
          // le port et le dbname ci-dessous sont À ADAPTER à vos données
          $mabd = new PDO('mysql:host=127.0.0.1;port=3306;
                    dbname=mmijlandre;charset=UTF8;', 
                    LUTILISATEUR, LEMOTDEPASSE);
          // on passe le codage en utf-8
          $mabd->query('SET NAMES utf8;');
        } catch (PDOException $e) {
          // s'il y a une erreur, on l'affiche
          echo '<p>Erreur : ' . $e->getMessage() . '</p>';
          die();
        }
        // on retourne la variable de connexion
        return $mabd;
      }
    
      // déconnexion de la base de données
      function deconnexionBD(&$mabd) {
        // on se déconnexte en mettant la variable de connexion à null 
        $mabd=null;
      }
        // affichage du catalogue des albums
        function afficherCatalogue($mabd) {
            $req = "SELECT * FROM bandes_dessinees 
                    INNER JOIN auteurs 
                    ON bandes_dessinees._auteur_id = auteurs.auteur_id";
            try {
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            // ICI VOTRE CODE POUR AFFICHER LES ALBUMS
            // ...
            // ...
        }
    ...
    	<body style="font-family:sans-serif;">
    		<a href="index.php">Accueil</a> | <a href="listing.php">Catalogue</a> | <a href="admin/admin.php">Admin.</a>
    		<hr />
    		<h1>Nos albums</h1>
    		<hr />
    		<?php
    		    require 'lib_crud.inc.php';
    		    $co=connexionBD();
    		    afficherCatalogue($co);
    		    deconnexionBD($co);
    		?>
    	</body>
    </html>
    <!DOCTYPE html>
        <html>
        <head>
            <title>SAE203</title>
        </head>
        <body style="font-family:sans-serif;">
            <a href="../index.php">Accueil</a>
            <hr />
            <h1>Gestion des données</h1>
            <ul>
                <li>Gestion des <a href="table1_gestion.php">albums</a></li>
                <li>Gestion des <a href="table2_gestion.php">auteurs</a></li>
            </ul>
        </body>
    </html>
    <!DOCTYPE html>
    <html>
        <head>
            <title>SAE203</title>
        </head>
        <body>
            <a href="../index.php">Accueil</a>
            <hr />
            <h1>Gestion des données</h1>
    
            <p><a href="table1_new_form.php">Ajouter une bande dessinée</a></p>
            <?php
                require '../lib_crud.inc.php';
                $co=connexionBD();
                afficherListe($co);
                deconnexionBD($co);
            ?>
        </body>
    </html>
    ...
        // affichage de la liste des albums pour la gestion
        function afficherListe($mabd) {
            $req = "SELECT * FROM bandes_dessinees 
                    INNER JOIN auteurs 
                    ON bandes_dessinees._auteur_id = auteurs.auteur_id";
            try {
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            echo '<table>'."\n";
            echo '<thead><tr><th>Photo</th><th>Titre</th><th>Prix (&euro;)</th><th>Pages</th><th>Auteur</th><th>Modifier</th><th>Supprimer</th></tr></thead>'."\n";
            echo '<tbody>'."\n";
            foreach ($resultat as $value) {
                echo '<tr>'."\n";
                echo '<td><img class="photo" src="../images/uploads/'.$value['bd_photo'].'" alt="image_'.$value['bd_id'].'" /></td>'."\n";
                echo '<td>'.$value['bd_titre'].'</td>'."\n";
                echo '<td>'.$value['bd_prix'].'</td>'."\n";
                echo '<td>'.$value['bd_nb_pages'].'</td>'."\n";
                echo '<td>'.$value['auteur_prenom'].' '.$value['auteur_nom'].'</td>'."\n";
                echo '<td><a href="table1_update_form.php?num='.$value['???'].'">Modifier</a></td>'."\n";
                echo '<td><a href="table1_delete.php?num='.$value['???'].'">Supprimer</a></td>'."\n";
                echo '</tr>'."\n";
            }
            echo '</tbody>'."\n";
            echo '</table>'."\n";
        }
    ...
    <!DOCTYPE html>
    <html>
    	<head>
    	    <title>SAE203</title>
    	</head>
    	<body style="font-family:sans-serif;">
    	    <a href="../index.php">Accueil</a> | <a href="admin.php">Gestion</a>
    	    <hr />
    	    <h1>Ajouter une bande dessinée</h1>
    	    <hr />
    	    <form action="table1_new_valide.php" method="POST" enctype="multipart/form-data">
    	        Titre : <input type="text" name="titre" required /><br />
    	        Année : <input type="number" name="annee" min="-5000" max="3000" required /><br />
    	        Nb pages : <input type="number" name="pages" required /><br />
    	        Prix : <input type="number" name="prix" min="0.00" max="10000.00" step="0.01" required /><br />
    	        Résumé : <textarea name="resume" required></textarea><br />
    	        Photo : <input type="file" name="photo" required /><br />
    	        Auteur : <select name="auteur" required>
    	        <?php
    	            require '../lib_crud.inc.php';
    	            $co=connexionBD();
    	            afficherAuteursOptions($co);
    	            deconnexionBD($co);
    	        ?>
    	        </select><br />
    	        <input type="submit" value="Ajouter" />
    	    </form>
    	</body>
    </html>
        // afficher les auteurs (prénom et nom) dans des champs "option"
        function afficherAuteursOptions($mabd) {
        	// on sélectionne tous les auteurs de la table auteurs
            $req = "SELECT * FROM auteurs";
            try {
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            // pour chaque auteur, on met son id, son prénom et son nom 
            // dans une balise <option>
            foreach ($resultat as $value) {
                echo '<option value="'.???.'">'; // id de l'auteur
                echo ???.' '.???; // prénom espace nom
                echo '</option>'."\n";
            }
        }
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>SAE203</title>
    	</head>
    	<body style="font-family:sans-serif;">
    	    <a href="../index.php">Accueil</a> | <a href="admin.php">Gestion</a>
    	    <hr />
    	    <h1>Ajouter une bande dessinée</h1>
    	    <hr />
    	    <?php
    	        require '../lib_crud.inc.php';
    	
    	        $titre=$_POST['titre'];
    	        $prix=$_POST['prix'];
    	        $annee=$_POST['annee'];
    	        $nbPages=$_POST['pages'];
    	        $resume=trim($_POST['resume']);
    	        $auteur=$_POST['auteur'];
    	        var_dump($_POST);
    	        var_dump($_FILES);
    	
    	        $imageType=$_FILES["photo"]["type"];
    	        if ( ($imageType != "image/png") &&
    	            ($imageType != "image/jpg") &&
    	            ($imageType != "image/jpeg") ) {
    	                echo '<p>Désolé, le type d\'image n\'est pas reconnu !';
    	                echo 'Seuls les formats PNG et JPEG sont autorisés.</p>'."\n";
    	                die();
    	        }
    	
    	        $nouvelleImage = date("Y_m_d_H_i_s")."---".$_FILES["photo"]["name"];
    	
    	        if(is_uploaded_file($_FILES["photo"]["tmp_name"])) {
    	            if(!move_uploaded_file($_FILES["photo"]["tmp_name"], 
    	            "../images/uploads/".$nouvelleImage)) {
    	                echo '<p>Problème avec la sauvegarde de l\'image, désolé...</p>'."\n";
    	                die();
    	            }
    	        } else {
    	            echo '<p>Problème : image non chargée...</p>'."\n";
    	            die();
    	        }
    	
    	        $co=connexionBD();
    	        ajouterBD($co, $titre, $annee, $prix, 
    	        		$nouvelleImage, $nbPages, $resume, $auteur);
    	        deconnexionBD($co);
    	    ?>
    	</body>
    </html>
        // fonction d'ajout d'une BD dans la table bande_dessinees
        function ajouterBD($mabd, $titre, $annee, $prix, $nouvelleImage, $nbPages, $resume, $auteur)
        {
            $req = 'INSERT INTO bandes_dessinees (bd_titre, bd_annee, bd_prix, bd_photo, bd_nb_pages, bd_resume, _auteur_id) VALUES (???)';
            echo '<p>' . $req . '</p>' . "\n";
            try {
                $resultat = $mabd->query($req);
            } catch (PDOException $e) {
                // s'il y a une erreur, on l'affiche
                echo '<p>Erreur : ' . $e->getMessage() . '</p>';
                die();
            }
            if ($resultat->rowCount() == 1) {
                echo '<p>La bande dessinée ' . $titre . ' a été ajoutée au catalogue.</p>' . "\n";
            } else {
                echo '<p>Erreur lors de l\'ajout.</p>' . "\n";
                die();
            }
        }
    //echo '<p>'.$req.'</p>."\n";
    
    //var_dump($_POST);
    
    //var_dump($_FILES);
    PREAMBULE

    Vous utilisez régulièrement la commande ssh pour vous connecter à votre VPS, ou aux machines de la salle H205 pendant les TPs d'hébergement. Mais ssh ce n'est pas qu'une commande, c'est aussi (et surtout) un protocole qui permet de communiquer entre deux machines de façon sécurisée. Comme vous allez le voir dans ce TD, il permet bien sur de chiffrer (crypter) les données transférées, mais garantit d'abord un niveau d'authentification élevé entre les protagonistes de la session de communication. C'est ce dernier point qui sera développé dans ce TD.

    LE PROTOCOLE SSH

    Le protocole SSH (Secure Shell) a été inventé en 1995 par le Finlandais Tatu Ylönen . Si à l'origine il a été écrit pour renforcer la sécurité des sessions à distance, il permet dans sa version 2 (1997) de faire aussi du transfert de fichier (SFTP, SCP) . Comme tout protocole applicatif, il s'appuie sur une protocole de transport (TCP) et possède un numéro de port par défaut : 22. Il est important de ne pas le confondre avec le protocole SSL que nous verrons plus tard, qui lui vient se positionner entre la couche transport et la couche applicative , renforçant ainsi la sécurité sur des protocoles existants comme HTTP ou FTP pour créer les connexions HTTPS et FTPS.

    AUTHENTIFICATION

    Toute communication sécurisée commence par une phase d'authentification. Que ce soit pour assurer à l'application cliente que le serveur en face de lui est bien le bon, ou pour assurer au serveur que la personne voulant se connecter est bien celle qu'elle prétend être.

    Cette phase consiste donc à contrôler de façon fiable l'identité d'une partie en vue d'un échange de données. Cette identité peut être prouvée de plusieurs manières : Soit par un élément que vous seul connaissez (un mot de passe), soit un élément qui vous est propre (une empreinte digitale) ou dans le cas qui nous intéresse par un élément que vous possédez (une clé ).

    CHIFFREMENT SYMETRIQUE

    La cryptographie moderne utilise des algorithmes de chiffrement associés à des clés.

    Chiffrement Symétrique : Une seule clé sert à chiffrer et à déchiffrer

    Jusqu'au début des années 70, on utilisait la même clé pour chiffrer et déchiffrer les données, ce qui pose de problèmes en terme de sécurité lors d'une communication

    1. Comment échanger la clé entre l'émetteur et le récepteur des données ?

    2. Comment savoir qui est à l'origine du message si les deux parties utilisent la même clé ?

    3. Il faut autant de clés que d'éléments dans le réseau de communication pour garantir un minimum de confidentialité.

    On parle alors de chiffrement symétrique, on ne garantie dans ce cas que la confidentialité des données . Pas d'authentification, ni de garantie de l'intégrité des données.

    CRYPTOGRAPHIE A CLE PUBLIQUE

    En 1976, Whitfield Diffie et Martin Hellman publie une méthode d'échange des données asymétrique utilisant deux clés : Une privée, Une publique. C'est ce qu'on nomme aujourd'hui la cryptographie à clé publique. Cette méthode sera reprise par de nombreux algorithmes comme RSA qui est surement le plus connu d'entre eux.

    Chiffrement Asymétrique, on chiffre avec la clé publique, on déchiffre avec la clé privée

    On voit donc dans le schéma ci dessus, que n'importe qui peut chiffrer les données, mais qu'une seule personne (celui qui possède la clé privée) sera capable de déchiffrer le cryptogramme. Tous les algorithmes à clé publique, reposent sur les postulats suivants:

    1. Les deux clés (privée et publique) sont générées conjointement et sont indissociables l'une de l'autre.

    2. On ne peut pas retrouver une clé privée à partir de la clé publique (et vice-versa)

    3. Seule la clé publique doit être distribuée

    4. La clé privée doit être protégée et rester unique (pas de duplication) pour garantir la sécurité de l'ensemble du système de chiffrement.

    AUTHENTIFICATION PAR CLE PUBLIQUE

    L'authentification par clé publique fonctionne sur le même principe que le chiffrement, mais en inversant l'utilisation des clés. Le procédé est en effet complétement réversible.

    On peut donc chiffrer les données avec la clé privée et les déchiffrer avec la clé publique. Si en terme de confidentialité des données, cela n'a aucun intérêt car tout le monde peut posséder la clé publique, cela permet en revanche de clairement identifier la personne (ou la machine) qui a effectué le chiffrement car elle est la seule à posséder la clé privée.

    Alice signe avec sa clé privée, Bob peut vérifier l'identité d'Alice grâce à sa clé publique

    Dans l'exemple ci-dessus, Alice s'authentifie auprès de Bob grâce à sa clé privée: a) Elle génère une empreinte à partir d'un challenge de son choix (ici : Hello Bob) Pour cela elle utilise un algorithme de hachage (md5 ou sha-256 par exemple) b) Elle chiffre l'empreinte obtenue avec sa clé privée en utilisant un algorithme de chiffrement asymétrique comme rsa ou ecdsa c) Elle envoi le challenge (en clair) et l'empreinte chiffrée à Bob d) Bob recalcule une empreinte à partir du challenge en clair e) Bob déchiffre l'empreinte chiffrée avec la clé publique d'Alice (qu'il doit posséder au préalable) f) Bob compare les deux résultats (empreinte recalculée et empreinte déchiffrée). Si les deux résultats sont identiques, cela confirme que c'est bien Alice qui à établit la communication car elle est la seule à posséder la clé privée qui a chiffré l'empreinte.

    Pour conclure cette partie théorique, il suffit donc que vous communiquiez vos clés publiques à vos correspondants pour qu'ils puissent vous authentifier. Voyons maintenant comment cela se concrétise en pratique.

    AUTHENTIFICATION SSH

    Commençons par quelque chose que vous connaissez déjà, l'authentification de votre VPS lorsque vous réalisez une connexion en SSH.

    IMPORTANT : Pour l'instant l'objectif n'est pas de vous authentifier , mais bien d'authentifier le serveur sur lequel vous vous connectez et de lui faire confiance. Dans les exemples qui suivent le CLIENT désigne votre poste de travail, le SERVEUR désigne votre VPS.

    SUPPRESSION DES CLES EXISTANTES

    Pour bien comprendre ce qu'il se passe, localisez le fichier known_hosts sur votre poste de travail.

    Si vous êtes sous Windows, il devrait se trouver dans C:\Users\NOM_UTILISATEUR\.ssh Sur MAC, il devrait se trouver dans ~/.ssh (~ étant le dossier de votre utilisateur) Sous Linux, il est dans /home/UTILISATEUR/.ssh ou /root/.ssh si vous êtes connecté en root.

    Une fois , le fichier localisé, éditez-le avec l'éditeur de texte de votre choix . Vous devriez voir une ou plusieurs clés publiques appartenant aux différents serveurs auxquels vous vous êtes précédemment connectés. En fonction de votre OS, vous devriez aussi voir le nom (ou l'IP des machines) ainsi que le nom des algorithmes de chiffrement utilisés (ici ecdsa).

    Pour continuer, supprimez toutes les lignes du fichier . Cela supprimera toutes les clés publiques connues par votre poste de travail. N'ayez pas peur, elles seront réécrites dans le fichier lorsque vous vous reconnecterez aux serveurs.

    CONNEXION SSH - AUTHENTIFICATION DU SERVEUR

    Une fois les clés supprimées, connectez-vous à votre VPS en utilisant SSH comme d'habitude:

    Votre poste de travail, ne connait plus la clé publique du serveur, vous devez confirmer la connexion

    Dans l'exemple ci-dessus, votre poste de travail ne connaissant plus la clé publique de votre serveur, il vous demande de l'authentifier manuellement en confirmant la connexion. Dans notre cas, ce message est bien sur tout à fait légitime car nous avons supprimé les clés connues de notre fichier known_hosts. Si vous ouvrez le fichier, vous devriez d'ailleurs constater que la clé est de nouveau présente.

    Voyons maintenant, un autre cas de figure que vous pourriez (ou avez) déjà rencontré

    La clé publique du serveur a été modifiée, la connexion SSH a échouée

    Dans l'exemple ci-dessus, la clé publique du serveur VPS a été modifiée, elle est donc différente de celle enregistrée dans votre fichier known_hosts. Comme vous l'indique le message, s'il est possible que vous soyez victime d'une attaque, il est aussi tout à fait probable que la clé ait été changée suite à une mise à jour du serveur ou à une opération de maintenance de votre VPS. Que fait-il faire ? Sauf si vous pensez vraiment avoir être victime d'une attaque , vous devez juste supprimer la ligne indiquée du fichier known_hosts comme nous l'avons fait précédemment dans ce TD ou saisissez simplement la commande : ssh-keygen -f avec les arguments indiqués dans le message .

    Vous pensez être victime d'une attaque ? Connectez-vous avec la console en passant par l'espace client de PulseHeberg et comparez la clé publique de votre fichier known_hosts avec le contenu du fichier /etc/ssh/ssh_host_ecdsa_key.pub de votre serveur.

    Si vous n'avez pas accepté la connexion précédente et que les clés publiques sont identiques, le message affiché est effectivement suspicieux. Dans ce cas "rebooter" votre serveur (reboot) et reconnectez-vous en ssh.

    CONNEXION SSH - AUTHENTIFICATION DU CLIENT

    Maintenant que vous avez compris comment le CLIENT authentifie le SERVEUR, voyons comment le SERVEUR fait avec le CLIENT. Pour l'instant lors de notre connexion SSH nous nous authentifions avec un compte utilisateur et un mot de passe.

    C'est donc cette méthode (login/mot de passe) qui permet au SERVEUR d'authentifier le CLIENT. Cette méthode est incontournable si la machine du CLIENT est amenée à changer souvent, mais dans le cas ou l'on se connecte toujours de la même machine, cela devient rapidement fastidieux, surtout si l'on a tendance à oublier son mot de passe 😂

    Nous allons donc voir comment nous authentifier auprès du serveur avec une clé SSH

    GENERATION DES CLES

    Première étape : Générer une paire de clés sur notre machine (et pour notre utilisateur) La procédure est assez simple, il suffit juste de choisir quel algorithme de chiffrement nous voulons utiliser. Le plus connu est rsa, mais depuis quelques années, on lui préfèrera ecdsa pour l'authentification. Par souci de compatibilité avec tous les systèmes, nous générerons une paire de clés avec chacun des algorithmes.

    GENERATION DES CLES avec WINDOWS

    Ouvrez une invite de commandes (cmd) ou PowerShell et saisissez simplement la commande suivante : ssh-keygen.exe -t CRYPT (en remplaçant CRYPT par rsa ou ecdsa)

    Attention, ne saisissez pas de passphrase (faites juste ENTREE) sinon vous devrez ressaisir cette passphrase à chaque authentification ce qui n'aurait aucun intérêt.

    Autre remarque importante, si le système vous dit que la clé existe, ne l'écrasez pas , répondez Non à la question et interrompez la génération de la nouvelle clé. Sauf si bien sur vous êtes certain que la clé existante ne sert à rien (ce dont je doute)

    répétez l'opération avec rsa.

    GENERATION DES CLES avec MAC

    La commande est la même (sans le .exe) : ssh-keygen -t ecdsa (et ssh-keygen -t rsa)

    ENVOI DE LA CLE PUBLIQUE AU SERVEUR

    Sur votre poste (que ce soit sur MAC ou un PC), les clés que vous venez de générer sont stockées dans le dossier .ssh de votre utilisateur au même endroit que votre fichier known_hosts

    Les clés privées (sans extension) et les clés publiques (.pub)

    On voit ici que pour chaque algorithme de chiffrement il existe 2 fichiers:

    • Un pour la clé privée que vous ne devez jamais communiqué

    Extrait du fichier de la clé privée chiffrée en RSA -id_rsa)
    • Un pour la clé publique (en .pub) que vous allez devoir transmettre au serveur pour qu'il puisse vous authentifier.

    Extrait de la clé publique chiffrée en RSA (id_rsa.pub)

    Voyons maintenant comment envoyer cette clé publique à votre VPS pour que celui-ci accepte de vous authentifier sans mot de passe.

    CAS 1: Vous êtes sous MAC, utilisez simplement la commande ssh-copy-id MMI@MMI.mmi-troyes.fr Renseignez votre mot de passe habituel Relancez la commande ssh MMI@MMI.mmi-troyes.fr, aucun mot de passe ne devrait plus vous être demandé par la suite.

    CAS 2: Windows ne disposant pas de la commande ssh-copy-id, nous allons devoir procéder en deux temps: Envoyer la clé sur notre serveur, puis la recopier dans le fichier .ssh/authorized_keys de notre utilisateur (sur le VPS) qui contient les clés publiques autorisées pour l'authentification.

    Première phase : On envoie la clé publique dans le dossier de notre utilisateur sur le VPS Remplacez bien MMI par votre identifiant et saisissez votre mot de passe habituel pour ssh

    Seconde Phase : On se connecte en SSH sur le serveur comme d'habitude avec le mot de passe. Ne faites pas de sudo -i !! . Ensuite on envoie la clé dans le fichier .ssh/authorized_keys de notre utilisateur.

    Vous pouvez vérifier le contenu du fichier .ssh/authorized_keys avec cat ou nano

    Ici la clé publique ecdsa du poste de travail

    Pour tester le résultat, fermez votre terminal et reconnectez-vous en SSH sur votre VPS avec ssh MMI@MMI.mmi-troyes.fr , vous ne devriez pas avoir de mot de passe à saisir.

    GIT SUR LE VPS avec AUTHENTIFICATION SSH

    Schéma de fonctionnement de notre déploiement

    Avant d'installer git sur notre VPS, nous allons d'abord continuer avec la gestion des clés SSH.

    AJOUT D'UNE CLE SSH sur votre compte GitHUB

    Ajout de la clé de votre poste de travail

    Connectez-vous à votre GitHUB. Dans votre profil , sélectionnez Settings puis SSH and GPG Keys Cliquez sur New SSH Key

    Ajout d'une clé publique SSH sur GitHUB

    Ouvrez votre le fichier .ssh/id_ecdsa.pub de votre utilisateur sur votre poste de travail et faites un Copier/Coller de son contenu dans la zone key. Donnez un titre à votre clé et validez par Add SSH Key.

    Cette clé vous permettra de vous identifier sans mot de passe en utilisant le lien SSH de vos dépôts GitHUB.

    Ajout de la clé de votre VPS

    Pour authentifier automatiquement votre VPS sur GitHUB et pouvoir récupérer le contenu d'un dépôt par exemple, nous avons aussi besoin d'ajouter la clé de celui-ci dans notre compte GitHUB.

    Coté GitHUB, la démarche reste la même (Profil / Settings / SSH Key / New Key / Add Key) Coté serveur, vous devez d'abord générer une clé pour notre utilisateur (sans faire de sudo -i !!)

    Ne faites pas de sudo -i avant de saisir les commandes

    Ne saisissez pas de passphrase lors de la génération des clés

    Ensuite , copiez le résultat de la commande cat dans le formulaire d'ajout des clés de GitHUB.

    CREATION ou MISE A JOUR DU DEPOT GITHUB SAE203

    Avant de poursuivre sur le serveur, revenons vers GitHUB. Voici une check-list de ce que vous devez avoir fait sur votre poste de travail à cette étape de la SAE

    1. Création d'un compte GitHUB

    2. Création d'un dépôt privé GitHUB nommé sae203

    3. Ajout des collaborateurs suivant pour le dépôt sae203 jlandre72 , pgommery , Dannebicque , haraou01, meuzer01 , f-libbrecht

    4. push de votre travail local vers votre dépôt GitHUB sae203

    5. Ajouter la clé publique de votre utilisateur MMI (vps) sur GitHUB

    Ne continuez pas si les étapes précédentes ne sont pas effectuées, vous risqueriez de perdre votre travail !!!!

    INSTALLATION DE GIT sur le VPS

    Tout est maintenant prêt pour la mise en place de Git sur votre serveur. Procédons à l'installation

    Avant de continuer, nous allons faire une sauvegarde du dossier sae203 existant sur notre serveur avant de le supprimer pour pouvoir cloner le dépôt GitHub sans erreurs

    INITIALISATION du dépôt Git Local sur le VPS

    Vous ne devez pas avoir fait sudo -i pour continuer. l'invite de commandes doit être MMI@MMI:~$ (et surtout pas #)

    Commençons par initialiser git pour avec votre compte github

    Ensuite dans GitHUB, récupérer le lien SSH de votre dépôt sae203

    Exemple : le lien ssh de mon dépôt sae203

    Pour terminer , placez-vous dans le dossier /var/www et clonez le dépôt distant sur votre VPS avec les commandes suivantes

    Ne faites pas de copier/coller, remplacez MMI par vos identifiants et surtout le LIEN SSH GITHUB par celui de votre dépôt

    Normalement, vous devriez retrouver tous vos fichiers dans votre dossier sae203. Vérifiez que votre site fonctionne avec l'URL: MMI.sae203.ovh

    ET MAINTENANT ....

    A partir de maintenant, terminé les envois de modifications par Filezilla !!!

    Pour continuer la mise à jour de votre site, vous devez utiliser le schéma suivant

    Développement en local, push vers github, pull depuis le VPS pour mettre à jour le site

    AUTOMATISATION DU PULL

    Si vous utilisez un IDE tel que PhpStorm ou VSCode, vous avez certainement vu comment envoyer (push) vos données vers le dépôt GitHUB, mais comment faire pour récupérer les données sur votre VPS ? Avec un pull bien sur, mais cela implique d'ouvrir un terminal, de se connecter en ssh, d'aller dans le dossier sae203 et de lancer le git pull manuellement. Et si on essayait d'automatiser un peu tout ça.

    CREATION D'UN SCRIPT et EXCUTION DU PULL

    • Connectez-vous à votre VPS en ssh

    • Ne faites pas de sudo -i

    • Ne changez pas de dossier et créez un fichier nommé pullrequest.sh avec le contenu suivant

    #!/bin/sh # Automatisation du Pull de la SAE203 cd /var/www/sae203 git pull origin main

    • Donnez les droits d'exécution sur le fichier avec la commande chmod 750 pullrequest.sh

    • Terminez votre connexion ssh avec exit

    Notre script est prêt à être exécuté. Saisissez la commande

    Le script fait le git pull et met à jour le site depuis le dépôt github

    Il ne vous reste plus qu'à tester

    1. Faites une modification d'une de vos pages en local

    2. Envoyez les modifications (commit, push) vers votre dépôt GitHUB

    3. Lancer le script pullrequest.sh pour effectuer un pull vers votre VPS

    4. Ouvrez votre site et constatez que tout est OK

    PREUVE DE DEPOT pour la SAE203

    A rendre avant Jeudi 12h30

    Tout est OK !! Bravo vous venez de mettre un pied dans le monde des DevOps !! Sur votre VPS, créez un fichier texte /root/MMI-git.txt où MMI est votre identifiant mmi21Xxx Dans ce fichier, mettez le lien https vers votre dépôt github sae203

    Attention à bien respectez les règles de nommage sous peine d'être pénalisé pour la correction. Le fichier doit être dans /root , se nommer MMI-git.txt et ne contenir qu'une seule ligne du type : https://github.com/PROFIL_GITHUB/sae203.git et rien d'autre

    89.224.182.217 ecdsa-sha2-nistp256 AAAAE2VjZHNhqdlkjqlsdjNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGiWIg+eNQCabe/HBHjG5zLveBSfsY09QpwMN7IxyY5YZCI0nmhZxAfxNr9ORQ7phqAUor47QxWXUIix7IXoaHA=
    149.91.84.92 ecdsa-sha2-nistp256 AAAAEqdqdqdItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBITA/dwnonEn9vXfgQYaMer/hH10QOQN/qXZC6VutRRQKyhydGR2y6ZfhVeqFUs9t4aGcCAeq4dlSJU/DyCUX9o=
    185.216.25.669 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoqdqdzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHQrYg7ta3uXK0ZLecv53vYEqlmQC9LG2p/g+KhdC++oDpztifUIdY2o1FkkVWx2JSu4FAN7nMh6H8nSlSPbFkQ=
    PS C:\Users\toto\.ssh> ssh-keygen.exe -t ecdsa
    Generating public/private ecdsa key pair.
    Enter file in which to save the key (C:\Users\toto/.ssh/id_ecdsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in C:\Users\toto/.ssh/id_ecdsa.
    Your public key has been saved in C:\Users\toto/.ssh/id_ecdsa.pub.
    The key fingerprint is:
    SHA256:DU6NECHrcsQcbabcfd+qbXOfh48Sh1G8PTquLVvKgl6hU ad-urca\toto@028P1-0H0013001
    The key's randomart image is:
    +---[ECDSA 256]---+
    |    o +o         |
    |   = + . o       |
    |    O   + .      |
    |   =   o o       |
    |  o E  .S..      |
    | . = .-o* .      |
    |  o o+o*o*       |
    |   ++=*.+.       |
    | .+==*+o.        |
    +----[SHA256]-----+
    cd
    cd .ssh
    scp id_ecdsa.pub [email protected]:/home/MMI/
    ssh [email protected]
    cd /home/MMI
    mkdir .ssh       (au cas ou il n'existerait pas)      
    cat id_ecdsa.pub >> .ssh/authorized_keys
    chmod 600 .ssh/authorized_keys
    rm id_ecdsa.pub
    cd /home/MMI
    ssh-keygen -t ecdsa
    cat .ssh/id_ecdsa.pub
    sudo -i
    apt update
    apt install git
    cd /var/www
    chown -R MMI:MMI sae203
    tar -czvf /home/MMI/sae203.tar.gz sae203
    rm -Rf sae203
    exit
    git config --global user.name NOM_GITHUB
    git config --global user.email EMAIL_UTILISEE_POUR_GITHUB
    cd /var/www
    sudo mkdir sae203
    sudo chown -R MMI:MMI sae203
    git clone LIEN_SSH_DU_DEPOT_GITHUB_SAE203 sae203
    cd sae203
    ls -l                  (pour vérifier que tout est là)
    ssh [email protected] ./pullrequest.sh
    Logo
    Logo