#!/usr/bin/env python3 """ Webhook receiver per Gitea — Diario Conversazioni Olimpic Nastri. Ascolta su porta 9000, verifica la firma HMAC del payload Gitea, e lancia deploy.sh quando riceve un push sul branch main. """ import hashlib import hmac import json import subprocess import sys from http.server import HTTPServer, BaseHTTPRequestHandler WEBHOOK_SECRET = "c91dca86b9a87d9f25e07a63354da9f2469998f9" DEPLOY_SCRIPT = "/home/marco/olimpic_nastri/deploy.sh" LISTEN_PORT = 9000 class WebhookHandler(BaseHTTPRequestHandler): def do_POST(self): if self.path != "/deploy": self.send_response(404) self.end_headers() return content_length = int(self.headers.get("Content-Length", 0)) if content_length > 1_000_000: # max 1 MB payload self.send_response(413) self.end_headers() return body = self.rfile.read(content_length) # Verifica firma HMAC-SHA256 di Gitea signature = self.headers.get("X-Gitea-Signature", "") expected = hmac.new( WEBHOOK_SECRET.encode(), body, hashlib.sha256 ).hexdigest() if not hmac.compare_digest(signature, expected): self.send_response(403) self.end_headers() self.wfile.write(b"Firma non valida") return # Controlla che sia un push su main try: payload = json.loads(body) except json.JSONDecodeError: self.send_response(400) self.end_headers() return ref = payload.get("ref", "") if ref != "refs/heads/main": self.send_response(200) self.end_headers() self.wfile.write(b"Push ignorato (non main)") return # Lancia il deploy in background subprocess.Popen([DEPLOY_SCRIPT], close_fds=True) self.send_response(200) self.end_headers() self.wfile.write(b"Deploy avviato") def log_message(self, format, *args): print(f"[webhook] {args[0]}", flush=True) def main(): server = HTTPServer(("127.0.0.1", LISTEN_PORT), WebhookHandler) print(f"Webhook receiver in ascolto su 127.0.0.1:{LISTEN_PORT}", flush=True) try: server.serve_forever() except KeyboardInterrupt: pass server.server_close() if __name__ == "__main__": main()