feat: add go backend skeleton

This commit is contained in:
Yoilun
2026-05-25 16:04:26 +08:00
parent de20fda424
commit be466ae5fc
8 changed files with 156 additions and 2 deletions

22
internal/app/config.go Normal file
View File

@@ -0,0 +1,22 @@
package app
import (
"os"
"path/filepath"
)
type Config struct {
CodexHome string
HTTPAddr string
}
func DefaultConfig() Config {
home, err := os.UserHomeDir()
if err != nil {
home = "."
}
return Config{
CodexHome: filepath.Join(home, ".codex"),
HTTPAddr: "127.0.0.1:18083",
}
}

View File

@@ -0,0 +1,55 @@
package codexhome
import (
"errors"
"path/filepath"
"strings"
)
var ErrOutsideCodexHome = errors.New("路径超出 Codex home")
var ErrForbiddenPath = errors.New("禁止访问敏感路径")
func ResolveInside(home string, rel string) (string, error) {
if filepath.IsAbs(rel) {
return "", ErrOutsideCodexHome
}
cleanHome, err := filepath.Abs(home)
if err != nil {
return "", err
}
candidate, err := filepath.Abs(filepath.Join(cleanHome, rel))
if err != nil {
return "", err
}
relative, err := filepath.Rel(cleanHome, candidate)
if err != nil {
return "", err
}
if relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
return "", ErrOutsideCodexHome
}
if IsForbidden(candidate, cleanHome) {
return "", ErrForbiddenPath
}
return candidate, nil
}
func IsForbidden(path string, home string) bool {
cleanHome, err := filepath.Abs(home)
if err != nil {
return true
}
cleanPath, err := filepath.Abs(path)
if err != nil {
return true
}
rel, err := filepath.Rel(cleanHome, cleanPath)
if err != nil {
return true
}
rel = filepath.ToSlash(rel)
forbidden := map[string]bool{
"auth.json": true,
}
return forbidden[rel]
}

View File

@@ -0,0 +1,34 @@
package codexhome
import (
"path/filepath"
"testing"
)
func TestResolveInsideCodexHomeAllowsAgentsToml(t *testing.T) {
home := filepath.Join(t.TempDir(), ".codex")
got, err := ResolveInside(home, "agents/product-manager.toml")
if err != nil {
t.Fatalf("ResolveInside returned error: %v", err)
}
want := filepath.Join(home, "agents", "product-manager.toml")
if got != want {
t.Fatalf("path mismatch: got %q want %q", got, want)
}
}
func TestResolveInsideCodexHomeRejectsTraversal(t *testing.T) {
home := filepath.Join(t.TempDir(), ".codex")
_, err := ResolveInside(home, "../auth.json")
if err == nil {
t.Fatal("expected traversal to be rejected")
}
}
func TestIsForbiddenPathBlocksAuthJSON(t *testing.T) {
home := filepath.Join(t.TempDir(), ".codex")
path := filepath.Join(home, "auth.json")
if !IsForbidden(path, home) {
t.Fatal("auth.json must be forbidden")
}
}