1package api
2
3import (
4	"context"
5	"errors"
6	"fmt"
7
8	"github.com/mitchellh/mapstructure"
9)
10
11func (c *Sys) ListPolicies() ([]string, error) {
12	r := c.c.NewRequest("LIST", "/v1/sys/policies/acl")
13	// Set this for broader compatibility, but we use LIST above to be able to
14	// handle the wrapping lookup function
15	r.Method = "GET"
16	r.Params.Set("list", "true")
17
18	ctx, cancelFunc := context.WithCancel(context.Background())
19	defer cancelFunc()
20	resp, err := c.c.RawRequestWithContext(ctx, r)
21	if err != nil {
22		return nil, err
23	}
24	defer resp.Body.Close()
25
26	secret, err := ParseSecret(resp.Body)
27	if err != nil {
28		return nil, err
29	}
30	if secret == nil || secret.Data == nil {
31		return nil, errors.New("data from server response is empty")
32	}
33
34	var result []string
35	err = mapstructure.Decode(secret.Data["keys"], &result)
36	if err != nil {
37		return nil, err
38	}
39
40	return result, err
41}
42
43func (c *Sys) GetPolicy(name string) (string, error) {
44	r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/policies/acl/%s", name))
45
46	ctx, cancelFunc := context.WithCancel(context.Background())
47	defer cancelFunc()
48	resp, err := c.c.RawRequestWithContext(ctx, r)
49	if resp != nil {
50		defer resp.Body.Close()
51		if resp.StatusCode == 404 {
52			return "", nil
53		}
54	}
55	if err != nil {
56		return "", err
57	}
58
59	secret, err := ParseSecret(resp.Body)
60	if err != nil {
61		return "", err
62	}
63	if secret == nil || secret.Data == nil {
64		return "", errors.New("data from server response is empty")
65	}
66
67	if policyRaw, ok := secret.Data["policy"]; ok {
68		return policyRaw.(string), nil
69	}
70
71	return "", fmt.Errorf("no policy found in response")
72}
73
74func (c *Sys) PutPolicy(name, rules string) error {
75	body := map[string]string{
76		"policy": rules,
77	}
78
79	r := c.c.NewRequest("PUT", fmt.Sprintf("/v1/sys/policies/acl/%s", name))
80	if err := r.SetJSONBody(body); err != nil {
81		return err
82	}
83
84	ctx, cancelFunc := context.WithCancel(context.Background())
85	defer cancelFunc()
86	resp, err := c.c.RawRequestWithContext(ctx, r)
87	if err != nil {
88		return err
89	}
90	defer resp.Body.Close()
91
92	return nil
93}
94
95func (c *Sys) DeletePolicy(name string) error {
96	r := c.c.NewRequest("DELETE", fmt.Sprintf("/v1/sys/policies/acl/%s", name))
97
98	ctx, cancelFunc := context.WithCancel(context.Background())
99	defer cancelFunc()
100	resp, err := c.c.RawRequestWithContext(ctx, r)
101	if err == nil {
102		defer resp.Body.Close()
103	}
104	return err
105}
106
107type getPoliciesResp struct {
108	Rules string `json:"rules"`
109}
110
111type listPoliciesResp struct {
112	Policies []string `json:"policies"`
113}
114