diff options
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/post-policy.go')
-rw-r--r-- | vendor/github.com/minio/minio-go/v7/post-policy.go | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/post-policy.go b/vendor/github.com/minio/minio-go/v7/post-policy.go deleted file mode 100644 index 3f4881e..0000000 --- a/vendor/github.com/minio/minio-go/v7/post-policy.go +++ /dev/null | |||
@@ -1,349 +0,0 @@ | |||
1 | /* | ||
2 | * MinIO Go Library for Amazon S3 Compatible Cloud Storage | ||
3 | * Copyright 2015-2023 MinIO, Inc. | ||
4 | * | ||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | * you may not use this file except in compliance with the License. | ||
7 | * You may obtain a copy of the License at | ||
8 | * | ||
9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | * | ||
11 | * Unless required by applicable law or agreed to in writing, software | ||
12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | * See the License for the specific language governing permissions and | ||
15 | * limitations under the License. | ||
16 | */ | ||
17 | |||
18 | package minio | ||
19 | |||
20 | import ( | ||
21 | "encoding/base64" | ||
22 | "fmt" | ||
23 | "net/http" | ||
24 | "strings" | ||
25 | "time" | ||
26 | |||
27 | "github.com/minio/minio-go/v7/pkg/encrypt" | ||
28 | ) | ||
29 | |||
30 | // expirationDateFormat date format for expiration key in json policy. | ||
31 | const expirationDateFormat = "2006-01-02T15:04:05.000Z" | ||
32 | |||
33 | // policyCondition explanation: | ||
34 | // http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html | ||
35 | // | ||
36 | // Example: | ||
37 | // | ||
38 | // policyCondition { | ||
39 | // matchType: "$eq", | ||
40 | // key: "$Content-Type", | ||
41 | // value: "image/png", | ||
42 | // } | ||
43 | type policyCondition struct { | ||
44 | matchType string | ||
45 | condition string | ||
46 | value string | ||
47 | } | ||
48 | |||
49 | // PostPolicy - Provides strict static type conversion and validation | ||
50 | // for Amazon S3's POST policy JSON string. | ||
51 | type PostPolicy struct { | ||
52 | // Expiration date and time of the POST policy. | ||
53 | expiration time.Time | ||
54 | // Collection of different policy conditions. | ||
55 | conditions []policyCondition | ||
56 | // ContentLengthRange minimum and maximum allowable size for the | ||
57 | // uploaded content. | ||
58 | contentLengthRange struct { | ||
59 | min int64 | ||
60 | max int64 | ||
61 | } | ||
62 | |||
63 | // Post form data. | ||
64 | formData map[string]string | ||
65 | } | ||
66 | |||
67 | // NewPostPolicy - Instantiate new post policy. | ||
68 | func NewPostPolicy() *PostPolicy { | ||
69 | p := &PostPolicy{} | ||
70 | p.conditions = make([]policyCondition, 0) | ||
71 | p.formData = make(map[string]string) | ||
72 | return p | ||
73 | } | ||
74 | |||
75 | // SetExpires - Sets expiration time for the new policy. | ||
76 | func (p *PostPolicy) SetExpires(t time.Time) error { | ||
77 | if t.IsZero() { | ||
78 | return errInvalidArgument("No expiry time set.") | ||
79 | } | ||
80 | p.expiration = t | ||
81 | return nil | ||
82 | } | ||
83 | |||
84 | // SetKey - Sets an object name for the policy based upload. | ||
85 | func (p *PostPolicy) SetKey(key string) error { | ||
86 | if strings.TrimSpace(key) == "" || key == "" { | ||
87 | return errInvalidArgument("Object name is empty.") | ||
88 | } | ||
89 | policyCond := policyCondition{ | ||
90 | matchType: "eq", | ||
91 | condition: "$key", | ||
92 | value: key, | ||
93 | } | ||
94 | if err := p.addNewPolicy(policyCond); err != nil { | ||
95 | return err | ||
96 | } | ||
97 | p.formData["key"] = key | ||
98 | return nil | ||
99 | } | ||
100 | |||
101 | // SetKeyStartsWith - Sets an object name that an policy based upload | ||
102 | // can start with. | ||
103 | // Can use an empty value ("") to allow any key. | ||
104 | func (p *PostPolicy) SetKeyStartsWith(keyStartsWith string) error { | ||
105 | policyCond := policyCondition{ | ||
106 | matchType: "starts-with", | ||
107 | condition: "$key", | ||
108 | value: keyStartsWith, | ||
109 | } | ||
110 | if err := p.addNewPolicy(policyCond); err != nil { | ||
111 | return err | ||
112 | } | ||
113 | p.formData["key"] = keyStartsWith | ||
114 | return nil | ||
115 | } | ||
116 | |||
117 | // SetBucket - Sets bucket at which objects will be uploaded to. | ||
118 | func (p *PostPolicy) SetBucket(bucketName string) error { | ||
119 | if strings.TrimSpace(bucketName) == "" || bucketName == "" { | ||
120 | return errInvalidArgument("Bucket name is empty.") | ||
121 | } | ||
122 | policyCond := policyCondition{ | ||
123 | matchType: "eq", | ||
124 | condition: "$bucket", | ||
125 | value: bucketName, | ||
126 | } | ||
127 | if err := p.addNewPolicy(policyCond); err != nil { | ||
128 | return err | ||
129 | } | ||
130 | p.formData["bucket"] = bucketName | ||
131 | return nil | ||
132 | } | ||
133 | |||
134 | // SetCondition - Sets condition for credentials, date and algorithm | ||
135 | func (p *PostPolicy) SetCondition(matchType, condition, value string) error { | ||
136 | if strings.TrimSpace(value) == "" || value == "" { | ||
137 | return errInvalidArgument("No value specified for condition") | ||
138 | } | ||
139 | |||
140 | policyCond := policyCondition{ | ||
141 | matchType: matchType, | ||
142 | condition: "$" + condition, | ||
143 | value: value, | ||
144 | } | ||
145 | if condition == "X-Amz-Credential" || condition == "X-Amz-Date" || condition == "X-Amz-Algorithm" { | ||
146 | if err := p.addNewPolicy(policyCond); err != nil { | ||
147 | return err | ||
148 | } | ||
149 | p.formData[condition] = value | ||
150 | return nil | ||
151 | } | ||
152 | return errInvalidArgument("Invalid condition in policy") | ||
153 | } | ||
154 | |||
155 | // SetContentType - Sets content-type of the object for this policy | ||
156 | // based upload. | ||
157 | func (p *PostPolicy) SetContentType(contentType string) error { | ||
158 | if strings.TrimSpace(contentType) == "" || contentType == "" { | ||
159 | return errInvalidArgument("No content type specified.") | ||
160 | } | ||
161 | policyCond := policyCondition{ | ||
162 | matchType: "eq", | ||
163 | condition: "$Content-Type", | ||
164 | value: contentType, | ||
165 | } | ||
166 | if err := p.addNewPolicy(policyCond); err != nil { | ||
167 | return err | ||
168 | } | ||
169 | p.formData["Content-Type"] = contentType | ||
170 | return nil | ||
171 | } | ||
172 | |||
173 | // SetContentTypeStartsWith - Sets what content-type of the object for this policy | ||
174 | // based upload can start with. | ||
175 | // Can use an empty value ("") to allow any content-type. | ||
176 | func (p *PostPolicy) SetContentTypeStartsWith(contentTypeStartsWith string) error { | ||
177 | policyCond := policyCondition{ | ||
178 | matchType: "starts-with", | ||
179 | condition: "$Content-Type", | ||
180 | value: contentTypeStartsWith, | ||
181 | } | ||
182 | if err := p.addNewPolicy(policyCond); err != nil { | ||
183 | return err | ||
184 | } | ||
185 | p.formData["Content-Type"] = contentTypeStartsWith | ||
186 | return nil | ||
187 | } | ||
188 | |||
189 | // SetContentLengthRange - Set new min and max content length | ||
190 | // condition for all incoming uploads. | ||
191 | func (p *PostPolicy) SetContentLengthRange(min, max int64) error { | ||
192 | if min > max { | ||
193 | return errInvalidArgument("Minimum limit is larger than maximum limit.") | ||
194 | } | ||
195 | if min < 0 { | ||
196 | return errInvalidArgument("Minimum limit cannot be negative.") | ||
197 | } | ||
198 | if max <= 0 { | ||
199 | return errInvalidArgument("Maximum limit cannot be non-positive.") | ||
200 | } | ||
201 | p.contentLengthRange.min = min | ||
202 | p.contentLengthRange.max = max | ||
203 | return nil | ||
204 | } | ||
205 | |||
206 | // SetSuccessActionRedirect - Sets the redirect success url of the object for this policy | ||
207 | // based upload. | ||
208 | func (p *PostPolicy) SetSuccessActionRedirect(redirect string) error { | ||
209 | if strings.TrimSpace(redirect) == "" || redirect == "" { | ||
210 | return errInvalidArgument("Redirect is empty") | ||
211 | } | ||
212 | policyCond := policyCondition{ | ||
213 | matchType: "eq", | ||
214 | condition: "$success_action_redirect", | ||
215 | value: redirect, | ||
216 | } | ||
217 | if err := p.addNewPolicy(policyCond); err != nil { | ||
218 | return err | ||
219 | } | ||
220 | p.formData["success_action_redirect"] = redirect | ||
221 | return nil | ||
222 | } | ||
223 | |||
224 | // SetSuccessStatusAction - Sets the status success code of the object for this policy | ||
225 | // based upload. | ||
226 | func (p *PostPolicy) SetSuccessStatusAction(status string) error { | ||
227 | if strings.TrimSpace(status) == "" || status == "" { | ||
228 | return errInvalidArgument("Status is empty") | ||
229 | } | ||
230 | policyCond := policyCondition{ | ||
231 | matchType: "eq", | ||
232 | condition: "$success_action_status", | ||
233 | value: status, | ||
234 | } | ||
235 | if err := p.addNewPolicy(policyCond); err != nil { | ||
236 | return err | ||
237 | } | ||
238 | p.formData["success_action_status"] = status | ||
239 | return nil | ||
240 | } | ||
241 | |||
242 | // SetUserMetadata - Set user metadata as a key/value couple. | ||
243 | // Can be retrieved through a HEAD request or an event. | ||
244 | func (p *PostPolicy) SetUserMetadata(key, value string) error { | ||
245 | if strings.TrimSpace(key) == "" || key == "" { | ||
246 | return errInvalidArgument("Key is empty") | ||
247 | } | ||
248 | if strings.TrimSpace(value) == "" || value == "" { | ||
249 | return errInvalidArgument("Value is empty") | ||
250 | } | ||
251 | headerName := fmt.Sprintf("x-amz-meta-%s", key) | ||
252 | policyCond := policyCondition{ | ||
253 | matchType: "eq", | ||
254 | condition: fmt.Sprintf("$%s", headerName), | ||
255 | value: value, | ||
256 | } | ||
257 | if err := p.addNewPolicy(policyCond); err != nil { | ||
258 | return err | ||
259 | } | ||
260 | p.formData[headerName] = value | ||
261 | return nil | ||
262 | } | ||
263 | |||
264 | // SetChecksum sets the checksum of the request. | ||
265 | func (p *PostPolicy) SetChecksum(c Checksum) { | ||
266 | if c.IsSet() { | ||
267 | p.formData[amzChecksumAlgo] = c.Type.String() | ||
268 | p.formData[c.Type.Key()] = c.Encoded() | ||
269 | } | ||
270 | } | ||
271 | |||
272 | // SetEncryption - sets encryption headers for POST API | ||
273 | func (p *PostPolicy) SetEncryption(sse encrypt.ServerSide) { | ||
274 | if sse == nil { | ||
275 | return | ||
276 | } | ||
277 | h := http.Header{} | ||
278 | sse.Marshal(h) | ||
279 | for k, v := range h { | ||
280 | p.formData[k] = v[0] | ||
281 | } | ||
282 | } | ||
283 | |||
284 | // SetUserData - Set user data as a key/value couple. | ||
285 | // Can be retrieved through a HEAD request or an event. | ||
286 | func (p *PostPolicy) SetUserData(key, value string) error { | ||
287 | if key == "" { | ||
288 | return errInvalidArgument("Key is empty") | ||
289 | } | ||
290 | if value == "" { | ||
291 | return errInvalidArgument("Value is empty") | ||
292 | } | ||
293 | headerName := fmt.Sprintf("x-amz-%s", key) | ||
294 | policyCond := policyCondition{ | ||
295 | matchType: "eq", | ||
296 | condition: fmt.Sprintf("$%s", headerName), | ||
297 | value: value, | ||
298 | } | ||
299 | if err := p.addNewPolicy(policyCond); err != nil { | ||
300 | return err | ||
301 | } | ||
302 | p.formData[headerName] = value | ||
303 | return nil | ||
304 | } | ||
305 | |||
306 | // addNewPolicy - internal helper to validate adding new policies. | ||
307 | // Can use starts-with with an empty value ("") to allow any content within a form field. | ||
308 | func (p *PostPolicy) addNewPolicy(policyCond policyCondition) error { | ||
309 | if policyCond.matchType == "" || policyCond.condition == "" { | ||
310 | return errInvalidArgument("Policy fields are empty.") | ||
311 | } | ||
312 | if policyCond.matchType != "starts-with" && policyCond.value == "" { | ||
313 | return errInvalidArgument("Policy value is empty.") | ||
314 | } | ||
315 | p.conditions = append(p.conditions, policyCond) | ||
316 | return nil | ||
317 | } | ||
318 | |||
319 | // String function for printing policy in json formatted string. | ||
320 | func (p PostPolicy) String() string { | ||
321 | return string(p.marshalJSON()) | ||
322 | } | ||
323 | |||
324 | // marshalJSON - Provides Marshaled JSON in bytes. | ||
325 | func (p PostPolicy) marshalJSON() []byte { | ||
326 | expirationStr := `"expiration":"` + p.expiration.Format(expirationDateFormat) + `"` | ||
327 | var conditionsStr string | ||
328 | conditions := []string{} | ||
329 | for _, po := range p.conditions { | ||
330 | conditions = append(conditions, fmt.Sprintf("[\"%s\",\"%s\",\"%s\"]", po.matchType, po.condition, po.value)) | ||
331 | } | ||
332 | if p.contentLengthRange.min != 0 || p.contentLengthRange.max != 0 { | ||
333 | conditions = append(conditions, fmt.Sprintf("[\"content-length-range\", %d, %d]", | ||
334 | p.contentLengthRange.min, p.contentLengthRange.max)) | ||
335 | } | ||
336 | if len(conditions) > 0 { | ||
337 | conditionsStr = `"conditions":[` + strings.Join(conditions, ",") + "]" | ||
338 | } | ||
339 | retStr := "{" | ||
340 | retStr = retStr + expirationStr + "," | ||
341 | retStr += conditionsStr | ||
342 | retStr += "}" | ||
343 | return []byte(retStr) | ||
344 | } | ||
345 | |||
346 | // base64 - Produces base64 of PostPolicy's Marshaled json. | ||
347 | func (p PostPolicy) base64() string { | ||
348 | return base64.StdEncoding.EncodeToString(p.marshalJSON()) | ||
349 | } | ||