Watch
1
0
Fork
You've already forked pkg-proxy
1
mirror of https://github.com/git-pkgs/proxy.git synced 2026-11-10 08:09:17 -05:00
pkg-proxy/internal/denylist/denylist.go
2026-09-20 14:42:30 +05:30

67 lines
1.8 KiB
Go

// Package denylist implements an immutable, exact-version package policy.
package denylist
import (
"fmt"
"strings"
"github.com/git-pkgs/purl"
)
// Policy is safe for concurrent reads. A nil policy allows every version.
type Policy struct {
packages map[string]map[string]bool
}
// New validates and canonicalizes versioned PURLs. Qualifiers and subpaths are
// rejected because the proxy cannot reliably distinguish them at every endpoint.
func New(packages []string) (*Policy, error) {
if len(packages) == 0 {
return nil, nil
}
p := &Policy{packages: make(map[string]map[string]bool)}
for _, value := range packages {
pkg, err := purl.Parse(value)
if err != nil {
return nil, fmt.Errorf("invalid denylist package %q: %w", value, err)
}
if pkg.Version == "" || len(pkg.Qualifiers) != 0 || pkg.Subpath != "" ||
strings.ContainsAny(pkg.Namespace+pkg.Name+pkg.Version, "*?[]<>=| \t\r\n") {
return nil, fmt.Errorf("invalid denylist package %q: expected an exact versioned PURL without qualifiers or subpath", value)
}
key := pkg.WithoutVersion().String()
if p.packages[key] == nil {
p.packages[key] = make(map[string]bool)
}
p.packages[key][pkg.Version] = true
}
return p, nil
}
// Denied reports whether a versioned PURL is denied.
func (p *Policy) Denied(value string) bool {
if p == nil || len(p.packages) == 0 {
return false
}
pkg, err := purl.Parse(value)
if err != nil {
return false
}
return p.packages[pkg.WithoutVersion().String()][pkg.Version]
}
// Versions returns a caller-owned set of denied versions for a package PURL.
func (p *Policy) Versions(packagePURL string) map[string]bool {
if p == nil {
return nil
}
versions := p.packages[packagePURL]
if len(versions) == 0 {
return nil
}
result := make(map[string]bool, len(versions))
for version := range versions {
result[version] = true
}
return result
}