labfy-investigation/src/models/osint_action_catalog.c
2026-07-22 11:54:01 +02:00

188 lines
6.9 KiB
C

/******************************************************************************
* @file osint_action_catalog.c
* @brief Implémentation du catalogue des actions OSINT.
******************************************************************************/
#include "models/osint_action_catalog.h"
struct OsintAction
{
char *identifier;
char *label;
char *description;
OsintSelectionContextKind target_kind;
char *compatible_type;
char *required_tool_identifier;
gboolean available;
char *unavailable_reason;
char *tool_version;
};
struct OsintActionCatalog
{
GPtrArray *actions;
};
/** @brief Libère une action possédée par le catalogue. */
static void osint_action_free(gpointer data)
{
OsintAction *action = data;
if (action == NULL) return;
g_free(action->unavailable_reason);
g_free(action->tool_version);
g_free(action->compatible_type);
g_free(action->required_tool_identifier);
g_free(action->description);
g_free(action->label);
g_free(action->identifier);
g_free(action);
}
/** @brief Crée une action en copiant toutes ses chaînes. */
static OsintAction *osint_action_new(
const char *identifier,
const char *label,
const char *description,
OsintSelectionContextKind target_kind,
const char *compatible_type,
const char *required_tool_identifier,
gboolean available,
const char *unavailable_reason
)
{
OsintAction *action = g_try_new0(OsintAction, 1);
if (action == NULL) return NULL;
action->identifier = g_strdup(identifier);
action->label = g_strdup(label);
action->description = g_strdup(description);
action->target_kind = target_kind;
action->compatible_type = g_strdup(compatible_type);
action->required_tool_identifier = g_strdup(required_tool_identifier);
action->available = available;
action->unavailable_reason = g_strdup(unavailable_reason);
if (action->identifier == NULL || action->label == NULL ||
action->description == NULL ||
(!available && action->unavailable_reason == NULL))
{
osint_action_free(action);
return NULL;
}
return action;
}
OsintActionCatalog *osint_action_catalog_new_defaults(void)
{
OsintActionCatalog *catalog = g_try_new0(OsintActionCatalog, 1);
OsintAction *demonstration_action = NULL;
OsintAction *dns_action = NULL;
if (catalog == NULL) return NULL;
catalog->actions = g_ptr_array_new_with_free_func(osint_action_free);
demonstration_action = osint_action_new(
"selection-preview", "Aperçu de la sélection",
"Action locale de démonstration sans exécution externe.",
OSINT_SELECTION_CONTEXT_KIND_UNKNOWN, NULL, NULL, TRUE, NULL
);
dns_action = osint_action_new(
"dns-preview", "Résolution DNS",
"Exécute dig sur le nom de domaine sélectionné.",
OSINT_SELECTION_CONTEXT_KIND_ENTITY, "domain_name", "dns.dig", FALSE,
"L'outil requis n'a pas encore été vérifié."
);
if (catalog->actions == NULL || demonstration_action == NULL ||
dns_action == NULL)
{
osint_action_free(demonstration_action);
osint_action_free(dns_action);
osint_action_catalog_free(catalog);
return NULL;
}
g_ptr_array_add(catalog->actions, demonstration_action);
g_ptr_array_add(catalog->actions, dns_action);
return catalog;
}
/** @brief Compare deux actions par libellé. */
static gint osint_action_compare(gconstpointer first, gconstpointer second)
{
const OsintAction *const *a = first;
const OsintAction *const *b = second;
return g_strcmp0((*a)->label, (*b)->label);
}
GPtrArray *osint_action_catalog_list_compatible(
const OsintActionCatalog *catalog,
const OsintSelectionContext *context
)
{
GPtrArray *compatible_actions = NULL;
guint index = 0;
if (catalog == NULL || context == NULL || catalog->actions == NULL)
return NULL;
compatible_actions = g_ptr_array_new();
if (compatible_actions == NULL) return NULL;
for (index = 0; index < catalog->actions->len; index++)
{
OsintAction *action = g_ptr_array_index(catalog->actions, index);
gboolean kind_matches = action->target_kind ==
OSINT_SELECTION_CONTEXT_KIND_UNKNOWN ||
action->target_kind == osint_selection_context_get_kind(context);
gboolean type_matches = action->compatible_type == NULL ||
g_strcmp0(action->compatible_type,
osint_selection_context_get_type(context)) == 0;
if (kind_matches && type_matches)
g_ptr_array_add(compatible_actions, action);
}
g_ptr_array_sort(compatible_actions, osint_action_compare);
return compatible_actions;
}
void osint_action_catalog_update_tool_state(
OsintActionCatalog *catalog,
const char *tool_identifier,
OsintActionToolState state,
const char *version
)
{
guint index = 0;
if (catalog == NULL || catalog->actions == NULL ||
tool_identifier == NULL || tool_identifier[0] == '\0') return;
for (index = 0; index < catalog->actions->len; index++)
{
OsintAction *action = g_ptr_array_index(catalog->actions, index);
if (g_strcmp0(action->required_tool_identifier, tool_identifier) != 0)
continue;
g_clear_pointer(&action->tool_version, g_free);
g_clear_pointer(&action->unavailable_reason, g_free);
action->available = state == OSINT_ACTION_TOOL_STATE_AVAILABLE;
if (action->available)
action->tool_version = g_strdup(version);
else if (state == OSINT_ACTION_TOOL_STATE_MISSING)
action->unavailable_reason = g_strdup("L'outil requis est absent.");
else if (state == OSINT_ACTION_TOOL_STATE_INCOMPATIBLE)
action->unavailable_reason = g_strdup("La version installée est incompatible.");
else
action->unavailable_reason = g_strdup("L'outil requis n'a pas encore été vérifié.");
}
}
void osint_action_catalog_free(OsintActionCatalog *catalog)
{
if (catalog == NULL) return;
g_clear_pointer(&catalog->actions, g_ptr_array_unref);
g_free(catalog);
}
const char *osint_action_get_identifier(const OsintAction *action)
{ return action != NULL ? action->identifier : NULL; }
const char *osint_action_get_label(const OsintAction *action)
{ return action != NULL ? action->label : NULL; }
const char *osint_action_get_description(const OsintAction *action)
{ return action != NULL ? action->description : NULL; }
const char *osint_action_get_required_tool_identifier(const OsintAction *action)
{ return action != NULL ? action->required_tool_identifier : NULL; }
gboolean osint_action_is_available(const OsintAction *action)
{ return action != NULL && action->available; }
const char *osint_action_get_unavailable_reason(const OsintAction *action)
{ return action != NULL ? action->unavailable_reason : NULL; }
const char *osint_action_get_tool_version(const OsintAction *action)
{ return action != NULL ? action->tool_version : NULL; }