aboutsummaryrefslogtreecommitdiff
path: root/internal/api/api.go
diff options
context:
space:
mode:
authorEthan Lee <ethanalee@google.com>2026-03-11 21:30:08 +0000
committerGopher Robot <gobot@golang.org>2026-03-30 13:36:55 -0700
commited9f544b260433d32a59bb7e9b52d7cafda78eec (patch)
tree48cb3a336a7a16de3f777f836ad2be1b57591a65 /internal/api/api.go
parent8514eebca6ca7b3213e879faa2a83c7e9ea6e181 (diff)
downloadgo-x-pkgsite-ed9f544b260433d32a59bb7e9b52d7cafda78eec.tar.xz
internal/api: implement vulnerabilities endpoint
- Create vulnerabilities endpoint using server vuln client. Change-Id: I234c96851f7682a13bda97aa3e5018d0439e05da Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/754866 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Ethan Lee <ethanalee@google.com> Reviewed-by: Jonathan Amsterdam <jba@google.com> kokoro-CI: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'internal/api/api.go')
-rw-r--r--internal/api/api.go54
1 files changed, 54 insertions, 0 deletions
diff --git a/internal/api/api.go b/internal/api/api.go
index 8cfe2151..60549f00 100644
--- a/internal/api/api.go
+++ b/internal/api/api.go
@@ -17,6 +17,7 @@ import (
"golang.org/x/pkgsite/internal/godoc"
"golang.org/x/pkgsite/internal/stdlib"
"golang.org/x/pkgsite/internal/version"
+ "golang.org/x/pkgsite/internal/vuln"
)
const (
@@ -460,6 +461,59 @@ func ServePackageImportedBy(w http.ResponseWriter, r *http.Request, ds internal.
return serveJSON(w, http.StatusOK, resp)
}
+// ServeVulnerabilities handles requests for the v1 module vulnerabilities endpoint.
+func ServeVulnerabilities(vc *vuln.Client) func(w http.ResponseWriter, r *http.Request, ds internal.DataSource) error {
+ return func(w http.ResponseWriter, r *http.Request, ds internal.DataSource) (err error) {
+ defer derrors.Wrap(&err, "ServeVulnerabilities")
+
+ modulePath := strings.TrimPrefix(r.URL.Path, "/v1/vulns/")
+ if modulePath == "" {
+ return serveErrorJSON(w, http.StatusBadRequest, "missing module path", nil)
+ }
+
+ var params VulnParams
+ if err := ParseParams(r.URL.Query(), &params); err != nil {
+ return serveErrorJSON(w, http.StatusBadRequest, err.Error(), nil)
+ }
+
+ if vc == nil {
+ return serveErrorJSON(w, http.StatusNotImplemented, "vulnerability data not available", nil)
+ }
+
+ requestedVersion := params.Version
+ if requestedVersion == "" {
+ requestedVersion = version.Latest
+ }
+
+ // Use VulnsForPackage from internal/vuln to get vulnerabilities for the module.
+ // Passing an empty packagePath gets all vulns for the module.
+ vulns := vuln.VulnsForPackage(r.Context(), modulePath, requestedVersion, "", vc)
+
+ limit := params.Limit
+ if limit <= 0 {
+ limit = 100
+ }
+ if limit > len(vulns) {
+ limit = len(vulns)
+ }
+
+ var items []Vulnerability
+ for _, v := range vulns[:limit] {
+ items = append(items, Vulnerability{
+ ID: v.ID,
+ Details: v.Details,
+ })
+ }
+
+ resp := PaginatedResponse[Vulnerability]{
+ Items: items,
+ Total: len(vulns),
+ }
+
+ return serveJSON(w, http.StatusOK, resp)
+ }
+}
+
// resolveModulePath determines the correct module path for a given package path and version.
// If the module path is not provided, it searches through potential candidate module paths
// derived from the package path. If multiple valid modules contain the package, it returns