Implemented admin pane + user permission
This commit is contained in:
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/uopi/uopi/internal/access"
|
||||
"github.com/uopi/uopi/internal/audit"
|
||||
"github.com/uopi/uopi/internal/broker"
|
||||
"github.com/uopi/uopi/internal/controllogic"
|
||||
"github.com/uopi/uopi/internal/datasource"
|
||||
"github.com/uopi/uopi/internal/metrics"
|
||||
)
|
||||
@@ -37,6 +38,14 @@ type inMsg struct {
|
||||
// dialogResponse — id of the control-logic dialog being answered.
|
||||
ID string `json:"id,omitempty"`
|
||||
|
||||
// debugSubscribe — live observation / dry-run of a control-logic graph.
|
||||
Mode string `json:"mode,omitempty"` // "live" | "simulate"
|
||||
GraphID string `json:"graphId,omitempty"` // live: id of the running graph
|
||||
Graph json.RawMessage `json:"graph,omitempty"` // simulate: the unsaved graph
|
||||
|
||||
// fireTrigger — force a trigger node of the current debug session to run.
|
||||
NodeID string `json:"nodeId,omitempty"`
|
||||
|
||||
// history
|
||||
Start time.Time `json:"start"`
|
||||
End time.Time `json:"end"`
|
||||
@@ -106,6 +115,8 @@ type wsHandler struct {
|
||||
audit audit.Recorder
|
||||
// dialogs fans control-logic dialogs to clients and routes responses.
|
||||
dialogs *DialogHub
|
||||
// debug fans control-logic node-execution events to watching editors.
|
||||
debug *DebugHub
|
||||
}
|
||||
|
||||
func (h *wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -149,6 +160,7 @@ func (h *wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
policy: h.policy,
|
||||
audit: rec,
|
||||
dialogs: h.dialogs,
|
||||
debug: h.debug,
|
||||
outCh: make(chan []byte, 512),
|
||||
updateCh: make(chan broker.Update, 1024),
|
||||
subs: make(map[broker.SignalRef]func()),
|
||||
@@ -160,6 +172,10 @@ func (h *wsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
h.dialogs.add(c)
|
||||
defer h.dialogs.remove(c)
|
||||
}
|
||||
// Tear down any debug subscription (and its simulate sandbox) on disconnect.
|
||||
if h.debug != nil {
|
||||
defer h.debug.unsubscribe(c)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(3)
|
||||
@@ -189,6 +205,7 @@ type wsClient struct {
|
||||
policy *access.Policy // global access-level enforcement
|
||||
audit audit.Recorder // signal-write audit recorder (never nil)
|
||||
dialogs *DialogHub // control-logic dialog fan-out (nil if disabled)
|
||||
debug *DebugHub // control-logic debug fan-out (nil if disabled)
|
||||
|
||||
outCh chan []byte // serialised outgoing messages
|
||||
updateCh chan broker.Update // raw updates from the broker
|
||||
@@ -287,6 +304,16 @@ func (c *wsClient) handleMessage(ctx context.Context, data []byte) {
|
||||
c.handleHistory(ctx, msg)
|
||||
case "dialogResponse":
|
||||
c.handleDialogResponse(ctx, msg)
|
||||
case "debugSubscribe":
|
||||
c.handleDebugSubscribe(ctx, msg)
|
||||
case "debugUnsubscribe":
|
||||
if c.debug != nil {
|
||||
c.debug.unsubscribe(c)
|
||||
}
|
||||
case "fireTrigger":
|
||||
if c.debug != nil {
|
||||
c.debug.fire(c, msg.NodeID)
|
||||
}
|
||||
default:
|
||||
c.sendError(ctx, "UNKNOWN_TYPE", "unknown message type: "+msg.Type)
|
||||
}
|
||||
@@ -423,6 +450,26 @@ func (c *wsClient) handleDialogResponse(ctx context.Context, msg inMsg) {
|
||||
c.dialogs.respond(ctx, c, msg.ID, num)
|
||||
}
|
||||
|
||||
// handleDebugSubscribe starts a control-logic debug session for this client.
|
||||
// mode "live" observes the running graph identified by GraphID; mode "simulate"
|
||||
// dry-runs the unsaved Graph payload in a sandbox (no real writes). Either way
|
||||
// the previous session (if any) is replaced; node events arrive as "debugNode".
|
||||
func (c *wsClient) handleDebugSubscribe(ctx context.Context, msg inMsg) {
|
||||
if c.debug == nil {
|
||||
return
|
||||
}
|
||||
if msg.Mode == "simulate" {
|
||||
var g controllogic.Graph
|
||||
if err := json.Unmarshal(msg.Graph, &g); err != nil {
|
||||
c.sendError(ctx, "DEBUG_ERROR", "invalid graph: "+err.Error())
|
||||
return
|
||||
}
|
||||
c.debug.subscribeSimulate(c, g)
|
||||
return
|
||||
}
|
||||
c.debug.subscribeLive(c, msg.GraphID)
|
||||
}
|
||||
|
||||
func (c *wsClient) handleHistory(ctx context.Context, msg inMsg) {
|
||||
metrics.IncHistoryReqs()
|
||||
ds, ok := c.broker.Source(msg.DS)
|
||||
|
||||
Reference in New Issue
Block a user