Stream beets imports over HTTP.

feat(server,beets): confine import paths to GOOSEFOOT_IMPORT_DIR #21

Merged glerp.sullen.net
targeting main from glerp.sullen.net/goosefoot:fix/confine-import-path
Merged opened by and assigned to glerp.sullen.net
targeting main from glerp.sullen.net/goosefoot:fix/confine-import-path

Summary #

Confines POST /import target paths to a required staging directory (GOOSEFOOT_IMPORT_DIR / server.Config.ImportDirectory) and terminates beet import option flags with --:

  • Startup canonicalization (internal/server/server.go, cmd/goosefoot/main.go): Require ImportDirectory (GOOSEFOOT_IMPORT_DIR), resolving filepath.Abs + filepath.EvalSymlinks and verifying it is an existing directory once at startup.
  • Request path confinement (internal/server/import.go): Require non-empty absolute paths, resolve symlinks, verify the resolved target is a strict subpath of ImportDirectory (rejecting the root staging directory itself, .. traversals, sibling prefix directories, escaping symlinks, and non-regular/non-directory special files), pass the canonical resolved path to beet and post-import hooks, and return sanitized 400 responses without leaking raw os.PathError details.
  • CLI option terminator (internal/beets/runner.go): Pass -- before the positional target path in both DryRun and Import.
  • Tests & documentation: Add behavioral tests covering startup and request-boundary path validation, and document GOOSEFOOT_IMPORT_DIR in README.md, env.example, and CHANGELOG.md.

Verification #

  • gofmt -l .
  • go vet ./...
  • go test -race -count=1 ./...
Commits 0