Files
gesthub/web/models/rgpd_model.py
2026-08-21 09:12:02 +02:00

55 lines
2.0 KiB
Python

"""
rgpd_model.py — Anonymisation des données personnelles (droit à l'effacement,
RGPD art. 17). Bloc 1 - C10 : traçabilité, et Bloc 2 - C4 : la seule donnée
personnelle stockée dans l'application est le `sub` OIDC (Keycloak) — aucune
autre table ne duplique d'attribut d'identité.
`sub` est référencé dans quatre tables : annonces.auteur_sub,
fichiers.uploader_sub, evenements.createur_sub (toutes NOT NULL — la donnée
ne peut donc pas être mise à NULL sans casser la contrainte, d'où le choix
d'un pseudonyme irréversible) et audit_log.utilisateur_sub (NULLable, mais
pseudonymisée elle aussi par cohérence, pour garder la traçabilité du volume
d'actions sans conserver l'identité).
Toutes les mises à jour sont exécutées dans UNE seule transaction InnoDB
(un seul curseur `commit=True`) : soit les quatre tables sont mises à jour,
soit aucune ne l'est en cas d'erreur (cohérence, pas d'anonymisation partielle).
"""
def anonymize(db, target_sub, anon_value):
"""Remplace `target_sub` par `anon_value` dans toutes les tables qui le
référencent. Retourne le nombre de lignes modifiées par table.
"""
with db.cursor(commit=True) as cur:
cur.execute(
"UPDATE annonces SET auteur_sub = %s WHERE auteur_sub = %s",
(anon_value, target_sub),
)
annonces_rows = cur.rowcount
cur.execute(
"UPDATE fichiers SET uploader_sub = %s WHERE uploader_sub = %s",
(anon_value, target_sub),
)
fichiers_rows = cur.rowcount
cur.execute(
"UPDATE evenements SET createur_sub = %s WHERE createur_sub = %s",
(anon_value, target_sub),
)
evenements_rows = cur.rowcount
cur.execute(
"UPDATE audit_log SET utilisateur_sub = %s WHERE utilisateur_sub = %s",
(anon_value, target_sub),
)
audit_rows = cur.rowcount
return {
"annonces": annonces_rows,
"fichiers": fichiers_rows,
"evenements": evenements_rows,
"audit_log": audit_rows,
}