Quarantine Management Module ( QuarantinePage)

1. Overview

The Quarantine module provides a user-facing interface to manage files isolated by BastionGuard. It lists quarantined items and allows the user to perform two controlled actions:

  • Restore a quarantined file to its original location (via the quarantine backend)
  • Delete a quarantined file permanently (via the quarantine backend)

The module is implemented as a GTKmm (GTK4) page. It continuously keeps the list synchronized with the quarantine directory using a filesystem monitor, with an additional periodic refresh fallback.


2. User Interface Structure

2.1 Layout

The page is implemented as a vertical container (Gtk::Box) containing:

  • A Gtk::ListBox (listBox) where quarantine rows are rendered
  • An empty-state label (emptyLabel) displayed when no quarantined files exist

The empty label is centered both horizontally and vertically and displays:

No files in quarantine

2.2 Quarantine Rows

Each quarantined file is represented as a row composed of:

  • A filename label (left-aligned, expandable)
  • A Restore button
  • A Delete button

Row structure:

[ FILENAME ]  [ Restore ]  [ Delete ]

3. Directory Monitoring and Refresh Model

3.1 Directory Monitor

To keep the list synchronized in near real time, the module creates a directory monitor using Gio::File::monitor_directory().

The monitor is installed by updateMonitor(), which:

  • Resets any previous monitor instance
  • Ensures the quarantine directory exists (creates it if missing)
  • Attaches a filesystem change callback

On any directory change event, the callback onDirChanged(...) triggers a full refresh by calling:

refreshList()

3.2 Periodic Refresh Fallback

In addition to the filesystem monitor, a fallback refresh is scheduled every 10 seconds. This ensures the UI remains correct even on filesystems or environments where directory notifications may not fire reliably.

Fallback timer:

Glib::signal_timeout().connect(..., 10000)

The callback is the same list rebuild function:

bool QuarantinePage::refreshList()

4. List Rendering Logic

4.1 Full Rebuild Strategy

refreshList() rebuilds the entire list on each refresh. The process is:

  1. Remove all existing children from the list box
  2. Read the quarantine directory path from the quarantine backend
  3. Enumerate directory entries and render one row per valid quarantined file
  4. Show or hide the empty-state label depending on results

4.2 File Filtering Rules

During directory iteration, the module applies the following filters:

  • Only regular files are listed (entry.is_regular_file())
  • Metadata files are ignored (files with extension .meta)

This ensures the UI presents only user-relevant quarantined payload files, not internal quarantine metadata.


5. Restore and Delete Actions

5.1 Restore

When the user clicks Restore, the module calls the quarantine backend:

Quarantine::restore(fullPath)

If the restore succeeds, the list is immediately refreshed.


5.2 Delete

When the user clicks Delete, the module calls:

Quarantine::remove(fullPath)

If deletion succeeds, the list is refreshed.


6. Change Handling

Filesystem changes are handled using a simple strategy: any monitor event triggers a full list rebuild. The change callback does not attempt to interpret event types; it simply calls:

refreshList()

This approach prioritizes correctness and simplicity over incremental UI updates.


7. Design and Security Considerations

  • Backend authority: restore/delete actions are delegated to the Quarantine backend, ensuring consistent enforcement of quarantine rules and metadata handling.
  • UI correctness: the combined use of a filesystem monitor and periodic fallback refresh reduces the risk of stale UI state.
  • Metadata isolation: the UI explicitly filters out .meta files to avoid exposing internal quarantine metadata to the user.
  • Controlled operations: the only supported operations are restore and delete; no direct editing or execution paths exist in the UI layer.