1package s3_test
2
3import (
4	"crypto/md5"
5	"encoding/base64"
6	"io/ioutil"
7	"testing"
8
9	"github.com/aws/aws-sdk-go/aws"
10	"github.com/aws/aws-sdk-go/aws/request"
11	"github.com/aws/aws-sdk-go/awstesting/unit"
12	"github.com/aws/aws-sdk-go/service/s3"
13)
14
15func assertMD5(t *testing.T, req *request.Request) {
16	err := req.Build()
17	if err != nil {
18		t.Errorf("expected no error, but received %v", err)
19	}
20
21	b, _ := ioutil.ReadAll(req.HTTPRequest.Body)
22	out := md5.Sum(b)
23	if len(b) == 0 {
24		t.Error("expected non-empty value")
25	}
26	if a := req.HTTPRequest.Header.Get("Content-MD5"); len(a) == 0 {
27		t.Fatal("Expected Content-MD5 header to be present in the operation request, was not")
28	} else if e := base64.StdEncoding.EncodeToString(out[:]); e != a {
29		t.Errorf("expected %s, but received %s", e, a)
30	}
31}
32
33func TestMD5InPutBucketCors(t *testing.T) {
34	svc := s3.New(unit.Session)
35	req, _ := svc.PutBucketCorsRequest(&s3.PutBucketCorsInput{
36		Bucket: aws.String("bucketname"),
37		CORSConfiguration: &s3.CORSConfiguration{
38			CORSRules: []*s3.CORSRule{
39				{
40					AllowedMethods: []*string{aws.String("GET")},
41					AllowedOrigins: []*string{aws.String("*")},
42				},
43			},
44		},
45	})
46	assertMD5(t, req)
47}
48
49func TestMD5InPutBucketLifecycle(t *testing.T) {
50	svc := s3.New(unit.Session)
51	req, _ := svc.PutBucketLifecycleRequest(&s3.PutBucketLifecycleInput{
52		Bucket: aws.String("bucketname"),
53		LifecycleConfiguration: &s3.LifecycleConfiguration{
54			Rules: []*s3.Rule{
55				{
56					ID:     aws.String("ID"),
57					Prefix: aws.String("Prefix"),
58					Status: aws.String("Enabled"),
59				},
60			},
61		},
62	})
63	assertMD5(t, req)
64}
65
66func TestMD5InPutBucketPolicy(t *testing.T) {
67	svc := s3.New(unit.Session)
68	req, _ := svc.PutBucketPolicyRequest(&s3.PutBucketPolicyInput{
69		Bucket: aws.String("bucketname"),
70		Policy: aws.String("{}"),
71	})
72	assertMD5(t, req)
73}
74
75func TestMD5InPutBucketTagging(t *testing.T) {
76	svc := s3.New(unit.Session)
77	req, _ := svc.PutBucketTaggingRequest(&s3.PutBucketTaggingInput{
78		Bucket: aws.String("bucketname"),
79		Tagging: &s3.Tagging{
80			TagSet: []*s3.Tag{
81				{Key: aws.String("KEY"), Value: aws.String("VALUE")},
82			},
83		},
84	})
85	assertMD5(t, req)
86}
87
88func TestMD5InDeleteObjects(t *testing.T) {
89	svc := s3.New(unit.Session)
90	req, _ := svc.DeleteObjectsRequest(&s3.DeleteObjectsInput{
91		Bucket: aws.String("bucketname"),
92		Delete: &s3.Delete{
93			Objects: []*s3.ObjectIdentifier{
94				{Key: aws.String("key")},
95			},
96		},
97	})
98	assertMD5(t, req)
99}
100
101func TestMD5InPutBucketLifecycleConfiguration(t *testing.T) {
102	svc := s3.New(unit.Session)
103	req, _ := svc.PutBucketLifecycleConfigurationRequest(&s3.PutBucketLifecycleConfigurationInput{
104		Bucket: aws.String("bucketname"),
105		LifecycleConfiguration: &s3.BucketLifecycleConfiguration{
106			Rules: []*s3.LifecycleRule{
107				{Prefix: aws.String("prefix"), Status: aws.String(s3.ExpirationStatusEnabled)},
108			},
109		},
110	})
111	assertMD5(t, req)
112}
113
114func TestMD5InPutBucketReplication(t *testing.T) {
115	svc := s3.New(unit.Session)
116	req, _ := svc.PutBucketReplicationRequest(&s3.PutBucketReplicationInput{
117		Bucket: aws.String("bucketname"),
118		ReplicationConfiguration: &s3.ReplicationConfiguration{
119			Role: aws.String("Role"),
120			Rules: []*s3.ReplicationRule{
121				{
122					Destination: &s3.Destination{
123						Bucket: aws.String("mock bucket"),
124					},
125					Status: aws.String(s3.ReplicationRuleStatusDisabled),
126				},
127			},
128		},
129		Token: aws.String("token"),
130	})
131	assertMD5(t, req)
132}
133
134func TestMD5InPutBucketAcl(t *testing.T) {
135	svc := s3.New(unit.Session)
136	req, _ := svc.PutBucketAclRequest(&s3.PutBucketAclInput{
137		Bucket: aws.String("bucketname"),
138		AccessControlPolicy: &s3.AccessControlPolicy{
139			Grants: []*s3.Grant{{
140				Grantee: &s3.Grantee{
141					ID:   aws.String("mock id"),
142					Type: aws.String("type"),
143				},
144				Permission: aws.String(s3.PermissionFullControl),
145			}},
146			Owner: &s3.Owner{
147				DisplayName: aws.String("mock name"),
148			},
149		},
150	})
151	assertMD5(t, req)
152}
153
154func TestMD5InPutBucketEncryption(t *testing.T) {
155	svc := s3.New(unit.Session)
156	req, _ := svc.PutBucketEncryptionRequest(&s3.PutBucketEncryptionInput{
157		Bucket: aws.String("bucketname"),
158		ServerSideEncryptionConfiguration: &s3.ServerSideEncryptionConfiguration{
159			Rules: []*s3.ServerSideEncryptionRule{
160				{
161					ApplyServerSideEncryptionByDefault: &s3.ServerSideEncryptionByDefault{
162						KMSMasterKeyID: aws.String("mock KMS master key id"),
163						SSEAlgorithm:   aws.String("mock SSE algorithm"),
164					},
165				},
166			},
167		},
168	})
169
170	assertMD5(t, req)
171}
172
173func TestMD5InPutBucketLogging(t *testing.T) {
174	svc := s3.New(unit.Session)
175	req, _ := svc.PutBucketLoggingRequest(&s3.PutBucketLoggingInput{
176		Bucket: aws.String("bucket name"),
177		BucketLoggingStatus: &s3.BucketLoggingStatus{LoggingEnabled: &s3.LoggingEnabled{
178			TargetBucket: aws.String("target bucket"),
179			TargetPrefix: aws.String("target prefix"),
180		}},
181	})
182
183	assertMD5(t, req)
184}
185
186func TestMD5InPutBucketNotification(t *testing.T) {
187	svc := s3.New(unit.Session)
188	req, _ := svc.PutBucketNotificationRequest(&s3.PutBucketNotificationInput{
189		Bucket: aws.String("bucket name"),
190		NotificationConfiguration: &s3.NotificationConfigurationDeprecated{
191			TopicConfiguration: &s3.TopicConfigurationDeprecated{
192				Id: aws.String("id"),
193			},
194		},
195	})
196
197	assertMD5(t, req)
198}
199
200func TestMD5InPutBucketRequestPayment(t *testing.T) {
201	svc := s3.New(unit.Session)
202	req, _ := svc.PutBucketRequestPaymentRequest(&s3.PutBucketRequestPaymentInput{
203		Bucket: aws.String("bucketname"),
204		RequestPaymentConfiguration: &s3.RequestPaymentConfiguration{
205			Payer: aws.String("payer"),
206		},
207	})
208
209	assertMD5(t, req)
210}
211
212func TestMD5InPutBucketVersioning(t *testing.T) {
213	svc := s3.New(unit.Session)
214	req, _ := svc.PutBucketVersioningRequest(&s3.PutBucketVersioningInput{
215		Bucket: aws.String("bucketname"),
216		VersioningConfiguration: &s3.VersioningConfiguration{
217			MFADelete: aws.String(s3.MFADeleteDisabled),
218			Status:    aws.String(s3.BucketVersioningStatusSuspended),
219		},
220	})
221
222	assertMD5(t, req)
223}
224
225func TestMD5InPutBucketWebsite(t *testing.T) {
226	svc := s3.New(unit.Session)
227	req, _ := svc.PutBucketWebsiteRequest(&s3.PutBucketWebsiteInput{
228		Bucket: aws.String("bucket name"),
229		WebsiteConfiguration: &s3.WebsiteConfiguration{
230			ErrorDocument: &s3.ErrorDocument{
231				Key: aws.String("error"),
232			},
233		},
234	})
235
236	assertMD5(t, req)
237}
238
239func TestMD5InPutObjectLegalHold(t *testing.T) {
240	svc := s3.New(unit.Session)
241	req, _ := svc.PutObjectLegalHoldRequest(&s3.PutObjectLegalHoldInput{
242		Bucket: aws.String("bucketname"),
243		Key:    aws.String("key"),
244		LegalHold: &s3.ObjectLockLegalHold{
245			Status: aws.String(s3.ObjectLockLegalHoldStatusOff),
246		},
247	})
248
249	assertMD5(t, req)
250}
251
252func TestMD5InPutObjectRetention(t *testing.T) {
253	svc := s3.New(unit.Session)
254	req, _ := svc.PutObjectRetentionRequest(&s3.PutObjectRetentionInput{
255		Bucket:                    aws.String("bucket name"),
256		BypassGovernanceRetention: nil,
257		Key:                       aws.String("key"),
258		RequestPayer:              nil,
259		Retention: &s3.ObjectLockRetention{
260			Mode: aws.String("mode"),
261		},
262		VersionId: nil,
263	})
264
265	assertMD5(t, req)
266}
267
268func TestMD5InPutObjectLockConfiguration(t *testing.T) {
269	svc := s3.New(unit.Session)
270	req, _ := svc.PutObjectLockConfigurationRequest(&s3.PutObjectLockConfigurationInput{
271		Bucket: aws.String("bucket name"),
272		ObjectLockConfiguration: &s3.ObjectLockConfiguration{
273			ObjectLockEnabled: aws.String(s3.ObjectLockEnabledEnabled),
274		},
275	})
276
277	assertMD5(t, req)
278}
279
280func TestMD5InPutObjectAcl(t *testing.T) {
281	svc := s3.New(unit.Session)
282	req, _ := svc.PutObjectAclRequest(&s3.PutObjectAclInput{
283		AccessControlPolicy: &s3.AccessControlPolicy{
284			Grants: []*s3.Grant{{
285				Grantee: &s3.Grantee{
286					ID:   aws.String("mock id"),
287					Type: aws.String("type"),
288				},
289				Permission: aws.String(s3.PermissionFullControl),
290			}},
291			Owner: &s3.Owner{
292				DisplayName: aws.String("mock name"),
293			},
294		},
295		Bucket: aws.String("bucket name"),
296		Key:    aws.String("key"),
297	})
298
299	assertMD5(t, req)
300}
301
302func TestMD5InPutObjectTagging(t *testing.T) {
303	svc := s3.New(unit.Session)
304	req, _ := svc.PutObjectTaggingRequest(&s3.PutObjectTaggingInput{
305		Bucket: aws.String("bucket name"),
306		Key:    aws.String("key"),
307		Tagging: &s3.Tagging{TagSet: []*s3.Tag{
308			{
309				Key:   aws.String("key"),
310				Value: aws.String("value"),
311			},
312		}},
313	})
314
315	assertMD5(t, req)
316}
317
318func TestMD5InPutPublicAccessBlock(t *testing.T) {
319	svc := s3.New(unit.Session)
320	req, _ := svc.PutPublicAccessBlockRequest(&s3.PutPublicAccessBlockInput{
321		Bucket: aws.String("bucket name"),
322		PublicAccessBlockConfiguration: &s3.PublicAccessBlockConfiguration{
323			BlockPublicAcls:       aws.Bool(true),
324			BlockPublicPolicy:     aws.Bool(true),
325			IgnorePublicAcls:      aws.Bool(true),
326			RestrictPublicBuckets: aws.Bool(true),
327		},
328	})
329
330	assertMD5(t, req)
331}
332