fix(session): real getMyProfiles shape {myprofiles:[...]} + active-profile detection [#767]

https://projects.knownelement.com/issues/767#note-4191
This commit is contained in:
2026-09-04 08:56:38 -05:00
parent 5da1eee08f
commit 9d71c690b3
7 changed files with 199 additions and 29 deletions
+36 -5
View File
@@ -116,6 +116,10 @@ type Server struct {
// Fail, when non-nil, is returned instead of normal handling; it is
// consumed by the first request that sees it.
Fail *FailSpec
// BreakActiveProfile, when non-zero, makes GET /getActiveProfile
// answer that error status (degradation tests: 403/404 degrade,
// 500 surfaces).
BreakActiveProfile int
mu sync.Mutex
srv *httptest.Server
@@ -355,6 +359,8 @@ func (s *Server) handler(w http.ResponseWriter, r *http.Request) {
respBody = `true`
case r.Method == http.MethodGet && path == "/getMyProfiles":
respStatus, respBody = s.getMyProfiles(tok)
case r.Method == http.MethodGet && path == "/getActiveProfile":
respStatus, respBody = s.getActiveProfile(tok)
case r.Method == http.MethodPost && path == "/changeActiveProfile":
respStatus, respBody = s.changeActiveProfile(tok, body)
case r.Method == http.MethodGet && strings.HasPrefix(path, "/Profile/"):
@@ -413,12 +419,37 @@ func (s *Server) initSession(r *http.Request) (int, string) {
}
func (s *Server) getMyProfiles(tok string) (int, string) {
out := make([]Profile, len(s.profiles))
copy(out, s.profiles)
for i := range out {
out[i].IsActive = out[i].ID == s.activeProfile[tok]
// GLPI's REAL wire shape (verified against prod cmdb 2026-09-03):
// WRAPPED object {"myprofiles":[...]}; rows carry id/name/entities
// and NO is_active — the active profile is GET /getActiveProfile.
rows := make([]map[string]any, 0, len(s.profiles))
for _, p := range s.profiles {
rows = append(rows, map[string]any{"id": p.ID, "name": p.Name, "entities": []any{}})
}
return jsonReply(out)
return jsonReply(map[string]any{"myprofiles": rows})
}
// getActiveProfile answers GLPI's {"active_profile":{...,"id":N,...}}.
func (s *Server) getActiveProfile(tok string) (int, string) {
if s.BreakActiveProfile != 0 {
switch s.BreakActiveProfile {
case http.StatusForbidden:
return http.StatusForbidden, `[{"ERROR_RIGHT_MISSING":true}]`
case http.StatusNotFound:
return http.StatusNotFound, `[{"ERROR_ITEM_NOT_FOUND":true}]`
default:
return s.BreakActiveProfile, `[{"ERROR_GLPI":true}]`
}
}
id := s.activeProfile[tok]
for _, p := range s.profiles {
if p.ID == id {
return jsonReply(map[string]any{
"active_profile": map[string]any{"id": p.ID, "name": p.Name, "entities": []any{}},
})
}
}
return http.StatusNotFound, `[{"ERROR_ITEM_NOT_FOUND":true}]`
}
func (s *Server) changeActiveProfile(tok string, body []byte) (int, string) {