2026-03-12 20:51:38 -07:00

177 lines
4.6 KiB
Go

package handlers
import (
"encoding/json"
"fmt"
"net/http"
"setec-manager/internal/system"
)
// ── System Users ────────────────────────────────────────────────────
type sysUser struct {
Username string `json:"username"`
UID string `json:"uid"`
HomeDir string `json:"home_dir"`
Shell string `json:"shell"`
}
func (h *Handler) UserList(w http.ResponseWriter, r *http.Request) {
users := listSystemUsers()
if acceptsJSON(r) {
writeJSON(w, http.StatusOK, users)
return
}
h.render(w, "users.html", users)
}
func (h *Handler) UserCreate(w http.ResponseWriter, r *http.Request) {
var body struct {
Username string `json:"username"`
Password string `json:"password"`
Shell string `json:"shell"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
body.Username = r.FormValue("username")
body.Password = r.FormValue("password")
body.Shell = r.FormValue("shell")
}
if body.Username == "" || body.Password == "" {
writeError(w, http.StatusBadRequest, "username and password required")
return
}
if body.Shell == "" {
body.Shell = "/bin/bash"
}
if err := system.CreateUser(body.Username, body.Password, body.Shell); err != nil {
writeError(w, http.StatusInternalServerError, fmt.Sprintf("create user failed: %s", err))
return
}
writeJSON(w, http.StatusCreated, map[string]string{"status": "created", "username": body.Username})
}
func (h *Handler) UserDelete(w http.ResponseWriter, r *http.Request) {
id := paramStr(r, "id") // actually username for system users
if id == "" {
writeError(w, http.StatusBadRequest, "username required")
return
}
// Safety check
if id == "root" || id == "autarch" {
writeError(w, http.StatusForbidden, "cannot delete system accounts")
return
}
if err := system.DeleteUser(id); err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
}
func listSystemUsers() []sysUser {
systemUsers, err := system.ListUsers()
if err != nil {
return nil
}
var users []sysUser
for _, su := range systemUsers {
users = append(users, sysUser{
Username: su.Username,
UID: fmt.Sprintf("%d", su.UID),
HomeDir: su.HomeDir,
Shell: su.Shell,
})
}
return users
}
// ── Panel Users ─────────────────────────────────────────────────────
func (h *Handler) PanelUserList(w http.ResponseWriter, r *http.Request) {
users, err := h.DB.ListManagerUsers()
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
if acceptsJSON(r) {
writeJSON(w, http.StatusOK, users)
return
}
h.render(w, "users.html", map[string]interface{}{"PanelUsers": users})
}
func (h *Handler) PanelUserCreate(w http.ResponseWriter, r *http.Request) {
var body struct {
Username string `json:"username"`
Password string `json:"password"`
Role string `json:"role"`
}
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
body.Username = r.FormValue("username")
body.Password = r.FormValue("password")
body.Role = r.FormValue("role")
}
if body.Username == "" || body.Password == "" {
writeError(w, http.StatusBadRequest, "username and password required")
return
}
if body.Role == "" {
body.Role = "admin"
}
id, err := h.DB.CreateManagerUser(body.Username, body.Password, body.Role)
if err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
writeJSON(w, http.StatusCreated, map[string]interface{}{"id": id, "username": body.Username})
}
func (h *Handler) PanelUserUpdate(w http.ResponseWriter, r *http.Request) {
id, err := paramInt(r, "id")
if err != nil {
writeError(w, http.StatusBadRequest, "invalid id")
return
}
var body struct {
Password string `json:"password"`
Role string `json:"role"`
}
json.NewDecoder(r.Body).Decode(&body)
if body.Password != "" {
h.DB.UpdateManagerUserPassword(id, body.Password)
}
if body.Role != "" {
h.DB.UpdateManagerUserRole(id, body.Role)
}
writeJSON(w, http.StatusOK, map[string]string{"status": "updated"})
}
func (h *Handler) PanelUserDelete(w http.ResponseWriter, r *http.Request) {
id, err := paramInt(r, "id")
if err != nil {
writeError(w, http.StatusBadRequest, "invalid id")
return
}
if err := h.DB.DeleteManagerUser(id); err != nil {
writeError(w, http.StatusInternalServerError, err.Error())
return
}
writeJSON(w, http.StatusOK, map[string]string{"status": "deleted"})
}