From 08d568a002ae4f66796ac3433b1b6fa185d1aea4 Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Tue, 14 Jul 2026 22:41:51 +0200 Subject: [PATCH] feat(core): validate investigation project structure --- docs/tickets/closed/TICKET-021.md | 254 ++++++++++++++++++++++++++ include/core/investigation_project.h | 18 ++ labfy-investigation | Bin 108784 -> 109712 bytes src/core/investigation_project.c | 220 +++++++++++++++++++---- tests/test_investigation_project | Bin 30688 -> 35416 bytes tests/test_investigation_project.c | 256 +++++++++++++++++++++++++++ 6 files changed, 712 insertions(+), 36 deletions(-) create mode 100644 docs/tickets/closed/TICKET-021.md diff --git a/docs/tickets/closed/TICKET-021.md b/docs/tickets/closed/TICKET-021.md new file mode 100644 index 0000000..d601285 --- /dev/null +++ b/docs/tickets/closed/TICKET-021.md @@ -0,0 +1,254 @@ +# Ticket #021 + +## Titre + +Valider une enquête existante. + +--- + +## Objectif + +Ajouter au module `InvestigationProject` la capacité de vérifier qu’un dossier +correspond bien à une enquête Labfy Investigation valide. + +La validation doit contrôler la présence et le type des éléments obligatoires, +sans modifier le contenu du dossier. + +--- + +## Architecture + +```text +Application + │ + ▼ +InvestigationProject + │ + ▼ +FileSystem +``` + +Toute ouverture d’enquête existante doit passer par +`InvestigationProject`. + +La GUI ne doit jamais décider seule si un dossier est valide. + +--- + +## Responsabilités + +### InvestigationProject + +Le module doit : + +- recevoir le chemin d’un dossier ; +- vérifier que le chemin existe ; +- vérifier qu’il désigne un dossier ; +- vérifier la présence de l’arborescence obligatoire ; +- vérifier que les dossiers attendus sont bien des dossiers ; +- vérifier la présence de `00_BaseDeDonnees/Enquete.sqlite` ; +- vérifier que `Enquete.sqlite` est un fichier régulier ; +- retourner un résultat clair sans modifier le dossier. + +--- + +## Interface publique attendue + +Faire évoluer : + +```text +include/core/investigation_project.h +src/core/investigation_project.c +``` + +Ajouter : + +```c +bool investigation_project_validate( + const char *investigation_path +); +``` + +--- + +## Contrat + +La fonction retourne : + +```c +true +``` + +si le dossier est une enquête valide. + +Elle retourne : + +```c +false +``` + +si : + +- le chemin est invalide ; +- le dossier n’existe pas ; +- le chemin désigne un fichier ; +- un dossier obligatoire manque ; +- un élément attendu comme dossier est en réalité un fichier ; +- `Enquete.sqlite` manque ; +- `Enquete.sqlite` n’est pas un fichier régulier. + +La fonction ne doit jamais modifier le système de fichiers. + +--- + +## Structure obligatoire + +Les dossiers suivants doivent exister : + +```text +00_BaseDeDonnees +01_Preuves_Originales +02_Preuves_Traitees +03_Chronologie +04_Entites +05_Rapports +06_Exports +07_Notes +08_Sources +09_Hash +``` + +Les sous-dossiers suivants doivent également exister : + +```text +01_Preuves_Originales/Captures_Ecran +01_Preuves_Originales/Conversations +01_Preuves_Originales/Documents +01_Preuves_Originales/Emails +01_Preuves_Originales/Photos +01_Preuves_Originales/Videos + +02_Preuves_Traitees/Annotations +02_Preuves_Traitees/Extractions +02_Preuves_Traitees/OCR +02_Preuves_Traitees/Redactions + +04_Entites/Adresses_Email +04_Entites/Comptes_Bancaires +04_Entites/Comptes_Facebook +04_Entites/Comptes_Instagram +04_Entites/Documents_Identite +04_Entites/IBAN +04_Entites/Personnes +04_Entites/Pseudonymes +04_Entites/Telephones +04_Entites/Autres +``` + +Le fichier suivant doit exister : + +```text +00_BaseDeDonnees/Enquete.sqlite +``` + +--- + +## Réutilisation de la structure déclarative + +La validation doit réutiliser la même liste de chemins que la création. + +Il ne doit pas exister deux listes indépendantes décrivant l’arborescence. + +La structure de référence doit rester centralisée dans +`investigation_project.c`. + +--- + +## Hors périmètre + +Ce ticket ne doit pas : + +- ouvrir SQLite ; +- lire le schéma SQL ; +- vérifier la version de la base ; +- créer les éléments manquants ; +- réparer une enquête ; +- importer automatiquement des fichiers ; +- modifier GTK ; +- ouvrir automatiquement l’enquête dans l’application. + +--- + +## Gestion des erreurs + +Dans ce ticket, la fonction retourne uniquement un booléen. + +Les détails d’erreur plus précis pourront être ajoutés plus tard avec : + +```c +GError +``` + +ou une énumération métier dédiée. + +La validation ne doit produire aucun `g_warning()` pour un dossier simplement +invalide : un résultat `false` suffit. + +--- + +## Contraintes techniques + +- C17 ; +- GLib autorisée ; +- aucune dépendance GTK ; +- aucune dépendance SQLite requise ; +- aucune écriture sur le disque ; +- aucun état global ; +- documentation Doxygen ; +- compilation sans warning. + +--- + +## Tests + +Faire évoluer : + +```text +tests/test_investigation_project.c +``` + +Le test doit vérifier : + +- une enquête complète est valide ; +- `NULL` est refusé ; +- une chaîne vide est refusée ; +- un chemin inexistant est refusé ; +- un fichier simple est refusé ; +- une enquête sans `Enquete.sqlite` est refusée ; +- une enquête avec un dossier obligatoire manquant est refusée ; +- un élément attendu comme dossier mais remplacé par un fichier est refusé ; +- une enquête valide reste inchangée après validation. + +--- + +## Critères d’acceptation + +- [ ] Le projet compile sans warning. +- [ ] `make test` reste entièrement valide. +- [ ] Une enquête créée par `investigation_project_create()` est valide. +- [ ] Un chemin invalide est refusé. +- [ ] Un dossier incomplet est refusé. +- [ ] Un faux fichier `Enquete.sqlite` incorrect est refusé. +- [ ] Aucun élément n’est créé pendant la validation. +- [ ] Aucun élément n’est supprimé pendant la validation. +- [ ] La structure de référence n’est pas dupliquée. +- [ ] Aucune dépendance GTK. +- [ ] Aucun `Gtk-CRITICAL`. + +--- + +## Commit attendu + +```text +feat(core): validate investigation project structure +``` diff --git a/include/core/investigation_project.h b/include/core/investigation_project.h index b45727e..3c4cf23 100644 --- a/include/core/investigation_project.h +++ b/include/core/investigation_project.h @@ -6,6 +6,8 @@ #ifndef LABFY_INVESTIGATION_INVESTIGATION_PROJECT_H #define LABFY_INVESTIGATION_INVESTIGATION_PROJECT_H +#include + /** * @brief Crée une nouvelle enquête dans un dossier parent. * @@ -36,4 +38,20 @@ char *investigation_project_create( const char *investigation_name ); +/****************************************************************************** + * @brief Vérifie qu'un dossier est une enquête valide. + * + * La fonction contrôle que tous les éléments obligatoires de la structure + * d'une enquête existent et sont du type attendu. + * + * Aucune modification n'est effectuée sur le système de fichiers. + * + * @param investigation_path Chemin de l'enquête à vérifier. + * + * @return true si l'enquête est valide, sinon false. + ******************************************************************************/ +bool investigation_project_validate( + const char *investigation_path +); + #endif diff --git a/labfy-investigation b/labfy-investigation index ec6ccc360eef30d6c0886c08cad1a00c22d5cf6d..d5a654ed3e6b17ea7638ad372b4bb32b6f9d795d 100755 GIT binary patch delta 24932 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 delta 23437 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 UMv|DXU^Q#2KJc1v{A!l #include +/** + * @brief Type d'un élément de la structure d'une enquête. + */ +typedef enum +{ + INVESTIGATION_PROJECT_DIRECTORY, + INVESTIGATION_PROJECT_FILE +} InvestigationProjectEntryType; + +/** + * @brief Décrit un élément attendu dans une enquête. + */ +typedef struct +{ + /** + * Chemin relatif depuis la racine de l'enquête. + */ + const char *relative_path; + + /** + * Nature de l'élément. + */ + InvestigationProjectEntryType type; + +} InvestigationProjectEntry; + /** * @brief Liste des dossiers relatifs composant une enquête. * * L'ordre est important : les dossiers parents doivent apparaître avant * leurs sous-dossiers. */ -static const char *const investigation_project_directories[] = +static const InvestigationProjectEntry +investigation_project_entries[] = { - "00_BaseDeDonnees", + { "00_BaseDeDonnees", INVESTIGATION_PROJECT_DIRECTORY }, + { "00_BaseDeDonnees/Enquete.sqlite", INVESTIGATION_PROJECT_FILE }, - "01_Preuves_Originales", - "01_Preuves_Originales/Captures_Ecran", - "01_Preuves_Originales/Conversations", - "01_Preuves_Originales/Documents", - "01_Preuves_Originales/Emails", - "01_Preuves_Originales/Photos", - "01_Preuves_Originales/Videos", + { "01_Preuves_Originales", INVESTIGATION_PROJECT_DIRECTORY }, + { "01_Preuves_Originales/Captures_Ecran", INVESTIGATION_PROJECT_DIRECTORY }, + { "01_Preuves_Originales/Conversations", INVESTIGATION_PROJECT_DIRECTORY }, + { "01_Preuves_Originales/Documents", INVESTIGATION_PROJECT_DIRECTORY }, + { "01_Preuves_Originales/Emails", INVESTIGATION_PROJECT_DIRECTORY }, + { "01_Preuves_Originales/Photos", INVESTIGATION_PROJECT_DIRECTORY }, + { "01_Preuves_Originales/Videos", INVESTIGATION_PROJECT_DIRECTORY }, - "02_Preuves_Traitees", - "02_Preuves_Traitees/Annotations", - "02_Preuves_Traitees/Extractions", - "02_Preuves_Traitees/OCR", - "02_Preuves_Traitees/Redactions", + { "02_Preuves_Traitees", INVESTIGATION_PROJECT_DIRECTORY }, + { "02_Preuves_Traitees/Annotations", INVESTIGATION_PROJECT_DIRECTORY }, + { "02_Preuves_Traitees/Extractions", INVESTIGATION_PROJECT_DIRECTORY }, + { "02_Preuves_Traitees/OCR", INVESTIGATION_PROJECT_DIRECTORY }, + { "02_Preuves_Traitees/Redactions", INVESTIGATION_PROJECT_DIRECTORY }, - "03_Chronologie", + { "03_Chronologie", INVESTIGATION_PROJECT_DIRECTORY }, - "04_Entites", - "04_Entites/Adresses_Email", - "04_Entites/Comptes_Bancaires", - "04_Entites/Comptes_Facebook", - "04_Entites/Comptes_Instagram", - "04_Entites/Documents_Identite", - "04_Entites/IBAN", - "04_Entites/Personnes", - "04_Entites/Pseudonymes", - "04_Entites/Telephones", - "04_Entites/Autres", + { "04_Entites", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Adresses_Email", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Comptes_Bancaires", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Comptes_Facebook", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Comptes_Instagram", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Documents_Identite", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/IBAN", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Personnes", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Pseudonymes", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Telephones", INVESTIGATION_PROJECT_DIRECTORY }, + { "04_Entites/Autres", INVESTIGATION_PROJECT_DIRECTORY }, - "05_Rapports", - "06_Exports", - "07_Notes", - "08_Sources", - "09_Hash" + { "05_Rapports", INVESTIGATION_PROJECT_DIRECTORY }, + { "06_Exports", INVESTIGATION_PROJECT_DIRECTORY }, + { "07_Notes", INVESTIGATION_PROJECT_DIRECTORY }, + { "08_Sources", INVESTIGATION_PROJECT_DIRECTORY }, + { "09_Hash", INVESTIGATION_PROJECT_DIRECTORY } }; /** * @brief Nombre de dossiers présents dans la table de création. */ -#define INVESTIGATION_PROJECT_DIRECTORY_COUNT \ - G_N_ELEMENTS(investigation_project_directories) +#define INVESTIGATION_PROJECT_ENTRY_COUNT \ + G_N_ELEMENTS(investigation_project_entries) /** * @brief Vérifie que les paramètres nécessaires à la création sont valides. @@ -226,6 +254,70 @@ static gboolean investigation_project_create_directory( return TRUE; } +/** + * @brief Vérifie qu'un élément existe avec le type attendu. + * + * @param investigation_root Racine de l'enquête. + * @param entry Élément à vérifier. + * + * @return TRUE si l'élément est valide. + */ +static gboolean investigation_project_validate_entry( + const char *investigation_root, + const InvestigationProjectEntry *entry +) +{ + char *path = NULL; + gboolean valid = FALSE; + + if (investigation_root == NULL || + entry == NULL) + { + return FALSE; + } + + path = g_build_filename( + investigation_root, + entry->relative_path, + NULL + ); + + if (path == NULL) + { + return FALSE; + } + + switch (entry->type) + { + case INVESTIGATION_PROJECT_DIRECTORY: + + valid = g_file_test( + path, + G_FILE_TEST_IS_DIR + ); + + break; + + case INVESTIGATION_PROJECT_FILE: + + valid = g_file_test( + path, + G_FILE_TEST_IS_REGULAR + ); + + break; + + default: + + valid = FALSE; + break; + } + + g_free(path); + + return valid; +} + char *investigation_project_create( const char *parent_directory, const char *investigation_name @@ -307,12 +399,21 @@ char *investigation_project_create( * Création de toute l'arborescence déclarée dans la table. */ for (gsize index = 0; - index < INVESTIGATION_PROJECT_DIRECTORY_COUNT; - ++index) + index < INVESTIGATION_PROJECT_ENTRY_COUNT; + ++index) { + const InvestigationProjectEntry *entry = NULL; + + entry = &investigation_project_entries[index]; + + if (entry->type != INVESTIGATION_PROJECT_DIRECTORY) + { + continue; + } + directory_path = g_build_filename( investigation_path, - investigation_project_directories[index], + entry->relative_path, NULL ); @@ -422,3 +523,50 @@ char *investigation_project_create( return investigation_path; } + +bool investigation_project_validate( + const char *investigation_path +) +{ + if (investigation_path == NULL) + { + return false; + } + + if (investigation_path[0] == '\0') + { + return false; + } + + if (!g_file_test( + investigation_path, + G_FILE_TEST_EXISTS)) + { + return false; + } + + if (!g_file_test( + investigation_path, + G_FILE_TEST_IS_DIR)) + { + return false; + } + + for (gsize index = 0; + index < INVESTIGATION_PROJECT_ENTRY_COUNT; + ++index) + { + const InvestigationProjectEntry *entry = NULL; + + entry = &investigation_project_entries[index]; + + if (!investigation_project_validate_entry( + investigation_path, + entry)) + { + return false; + } + } + + return true; +} diff --git a/tests/test_investigation_project b/tests/test_investigation_project index 14e5237bd29c2ec29e24284520bdeb41b7f25159..6fdc14da7553d9b3541418c1f18276bc8156a6b6 100755 GIT binary patch literal 35416 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 qBmT(vOY6qsI}WXMuuUI6Dh