feat: add evidence integrity verification action

This commit is contained in:
grayTerminal-sh 2026-07-20 14:01:53 +02:00
parent 5ad959315a
commit 4de91a7ad0
5 changed files with 337 additions and 0 deletions

View file

@ -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 ».
*

View file

@ -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.
*

View file

@ -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,

View file

@ -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
);

View file

@ -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);
}