Files

90 lines
2.8 KiB
Go

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})
}