What are its main components?
What problem??
What is a Python variable?
personnage.py
What is a Python object?
We want to save a tree 🌳
Separation of responsibilities
Use a dedicated library
pip install psycopg2-binaryconnection: Establishes the connection to the database Not super interesting to do, the code is provideddb_connection.py
import os
import dotenv
import psycopg2
from psycopg2.extras import RealDictCursor
from utils.singleton import Singleton
class DBConnection(metaclass=Singleton):
"""
Database connection class
It allows opening only one unique connection
"""
def __init__(self):
"""Open the connection"""
dotenv.load_dotenv()
self.__connection = psycopg2.connect(
host=os.environ["POSTGRES_HOST"],
port=os.environ["POSTGRES_PORT"],
database=os.environ["POSTGRES_DATABASE"],
user=os.environ["POSTGRES_USER"],
password=os.environ["POSTGRES_PASSWORD"],
options=f"-c search_path={os.environ['POSTGRES_SCHEMA']}",
cursor_factory=RealDictCursor,
)
@property
def connection(self):
return self.__connectioncursor: Encapsulates the query
cursor.execute("<a SQL query>"): Executes a query
cursor.fetchone()/fetchall()/fetchmany(): Retrieves the results
def dao_function(self, arg1, arg2, ...):
# Get the database connection
with DBConnection().connection as connection:
# Create a cursor to make a query
with connection.cursor() as cursor:
# Send the SQL query to the server
cursor.execute(
"<a_sql_query_with_placeholders>",
fill_in_the_placeholders)
# Retrieve the query result
res = cursor.fetchone() # or fetchall()/fetchmany()
# If the query returns something
if res:
something = "<res formatted>"
return somethingdef create(self, livre) -> Livre:
"""To create a book in the database"""
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 livredef find_all(self) -> list[Livre]:
"""To retrieve all books from the database"""
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_livresdef find_by_isbm(self, isbm) -> Livre:
"""To retrieve a book by its isbm"""
with DBConnection().connection as conn:
with conn.cursor() as cursor:
cursor.execute(
"SELECT * "
" FROM livre "
" WHERE isbm = %(isbm)s ",
{"isbm": 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 livreOnly authorized individuals should have access to the information intended for them (notions of rights or permissions). Any undesirable access must be prevented.
Associated Mechanisms:
Data must be as expected and must not be altered accidentally, unlawfully, or maliciously.
Associated Mechanisms:
Access to the information system’s resources must be permanent and flawless during the planned usage periods.
Associated Mechanisms:
Ensures that accesses and access attempts to the considered elements are traced and that these traces are preserved and usable.
Associated Mechanism:
Users must prove their identity by responding to a “challenge.”
Associated Mechanisms:
No user should be able to dispute the operations they have performed within the scope of their authorized actions, and no third party should be able to attribute the actions of one user to another.
Associated Mechanisms:
Your users
Source: https://xkcd.com/
Involves entering SQL to execute a different query than intended.
Problems:
Authentication query
You Enter
You Enter
' OR 1=1; --You Enter
'; DROP TABLE user CASCADE; --The library you use only escapes special characters 😨
Involves injecting code that causes actions on the browser. This can allow:
Tip
Web libraries often do this for you!
Never trust user inputs, verify/clean them
Never trust user inputs, verify/clean them
Never trust user inputs, verify/clean them
NEVER TRUST USER INPUTS
USERS ARE YOUR N°1 VULNERABILTY
USERS ARE THE DEVIL
To test the strength of a password:
Authentication without persisting passwords!!!!
Instead of hashing and storing the password
Store and hash the password,
AND an element linked to the user in a deterministic way (the salt).
Now even if two people have the same password, they will have different hashes.
Honest version :