DENEUVILLE Ludovic (sur la base des cours de Rémi Pépin)
ludovic.deneuville@ensai.fr
C'est quoi une variable python ?
C'est quoi un objet python ?
On veut sauvegarder des couples clef-valeur
Avec des valeurs qui peuvent être elles-mêmes constituées de couples clef-valeur
On veut sauvegarder un arbre 🌳
CRUD
Séparation des responsabilités
Utilisation d'une bibliothèque dédiée
pip install psycopg2-binary
with getConnexion() as conn :
with conn.cursor() as curseur :
def dao_function(self, arg1, arg2...):
# Récupération de la connexion à la base
with getConnexion() as conn :
# Création d'un curseur pour faire une requête
# (le curseur stocke les résultats de la requête)
with conn.cursor() as curseur :
# On envoie au serveur la requête SQL
curseur.execute(
une_requete_sql_à_trous,
remplisage_des_trous)
# On récupère le résultat de la requête
res = curseur.fetchone() # ou /fetchall()/fetchmany()
return something
def create(self, livre) -> Livre:
"""Pour créer un livre en base"""
with DBConnection().connection as conn:
with conn.cursor() as cursor:
cursor.execute(
"INSERT INTO livre (isbm, titre, auteur) "
" VALUES (%(isbm)s, %(titre)s, %(auteur)s) "
" RETURNING id_livre; ",
{"isbm": livre.isbm,
"titre": livre.titre,
"auteur": livre.auteur},
)
livre.id = cursor.fetchone()["id_livre"]
return livre
def find_all(self) -> list[Livre]:
"""Pour récupérer tous les livres en base"""
with DBConnection().connection as conn:
with conn.cursor() as cursor:
cursor.execute(
"SELECT id_livre, "
" isbm, "
" titre, "
" auteur "
" FROM livre ; "
)
livre_bdd = cursor.fetchall()
liste_livres = []
if livre_bdd:
for livre in livre_bdd:
liste_livres.append(
Livre(
id=livre["id_livre"],
isbm=livre["isbm"],
titre=livre["titre"],
auteur=livre["auteur"],
)
)
return liste_livres
def find_by_isbm(self, isbm) -> Livre:
"""Pour récupérer un livre depuis son isbm"""
with DBConnection().connection as conn:
with conn.cursor() as cursor:
cursor.execute(
"SELECT * "
" FROM livre "
" WHERE isbm = %(isbm)s ",
{"isbm": livre.isbm}
livre_bdd = cursor.fetchone()
livre = None
if livre_bdd:
livre = Livre(
id=livre_bdd["id_livre"],
isbm=livre_bdd["isbm"],
titre=livre_bdd["titre"],
auteur=livre_bdd["auteur"],
)
return livre
Mécanismes associés : gestion des droits (annuaires, rôles ...), cryptographie
Mécanismes associés : authentification faible (idep, mdp), forte (données biométriques, multi facteurs)
Mécanismes associés : signature électronique, checksum
Mécanismes associés : redondance des serveurs, virtualisation, conteneurisation
Mécanisme associé : journalisation
Mécanismes associés : traçabilité + authentification + intégrité
De vos utilisateurs
Problèmes
SELECT *
FROM user
WHERE name = 'input_name'
AND mdp = 'input_mdp';
Saisie
SELECT *
FROM user
WHERE name = 'Rémi'
AND mdp = 'mon_super_password';
Cas classique
Saisie
SELECT *
FROM user
WHERE name = 'Rémi'
AND mdp = '' OR 1=1; --';
Connection sans mdp
Saisie
SELECT *
FROM user
WHERE name='Rémi'
AND mdp=''; DROP TABLE user CASCADE; --;
Bye bye la table user
La bibliothèque que vous utiliserez ne fait que de l'échappement de caractères spéciaux 😨
<script> while(1==1){alert('bonjour')}</script>
Les bibliothèques web le font souvent pour vous !😁
Au lieu de hacher et stocker le mdp vous stockez et hachez le mdp ET un élément lié à l'utilisateur de manière déterministe (le sel).
Maintenant même si 2 personnes ont le même mdp, elles auront des hash différents.
import hashlib
def hash_password(password, idep):
salt = idep
return hashlib.sha256(salt.encode() + password.encode()).hexdigest()
print(hash_password("mon_super_password", "remi"))