Only allow local folder uploads when SHOW_LOCAL=true
Local folder jobs are now refused with 403 unless the server runs with SHOW_LOCAL=true, and job kinds other than local or github are rejected. /api/health reports localFolders so the frontend can hide the option. Tests enable it explicitly where they index local folders.
This commit is contained in:
@@ -71,6 +71,7 @@ type Server struct {
|
||||
github githubApp
|
||||
authMu sync.Mutex
|
||||
auth map[string]*githubAuth // by session ID
|
||||
showLocal bool // SHOW_LOCAL=true allows uploading local folders
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -93,6 +94,7 @@ func NewServer(workspace string) *Server {
|
||||
indexSlots: make(chan struct{}, maxIndexing),
|
||||
github: githubAppFromEnv(),
|
||||
auth: map[string]*githubAuth{},
|
||||
showLocal: os.Getenv("SHOW_LOCAL") == "true",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +140,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case r.Method == http.MethodOptions:
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
case path == "/api/health" && r.Method == http.MethodGet:
|
||||
writeJSON(w, 200, map[string]any{"ok": true, "version": "0.1.0"})
|
||||
writeJSON(w, 200, map[string]any{"ok": true, "version": "0.1.0", "localFolders": s.showLocal})
|
||||
case path == "/api/jobs" && r.Method == http.MethodPost:
|
||||
s.createJob(w, r)
|
||||
case strings.HasPrefix(path, "/api/jobs/"):
|
||||
@@ -164,6 +166,14 @@ func (s *Server) createJob(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, 400, "Invalid job request")
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case request.Kind == "local" && !s.showLocal:
|
||||
writeError(w, 403, "Local folders are disabled on this server")
|
||||
return
|
||||
case request.Kind != "local" && request.Kind != "github":
|
||||
writeError(w, 400, "Invalid job request")
|
||||
return
|
||||
}
|
||||
owner := sessionID(w, r)
|
||||
url := ""
|
||||
if request.Kind == "github" {
|
||||
|
||||
+27
-1
@@ -107,6 +107,7 @@ func (c client) json(method, path, body string, wantStatus int, out any) {
|
||||
|
||||
func newTestServer(t *testing.T) (*Server, client) {
|
||||
server := NewServer(filepath.Join(t.TempDir(), "codenavigator"))
|
||||
server.showLocal = true // most tests index local folders
|
||||
ts := httptest.NewServer(server)
|
||||
t.Cleanup(ts.Close)
|
||||
return server, client{t, ts.URL, nil}.stranger()
|
||||
@@ -240,7 +241,7 @@ func TestRoutesAndHeaders(t *testing.T) {
|
||||
t.Fatalf("preflight = %d %v", res.StatusCode, res.Header)
|
||||
}
|
||||
|
||||
for path, contentType := range map[string]string{"/": "text/html", "/api.mjs": "text/javascript", "/styles.css": "text/css", "/config.js": "text/javascript", "/inter-latin.woff2": "font/woff2"} {
|
||||
for path, contentType := range map[string]string{"/": "text/html", "/api.mjs": "text/javascript", "/styles.css": "text/css", "/config.js": "text/javascript", "/fonts/archivo-black.woff2": "font/woff2"} {
|
||||
res, err := http.Get(c.url + path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -434,3 +435,28 @@ func TestProgressStreamSendsKeepAlivesWhileQueued(t *testing.T) {
|
||||
t.Fatalf("stream ended without a snapshot: %+v", job)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalFoldersDisabledByDefault(t *testing.T) {
|
||||
t.Setenv("SHOW_LOCAL", "")
|
||||
server := NewServer(filepath.Join(t.TempDir(), "codenavigator"))
|
||||
ts := httptest.NewServer(server)
|
||||
defer ts.Close()
|
||||
c := client{t, ts.URL, nil}.stranger()
|
||||
var health map[string]any
|
||||
c.json("GET", "/api/health", "", 200, &health)
|
||||
if health["localFolders"] != false {
|
||||
t.Fatalf("health = %v", health)
|
||||
}
|
||||
c.json("POST", "/api/jobs", `{"kind":"local"}`, 403, nil)
|
||||
c.json("POST", "/api/jobs", `{"kind":"mystery"}`, 400, nil)
|
||||
|
||||
t.Setenv("SHOW_LOCAL", "true")
|
||||
enabled := httptest.NewServer(NewServer(filepath.Join(t.TempDir(), "codenavigator")))
|
||||
defer enabled.Close()
|
||||
on := client{t, enabled.URL, nil}.stranger()
|
||||
on.json("GET", "/api/health", "", 200, &health)
|
||||
if health["localFolders"] != true {
|
||||
t.Fatalf("health with SHOW_LOCAL=true = %v", health)
|
||||
}
|
||||
on.json("POST", "/api/jobs", `{"kind":"local"}`, 201, nil)
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user