Bump version to 1.0.23
This commit is contained in:
@@ -1,16 +1,19 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/syncserver/internal/models"
|
||||
"github.com/syncserver/internal/sshmanager"
|
||||
"github.com/syncserver/internal/syncengine"
|
||||
"github.com/syncserver/internal/wol"
|
||||
)
|
||||
@@ -218,6 +221,103 @@ func (h *MachineHandler) TestWoL(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, map[string]interface{}{"ok": true, "sent": 3})
|
||||
}
|
||||
|
||||
func (h *MachineHandler) TestConnection(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
repo := models.NewMachineRepository(h.db)
|
||||
m, err := repo.GetByID(id)
|
||||
if err == sql.ErrNoRows {
|
||||
writeError(w, http.StatusNotFound, "machine not found")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
slog.Error("failed to fetch machine", "id", id, "error", err)
|
||||
writeError(w, http.StatusInternalServerError, "failed to fetch machine")
|
||||
return
|
||||
}
|
||||
|
||||
knownHostsPath, err := sshmanager.EnsureKnownHosts(filepath.Join("/var/lib/syncserver", "ssh"))
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, "failed to ensure known_hosts")
|
||||
return
|
||||
}
|
||||
|
||||
privKeyPath := filepath.Join("/var/lib/syncserver", "ssh", "id_ed25519")
|
||||
if m.SSHKeyID != nil {
|
||||
sshKeyRepo := models.NewSSHKeyRepository(h.db)
|
||||
sshKey, err := sshKeyRepo.GetByID(*m.SSHKeyID)
|
||||
if err == nil && sshKey.PrivateKeyPath != "" {
|
||||
privKeyPath = sshKey.PrivateKeyPath
|
||||
}
|
||||
}
|
||||
|
||||
result, err := sshmanager.TestSSHConnection(
|
||||
context.Background(),
|
||||
m.Host, m.Port, m.SSHUser,
|
||||
privKeyPath, knownHostsPath,
|
||||
m.FingerprintConfirmed,
|
||||
)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
writeJSON(w, TestConnectionResponse{
|
||||
Success: result.Success,
|
||||
Output: result.Output,
|
||||
Error: result.Error,
|
||||
Fingerprint: result.Fingerprint,
|
||||
})
|
||||
}
|
||||
|
||||
func (h *MachineHandler) ApproveFingerprint(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.ParseInt(chi.URLParam(r, "id"), 10, 64)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid id")
|
||||
return
|
||||
}
|
||||
repo := models.NewMachineRepository(h.db)
|
||||
m, err := repo.GetByID(id)
|
||||
if err == sql.ErrNoRows {
|
||||
writeError(w, http.StatusNotFound, "machine not found")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
slog.Error("failed to fetch machine", "id", id, "error", err)
|
||||
writeError(w, http.StatusInternalServerError, "failed to fetch machine")
|
||||
return
|
||||
}
|
||||
|
||||
var req struct {
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
writeError(w, http.StatusBadRequest, "invalid request body")
|
||||
return
|
||||
}
|
||||
if req.Fingerprint == "" {
|
||||
writeError(w, http.StatusBadRequest, "fingerprint is required")
|
||||
return
|
||||
}
|
||||
|
||||
if err := repo.UpdateFingerprint(id, true, req.Fingerprint); err != nil {
|
||||
slog.Error("failed to update fingerprint", "id", id, "error", err)
|
||||
writeError(w, http.StatusInternalServerError, "failed to update fingerprint")
|
||||
return
|
||||
}
|
||||
|
||||
sshDir := filepath.Join("/var/lib/syncserver", "ssh")
|
||||
if err := sshmanager.AddKnownHost(sshDir, m.Host, m.Port, []byte(req.Fingerprint)); err != nil {
|
||||
slog.Warn("failed to add known_host entry", "host", m.Host, "error", err)
|
||||
}
|
||||
|
||||
m.FingerprintConfirmed = true
|
||||
m.HostKeyFingerprint = &req.Fingerprint
|
||||
writeJSON(w, machineToResp(*m))
|
||||
}
|
||||
|
||||
func (h *MachineHandler) Refresh(w http.ResponseWriter, r *http.Request) {
|
||||
if h.engine == nil {
|
||||
writeError(w, http.StatusInternalServerError, "engine not available")
|
||||
@@ -269,8 +369,9 @@ func machineToResp(m models.Machine) MachineResponse {
|
||||
WoLEnabled: m.WoLEnabled,
|
||||
BroadcastAddr: m.BroadcastAddr,
|
||||
WakeTimeoutSeconds: m.WakeTimeoutSeconds,
|
||||
WakeCheckIntervalSeconds: m.WakeCheckIntervalSeconds,
|
||||
WakeCheckIntervalSeconds: m.WakeCheckIntervalSeconds,
|
||||
FingerprintConfirmed: m.FingerprintConfirmed,
|
||||
HostKeyFingerprint: m.HostKeyFingerprint,
|
||||
Status: status,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user