fix: reject unknown ecosystems instead of silently defaulting to pypi
This commit is contained in:
@@ -10,7 +10,6 @@ from fastapi import APIRouter, BackgroundTasks, Header, HTTPException, Request,
|
|||||||
|
|
||||||
from ..config import config
|
from ..config import config
|
||||||
from ..constants import (
|
from ..constants import (
|
||||||
DEFAULT_ECOSYSTEM,
|
|
||||||
METADATA_PATTERNS,
|
METADATA_PATTERNS,
|
||||||
PACKAGE_EXTENSIONS,
|
PACKAGE_EXTENSIONS,
|
||||||
RELEVANT_WEBHOOK_ACTIONS,
|
RELEVANT_WEBHOOK_ACTIONS,
|
||||||
@@ -50,7 +49,7 @@ def _extract_asset_path(asset: dict) -> str | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _detect_ecosystem(source: dict) -> str:
|
def _detect_ecosystem(source: dict) -> str | None:
|
||||||
"""Detect ecosystem from asset or component format field."""
|
"""Detect ecosystem from asset or component format field."""
|
||||||
fmt = source.get("format", "").lower()
|
fmt = source.get("format", "").lower()
|
||||||
if fmt in ("pypi", "pip", "python"):
|
if fmt in ("pypi", "pip", "python"):
|
||||||
@@ -59,7 +58,7 @@ def _detect_ecosystem(source: dict) -> str:
|
|||||||
return "go"
|
return "go"
|
||||||
if fmt in ("npm", "node"):
|
if fmt in ("npm", "node"):
|
||||||
return "npm"
|
return "npm"
|
||||||
return DEFAULT_ECOSYSTEM
|
return None
|
||||||
|
|
||||||
|
|
||||||
@router.post("/nexus")
|
@router.post("/nexus")
|
||||||
@@ -121,6 +120,8 @@ async def nexus_webhook(
|
|||||||
|
|
||||||
download_url = asset.get("downloadUrl") or _build_download_url(repository, asset_path)
|
download_url = asset.get("downloadUrl") or _build_download_url(repository, asset_path)
|
||||||
ecosystem = _detect_ecosystem(asset)
|
ecosystem = _detect_ecosystem(asset)
|
||||||
|
if ecosystem is None:
|
||||||
|
return {"status": WEBHOOK_STATUS_IGNORED, "reason": "unknown_ecosystem"}
|
||||||
|
|
||||||
log.info("Webhook: %s asset %s (%s) in %s", action, asset_path, ecosystem, repository)
|
log.info("Webhook: %s asset %s (%s) in %s", action, asset_path, ecosystem, repository)
|
||||||
|
|
||||||
@@ -145,6 +146,9 @@ async def nexus_webhook(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ecosystem = _detect_ecosystem(component)
|
ecosystem = _detect_ecosystem(component)
|
||||||
|
if ecosystem is None:
|
||||||
|
return {"status": WEBHOOK_STATUS_IGNORED, "reason": "unknown_ecosystem"}
|
||||||
|
|
||||||
background_tasks.add_task(_scan_component, repository, name, version, ecosystem)
|
background_tasks.add_task(_scan_component, repository, name, version, ecosystem)
|
||||||
return {
|
return {
|
||||||
"status": WEBHOOK_STATUS_ACCEPTED,
|
"status": WEBHOOK_STATUS_ACCEPTED,
|
||||||
|
|||||||
@@ -201,6 +201,22 @@ class TestErrorHandlingE2e:
|
|||||||
resp = await e2e_client.post("/webhooks/nexus", json=payload)
|
resp = await e2e_client.post("/webhooks/nexus", json=payload)
|
||||||
assert resp.status_code == 400
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_e2e_webhook_unknown_ecosystem(self, e2e_client):
|
||||||
|
"""Verify that webhooks with unknown ecosystem are rejected."""
|
||||||
|
payload = {
|
||||||
|
"action": "UPDATED",
|
||||||
|
"repositoryName": "test-repo",
|
||||||
|
"asset": {
|
||||||
|
"format": "maven",
|
||||||
|
"name": "/packages/test/1.0/test-1.0.tar.gz",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resp = await e2e_client.post("/webhooks/nexus", json=payload)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert resp.json()["status"] == "ignored"
|
||||||
|
assert resp.json()["reason"] == "unknown_ecosystem"
|
||||||
|
|
||||||
|
|
||||||
class TestWebsocketFragmentE2e:
|
class TestWebsocketFragmentE2e:
|
||||||
"""E2E tests for HTMX fragment responses."""
|
"""E2E tests for HTMX fragment responses."""
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ def test_detect_ecosystem_npm():
|
|||||||
def test_detect_ecosystem_unknown():
|
def test_detect_ecosystem_unknown():
|
||||||
from guarddog_nexus.routes.webhooks import _detect_ecosystem
|
from guarddog_nexus.routes.webhooks import _detect_ecosystem
|
||||||
|
|
||||||
assert _detect_ecosystem({"format": "maven"}) == "pypi" # unknown → default
|
assert _detect_ecosystem({"format": "maven"}) is None
|
||||||
assert _detect_ecosystem({}) == "pypi" # default
|
assert _detect_ecosystem({}) is None
|
||||||
|
|
||||||
|
|
||||||
# --- Go/npm webhook integration ---
|
# --- Go/npm webhook integration ---
|
||||||
|
|||||||
Reference in New Issue
Block a user