Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/github_agent_bridge/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
26 changes: 26 additions & 0 deletions tests/test_webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading