From a3a60c4deb7afb14bc3bb503faa9b51d2f976087 Mon Sep 17 00:00:00 2001 From: Konstantin Dudkov Date: Sun, 5 Nov 2023 17:34:33 +0300 Subject: [PATCH] . --- cmd/goatak_server/http_server.go | 23 +++++++++++++++++-- cmd/goatak_server/udpserver.go | 38 ++++++++++--------------------- cmd/goatak_server/ws.go | 21 ++++++----------- internal/client/client_handler.go | 19 +--------------- internal/model/user.go | 31 +++++++++++++++++++++++++ pkg/cot/cotmessage.go | 25 ++++++++++++++++---- 6 files changed, 93 insertions(+), 64 deletions(-) diff --git a/cmd/goatak_server/http_server.go b/cmd/goatak_server/http_server.go index 4e3a6d4..4421015 100644 --- a/cmd/goatak_server/http_server.go +++ b/cmd/goatak_server/http_server.go @@ -2,7 +2,9 @@ package main import ( "embed" + "encoding/json" "errors" + "github.com/kdudkov/goatak/pkg/cot" "go.uber.org/zap" "net/http" "path/filepath" @@ -75,6 +77,7 @@ func getAdminApi(app *App, addr string, renderer *staticfiles.Renderer, webtakRo adminApi.DELETE("/unit/:uid", deleteItemHandler(app)) adminApi.GET("/takproto/1", getWsHandler(app)) + adminApi.POST("/cot", getCotPostHandler(app)) if webtakRoot != "" { adminApi.FILE("/webtak/", filepath.Join(webtakRoot, "index.html")) @@ -209,10 +212,10 @@ func getConnHandler(app *App) func(req *air.Request, res *air.Response) error { app.ForAllClients(func(ch client.ClientHandler) bool { c := &Connection{ Uids: ch.GetUids(), - User: ch.GetUser().Login, + User: ch.GetUser().GetLogin(), Ver: ch.GetVersion(), Addr: ch.GetName(), - Scope: ch.GetUser().Scope, + Scope: ch.GetUser().GetScope(), LastSeen: ch.GetLastSeen(), } conn = append(conn, c) @@ -226,3 +229,19 @@ func getConnHandler(app *App) func(req *air.Request, res *air.Response) error { return res.WriteJSON(conn) } } + +func getCotPostHandler(app *App) func(req *air.Request, res *air.Response) error { + return func(req *air.Request, res *air.Response) error { + c := new(cot.CotMessage) + + dec := json.NewDecoder(req.Body) + + if err := dec.Decode(c); err != nil { + app.Logger.Errorf("cot decode error %s", err) + return err + } + + app.NewCotMessage(c) + return nil + } +} diff --git a/cmd/goatak_server/udpserver.go b/cmd/goatak_server/udpserver.go index 8077622..258c049 100644 --- a/cmd/goatak_server/udpserver.go +++ b/cmd/goatak_server/udpserver.go @@ -41,20 +41,16 @@ func (app *App) ListenUDP(addr string) error { app.Logger.Errorf("protobuf decode error: %s", err.Error()) continue } - xd, err := cot.DetailsFromString(msg.GetCotEvent().GetDetail().GetXmlDetail()) - if err != nil { - app.Logger.Errorf("protobuf detail extract error: %s", err.Error()) - continue - } scope := msg.GetCotEvent().GetAccess() if scope == "" { scope = "broadcast" } - app.NewCotMessage(&cot.CotMessage{ - TakMessage: msg, - Detail: xd, - Scope: scope, - }) + c, err := cot.CotFromProto(msg, "", scope) + if err != nil { + app.Logger.Errorf("protobuf detail extract error: %s", err.Error()) + continue + } + app.NewCotMessage(c) } else { ev := &cot.Event{} err = xml.Unmarshal(buf[3:n], ev) @@ -63,30 +59,20 @@ func (app *App) ListenUDP(addr string) error { continue } - msg, xd := cot.EventToProto(ev) - scope := msg.GetCotEvent().GetAccess() + scope := ev.Access if scope == "" { scope = "broadcast" } - app.NewCotMessage(&cot.CotMessage{ - TakMessage: msg, - Detail: xd, - Scope: scope, - }) + c := cot.CotFromEvent(ev, "", scope) + app.NewCotMessage(c) } } else { - evt := &cot.Event{} - if err := xml.Unmarshal(buf[:n], evt); err != nil { + ev := &cot.Event{} + if err := xml.Unmarshal(buf[:n], ev); err != nil { app.Logger.Errorf("decode error: %v", err) continue } - msg, xd := cot.EventToProto(evt) - - app.NewCotMessage(&cot.CotMessage{ - TakMessage: msg, - Detail: xd, - Scope: "broadcast", - }) + app.NewCotMessage(cot.CotFromEvent(ev, "", "broadcast")) } } diff --git a/cmd/goatak_server/ws.go b/cmd/goatak_server/ws.go index a9a6788..0004560 100644 --- a/cmd/goatak_server/ws.go +++ b/cmd/goatak_server/ws.go @@ -19,6 +19,7 @@ import ( type WsClientHandler struct { name string + user *model.User ws *air.WebSocket ch chan []byte uids sync.Map @@ -30,12 +31,9 @@ type WsClientHandler struct { func (w *WsClientHandler) GetName() string { return w.name } -func (w *WsClientHandler) GetUser() *model.User { - return nil -} -func (w *WsClientHandler) CanSeeScope(scope string) bool { - return true +func (w *WsClientHandler) GetUser() *model.User { + return w.user } func (w *WsClientHandler) GetVersion() int32 { @@ -60,9 +58,10 @@ func (w *WsClientHandler) GetLastSeen() *time.Time { return nil } -func NewWsClient(name string, ws *air.WebSocket, log *zap.SugaredLogger, mc func(msg *cot.CotMessage)) *WsClientHandler { +func NewWsClient(name string, user *model.User, ws *air.WebSocket, log *zap.SugaredLogger, mc func(msg *cot.CotMessage)) *WsClientHandler { return &WsClientHandler{ name: name, + user: user, ws: ws, uids: sync.Map{}, ch: make(chan []byte, 10), @@ -128,18 +127,12 @@ func (w *WsClientHandler) Listen() { return err } - d, err := cot.DetailsFromString(msg.GetCotEvent().GetDetail().GetXmlDetail()) + cotmsg, err := cot.CotFromProto(msg, w.name, w.GetUser().GetScope()) if err != nil { w.logger.Errorf("details get error: %s", err.Error()) return err } - cotmsg := &cot.CotMessage{ - From: w.name, - TakMessage: msg, - Detail: d, - } - if cotmsg.IsContact() { uid := msg.GetCotEvent().GetUid() if strings.HasSuffix(uid, "-ping") { @@ -174,7 +167,7 @@ func getWsHandler(app *App) func(req *air.Request, res *air.Response) error { app.Logger.Infof("WS connection from %s", req.ClientAddress()) name := "ws:" + req.ClientAddress() - w := NewWsClient(name, ws, app.Logger, app.NewCotMessage) + w := NewWsClient(name, nil, ws, app.Logger, app.NewCotMessage) app.AddClientHandler(w) w.Listen() diff --git a/internal/client/client_handler.go b/internal/client/client_handler.go index c9b9fac..a2cb0af 100644 --- a/internal/client/client_handler.go +++ b/internal/client/client_handler.go @@ -103,23 +103,6 @@ func (h *ConnClientHandler) GetUser() *model.User { return h.user } -func (h *ConnClientHandler) CanSeeScope(scope string) bool { - if h.user == nil { - return true - } - if h.user.Scope == "" || h.user.Scope == scope { - return true - } - - for _, s := range h.user.ReadScope { - if s == "*" || s == scope { - return true - } - } - - return false -} - func (h *ConnClientHandler) GetUids() map[string]string { res := make(map[string]string) h.uids.Range(func(key, value any) bool { @@ -435,7 +418,7 @@ func (h *ConnClientHandler) sendEvent(evt *cot.Event) error { } func (h *ConnClientHandler) SendMsg(msg *cot.CotMessage) error { - if h.CanSeeScope(msg.Scope) { + if h.GetUser().CanSeeScope(msg.Scope) { return h.SendCot(msg.TakMessage) } diff --git a/internal/model/user.go b/internal/model/user.go index 103ac2e..dc1b538 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -10,3 +10,34 @@ type User struct { Scope string `yaml:"scope,omitempty"` ReadScope []string `yaml:"read_scope"` } + +func (u *User) GetLogin() string { + if u == nil { + return "" + } + return u.Login +} + +func (u *User) GetScope() string { + if u == nil { + return "" + } + return u.Scope +} + +func (u *User) CanSeeScope(scope string) bool { + if u == nil { + return true + } + if u.Scope == "" || u.Scope == scope { + return true + } + + for _, s := range u.ReadScope { + if s == "*" || s == scope { + return true + } + } + + return false +} diff --git a/pkg/cot/cotmessage.go b/pkg/cot/cotmessage.go index 71a8245..f44a774 100644 --- a/pkg/cot/cotmessage.go +++ b/pkg/cot/cotmessage.go @@ -9,10 +9,27 @@ import ( ) type CotMessage struct { - From string - Scope string - TakMessage *cotproto.TakMessage - Detail *Node + From string `json:"from,omitempty"` + Scope string `json:"scope"` + TakMessage *cotproto.TakMessage `json:"tak_message"` + Detail *Node `json:"-"` +} + +func CotFromEvent(evt *Event, from, scope string) *CotMessage { + if evt == nil { + return nil + } + msg, xd := EventToProto(evt) + + return &CotMessage{TakMessage: msg, Detail: xd, From: from, Scope: scope} +} + +func CotFromProto(msg *cotproto.TakMessage, from, scope string) (*CotMessage, error) { + if msg == nil { + return nil, nil + } + d, err := DetailsFromString(msg.GetCotEvent().GetDetail().GetXmlDetail()) + return &CotMessage{From: from, Scope: scope, TakMessage: msg, Detail: d}, err } func (m *CotMessage) GetSendTime() time.Time {