Watch
1
0
Fork
You've already forked pkg-proxy
1
mirror of https://github.com/git-pkgs/proxy.git synced 2026-11-09 15:49:16 -05:00
pkg-proxy/internal/config/hosted.go

77 lines
2.6 KiB
Go
Raw Permalink Normal View History

package config
import (
"fmt"
"strings"
)
const defaultHostedMaxUploadSize = "100MB"
// HostedConfig configures packages pushed to the proxy through the
// /api/hosted endpoints. Pushed versions are served in place of upstream
// versions with the same number, so writes always require a token.
type HostedConfig struct {
// Enabled registers the /api/hosted endpoints. Off by default.
Enabled bool `json:"enabled" yaml:"enabled"`
// Token is the bearer token required to push and delete packages.
// Required when Enabled. Supports ${VAR_NAME} expansion like AuthConfig
// fields.
Token string `json:"token" yaml:"token"`
// MaxUploadSize caps a single pushed archive (e.g., "100MB"). Must be > 0.
// Default: "100MB".
MaxUploadSize string `json:"max_upload_size" yaml:"max_upload_size"`
// NPMScopes are npm scopes (e.g. "@acme") served only from pushed
// packages. The upstream registry is never asked about them, so a package
// published there under the same name can't be mixed in.
NPMScopes []string `json:"npm_scopes" yaml:"npm_scopes"`
// ComposerVendors are Composer vendors (e.g. "acme") served only from
// pushed packages, like NPMScopes.
ComposerVendors []string `json:"composer_vendors" yaml:"composer_vendors"`
maxUploadBytes int64
}
// TokenExpanded returns Token with ${VAR_NAME} references expanded.
func (h *HostedConfig) TokenExpanded() string {
return expandEnv(h.Token)
}
// MaxUploadBytes returns the parsed MaxUploadSize. Validate must run first.
func (h *HostedConfig) MaxUploadBytes() int64 {
return h.maxUploadBytes
}
// Validate checks the hosted package settings, applying the default upload
// size if unset.
func (h *HostedConfig) Validate() error {
if h.MaxUploadSize == "" {
h.MaxUploadSize = defaultHostedMaxUploadSize
}
size, err := ParseSize(h.MaxUploadSize)
if err != nil {
return fmt.Errorf("invalid hosted.max_upload_size: %w", err)
}
if size <= 0 {
return fmt.Errorf("invalid hosted.max_upload_size %q: must be > 0", h.MaxUploadSize)
}
h.maxUploadBytes = size
if h.Enabled && h.TokenExpanded() == "" {
return fmt.Errorf("hosted.token is required when hosted.enabled is true")
}
for _, scope := range h.NPMScopes {
if len(scope) < 2 || scope[0] != '@' || strings.Contains(scope, "/") {
return fmt.Errorf("invalid hosted.npm_scopes entry %q: must be a scope such as \"@acme\"", scope)
}
}
for _, vendor := range h.ComposerVendors {
if vendor == "" || strings.Contains(vendor, "/") {
return fmt.Errorf("invalid hosted.composer_vendors entry %q: must be a vendor such as \"acme\"", vendor)
}
}
return nil
}