Full web : fichiers restants

This commit is contained in:
cedric committed 2026-10-23 17:43:20 +02:00
1 parent ec3b7c9a01
commit 4826fa5b82
26 files changed
+2537 -793

No files matched your search

+187
View File
@@ -0,0 +1,187 @@
package pvetest
import (
"net/http"
"sort"
"strings"
)
// access fakes /access/groups, /access/roles and /access/users (user.cfg).
func (s *Server) access(w http.ResponseWriter, r *http.Request, method string, seg []string) {
f := r.PostForm
if method == http.MethodDelete {
f = r.URL.Query()
}
switch {
case len(seg) == 2 && seg[1] == "groups" && method == "GET":
var out []any
for _, id := range sortedKeys(s.Groups) {
o := map[string]any{"groupid": id, "users": strings.Join(s.members(id), ",")}
for k, v := range s.Groups[id] {
o[k] = v
}
out = append(out, o)
}
reply(w, out)
case len(seg) == 2 && seg[1] == "groups" && method == "POST":
id := f.Get("groupid")
if s.Groups[id] != nil {
fail(w, 500, "create group failed: group '"+id+"' already exists")
return
}
s.Groups[id] = setFields(map[string]any{}, f, "groupid")
reply(w, nil)
case len(seg) == 3 && seg[1] == "groups":
g := s.Groups[seg[2]]
if g == nil {
fail(w, 500, "group '"+seg[2]+"' does not exist")
return
}
switch method {
case "PUT":
setFields(g, f)
case "DELETE":
delete(s.Groups, seg[2])
for _, u := range s.Users {
u["groups"] = strings.Join(remove(split(u["groups"]), seg[2]), ",")
}
}
reply(w, nil)
case len(seg) == 2 && seg[1] == "roles" && method == "GET":
out := []any{
map[string]any{"roleid": "Administrator", "privs": "Sys.Audit,Sys.Modify", "special": 1},
map[string]any{"roleid": "PVEAuditor", "privs": "Sys.Audit", "special": 1},
}
for _, id := range sortedKeys(s.Roles) {
out = append(out, map[string]any{"roleid": id, "privs": s.Roles[id], "special": 0})
}
reply(w, out)
case len(seg) == 2 && seg[1] == "roles" && method == "POST":
s.Roles[f.Get("roleid")] = f.Get("privs")
reply(w, nil)
case len(seg) == 3 && seg[1] == "roles":
if _, ok := s.Roles[seg[2]]; !ok {
fail(w, 500, "role '"+seg[2]+"' does not exist")
return
}
if method == "DELETE" {
delete(s.Roles, seg[2])
} else {
s.Roles[seg[2]] = f.Get("privs")
}
reply(w, nil)
case len(seg) == 2 && seg[1] == "users" && method == "GET":
var out []any
for _, id := range sortedKeys(s.Users) {
realm := id[strings.LastIndex(id, "@")+1:]
o := map[string]any{"userid": id, "realm-type": realm, "tokens": []any{}}
for k, v := range s.Users[id] {
o[k] = v
}
out = append(out, o)
}
reply(w, out)
case len(seg) == 2 && seg[1] == "users" && method == "POST":
id := f.Get("userid")
if s.Users[id] != nil {
fail(w, 500, "create user failed: user '"+id+"' already exists")
return
}
if !s.groupsExist(w, f.Get("groups")) {
return
}
s.Users[id] = setFields(map[string]any{"enable": 1}, f, "userid", "password")
reply(w, nil)
case len(seg) == 3 && seg[1] == "users":
u := s.Users[seg[2]]
if u == nil {
fail(w, 500, "user '"+seg[2]+"' does not exist")
return
}
switch method {
case "PUT":
if !s.groupsExist(w, f.Get("groups")) {
return
}
setFields(u, f)
case "DELETE":
delete(s.Users, seg[2])
delete(s.Shadow, strings.TrimSuffix(seg[2], "@pve"))
}
reply(w, nil)
default:
fail(w, 501, "not implemented in fake: "+method+" "+strings.Join(seg, "/"))
}
}
func (s *Server) groupsExist(w http.ResponseWriter, groups string) bool {
for _, g := range split(groups) {
if s.Groups[g] == nil {
fail(w, 500, "no such group '"+g+"'")
return false
}
}
return true
}
func (s *Server) members(group string) []string {
var out []string
for id, u := range s.Users {
for _, g := range split(u["groups"]) {
if g == group {
out = append(out, id)
}
}
}
sort.Strings(out)
return out
}
// setFields copies form values; an empty value removes the field (like user.cfg).
func setFields(m map[string]any, f map[string][]string, skip ...string) map[string]any {
sk := map[string]bool{}
for _, k := range skip {
sk[k] = true
}
for k, v := range f {
if sk[k] || len(v) == 0 {
continue
}
if v[0] == "" {
delete(m, k)
continue
}
m[k] = v[0]
}
return m
}
func split(v any) []string {
s, _ := v.(string)
var out []string
for _, x := range strings.Split(s, ",") {
if x = strings.TrimSpace(x); x != "" {
out = append(out, x)
}
}
return out
}
func remove(l []string, x string) []string {
out := l[:0]
for _, e := range l {
if e != x {
out = append(out, e)
}
}
return out
}
func sortedKeys[V any](m map[string]V) []string {
out := make([]string, 0, len(m))
for k := range m {
out = append(out, k)
}
sort.Strings(out)
return out
}