token_policies.go raw
1 package desec
2
3 import (
4 "context"
5 "fmt"
6 "net/http"
7 )
8
9 // TokenPolicy represents a policy applied to a token.
10 type TokenPolicy struct {
11 ID string `json:"id,omitempty"`
12 Domain *string `json:"domain"`
13 SubName *string `json:"subname"`
14 Type *string `json:"type"`
15 WritePermission bool `json:"perm_write,omitempty"`
16 }
17
18 // TokenPoliciesService handles communication with the token policy related methods of the deSEC API.
19 //
20 // https://desec.readthedocs.io/en/latest/auth/tokens.html
21 type TokenPoliciesService struct {
22 client *Client
23 }
24
25 // Deprecated: use [TokenPoliciesService.GetAll] instead.
26 func (s *TokenPoliciesService) Get(ctx context.Context, tokenID string) ([]TokenPolicy, error) {
27 return s.GetAll(ctx, tokenID)
28 }
29
30 // GetOne retrieves a specific token rrset policy.
31 // https://desec.readthedocs.io/en/latest/auth/tokens.html#token-policy-management
32 func (s *TokenPoliciesService) GetOne(ctx context.Context, tokenID, policyID string) (*TokenPolicy, error) {
33 endpoint, err := s.client.createEndpoint("auth", "tokens", tokenID, "policies", "rrsets", policyID)
34 if err != nil {
35 return nil, fmt.Errorf("failed to create endpoint: %w", err)
36 }
37
38 req, err := s.client.newRequest(ctx, http.MethodGet, endpoint, nil)
39 if err != nil {
40 return nil, err
41 }
42
43 resp, err := s.client.httpClient.Do(req)
44 if err != nil {
45 return nil, fmt.Errorf("failed to call API: %w", err)
46 }
47
48 defer func() { _ = resp.Body.Close() }()
49
50 if resp.StatusCode != http.StatusOK {
51 return nil, handleError(resp)
52 }
53
54 policy := &TokenPolicy{}
55
56 err = handleResponse(resp, policy)
57 if err != nil {
58 return nil, err
59 }
60
61 return policy, nil
62 }
63
64 // GetAll retrieves all rrset policies for a token.
65 // https://desec.readthedocs.io/en/latest/auth/tokens.html#token-policy-management
66 func (s *TokenPoliciesService) GetAll(ctx context.Context, tokenID string) ([]TokenPolicy, error) {
67 endpoint, err := s.client.createEndpoint("auth", "tokens", tokenID, "policies", "rrsets")
68 if err != nil {
69 return nil, fmt.Errorf("failed to create endpoint: %w", err)
70 }
71
72 req, err := s.client.newRequest(ctx, http.MethodGet, endpoint, nil)
73 if err != nil {
74 return nil, err
75 }
76
77 resp, err := s.client.httpClient.Do(req)
78 if err != nil {
79 return nil, fmt.Errorf("failed to call API: %w", err)
80 }
81
82 defer func() { _ = resp.Body.Close() }()
83
84 if resp.StatusCode != http.StatusOK {
85 return nil, handleError(resp)
86 }
87
88 var policies []TokenPolicy
89
90 err = handleResponse(resp, &policies)
91 if err != nil {
92 return nil, err
93 }
94
95 return policies, nil
96 }
97
98 // Create creates token policy.
99 // https://desec.readthedocs.io/en/latest/auth/tokens.html#create-additional-tokens
100 func (s *TokenPoliciesService) Create(ctx context.Context, tokenID string, policy TokenPolicy) (*TokenPolicy, error) {
101 endpoint, err := s.client.createEndpoint("auth", "tokens", tokenID, "policies", "rrsets")
102 if err != nil {
103 return nil, fmt.Errorf("failed to create endpoint: %w", err)
104 }
105
106 req, err := s.client.newRequest(ctx, http.MethodPost, endpoint, policy)
107 if err != nil {
108 return nil, err
109 }
110
111 resp, err := s.client.httpClient.Do(req)
112 if err != nil {
113 return nil, fmt.Errorf("failed to call API: %w", err)
114 }
115
116 defer func() { _ = resp.Body.Close() }()
117
118 if resp.StatusCode != http.StatusCreated {
119 return nil, handleError(resp)
120 }
121
122 var tokenPolicy TokenPolicy
123
124 err = handleResponse(resp, &tokenPolicy)
125 if err != nil {
126 return nil, err
127 }
128
129 return &tokenPolicy, nil
130 }
131
132 // Update a token policy
133 // https://desec.readthedocs.io/en/latest/auth/tokens.html#token-policy-management
134 func (s *TokenPoliciesService) Update(ctx context.Context, tokenID, policyID string, policy TokenPolicy) (*TokenPolicy, error) {
135 endpoint, err := s.client.createEndpoint("auth", "tokens", tokenID, "policies", "rrsets", policyID)
136 if err != nil {
137 return nil, fmt.Errorf("failed to create endpoint: %w", err)
138 }
139
140 // Copy values, including only fields that can be modified
141 req, err := s.client.newRequest(ctx, http.MethodPatch, endpoint, TokenPolicy{
142 Domain: policy.Domain,
143 SubName: policy.SubName,
144 Type: policy.Type,
145 WritePermission: policy.WritePermission,
146 })
147 if err != nil {
148 return nil, err
149 }
150
151 resp, err := s.client.httpClient.Do(req)
152 if err != nil {
153 return nil, fmt.Errorf("failed to call API: %w", err)
154 }
155
156 defer func() { _ = resp.Body.Close() }()
157
158 if resp.StatusCode != http.StatusOK {
159 return nil, handleError(resp)
160 }
161
162 result := &TokenPolicy{}
163
164 err = handleResponse(resp, result)
165 if err != nil {
166 return nil, err
167 }
168
169 return result, nil
170 }
171
172 // Delete deletes a token rrset's policy.
173 // https://desec.readthedocs.io/en/latest/auth/tokens.html#token-policy-management
174 func (s *TokenPoliciesService) Delete(ctx context.Context, tokenID, policyID string) error {
175 endpoint, err := s.client.createEndpoint("auth", "tokens", tokenID, "policies", "rrsets", policyID)
176 if err != nil {
177 return fmt.Errorf("failed to create endpoint: %w", err)
178 }
179
180 req, err := s.client.newRequest(ctx, http.MethodDelete, endpoint, nil)
181 if err != nil {
182 return err
183 }
184
185 resp, err := s.client.httpClient.Do(req)
186 if err != nil {
187 return fmt.Errorf("failed to call API: %w", err)
188 }
189
190 defer func() { _ = resp.Body.Close() }()
191
192 if resp.StatusCode != http.StatusNoContent {
193 return handleError(resp)
194 }
195
196 return nil
197 }
198