Skip to content

Admin panel: torrent management (list, toggle listed, delete) #56

@lewisgoddard

Description

@lewisgoddard

Part of the admin-panel expansion epic. Depends on Foundation (CSRF + layout/router). Highest operator value.

Torrents are auto-created on first announce and listed is the only visibility control — today with no UI to flip it and no way to delete a torrent.

New models

  • List all torrents with swarm stats: src/model/torrents.select.all.phptorrents_select_all(). Copy of torrents_select_listed() (src/model/torrents.select.listed.php) with the WHERE t.listed = 1 clause removed and the listed column added to the SELECT/return shape. Reuse its LEFT JOIN peers ... GROUP BY and intval() normalisation idiom.
  • Toggle listed: src/model/torrent.set.listed.phptorrent_set_listed(mysqli, settings, string $info_hash, int $listed): bool (UPDATE <prefix>torrents SET listed=? WHERE info_hash=?).
  • Delete torrent + its peers: src/model/torrent.delete.phptorrent_delete() and src/model/peers.delete.by.torrent.phppeers_delete_by_torrent(). Pattern mirrors torrents_clean() / peers_clean().

Security (critical)

info_hash arrives from the form, so it MUST pass through maybe_binary_to_hex() (src/functions/sanitize.maybe_binary_to_hex.php) before any query — the project's documented SQL-injection defense for the string-concatenated queries. Validate it is a 40-char hex string; bail via tracker_error() otherwise.

Controllers (one per file, matching admin.clean.php style)

  • src/controller/admin.torrents.phpadmin_torrents_controller() — fetches torrents_select_all() and renders the list page.
  • src/controller/admin.torrent.listed.phpadmin_torrent_listed_action()process=torrent_listed.
  • src/controller/admin.torrent.delete.phpadmin_torrent_delete_action()process=torrent_delete.

View

src/views/html.admin.torrents.phpview_admin_torrents_html() — a table of torrents (name, info_hash, size, seeders/leechers, downloads, traffic) with a per-row List/Unlist toggle and Delete button (each a CSRF-protected POST form carrying info_hash). htmlspecialchars() the name.

Optional — peer drill-down

src/model/peers.select.by.torrent.phppeers_select_by_torrent(), src/controller/admin.torrent.peers.php, src/views/html.admin.torrent.peers.php to inspect a torrent's peers (IP/port/state/up/down/left/last-seen).

Tests

TorrentsSelectAllTest, TorrentSetListedTest, TorrentDeleteTest, PeersDeleteByTorrentTest (+ PeersSelectByTorrentTest if built). Seed __TEST_% rows, clean up in tearDown().

Metadata

Metadata

Assignees

No one assigned

    Priority

    ⚠️ Medium

    Effort

    😏 Medium

    Stage

    👍 Confirmed

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions