@@ -10,10 +10,11 @@
10 10 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
11 11 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
type registerRequest struct {
12 12 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Nick string `json:"nick"`
13 13 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Type registry.AgentType `json:"type"`
14 14 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Channels []string `json:"channels"`
15 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ OpsChannels []string `json:"ops_channels,omitempty"`
15 16 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Permissions []string `json:"permissions"`
16 17 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
RateLimit *registry.RateLimitConfig `json:"rate_limit,omitempty"`
17 18 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Rules *registry.EngagementRules `json:"engagement,omitempty"`
18 19 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
19 20 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
@@ -36,10 +37,11 @@
36 37 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
req.Type = registry.AgentTypeWorker
37 38 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
38 39 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
39 40 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
cfg := registry.EngagementConfig{
40 41 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Channels: req.Channels,
42 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ OpsChannels: req.OpsChannels,
41 43 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Permissions: req.Permissions,
42 44 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
43 45 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if req.RateLimit != nil {
44 46 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
cfg.RateLimit = *req.RateLimit
45 47 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -56,11 +58,11 @@
56 58 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
writeError(w, http.StatusInternalServerError, "registration failed")
57 59 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
58 60 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
59 61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
60 62 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
s.registry.Touch(req.Nick)
61 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- s.setAgentModes(req.Nick, req.Type, cfg.Channels)
63 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ s.setAgentModes(req.Nick, req.Type, cfg)
62 64 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
writeJSON(w, http.StatusCreated, registerResponse{
63 65 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Credentials: creds,
64 66 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Payload: payload,
65 67 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
})
66 68 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -68,10 +70,11 @@
68 70 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
func (s *Server) handleAdopt(w http.ResponseWriter, r *http.Request) {
69 71 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
nick := r.PathValue("nick")
70 72 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
var req struct {
71 73 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Type registry.AgentType `json:"type"`
72 74 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Channels []string `json:"channels"`
75 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ OpsChannels []string `json:"ops_channels,omitempty"`
73 76 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Permissions []string `json:"permissions"`
74 77 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
75 78 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
76 79 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
writeError(w, http.StatusBadRequest, "invalid request body")
77 80 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
@@ -79,10 +82,11 @@
79 82 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if req.Type == "" {
80 83 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
req.Type = registry.AgentTypeWorker
81 84 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
82 85 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
cfg := registry.EngagementConfig{
83 86 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Channels: req.Channels,
87 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ OpsChannels: req.OpsChannels,
84 88 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
Permissions: req.Permissions,
85 89 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
86 90 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
payload, err := s.registry.Adopt(nick, req.Type, cfg)
87 91 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if err != nil {
88 92 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if strings.Contains(err.Error(), "already registered") {
@@ -91,11 +95,11 @@
91 95 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
92 96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
s.log.Error("adopt agent", "nick", nick, "err", err)
93 97 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
writeError(w, http.StatusInternalServerError, "adopt failed")
94 98 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
95 99 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
96 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- s.setAgentModes(nick, req.Type, cfg.Channels)
100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ s.setAgentModes(nick, req.Type, cfg)
97 101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
writeJSON(w, http.StatusOK, map[string]any{"nick": nick, "payload": payload})
98 102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
99 103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
100 104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
func (s *Server) handleRotate(w http.ResponseWriter, r *http.Request) {
101 105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
nick := r.PathValue("nick")
@@ -197,21 +201,40 @@
197 201 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return ""
198 202 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
199 203 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
200 204 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
201 205 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
// setAgentModes grants the appropriate ChanServ access for an agent on all
202 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- // its assigned channels based on its type. No-op when topology is not configured
203 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- // or the agent type doesn't warrant a mode.
204 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- func (s *Server) setAgentModes(nick string, agentType registry.AgentType, channels []string) {
206 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ // its assigned channels based on its type. For orchestrators with OpsChannels
207 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ // configured, +o is granted only on those channels and +v on the rest.
208 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ // No-op when topology is not configured or the agent type doesn't warrant a mode.
209 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ func (s *Server) setAgentModes(nick string, agentType registry.AgentType, cfg registry.EngagementConfig) {
205 210 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if s.topoMgr == nil {
206 211 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
207 212 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
208 213 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
level := agentModeLevel(agentType)
209 214 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if level == "" {
210 215 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return
211 216 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
212 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- for _, ch := range channels {
217 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
218 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ // Orchestrators with explicit OpsChannels get +o only on those channels
219 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ // and +v on remaining channels.
220 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if level == "OP" && len(cfg.OpsChannels) > 0 {
221 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ opsSet := make(map[string]struct{}, len(cfg.OpsChannels))
222 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for _, ch := range cfg.OpsChannels {
223 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ opsSet[ch] = struct{}{}
224 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
225 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for _, ch := range cfg.Channels {
226 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if _, isOps := opsSet[ch]; isOps {
227 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ s.topoMgr.GrantAccess(nick, ch, "OP")
228 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ } else {
229 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ s.topoMgr.GrantAccess(nick, ch, "VOICE")
230 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
231 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
232 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ return
233 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
234 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
235 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ for _, ch := range cfg.Channels {
213 236 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
s.topoMgr.GrantAccess(nick, ch, level)
214 237 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
215 238 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
216 239 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
217 240 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
// removeAgentModes revokes ChanServ access for an agent on all its assigned
218 241 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!