Fix webhook signature handling

This commit is contained in:
AppFactory Bot
2026-05-27 12:50:47 +02:00
parent 26bfba5a73
commit 4c1696d97e
+28 -9
View File
@@ -7,7 +7,25 @@ import threading
from fastapi import FastAPI, Header, HTTPException, Request from fastapi import FastAPI, Header, HTTPException, Request
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET", "change-me-webhook-secret")
def read_env_file_value(key: str, default: str = "") -> str:
try:
with open("/opt/appfactory/config/appfactory.env", "r", encoding="utf-8") as f:
for line in f:
line = line.strip()
if line.startswith(f"{key}="):
return line.split("=", 1)[1].strip().strip('"')
except Exception:
pass
return default
WEBHOOK_SECRET = os.getenv(
"WEBHOOK_SECRET",
read_env_file_value("WEBHOOK_SECRET", "change-me-webhook-secret")
)
APP_DEPLOY_SCRIPT = "/tools/deploy-app.sh" APP_DEPLOY_SCRIPT = "/tools/deploy-app.sh"
CORE_DEPLOY_SCRIPT = "/tools/deploy-core-service.sh" CORE_DEPLOY_SCRIPT = "/tools/deploy-core-service.sh"
@@ -17,6 +35,7 @@ CORE_SERVICES = {
"appfactory-webhook", "appfactory-webhook",
} }
app = FastAPI(title="AppFactory Webhook") app = FastAPI(title="AppFactory Webhook")
@@ -29,15 +48,13 @@ def verify_signature(body: bytes, signature: str | None):
if not signature: if not signature:
raise HTTPException(status_code=401, detail="Missing signature") raise HTTPException(status_code=401, detail="Missing signature")
valid_signatures = [ expected = "sha256=" + hmac.new(
"sha256=" + hmac.new( WEBHOOK_SECRET.encode("utf-8"),
WEBHOOK_SECRET.encode("utf-8"), body,
body, hashlib.sha256
hashlib.sha256 ).hexdigest()
).hexdigest()
]
if not any(hmac.compare_digest(s, signature) for s in valid_signatures): if not hmac.compare_digest(expected, signature):
raise HTTPException(status_code=401, detail="Invalid signature") raise HTTPException(status_code=401, detail="Invalid signature")
@@ -69,9 +86,11 @@ async def gitea_webhook(
x_gitea_signature: str | None = Header(default=None), x_gitea_signature: str | None = Header(default=None),
): ):
body = await request.body() body = await request.body()
verify_signature(body, x_gitea_signature) verify_signature(body, x_gitea_signature)
payload = json.loads(body.decode("utf-8")) payload = json.loads(body.decode("utf-8"))
repo_name = payload.get("repository", {}).get("name") repo_name = payload.get("repository", {}).get("name")
if not repo_name: if not repo_name: