1package api
2
3import "context"
4
5// TokenAuth is used to perform token backend operations on Vault
6type TokenAuth struct {
7	c *Client
8}
9
10// Token is used to return the client for token-backend API calls
11func (a *Auth) Token() *TokenAuth {
12	return &TokenAuth{c: a.c}
13}
14
15func (c *TokenAuth) Create(opts *TokenCreateRequest) (*Secret, error) {
16	r := c.c.NewRequest("POST", "/v1/auth/token/create")
17	if err := r.SetJSONBody(opts); err != nil {
18		return nil, err
19	}
20
21	ctx, cancelFunc := context.WithCancel(context.Background())
22	defer cancelFunc()
23	resp, err := c.c.RawRequestWithContext(ctx, r)
24	if err != nil {
25		return nil, err
26	}
27	defer resp.Body.Close()
28
29	return ParseSecret(resp.Body)
30}
31
32func (c *TokenAuth) CreateOrphan(opts *TokenCreateRequest) (*Secret, error) {
33	r := c.c.NewRequest("POST", "/v1/auth/token/create-orphan")
34	if err := r.SetJSONBody(opts); err != nil {
35		return nil, err
36	}
37
38	ctx, cancelFunc := context.WithCancel(context.Background())
39	defer cancelFunc()
40	resp, err := c.c.RawRequestWithContext(ctx, r)
41	if err != nil {
42		return nil, err
43	}
44	defer resp.Body.Close()
45
46	return ParseSecret(resp.Body)
47}
48
49func (c *TokenAuth) CreateWithRole(opts *TokenCreateRequest, roleName string) (*Secret, error) {
50	r := c.c.NewRequest("POST", "/v1/auth/token/create/"+roleName)
51	if err := r.SetJSONBody(opts); err != nil {
52		return nil, err
53	}
54
55	ctx, cancelFunc := context.WithCancel(context.Background())
56	defer cancelFunc()
57	resp, err := c.c.RawRequestWithContext(ctx, r)
58	if err != nil {
59		return nil, err
60	}
61	defer resp.Body.Close()
62
63	return ParseSecret(resp.Body)
64}
65
66func (c *TokenAuth) Lookup(token string) (*Secret, error) {
67	r := c.c.NewRequest("POST", "/v1/auth/token/lookup")
68	if err := r.SetJSONBody(map[string]interface{}{
69		"token": token,
70	}); err != nil {
71		return nil, err
72	}
73
74	ctx, cancelFunc := context.WithCancel(context.Background())
75	defer cancelFunc()
76	resp, err := c.c.RawRequestWithContext(ctx, r)
77	if err != nil {
78		return nil, err
79	}
80	defer resp.Body.Close()
81
82	return ParseSecret(resp.Body)
83}
84
85func (c *TokenAuth) LookupAccessor(accessor string) (*Secret, error) {
86	r := c.c.NewRequest("POST", "/v1/auth/token/lookup-accessor")
87	if err := r.SetJSONBody(map[string]interface{}{
88		"accessor": accessor,
89	}); err != nil {
90		return nil, err
91	}
92
93	ctx, cancelFunc := context.WithCancel(context.Background())
94	defer cancelFunc()
95	resp, err := c.c.RawRequestWithContext(ctx, r)
96	if err != nil {
97		return nil, err
98	}
99	defer resp.Body.Close()
100
101	return ParseSecret(resp.Body)
102}
103
104func (c *TokenAuth) LookupSelf() (*Secret, error) {
105	r := c.c.NewRequest("GET", "/v1/auth/token/lookup-self")
106
107	ctx, cancelFunc := context.WithCancel(context.Background())
108	defer cancelFunc()
109	resp, err := c.c.RawRequestWithContext(ctx, r)
110	if err != nil {
111		return nil, err
112	}
113	defer resp.Body.Close()
114
115	return ParseSecret(resp.Body)
116}
117
118func (c *TokenAuth) Renew(token string, increment int) (*Secret, error) {
119	r := c.c.NewRequest("PUT", "/v1/auth/token/renew")
120	if err := r.SetJSONBody(map[string]interface{}{
121		"token":     token,
122		"increment": increment,
123	}); err != nil {
124		return nil, err
125	}
126
127	ctx, cancelFunc := context.WithCancel(context.Background())
128	defer cancelFunc()
129	resp, err := c.c.RawRequestWithContext(ctx, r)
130	if err != nil {
131		return nil, err
132	}
133	defer resp.Body.Close()
134
135	return ParseSecret(resp.Body)
136}
137
138func (c *TokenAuth) RenewSelf(increment int) (*Secret, error) {
139	r := c.c.NewRequest("PUT", "/v1/auth/token/renew-self")
140
141	body := map[string]interface{}{"increment": increment}
142	if err := r.SetJSONBody(body); err != nil {
143		return nil, err
144	}
145
146	ctx, cancelFunc := context.WithCancel(context.Background())
147	defer cancelFunc()
148	resp, err := c.c.RawRequestWithContext(ctx, r)
149	if err != nil {
150		return nil, err
151	}
152	defer resp.Body.Close()
153
154	return ParseSecret(resp.Body)
155}
156
157// RenewTokenAsSelf behaves like renew-self, but authenticates using a provided
158// token instead of the token attached to the client.
159func (c *TokenAuth) RenewTokenAsSelf(token string, increment int) (*Secret, error) {
160	r := c.c.NewRequest("PUT", "/v1/auth/token/renew-self")
161	r.ClientToken = token
162
163	body := map[string]interface{}{"increment": increment}
164	if err := r.SetJSONBody(body); err != nil {
165		return nil, err
166	}
167
168	ctx, cancelFunc := context.WithCancel(context.Background())
169	defer cancelFunc()
170	resp, err := c.c.RawRequestWithContext(ctx, r)
171	if err != nil {
172		return nil, err
173	}
174	defer resp.Body.Close()
175
176	return ParseSecret(resp.Body)
177}
178
179// RevokeAccessor revokes a token associated with the given accessor
180// along with all the child tokens.
181func (c *TokenAuth) RevokeAccessor(accessor string) error {
182	r := c.c.NewRequest("POST", "/v1/auth/token/revoke-accessor")
183	if err := r.SetJSONBody(map[string]interface{}{
184		"accessor": accessor,
185	}); err != nil {
186		return err
187	}
188
189	ctx, cancelFunc := context.WithCancel(context.Background())
190	defer cancelFunc()
191	resp, err := c.c.RawRequestWithContext(ctx, r)
192	if err != nil {
193		return err
194	}
195	defer resp.Body.Close()
196
197	return nil
198}
199
200// RevokeOrphan revokes a token without revoking the tree underneath it (so
201// child tokens are orphaned rather than revoked)
202func (c *TokenAuth) RevokeOrphan(token string) error {
203	r := c.c.NewRequest("PUT", "/v1/auth/token/revoke-orphan")
204	if err := r.SetJSONBody(map[string]interface{}{
205		"token": token,
206	}); err != nil {
207		return err
208	}
209
210	ctx, cancelFunc := context.WithCancel(context.Background())
211	defer cancelFunc()
212	resp, err := c.c.RawRequestWithContext(ctx, r)
213	if err != nil {
214		return err
215	}
216	defer resp.Body.Close()
217
218	return nil
219}
220
221// RevokeSelf revokes the token making the call. The `token` parameter is kept
222// for backwards compatibility but is ignored; only the client's set token has
223// an effect.
224func (c *TokenAuth) RevokeSelf(token string) error {
225	r := c.c.NewRequest("PUT", "/v1/auth/token/revoke-self")
226
227	ctx, cancelFunc := context.WithCancel(context.Background())
228	defer cancelFunc()
229	resp, err := c.c.RawRequestWithContext(ctx, r)
230	if err != nil {
231		return err
232	}
233	defer resp.Body.Close()
234
235	return nil
236}
237
238// RevokeTree is the "normal" revoke operation that revokes the given token and
239// the entire tree underneath -- all of its child tokens, their child tokens,
240// etc.
241func (c *TokenAuth) RevokeTree(token string) error {
242	r := c.c.NewRequest("PUT", "/v1/auth/token/revoke")
243	if err := r.SetJSONBody(map[string]interface{}{
244		"token": token,
245	}); err != nil {
246		return err
247	}
248
249	ctx, cancelFunc := context.WithCancel(context.Background())
250	defer cancelFunc()
251	resp, err := c.c.RawRequestWithContext(ctx, r)
252	if err != nil {
253		return err
254	}
255	defer resp.Body.Close()
256
257	return nil
258}
259
260// TokenCreateRequest is the options structure for creating a token.
261type TokenCreateRequest struct {
262	ID              string            `json:"id,omitempty"`
263	Policies        []string          `json:"policies,omitempty"`
264	Metadata        map[string]string `json:"meta,omitempty"`
265	Lease           string            `json:"lease,omitempty"`
266	TTL             string            `json:"ttl,omitempty"`
267	ExplicitMaxTTL  string            `json:"explicit_max_ttl,omitempty"`
268	Period          string            `json:"period,omitempty"`
269	NoParent        bool              `json:"no_parent,omitempty"`
270	NoDefaultPolicy bool              `json:"no_default_policy,omitempty"`
271	DisplayName     string            `json:"display_name"`
272	NumUses         int               `json:"num_uses"`
273	Renewable       *bool             `json:"renewable,omitempty"`
274	Type            string            `json:"type"`
275	EntityAlias     string            `json:"entity_alias"`
276}
277