""" Federation blueprint — peer status dashboard and management. """ from auth import admin_required, login_required from flask import Blueprint, flash, redirect, render_template, request, url_for bp = Blueprint("federation", __name__, url_prefix="/federation") @bp.route("/") @login_required def status(): """Federation status dashboard.""" from fieldwitness.attest.peer_store import PeerStore store = PeerStore() peers = store.list_peers() history = store.get_sync_history(limit=20) # Get local node info node_info = {"root": None, "size": 0} try: from fieldwitness.attest.storage import LocalStorage import fieldwitness.paths as _paths storage = LocalStorage(_paths.ATTESTATIONS_DIR) stats = storage.get_stats() merkle_log = storage.load_merkle_log() node_info = { "root": merkle_log.root_hash[:16] + "..." if merkle_log.root_hash else "empty", "size": merkle_log.size, "record_count": stats.record_count, } except Exception: pass return render_template( "federation/status.html", peers=peers, history=history, node_info=node_info, ) @bp.route("/peer/add", methods=["POST"]) @admin_required def peer_add(): """Add a federation peer.""" from fieldwitness.attest.peer_store import PeerStore url = request.form.get("url", "").strip() fingerprint = request.form.get("fingerprint", "").strip() if not url or not fingerprint: flash("URL and fingerprint are required.", "error") return redirect(url_for("federation.status")) store = PeerStore() store.add_peer(url, fingerprint) flash(f"Peer added: {url}", "success") return redirect(url_for("federation.status")) @bp.route("/peer/remove", methods=["POST"]) @admin_required def peer_remove(): """Remove a federation peer.""" from fieldwitness.attest.peer_store import PeerStore url = request.form.get("url", "").strip() store = PeerStore() if store.remove_peer(url): flash(f"Peer removed: {url}", "success") else: flash(f"Peer not found: {url}", "error") return redirect(url_for("federation.status"))