#!/usr/bin/env python3 import argparse import os import sys from pathlib import Path # Add project root to sys.path to allow imports PROJECT_ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(PROJECT_ROOT)) import httpx from backend.settings import get_settings from backend.update import _ensure_parent def main(): parser = argparse.ArgumentParser(description="Manual Enrollment Client") parser.add_argument("--url", default="https://update.wlkns.org", help="Update Service URL") parser.add_argument("--token", required=True, help="Enrollment Token") parser.add_argument("--project", default="safe-kiddo-control", help="Project ID") parser.add_argument("--insecure", action="store_true", help="Disable SSL verification") args = parser.parse_args() settings = get_settings() print(f"[*] Enrolling client {os.uname().nodename}...") print(f"[*] Service URL: {args.url}") print(f"[*] Project ID: {args.project}") enroll_url = f"{args.url}/v1/enroll" payload = { "project_id": args.project, "client_id": os.uname().nodename, "software_id": "safe-kiddo", "enroll_token": args.token, } try: with httpx.Client(verify=not args.insecure, timeout=10.0) as client: response = client.post(enroll_url, json=payload) if response.status_code != 200: print(f"[!] Error {response.status_code}: {response.text}") sys.exit(1) data = response.json() token = data.get("token") if not token: print("[!] Error: No token received in response") sys.exit(1) token_path = Path(settings.update_token_file) _ensure_parent(token_path) token_path.write_text(token, encoding="utf-8") # Make sure only root/service user can read it os.chmod(token_path, 0o600) print(f"[+] Success! Token saved to {token_path}") except Exception as e: print(f"[!] Exception: {e}") sys.exit(1) if __name__ == "__main__": main()