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
22 changes: 11 additions & 11 deletions internal/database/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,16 @@ type MetadataCacheEntry struct {

// Vulnerability represents a cached vulnerability record.
type Vulnerability struct {
ID int64 `db:"id" json:"id"`
VulnID string `db:"vuln_id" json:"vuln_id"`
Ecosystem string `db:"ecosystem" json:"ecosystem"`
PackageName string `db:"package_name" json:"package_name"`
Severity sql.NullString `db:"severity" json:"severity,omitempty"`
Summary sql.NullString `db:"summary" json:"summary,omitempty"`
FixedVersion sql.NullString `db:"fixed_version" json:"fixed_version,omitempty"`
ID int64 `db:"id" json:"id"`
VulnID string `db:"vuln_id" json:"vuln_id"`
Ecosystem string `db:"ecosystem" json:"ecosystem"`
PackageName string `db:"package_name" json:"package_name"`
Severity sql.NullString `db:"severity" json:"severity,omitempty"`
Summary sql.NullString `db:"summary" json:"summary,omitempty"`
FixedVersion sql.NullString `db:"fixed_version" json:"fixed_version,omitempty"`
CVSSScore sql.NullFloat64 `db:"cvss_score" json:"cvss_score,omitempty"`
References sql.NullString `db:"references" json:"references,omitempty"`
FetchedAt sql.NullTime `db:"fetched_at" json:"fetched_at,omitempty"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
References sql.NullString `db:"references" json:"references,omitempty"`
FetchedAt sql.NullTime `db:"fetched_at" json:"fetched_at,omitempty"`
CreatedAt time.Time `db:"created_at" json:"created_at"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
}
8 changes: 4 additions & 4 deletions internal/handler/composer.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ func (h *ComposerHandler) Routes() http.Handler {
func (h *ComposerHandler) handleServiceIndex(w http.ResponseWriter, r *http.Request) {
// Return a minimal service index pointing to our proxy
index := map[string]any{
"packages": map[string]any{},
"metadata-url": h.proxyURL + "/composer/p2/%package%.json",
"notify-batch": h.upstreamURL + "/downloads/",
"search": h.proxyURL + "/composer/search.json?q=%query%&type=%type%",
"packages": map[string]any{},
"metadata-url": h.proxyURL + "/composer/p2/%package%.json",
"notify-batch": h.upstreamURL + "/downloads/",
"search": h.proxyURL + "/composer/search.json?q=%query%&type=%type%",
"providers-lazy-url": h.proxyURL + "/composer/p2/%package%.json",
}

Expand Down
6 changes: 3 additions & 3 deletions internal/handler/conda_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ func TestCondaIsPackageFile(t *testing.T) {

func TestCondaCooldownFiltering(t *testing.T) {
now := time.Now()
oldTimestamp := float64(now.Add(-7*24*time.Hour).UnixMilli())
recentTimestamp := float64(now.Add(-1*time.Hour).UnixMilli())
oldTimestamp := float64(now.Add(-7 * 24 * time.Hour).UnixMilli())
recentTimestamp := float64(now.Add(-1 * time.Hour).UnixMilli())

repodata := map[string]any{
"info": map[string]any{},
"info": map[string]any{},
"packages": map[string]any{
"numpy-1.24.0-old.tar.bz2": map[string]any{
"name": "numpy",
Expand Down
1 change: 0 additions & 1 deletion internal/handler/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,6 @@ func (h *ContainerHandler) proxyBlobHead(w http.ResponseWriter, r *http.Request,
w.WriteHeader(resp.StatusCode)
}


// containerError writes an OCI-compliant error response.
func (h *ContainerHandler) containerError(w http.ResponseWriter, status int, code, message string) {
w.Header().Set("Content-Type", "application/json")
Expand Down
4 changes: 2 additions & 2 deletions internal/handler/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ func TestContainerHandler_parseManifestPath(t *testing.T) {
wantReference: "sha256:abc123",
},
{
path: "invalid/path",
wantName: "",
path: "invalid/path",
wantName: "",
},
}

Expand Down
9 changes: 4 additions & 5 deletions internal/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,11 @@ func (p *Proxy) updateCacheDB(ecosystem, name, filename, pkgPURL, versionPURL, u

// Upsert package
pkg := &database.Package{
PURL: pkgPURL,
Ecosystem: ecosystem,
Name: name,
PURL: pkgPURL,
Ecosystem: ecosystem,
Name: name,
RegistryURL: sql.NullString{String: upstreamURL, Valid: true},
EnrichedAt: sql.NullTime{Time: now, Valid: true},
EnrichedAt: sql.NullTime{Time: now, Valid: true},
}
if err := p.DB.UpsertPackage(pkg); err != nil {
return fmt.Errorf("upserting package: %w", err)
Expand Down Expand Up @@ -728,4 +728,3 @@ func (p *Proxy) fetchAndCacheFromURL(ctx context.Context, ecosystem, name, versi
Cached: false,
}, nil
}

6 changes: 3 additions & 3 deletions internal/handler/npm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ func TestNPMExtractVersionFromFilename(t *testing.T) {
{"@babel/core", "core-7.23.0.tgz", "7.23.0"},
{"@types/node", "node-20.10.0.tgz", "20.10.0"},
{"express", "express-4.18.2.tgz", "4.18.2"},
{"lodash", "lodash.tgz", ""}, // no version
{"lodash", "lodash-4.17.21.zip", ""}, // wrong extension
{"lodash", "other-4.17.21.tgz", ""}, // wrong package name
{"lodash", "lodash.tgz", ""}, // no version
{"lodash", "lodash-4.17.21.zip", ""}, // wrong extension
{"lodash", "other-4.17.21.tgz", ""}, // wrong package name
}

for _, tt := range tests {
Expand Down
6 changes: 3 additions & 3 deletions internal/handler/nuget.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ func (h *NuGetHandler) shouldRewriteService(serviceType string) bool {
func (h *NuGetHandler) rewriteNuGetURL(origURL string) string {
// Map known NuGet API endpoints to our proxy paths
replacements := map[string]string{
"https://api.nuget.org/v3-flatcontainer/": h.proxyURL + "/nuget/v3-flatcontainer/",
"https://api.nuget.org/v3-flatcontainer/": h.proxyURL + "/nuget/v3-flatcontainer/",
"https://api.nuget.org/v3/registration5-gz-semver2/": h.proxyURL + "/nuget/v3/registration5-gz-semver2/",
"https://azuresearch-usnc.nuget.org/query": h.proxyURL + "/nuget/query",
"https://azuresearch-usnc.nuget.org/autocomplete": h.proxyURL + "/nuget/autocomplete",
"https://azuresearch-usnc.nuget.org/query": h.proxyURL + "/nuget/query",
"https://azuresearch-usnc.nuget.org/autocomplete": h.proxyURL + "/nuget/autocomplete",
}

for old, new := range replacements {
Expand Down
8 changes: 4 additions & 4 deletions internal/handler/nuget_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ func TestNuGetRewriteServiceIndex(t *testing.T) {
}

expectations := map[string]string{
"PackageBaseAddress/3.0.0": "http://localhost:8080/nuget/v3-flatcontainer/",
"RegistrationsBaseUrl/3.6.0": "http://localhost:8080/nuget/v3/registration5-gz-semver2/",
"SearchQueryService/3.5.0": "http://localhost:8080/nuget/query",
"PackageBaseAddress/3.0.0": "http://localhost:8080/nuget/v3-flatcontainer/",
"RegistrationsBaseUrl/3.6.0": "http://localhost:8080/nuget/v3/registration5-gz-semver2/",
"SearchQueryService/3.5.0": "http://localhost:8080/nuget/query",
"SearchAutocompleteService/3.5.0": "http://localhost:8080/nuget/autocomplete",
"SomeOtherService/1.0.0": "https://example.com/other-service",
"SomeOtherService/1.0.0": "https://example.com/other-service",
}

for _, res := range resources {
Expand Down
10 changes: 5 additions & 5 deletions internal/handler/pypi.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ import (
)

const (
pypiUpstream = "https://pypi.org"
minWheelParts = 5 // name + version + python + abi + platform
minSubmatchParts = 2 // full match + first capture group
minPyPIPathParts = 3 // hash_prefix + hash + filename
minPythonTagLen = 2 // minimum length for a python tag (e.g., "py")
pypiUpstream = "https://pypi.org"
minWheelParts = 5 // name + version + python + abi + platform
minSubmatchParts = 2 // full match + first capture group
minPyPIPathParts = 3 // hash_prefix + hash + filename
minPythonTagLen = 2 // minimum length for a python tag (e.g., "py")
)

// PyPIHandler handles PyPI registry protocol requests.
Expand Down
2 changes: 1 addition & 1 deletion internal/metrics/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestRecordStorageOperations(t *testing.T) {

func TestUpdateCacheStats(t *testing.T) {
UpdateCacheStats(1024*1024*1024, 100) // 1GB, 100 artifacts
UpdateCacheStats(0, 0) // Empty cache
UpdateCacheStats(0, 0) // Empty cache

// No panics = success
}
Expand Down
6 changes: 3 additions & 3 deletions internal/mirror/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ type JobRequest struct {

// JobStore manages in-memory mirror jobs.
type JobStore struct {
mu sync.RWMutex
jobs map[string]*Job
mirror *Mirror
mu sync.RWMutex
jobs map[string]*Job
mirror *Mirror
parentCtx context.Context
}

Expand Down
14 changes: 7 additions & 7 deletions internal/mirror/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ func New(proxy *handler.Proxy, db *database.DB, store storage.Storage, logger *s

// Progress tracks the state of a mirror operation.
type Progress struct {
Total int64 `json:"total"`
Completed int64 `json:"completed"`
Skipped int64 `json:"skipped"`
Failed int64 `json:"failed"`
Bytes int64 `json:"bytes"`
Total int64 `json:"total"`
Completed int64 `json:"completed"`
Skipped int64 `json:"skipped"`
Failed int64 `json:"failed"`
Bytes int64 `json:"bytes"`
Errors []MirrorError `json:"errors,omitempty"`
StartedAt time.Time `json:"started_at"`
Phase string `json:"phase"`
StartedAt time.Time `json:"started_at"`
Phase string `json:"phase"`
}

// MirrorError records a single failed mirror attempt.
Expand Down
2 changes: 1 addition & 1 deletion internal/mirror/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/git-pkgs/purl"
"github.com/git-pkgs/registries"
_ "github.com/git-pkgs/registries/all"
"github.com/spdx/tools-golang/spdx"
spdxjson "github.com/spdx/tools-golang/json"
"github.com/spdx/tools-golang/spdx"
spdxtv "github.com/spdx/tools-golang/tagvalue"
)

Expand Down
6 changes: 3 additions & 3 deletions internal/mirror/source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ func TestSBOMSourceSPDXJSON(t *testing.T) {
"documentNamespace": "https://example.com/test",
"packages": []map[string]any{
{
"SPDXID": "SPDXRef-Package",
"name": "lodash",
"version": "4.17.21",
"SPDXID": "SPDXRef-Package",
"name": "lodash",
"version": "4.17.21",
"downloadLocation": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"externalRefs": []map[string]any{
{
Expand Down
10 changes: 5 additions & 5 deletions internal/server/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,11 +585,11 @@ func (h *APIHandler) HandlePackagesList(w http.ResponseWriter, r *http.Request)

validSorts := map[string]bool{
defaultSortBy: true,
"name": true,
"size": true,
"cached_at": true,
"ecosystem": true,
"vulns": true,
"name": true,
"size": true,
"cached_at": true,
"ecosystem": true,
"vulns": true,
}
if !validSorts[sortBy] {
http.Error(w, "invalid sort parameter", http.StatusBadRequest)
Expand Down
1 change: 0 additions & 1 deletion internal/server/browse.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ func openArchive(filename string, content io.Reader, ecosystem string) (archives
return archives.OpenWithPrefix(fname, bytes.NewReader(data), prefix)
}


// BrowseListResponse contains the file listing for a directory in an archives.
type BrowseListResponse struct {
Path string `json:"path"`
Expand Down
10 changes: 5 additions & 5 deletions internal/server/browse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ func TestHandleBrowseFile(t *testing.T) {

func TestDetectContentType(t *testing.T) {
tests := []struct {
filename string
expectedCT string
filename string
expectedCT string
}{
{"file.txt", contentTypePlainText},
{"file.md", contentTypePlainText},
Expand Down Expand Up @@ -616,9 +616,9 @@ func TestArchiveFilename(t *testing.T) {

func TestOpenArchiveStripsSingleRootDir(t *testing.T) {
data := createZipArchive(t, map[string]string{
"repo-abc123/README.md": "hello",
"repo-abc123/src/main.go": "package main",
"repo-abc123/go.mod": "module test",
"repo-abc123/README.md": "hello",
"repo-abc123/src/main.go": "package main",
"repo-abc123/go.mod": "module test",
})
reader, err := openArchive("test.zip", bytes.NewReader(data), "composer")
if err != nil {
Expand Down
1 change: 0 additions & 1 deletion internal/server/templates_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,6 @@ func TestSearchPage_EcosystemFilter(t *testing.T) {
}
}


func TestEcosystemBadgeLabel(t *testing.T) {
tests := []struct {
ecosystem string
Expand Down
6 changes: 3 additions & 3 deletions internal/storage/filesystem_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ func TestFilesystemUsedSpace(t *testing.T) {
}

// Add some files
_, _, _ = fs.Store(ctx, "a.txt", strings.NewReader("aaaa")) // 4 bytes
_, _, _ = fs.Store(ctx, "b.txt", strings.NewReader("bbbbbb")) // 6 bytes
_, _, _ = fs.Store(ctx, "c/d.txt", strings.NewReader("ccccc")) // 5 bytes
_, _, _ = fs.Store(ctx, "a.txt", strings.NewReader("aaaa")) // 4 bytes
_, _, _ = fs.Store(ctx, "b.txt", strings.NewReader("bbbbbb")) // 6 bytes
_, _, _ = fs.Store(ctx, "c/d.txt", strings.NewReader("ccccc")) // 5 bytes

used, err = fs.UsedSpace(ctx)
if err != nil {
Expand Down