package server import ( "encoding/json" "net/http" "strconv" ) // GET /api/panel/users/{id}/agents - every machine, and which of them the // user may use, for the editor of a user's machines. func (s *Server) handleUserAgents(w http.ResponseWriter, r *http.Request) { id, _ := strconv.ParseInt(r.PathValue("id"), 10, 64) u, _ := s.db.AdminByID(id) if u == nil { http.NotFound(w, r) return } agents, _ := s.db.ListAgents() mine := s.db.UserAgents(id) type item struct { ID string `json:"id"` Name string `json:"name"` Hostname string `json:"hostname"` Online bool `json:"online"` On bool `json:"on"` } out := make([]item, 0, len(agents)) for _, a := range agents { out = append(out, item{a.ID, a.Name, a.Hostname, s.online(&a), mine[a.ID]}) } writeJSON(w, map[string]any{"username": u.Username, "agents": out}) } // POST /api/panel/users/{id} - change a user: the role, the machines, the // password sign-in, and whether they may switch it themselves. Fields left // out stay as they are. func (s *Server) handleUserEdit(w http.ResponseWriter, r *http.Request) { me := s.currentAdmin(r) id, _ := strconv.ParseInt(r.PathValue("id"), 10, 64) u, _ := s.db.AdminByID(id) if u == nil { writeJSON(w, map[string]any{"ok": false, "error": "нет такого пользователя"}) return } var in struct { Role *string `json:"role"` Agents *[]string `json:"agents"` PasswordOff *bool `json:"password_off"` PwLocked *bool `json:"pw_locked"` } if err := json.NewDecoder(http.MaxBytesReader(w, r.Body, 64<<10)).Decode(&in); err != nil { writeJSON(w, map[string]any{"ok": false, "error": "плохой запрос"}) return } fail := func(msg string) { writeJSON(w, map[string]any{"ok": false, "error": msg}) } if in.Role != nil { role := *in.Role if role != RoleAdmin && role != RoleUser { fail("нет такой роли") return } if role == RoleUser && u.IsAdmin() && s.db.CountRole(RoleAdmin) <= 1 { fail("это последний администратор") return } _ = s.db.SetUserRole(id, role) s.db.Audit(me.ID, "", "user_role:"+u.Username+":"+role) } if in.Agents != nil { _ = s.db.SetUserAgents(id, *in.Agents) s.db.Audit(me.ID, "", "user_agents:"+u.Username+":"+strconv.Itoa(len(*in.Agents))) } if in.PasswordOff != nil { if *in.PasswordOff && s.db.CountAdminKeys(id) == 0 { fail("у пользователя нет ключей доступа - без пароля он не войдёт") return } _ = s.db.SetPasswordOff(id, *in.PasswordOff) action := "password_on" if *in.PasswordOff { action = "password_off" } s.db.Audit(me.ID, "", action+":"+u.Username) } if in.PwLocked != nil { _ = s.db.SetPwLocked(id, *in.PwLocked) } writeJSON(w, map[string]any{"ok": true}) }