package glpi import ( "context" "fmt" "net/http" ) // Profile is one GLPI profile of the logged-in user (GET /getMyProfiles, // GET /Profile/). The myprofiles rows carry NO is_active on the // real wire — the active profile is detected via GetActiveProfile. type Profile struct { ID int `json:"id"` Name string `json:"name"` IsActive bool `json:"is_active"` } // GetMyProfiles lists the profiles of the logged-in user. GLPI's REAL // wire shape (verified against prod cmdb 2026-09-03) is a WRAPPED // object — {"myprofiles":[{"id":N,"name":"...","entities":[...]},...]} — // NOT a bare array; rows may carry extra fields (entities, comments) // which are ignored here. IsActive is left false by this call. func (c *Client) GetMyProfiles(ctx context.Context) ([]Profile, error) { var body struct { MyProfiles []Profile `json:"myprofiles"` } if err := c.call(ctx, http.MethodGet, "/getMyProfiles", nil, nil, &body); err != nil { return nil, err } return body.MyProfiles, nil } // GetActiveProfile returns the id of the session's active profile // (GET /getActiveProfile → {"active_profile":{...,"id":N,...}}). func (c *Client) GetActiveProfile(ctx context.Context) (int, error) { var body struct { ActiveProfile struct { ID int `json:"id"` } `json:"active_profile"` } if err := c.call(ctx, http.MethodGet, "/getActiveProfile", nil, nil, &body); err != nil { return 0, err } if body.ActiveProfile.ID == 0 { return 0, fmt.Errorf("%w: getActiveProfile returned no id", ErrMalformedResponse) } return body.ActiveProfile.ID, nil } // ChangeActiveProfile switches the session's active profile // (POST /changeActiveProfile with {"profiles_id":N}). Agent mode uses // this to move into the right role (e.g. 5 = Hotliner) after // InitSession; servers that gate operations per profile then accept the // calls that were previously rejected. func (c *Client) ChangeActiveProfile(ctx context.Context, profileID int) error { if profileID <= 0 { return fmt.Errorf("%w: profile id must be positive", ErrValidation) } payload := map[string]any{"profiles_id": profileID} // The endpoint answers `true` — nothing to parse. return c.call(ctx, http.MethodPost, "/changeActiveProfile", nil, payload, nil) }