From 3f2c5699392e779139efbcfe4348642b861012d6 Mon Sep 17 00:00:00 2001 From: GISCE Bot Date: Mon, 2 Nov 2026 18:04:10 +0100 Subject: [PATCH] fix: select owner secret for organization pings Co-authored-by: Eduard Carreras --- src/github_agent_bridge/backend.py | 6 +++++- tests/test_webhook.py | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/github_agent_bridge/backend.py b/src/github_agent_bridge/backend.py index ddfbb67..7683367 100644 --- a/src/github_agent_bridge/backend.py +++ b/src/github_agent_bridge/backend.py @@ -858,7 +858,11 @@ async def _receive_github_webhook( raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="invalid_json") repository = payload.get("repository") if isinstance(payload, dict) else None full_name = repository.get("full_name") if isinstance(repository, dict) else None - owner = str(full_name or "").partition("/")[0].lower() + organization = payload.get("organization") if isinstance(payload, dict) else None + organization_login = ( + organization.get("login") if isinstance(organization, dict) else None + ) + owner = str(full_name or organization_login or "").partition("/")[0].lower() if config.webhook_secrets_by_owner: webhook_secrets = config.webhook_secrets_by_owner.get(owner, ()) if not webhook_secrets: diff --git a/tests/test_webhook.py b/tests/test_webhook.py index 700c9bf..c145122 100644 --- a/tests/test_webhook.py +++ b/tests/test_webhook.py @@ -1767,6 +1767,32 @@ def test_webhook_shadow_selects_secret_by_repository_owner(tmp_path): ).status_code == 401 +def test_webhook_shadow_selects_secret_by_organization_owner_for_ping(tmp_path): + payload = json.dumps({ + "zen": "Keep it logically awesome.", + "hook": {"id": 42, "type": "Organization"}, + "organization": {"login": "gisce"}, + }).encode() + client = TestClient(create_app(DashboardConfig( + db=tmp_path / "bridge.sqlite3", + require_auth=False, + webhook_secrets_by_owner={"gisce": ("gisce-secret",)}, + ))) + + response = client.post( + "/api/webhooks/github", + content=payload, + headers=signed_headers( + payload, + delivery="organization-ping", + event="ping", + secret="gisce-secret", + ), + ) + + assert response.status_code == 200 + + def test_webhook_shadow_rejects_unconfigured_repository_owner(tmp_path): payload = json.dumps({ "action": "created",