package server import ( "net/http" "net/http/httptest" "strings" "testing" "github.com/x-grk/longpolling-remote-access/internal/proto" ) // A saved host's secret is stored encrypted, and only its owner gets it back. func TestSavedSSHHosts(t *testing.T) { s, _ := newTestServer(t) a, _ := s.db.AdminByUsername("adm") id, err := s.saveSSHHost(a.ID, savedHost{Label: "web", Host: "h", Port: 22, User: "root", Auth: "password"}, sshSecret{Password: "s3cret-pass"}) if err != nil { t.Fatal(err) } var raw string _ = s.db.sql.QueryRow(`SELECT secret FROM ssh_hosts WHERE id = ?`, id).Scan(&raw) if raw == "" || strings.Contains(raw, "s3cret-pass") { t.Fatalf("secret stored as %q", raw) } got := &proto.SSHTarget{Saved: id} if err := s.fillSaved(a.ID, got); err != nil || got.Password != "s3cret-pass" || got.Host != "h" || got.User != "root" || got.Saved != 0 { t.Fatalf("own: %+v %v", got, err) } if err := s.fillSaved(a.ID+1, &proto.SSHTarget{Saved: id}); err == nil { t.Fatal("another user got the host") } if list := s.listSSHHosts(a.ID); len(list) != 1 || list[0].Label != "web" { t.Fatalf("list: %+v", list) } if len(s.listSSHHosts(a.ID+1)) != 0 { t.Fatal("another user sees the host") } } // The routes: a saved host shows without its secret. func TestSavedSSHHostsRoute(t *testing.T) { s, c := newTestServer(t) req := httptest.NewRequest(http.MethodPost, "/api/panel/ssh/hosts", strings.NewReader(`{"label":"db","host":"h2","user":"u","auth":"password","password":"pw-xyz"}`)) req.AddCookie(c) w := httptest.NewRecorder() s.Handler().ServeHTTP(w, req) if !strings.Contains(w.Body.String(), `"ok":true`) { t.Fatalf("save: %s", w.Body.String()) } w = get(t, s, c, "/api/panel/ssh/hosts") if !strings.Contains(w.Body.String(), `"h2"`) || strings.Contains(w.Body.String(), "pw-xyz") { t.Fatalf("list: %s", w.Body.String()) } }