From 4de91a7ad097054cdac47140f865402fefeb9205 Mon Sep 17 00:00:00 2001 From: grayTerminal-sh Date: Mon, 20 Jul 2026 14:01:53 +0200 Subject: [PATCH] feat: add evidence integrity verification action --- include/views/main_window.h | 28 +++++++ include/widgets/workspace.h | 29 +++++++ src/core/application.c | 58 +++++++++++++ src/views/main_window.c | 64 +++++++++++++++ src/widgets/workspace.c | 158 ++++++++++++++++++++++++++++++++++++ 5 files changed, 337 insertions(+) diff --git a/include/views/main_window.h b/include/views/main_window.h index 626de90..ab229eb 100644 --- a/include/views/main_window.h +++ b/include/views/main_window.h @@ -53,6 +53,34 @@ typedef void (*MainWindowEvidenceSelectionCallback)( gpointer user_data ); +/** + * @brief Callback appelé lorsque l'utilisateur demande une vérification. + * + * L'identifiant est emprunté et uniquement valide pendant l'appel. + * + * @param evidence_identifier UUID de la preuve. + * @param user_data Données privées du callback. + */ +typedef void (*MainWindowVerifyEvidenceCallback)( + const char *evidence_identifier, + gpointer user_data +); + +/** + * @brief Définit le callback de vérification d'une preuve. + * + * MainWindow relaie la demande provenant du Workspace. + * + * @param main_window Fenêtre principale. + * @param callback Callback facultatif. + * @param user_data Données privées transmises au callback. + */ +void main_window_set_verify_evidence_callback( + MainWindow *main_window, + MainWindowVerifyEvidenceCallback callback, + gpointer user_data +); + /** * @brief Définit le callback du bouton « Nouvelle enquête ». * diff --git a/include/widgets/workspace.h b/include/widgets/workspace.h index b5561cb..f1ad576 100644 --- a/include/widgets/workspace.h +++ b/include/widgets/workspace.h @@ -27,6 +27,20 @@ typedef struct Workspace Workspace; */ Workspace *workspace_new(void); +/** + * @brief Callback appelé lorsque l'utilisateur demande la vérification + * de la preuve affichée. + * + * L'identifiant est emprunté et uniquement valide pendant l'appel. + * + * @param evidence_identifier UUID de la preuve. + * @param user_data Données privées du callback. + */ +typedef void (*WorkspaceVerifyEvidenceCallback)( + const char *evidence_identifier, + gpointer user_data +); + /** * @brief Retourne le widget GTK racine de la zone de travail. * @@ -73,6 +87,21 @@ void workspace_set_selected_evidence( const EvidenceRecord *evidence_record ); +/** + * @brief Définit le callback de vérification d'une preuve. + * + * Le Workspace transmet uniquement l'identifiant de la preuve affichée. + * + * @param workspace Zone de travail. + * @param callback Callback facultatif. + * @param user_data Données privées transmises au callback. + */ +void workspace_set_verify_evidence_callback( + Workspace *workspace, + WorkspaceVerifyEvidenceCallback callback, + gpointer user_data +); + /** * @brief Libère la structure d'encapsulation de la zone de travail. * diff --git a/src/core/application.c b/src/core/application.c index 9a89dbf..957ac28 100644 --- a/src/core/application.c +++ b/src/core/application.c @@ -2765,6 +2765,58 @@ static void application_on_evidence_selected( ); } +/** + * @brief Reçoit la demande de vérification d'une preuve. + * + * Cette première étape valide uniquement le relais de l'interface. + * Le lancement de la tâche sera ajouté ensuite. + * + * @param evidence_identifier UUID de la preuve. + * @param user_data Pointeur vers Application. + */ +static void application_on_verify_evidence_requested( + const char *evidence_identifier, + gpointer user_data +) +{ + Application *application = + user_data; + + char *status_message = + NULL; + + if (application == NULL || + application->main_window == NULL || + application->session == NULL || + evidence_identifier == NULL || + !g_uuid_string_is_valid( + evidence_identifier + )) + { + return; + } + + status_message = + g_strdup_printf( + "Vérification demandée pour la preuve : %s", + evidence_identifier + ); + + main_window_set_status( + application->main_window, + status_message + ); + + g_message( + "Demande de vérification reçue pour la preuve '%s'.", + evidence_identifier + ); + + g_free( + status_message + ); +} + /** * @brief Ferme proprement l'application. * @@ -2849,6 +2901,12 @@ static void application_on_activate( application ); + main_window_set_verify_evidence_callback( + application->main_window, + application_on_verify_evidence_requested, + application + ); + main_window_set_new_investigation_callback( application->main_window, application_on_new_investigation_requested, diff --git a/src/views/main_window.c b/src/views/main_window.c index b4fdf6d..e7f1970 100644 --- a/src/views/main_window.c +++ b/src/views/main_window.c @@ -86,6 +86,12 @@ struct MainWindow gpointer import_evidence_user_data; + MainWindowVerifyEvidenceCallback + verify_evidence_callback; + + gpointer + verify_evidence_user_data; + MainWindowQuitCallback quit_callback; @@ -246,6 +252,31 @@ static GtkWidget *main_window_create_action_button( return button; } +/** + * @brief Relaie la demande de vérification provenant du Workspace. + */ +static void main_window_on_verify_evidence_requested( + const char *evidence_identifier, + gpointer user_data +) +{ + MainWindow *main_window = + user_data; + + if (main_window == NULL || + main_window->verify_evidence_callback == NULL || + evidence_identifier == NULL || + evidence_identifier[0] == '\0') + { + return; + } + + main_window->verify_evidence_callback( + evidence_identifier, + main_window->verify_evidence_user_data + ); +} + MainWindow *main_window_new( GtkApplication *application, TaskManager *task_manager @@ -478,6 +509,12 @@ MainWindow *main_window_new( return NULL; } + workspace_set_verify_evidence_callback( + main_window->workspace, + main_window_on_verify_evidence_requested, + main_window + ); + workspace_widget = workspace_get_widget( main_window->workspace ); @@ -942,6 +979,24 @@ void main_window_set_import_evidence_enabled( ); } +void main_window_set_verify_evidence_callback( + MainWindow *main_window, + MainWindowVerifyEvidenceCallback callback, + gpointer user_data +) +{ + if (main_window == NULL) + { + return; + } + + main_window->verify_evidence_callback = + callback; + + main_window->verify_evidence_user_data = + user_data; +} + void main_window_set_quit_callback( MainWindow *main_window, MainWindowQuitCallback callback, @@ -1050,6 +1105,15 @@ void main_window_free( main_window->sidebar ); + if (main_window->workspace != NULL) + { + workspace_set_verify_evidence_callback( + main_window->workspace, + NULL, + NULL + ); + } + workspace_free( main_window->workspace ); diff --git a/src/widgets/workspace.c b/src/widgets/workspace.c index f16ac6a..a4e042f 100644 --- a/src/widgets/workspace.c +++ b/src/widgets/workspace.c @@ -41,6 +41,15 @@ struct Workspace GtkWidget *evidence_internal_name_label; GtkWidget *evidence_identifier_label; GtkWidget *evidence_sha256_label; + GtkWidget *verify_evidence_button; + + char *selected_evidence_identifier; + + WorkspaceVerifyEvidenceCallback + verify_evidence_callback; + + gpointer + verify_evidence_user_data; GtkWidget *node_name_label; GtkWidget *node_path_label; @@ -234,6 +243,33 @@ static void workspace_show_welcome( ); } +/** + * @brief Transmet la demande de vérification de la preuve affichée. + */ +static void workspace_on_verify_evidence_clicked( + GtkButton *button, + gpointer user_data +) +{ + Workspace *workspace = + user_data; + + (void) button; + + if (workspace == NULL || + workspace->verify_evidence_callback == NULL || + workspace->selected_evidence_identifier == NULL || + workspace->selected_evidence_identifier[0] == '\0') + { + return; + } + + workspace->verify_evidence_callback( + workspace->selected_evidence_identifier, + workspace->verify_evidence_user_data + ); +} + Workspace *workspace_new(void) { GtkWidget *evidence_content = NULL; @@ -534,6 +570,52 @@ Workspace *workspace_new(void) workspace->evidence_name_label ); + workspace->verify_evidence_button = + gtk_button_new_with_label( + "Vérifier l'intégrité" + ); + + if (workspace->verify_evidence_button == NULL) + { + workspace_free( + workspace + ); + + return NULL; + } + + gtk_widget_set_halign( + workspace->verify_evidence_button, + GTK_ALIGN_START + ); + + gtk_widget_set_tooltip_text( + workspace->verify_evidence_button, + "Recalculer le SHA-256 et le comparer à l'empreinte enregistrée" + ); + + /* + * Aucun bouton actif tant qu'aucune preuve n'est affichée. + */ + gtk_widget_set_sensitive( + workspace->verify_evidence_button, + FALSE + ); + + g_signal_connect( + workspace->verify_evidence_button, + "clicked", + G_CALLBACK( + workspace_on_verify_evidence_clicked + ), + workspace + ); + + gtk_box_append( + GTK_BOX(evidence_content), + workspace->verify_evidence_button + ); + evidence_separator = gtk_separator_new( GTK_ORIENTATION_HORIZONTAL @@ -723,6 +805,19 @@ void workspace_set_selected_node( return; } + g_clear_pointer( + &workspace->selected_evidence_identifier, + g_free + ); + + if (workspace->verify_evidence_button != NULL) + { + gtk_widget_set_sensitive( + workspace->verify_evidence_button, + FALSE + ); + } + if (node == NULL) { workspace_show_welcome(workspace); @@ -834,6 +929,19 @@ void workspace_set_selected_evidence( return; } + g_clear_pointer( + &workspace->selected_evidence_identifier, + g_free + ); + + if (workspace->verify_evidence_button != NULL) + { + gtk_widget_set_sensitive( + workspace->verify_evidence_button, + FALSE + ); + } + if (evidence_record == NULL) { workspace_show_welcome( @@ -843,6 +951,27 @@ void workspace_set_selected_evidence( return; } + workspace->selected_evidence_identifier = + g_strdup( + evidence_record_get_identifier( + evidence_record + ) + ); + + if (workspace->selected_evidence_identifier == NULL) + { + workspace_show_welcome( + workspace + ); + + return; + } + + gtk_widget_set_sensitive( + workspace->verify_evidence_button, + TRUE + ); + size_bytes = evidence_record_get_size_bytes( evidence_record @@ -973,6 +1102,24 @@ void workspace_set_selected_evidence( ); } +void workspace_set_verify_evidence_callback( + Workspace *workspace, + WorkspaceVerifyEvidenceCallback callback, + gpointer user_data +) +{ + if (workspace == NULL) + { + return; + } + + workspace->verify_evidence_callback = + callback; + + workspace->verify_evidence_user_data = + user_data; +} + void workspace_free(Workspace *workspace) { if (workspace == NULL) @@ -980,5 +1127,16 @@ void workspace_free(Workspace *workspace) return; } + workspace->verify_evidence_callback = + NULL; + + workspace->verify_evidence_user_data = + NULL; + + g_clear_pointer( + &workspace->selected_evidence_identifier, + g_free + ); + g_free(workspace); }