90 lines
2.8 KiB
Go
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})
|
|
}
|