mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
fix(serve): a paired device opens only folders the window already lists
This commit is contained in:
1 parent
3463385901
commit
b8b7ac87f9
3 files changed
+92
No files matched your search
@@ -583,6 +583,10 @@ func (h *Hub) openRuntime(w http.ResponseWriter, r *http.Request) {
|
||||
badBody(w)
|
||||
return
|
||||
}
|
||||
if !hostReach(r) && !deviceMayOpenRoot(req.Root, h.knownRoots()) {
|
||||
refuse(w, http.StatusNotFound, codeDeviceHostOnly, "a paired device cannot use this", nil)
|
||||
return
|
||||
}
|
||||
rt, err := h.Open(r.Context(), req)
|
||||
if err != nil {
|
||||
// Every refusal Open produces carries its own status; what is left is
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package serve
|
||||
|
||||
import "path/filepath"
|
||||
|
||||
// deviceMayOpenRoot reports whether a paired device may open a pane on root: the
|
||||
// default folder, or one the window already lists. A folder the device names
|
||||
// itself would point the agent at whatever directory this machine can read.
|
||||
func deviceMayOpenRoot(root string, known []string) bool {
|
||||
if root == "" {
|
||||
return true
|
||||
}
|
||||
want := filepath.Clean(root)
|
||||
for _, k := range known {
|
||||
if filepath.Clean(k) == want {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// knownRoots are the folders open as panes now and the project list the
|
||||
// sidebar remembers.
|
||||
func (h *Hub) knownRoots() []string {
|
||||
roots := Workspaces()
|
||||
for _, v := range h.List() {
|
||||
roots = append(roots, v.Root)
|
||||
}
|
||||
return roots
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package serve
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"reasonix/internal/base/testenv"
|
||||
"reasonix/internal/contract/config"
|
||||
"reasonix/internal/session/control"
|
||||
)
|
||||
|
||||
func TestADeviceOpensOnlyFoldersTheWindowAlreadyListsAsRuntimes(t *testing.T) {
|
||||
t.Setenv("REASONIX_HOME", testenv.TempDir(t))
|
||||
hub := NewHub(HubOptions{Serve: config.ServeConfig{AuthMode: "none"}})
|
||||
defer hub.Shutdown()
|
||||
bc := NewBroadcaster()
|
||||
if _, err := hub.Adopt(New(control.New(control.Options{Sink: bc}), bc, config.ServeConfig{}), bc); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
before := len(hub.List())
|
||||
elsewhere := testenv.TempDir(t)
|
||||
|
||||
reg := NewDeviceRegistry()
|
||||
code, _ := reg.Offer()
|
||||
cred, _, err := reg.Redeem(code, "phone")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gate := NewDeviceGate(hub.Handler(), DeviceGateOptions{Registry: reg, Origin: "http://192.168.1.5:9000"})
|
||||
req := httptest.NewRequest(http.MethodPost, "http://192.168.1.5:9000/runtimes", strings.NewReader(`{"root":`+quoteJSON(elsewhere)+`}`))
|
||||
req.Header.Set("Origin", "http://192.168.1.5:9000")
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.AddCookie(&http.Cookie{Name: DeviceCookie, Value: cred})
|
||||
rec := httptest.NewRecorder()
|
||||
gate.ServeHTTP(rec, req)
|
||||
if rec.Code != http.StatusNotFound || !strings.Contains(rec.Body.String(), codeDeviceHostOnly) {
|
||||
t.Fatalf("a device opening an unlisted folder: %d %s, want 404 %s", rec.Code, rec.Body.String(), codeDeviceHostOnly)
|
||||
}
|
||||
if after := len(hub.List()); after != before {
|
||||
t.Fatalf("a runtime was opened for the device: %d -> %d", before, after)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeviceMayOpenRootNamesOnlyKnownFolders(t *testing.T) {
|
||||
known := []string{"/work/a", "/work/b"}
|
||||
for root, want := range map[string]bool{"": true, "/work/a": true, "/work/a/": true, "/work/b/../b": true, "/work": false, "/etc": false, "/work/a/sub": false} {
|
||||
if got := deviceMayOpenRoot(root, known); got != want {
|
||||
t.Errorf("deviceMayOpenRoot(%q) = %v, want %v", root, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func quoteJSON(s string) string {
|
||||
b, _ := json.Marshal(s)
|
||||
return string(b)
|
||||
}
|
||||
Reference in new issue
Block a user