1package api
2
3import (
4	"context"
5	"errors"
6	"fmt"
7
8	"github.com/mitchellh/mapstructure"
9)
10
11func (c *Sys) CapabilitiesSelf(path string) ([]string, error) {
12	return c.Capabilities(c.c.Token(), path)
13}
14
15func (c *Sys) Capabilities(token, path string) ([]string, error) {
16	body := map[string]string{
17		"token": token,
18		"path":  path,
19	}
20
21	reqPath := "/v1/sys/capabilities"
22	if token == c.c.Token() {
23		reqPath = fmt.Sprintf("%s-self", reqPath)
24	}
25
26	r := c.c.NewRequest("POST", reqPath)
27	if err := r.SetJSONBody(body); err != nil {
28		return nil, err
29	}
30
31	ctx, cancelFunc := context.WithCancel(context.Background())
32	defer cancelFunc()
33	resp, err := c.c.RawRequestWithContext(ctx, r)
34	if err != nil {
35		return nil, err
36	}
37	defer resp.Body.Close()
38
39	secret, err := ParseSecret(resp.Body)
40	if err != nil {
41		return nil, err
42	}
43	if secret == nil || secret.Data == nil {
44		return nil, errors.New("data from server response is empty")
45	}
46
47	var res []string
48	err = mapstructure.Decode(secret.Data[path], &res)
49	if err != nil {
50		return nil, err
51	}
52
53	if len(res) == 0 {
54		_, ok := secret.Data["capabilities"]
55		if ok {
56			err = mapstructure.Decode(secret.Data["capabilities"], &res)
57			if err != nil {
58				return nil, err
59			}
60		}
61	}
62
63	return res, nil
64}
65