Initial commit — DRB server stack

Includes c2-core (FastAPI/MQTT/Firestore), discord-bot (slash commands),
frontend (Next.js admin UI), and mosquitto config.
This commit is contained in:
Logan
2026-04-05 19:01:39 -04:00
commit 2f0597c81b
77 changed files with 4126 additions and 0 deletions
@@ -0,0 +1,56 @@
import httpx
from typing import Optional
from app.config import settings
from app.internal.logger import logger
class C2Client:
def __init__(self):
self.base = settings.c2_url.rstrip("/")
async def get_nodes(self) -> list:
try:
async with httpx.AsyncClient(timeout=10) as client:
r = await client.get(f"{self.base}/nodes")
r.raise_for_status()
return r.json()
except Exception as e:
logger.error(f"C2 get_nodes failed: {e}")
return []
async def get_systems(self) -> list:
try:
async with httpx.AsyncClient(timeout=10) as client:
r = await client.get(f"{self.base}/systems")
r.raise_for_status()
return r.json()
except Exception as e:
logger.error(f"C2 get_systems failed: {e}")
return []
async def send_command(self, node_id: str, payload: dict) -> bool:
try:
async with httpx.AsyncClient(timeout=10) as client:
r = await client.post(
f"{self.base}/nodes/{node_id}/command",
json=payload,
)
r.raise_for_status()
return True
except Exception as e:
logger.error(f"C2 send_command failed: {e}")
return False
async def find_node_for_system(self, system_id: str) -> Optional[dict]:
"""Return the first online node assigned to the given system."""
nodes = await self.get_nodes()
for node in nodes:
if (
node.get("assigned_system_id") == system_id
and node.get("status") in ("online", "recording")
):
return node
return None
c2 = C2Client()