| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 	"bytes" | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	"io/ioutil" | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"net/http/httptest" | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 	"reflect" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2021-08-20 04:21:02 +08:00
										 |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 	"testing" | 
					
						
							| 
									
										
										
										
											2016-08-20 18:16:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	"github.com/minio/minio/internal/auth" | 
					
						
							| 
									
										
										
										
											2021-05-30 12:16:42 +08:00
										 |  |  | 	"github.com/minio/pkg/bucket/policy" | 
					
						
							|  |  |  | 	"github.com/minio/pkg/bucket/policy/condition" | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | func getAnonReadOnlyBucketPolicy(bucketName string) *policy.Policy { | 
					
						
							|  |  |  | 	return &policy.Policy{ | 
					
						
							|  |  |  | 		Version: policy.DefaultVersion, | 
					
						
							| 
									
										
										
										
											2022-01-11 06:26:26 +08:00
										 |  |  | 		Statements: []policy.Statement{ | 
					
						
							|  |  |  | 			policy.NewStatement( | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				policy.Allow, | 
					
						
							|  |  |  | 				policy.NewPrincipal("*"), | 
					
						
							|  |  |  | 				policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction), | 
					
						
							|  |  |  | 				policy.NewResourceSet(policy.NewResource(bucketName, "")), | 
					
						
							|  |  |  | 				condition.NewFunctions(), | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | func getAnonWriteOnlyBucketPolicy(bucketName string) *policy.Policy { | 
					
						
							|  |  |  | 	return &policy.Policy{ | 
					
						
							|  |  |  | 		Version: policy.DefaultVersion, | 
					
						
							| 
									
										
										
										
											2022-01-11 06:26:26 +08:00
										 |  |  | 		Statements: []policy.Statement{ | 
					
						
							|  |  |  | 			policy.NewStatement( | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				policy.Allow, | 
					
						
							|  |  |  | 				policy.NewPrincipal("*"), | 
					
						
							|  |  |  | 				policy.NewActionSet( | 
					
						
							|  |  |  | 					policy.GetBucketLocationAction, | 
					
						
							|  |  |  | 					policy.ListBucketMultipartUploadsAction, | 
					
						
							|  |  |  | 				), | 
					
						
							|  |  |  | 				policy.NewResourceSet(policy.NewResource(bucketName, "")), | 
					
						
							|  |  |  | 				condition.NewFunctions(), | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 			), | 
					
						
							| 
									
										
										
										
											2022-01-11 06:26:26 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | func getAnonReadOnlyObjectPolicy(bucketName, prefix string) *policy.Policy { | 
					
						
							|  |  |  | 	return &policy.Policy{ | 
					
						
							|  |  |  | 		Version: policy.DefaultVersion, | 
					
						
							| 
									
										
										
										
											2022-01-11 06:26:26 +08:00
										 |  |  | 		Statements: []policy.Statement{ | 
					
						
							|  |  |  | 			policy.NewStatement( | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				policy.Allow, | 
					
						
							|  |  |  | 				policy.NewPrincipal("*"), | 
					
						
							|  |  |  | 				policy.NewActionSet(policy.GetObjectAction), | 
					
						
							|  |  |  | 				policy.NewResourceSet(policy.NewResource(bucketName, prefix)), | 
					
						
							|  |  |  | 				condition.NewFunctions(), | 
					
						
							|  |  |  | 			), | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-05-05 07:56:57 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-01 14:49:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | func getAnonWriteOnlyObjectPolicy(bucketName, prefix string) *policy.Policy { | 
					
						
							|  |  |  | 	return &policy.Policy{ | 
					
						
							|  |  |  | 		Version: policy.DefaultVersion, | 
					
						
							| 
									
										
										
										
											2022-01-11 06:26:26 +08:00
										 |  |  | 		Statements: []policy.Statement{ | 
					
						
							|  |  |  | 			policy.NewStatement( | 
					
						
							|  |  |  | 				"", | 
					
						
							|  |  |  | 				policy.Allow, | 
					
						
							|  |  |  | 				policy.NewPrincipal("*"), | 
					
						
							|  |  |  | 				policy.NewActionSet( | 
					
						
							|  |  |  | 					policy.AbortMultipartUploadAction, | 
					
						
							|  |  |  | 					policy.DeleteObjectAction, | 
					
						
							|  |  |  | 					policy.ListMultipartUploadPartsAction, | 
					
						
							|  |  |  | 					policy.PutObjectAction, | 
					
						
							|  |  |  | 				), | 
					
						
							|  |  |  | 				policy.NewResourceSet(policy.NewResource(bucketName, prefix)), | 
					
						
							|  |  |  | 				condition.NewFunctions(), | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 			), | 
					
						
							| 
									
										
										
										
											2022-01-11 06:26:26 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-07-01 14:49:59 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-01 14:49:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-20 04:21:02 +08:00
										 |  |  | // Wrapper for calling Create Bucket and ensure we get one and only one success.
 | 
					
						
							|  |  |  | func TestCreateBucket(t *testing.T) { | 
					
						
							|  |  |  | 	ExecObjectLayerAPITest(t, testCreateBucket, []string{"MakeBucketWithLocation"}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // testCreateBucket - Test for calling Create Bucket and ensure we get one and only one success.
 | 
					
						
							|  |  |  | func testCreateBucket(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler, | 
					
						
							|  |  |  | 	credentials auth.Credentials, t *testing.T) { | 
					
						
							|  |  |  | 	bucketName1 := fmt.Sprintf("%s-1", bucketName) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const n = 100 | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | 	start := make(chan struct{}) | 
					
						
							| 
									
										
										
										
											2021-08-20 04:21:02 +08:00
										 |  |  | 	var ok, errs int | 
					
						
							|  |  |  | 	var wg sync.WaitGroup | 
					
						
							|  |  |  | 	var mu sync.Mutex | 
					
						
							|  |  |  | 	wg.Add(n) | 
					
						
							|  |  |  | 	for i := 0; i < n; i++ { | 
					
						
							|  |  |  | 		go func() { | 
					
						
							|  |  |  | 			defer wg.Done() | 
					
						
							|  |  |  | 			// Sync start.
 | 
					
						
							|  |  |  | 			<-start | 
					
						
							|  |  |  | 			if err := obj.MakeBucketWithLocation(GlobalContext, bucketName1, BucketOptions{}); err != nil { | 
					
						
							|  |  |  | 				if _, ok := err.(BucketExists); !ok { | 
					
						
							|  |  |  | 					t.Logf("unexpected error: %T: %v", err, err) | 
					
						
							|  |  |  | 					return | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				mu.Lock() | 
					
						
							|  |  |  | 				errs++ | 
					
						
							|  |  |  | 				mu.Unlock() | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			mu.Lock() | 
					
						
							|  |  |  | 			ok++ | 
					
						
							|  |  |  | 			mu.Unlock() | 
					
						
							|  |  |  | 		}() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	close(start) | 
					
						
							|  |  |  | 	wg.Wait() | 
					
						
							|  |  |  | 	if ok != 1 { | 
					
						
							|  |  |  | 		t.Fatalf("want 1 ok, got %d", ok) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if errs != n-1 { | 
					
						
							|  |  |  | 		t.Fatalf("want %d errors, got %d", n-1, errs) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:04:01 +08:00
										 |  |  | // Wrapper for calling Put Bucket Policy HTTP handler tests for both Erasure multiple disks and single node setup.
 | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | func TestPutBucketPolicyHandler(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-06 17:02:42 +08:00
										 |  |  | 	ExecObjectLayerAPITest(t, testPutBucketPolicyHandler, []string{"PutBucketPolicy"}) | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // testPutBucketPolicyHandler - Test for Bucket policy end point.
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:02:42 +08:00
										 |  |  | func testPutBucketPolicyHandler(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler, | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | 	credentials auth.Credentials, t *testing.T, | 
					
						
							|  |  |  | ) { | 
					
						
							| 
									
										
										
										
											2016-11-15 07:45:00 +08:00
										 |  |  | 	bucketName1 := fmt.Sprintf("%s-1", bucketName) | 
					
						
							| 
									
										
										
										
											2020-06-13 11:04:01 +08:00
										 |  |  | 	if err := obj.MakeBucketWithLocation(GlobalContext, bucketName1, BucketOptions{}); err != nil { | 
					
						
							| 
									
										
										
										
											2016-11-15 07:45:00 +08:00
										 |  |  | 		t.Fatal(err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 	// template for constructing HTTP request body for PUT bucket policy.
 | 
					
						
							| 
									
										
										
										
											2016-08-11 11:10:48 +08:00
										 |  |  | 	bucketPolicyTemplate := `{"Version":"2012-10-17","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetBucketLocation","s3:ListBucket"],"Resource":["arn:aws:s3:::%s"]},{"Sid":"","Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetObject"],"Resource":["arn:aws:s3:::%s/this*"]}]}` | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-28 06:02:54 +08:00
										 |  |  | 	bucketPolicyTemplateWithoutVersion := `{"Version":"","Statement":[{"Sid":"","Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetBucketLocation","s3:ListBucket"],"Resource":["arn:aws:s3:::%s"]},{"Sid":"","Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetObject"],"Resource":["arn:aws:s3:::%s/this*"]}]}` | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 	// test cases with sample input and expected output.
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		bucketName string | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		// bucket policy to be set,
 | 
					
						
							|  |  |  | 		// set as request body.
 | 
					
						
							|  |  |  | 		bucketPolicyReader io.ReadSeeker | 
					
						
							|  |  |  | 		// length in bytes of the bucket policy being set.
 | 
					
						
							|  |  |  | 		policyLen int | 
					
						
							|  |  |  | 		accessKey string | 
					
						
							|  |  |  | 		secretKey string | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 		// expected Response.
 | 
					
						
							|  |  |  | 		expectedRespStatus int | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		// Test case - 1.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							|  |  |  | 			bucketPolicyReader: bytes.NewReader([]byte(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName))), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          len(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName)), | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusNoContent, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 2.
 | 
					
						
							|  |  |  | 		// Setting the content length to be more than max allowed size.
 | 
					
						
							|  |  |  | 		// Expecting StatusBadRequest (400).
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							|  |  |  | 			bucketPolicyReader: bytes.NewReader([]byte(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName))), | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 			policyLen:          maxBucketPolicySize + 1, | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 3.
 | 
					
						
							|  |  |  | 		// Case with content-length of the HTTP request set to 0.
 | 
					
						
							|  |  |  | 		// Expecting the HTTP response status to be StatusLengthRequired (411).
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							|  |  |  | 			bucketPolicyReader: bytes.NewReader([]byte(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName))), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          0, | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusLengthRequired, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 4.
 | 
					
						
							|  |  |  | 		// setting the readSeeker to `nil`, bucket policy parser will fail.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							|  |  |  | 			bucketPolicyReader: nil, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          10, | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 5.
 | 
					
						
							|  |  |  | 		// setting the keys to be empty.
 | 
					
						
							|  |  |  | 		// Expecting statusForbidden.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							|  |  |  | 			bucketPolicyReader: nil, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          10, | 
					
						
							|  |  |  | 			accessKey:          "", | 
					
						
							|  |  |  | 			secretKey:          "", | 
					
						
							|  |  |  | 			expectedRespStatus: http.StatusForbidden, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 6.
 | 
					
						
							|  |  |  | 		// setting an invalid bucket policy.
 | 
					
						
							|  |  |  | 		// the bucket policy parser will fail.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-11-15 07:45:00 +08:00
										 |  |  | 			bucketName:         bucketName, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			bucketPolicyReader: bytes.NewReader([]byte("dummy-policy")), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          len([]byte("dummy-policy")), | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 7.
 | 
					
						
							|  |  |  | 		// Different bucket name used in the HTTP request and the policy string.
 | 
					
						
							|  |  |  | 		// checkBucketPolicyResources should fail.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2016-11-15 07:45:00 +08:00
										 |  |  | 			bucketName:         bucketName1, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			bucketPolicyReader: bytes.NewReader([]byte(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName))), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          len(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName)), | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 8.
 | 
					
						
							|  |  |  | 		// non-existent bucket is used.
 | 
					
						
							|  |  |  | 		// writing BucketPolicy should fail.
 | 
					
						
							| 
									
										
										
										
											2018-04-28 06:02:54 +08:00
										 |  |  | 		// should result in 404 StatusNotFound
 | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         "non-existent-bucket", | 
					
						
							|  |  |  | 			bucketPolicyReader: bytes.NewReader([]byte(fmt.Sprintf(bucketPolicyTemplate, "non-existent-bucket", "non-existent-bucket"))), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          len(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName)), | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-11-15 07:45:00 +08:00
										 |  |  | 			expectedRespStatus: http.StatusNotFound, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 9.
 | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 		// non-existent bucket is used (with invalid bucket name)
 | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		// writing BucketPolicy should fail.
 | 
					
						
							| 
									
										
										
										
											2018-04-28 06:02:54 +08:00
										 |  |  | 		// should result in 404 StatusNotFound
 | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         ".invalid-bucket", | 
					
						
							|  |  |  | 			bucketPolicyReader: bytes.NewReader([]byte(fmt.Sprintf(bucketPolicyTemplate, ".invalid-bucket", ".invalid-bucket"))), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          len(fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName)), | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 			expectedRespStatus: http.StatusNotFound, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-04-28 06:02:54 +08:00
										 |  |  | 		// Test case - 10.
 | 
					
						
							|  |  |  | 		// Existent bucket with policy with Version field empty.
 | 
					
						
							|  |  |  | 		// writing BucketPolicy should fail.
 | 
					
						
							|  |  |  | 		// should result in 400 StatusBadRequest.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							|  |  |  | 			bucketPolicyReader: bytes.NewReader([]byte(fmt.Sprintf(bucketPolicyTemplateWithoutVersion, bucketName, bucketName))), | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			policyLen:          len(fmt.Sprintf(bucketPolicyTemplateWithoutVersion, bucketName, bucketName)), | 
					
						
							|  |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							|  |  |  | 			expectedRespStatus: http.StatusBadRequest, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Iterating over the test cases, calling the function under test and asserting the response.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		// obtain the put bucket policy request body.
 | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		recV4 := httptest.NewRecorder() | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV4, err := newTestSignedRequestV4(http.MethodPut, getPutPolicyURL("", testCase.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			int64(testCase.policyLen), testCase.bucketPolicyReader, testCase.accessKey, testCase.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-08-01 05:11:14 +08:00
										 |  |  | 			t.Fatalf("Test %d: %s: Failed to create HTTP request for PutBucketPolicyHandler: <ERROR> %v", i+1, instanceType, err) | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic ofthe handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		apiRouter.ServeHTTP(recV4, reqV4) | 
					
						
							|  |  |  | 		if recV4.Code != testCase.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: %s: Expected the response status to be `%d`, but instead found `%d`", i+1, instanceType, testCase.expectedRespStatus, recV4.Code) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							|  |  |  | 		recV2 := httptest.NewRecorder() | 
					
						
							|  |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV2, err := newTestSignedRequestV2(http.MethodPut, getPutPolicyURL("", testCase.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			int64(testCase.policyLen), testCase.bucketPolicyReader, testCase.accessKey, testCase.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: %s: Failed to create HTTP request for PutBucketPolicyHandler: <ERROR> %v", i+1, instanceType, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic ofthe handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler.
 | 
					
						
							|  |  |  | 		apiRouter.ServeHTTP(recV2, reqV2) | 
					
						
							|  |  |  | 		if recV2.Code != testCase.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Errorf("Test %d: %s: Expected the response status to be `%d`, but instead found `%d`", i+1, instanceType, testCase.expectedRespStatus, recV2.Code) | 
					
						
							| 
									
										
										
										
											2016-07-03 10:05:16 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 	// Test for Anonymous/unsigned http request.
 | 
					
						
							|  |  |  | 	// Bucket policy related functions doesn't support anonymous requests, setting policies shouldn't make a difference.
 | 
					
						
							|  |  |  | 	bucketPolicyStr := fmt.Sprintf(bucketPolicyTemplate, bucketName, bucketName) | 
					
						
							|  |  |  | 	// create unsigned HTTP request for PutBucketPolicyHandler.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 	anonReq, err := newTestRequest(http.MethodPut, getPutPolicyURL("", bucketName), | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 		int64(len(bucketPolicyStr)), bytes.NewReader([]byte(bucketPolicyStr))) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 		t.Fatalf("MinIO %s: Failed to create an anonymous request for bucket \"%s\": <ERROR> %v", | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 			instanceType, bucketName, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 | 
					
						
							|  |  |  | 	// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 | 
					
						
							|  |  |  | 	// unsigned request goes through and its validated again.
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 	ExecObjectLayerAPIAnonTest(t, obj, "PutBucketPolicyHandler", bucketName, "", instanceType, apiRouter, anonReq, getAnonWriteOnlyBucketPolicy(bucketName)) | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	// HTTP request for testing when `objectLayer` is set to `nil`.
 | 
					
						
							|  |  |  | 	// There is no need to use an existing bucket and valid input for creating the request
 | 
					
						
							|  |  |  | 	// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 | 
					
						
							|  |  |  | 	// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 | 
					
						
							|  |  |  | 	nilBucket := "dummy-bucket" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 	nilReq, err := newTestSignedRequestV4(http.MethodPut, getPutPolicyURL("", nilBucket), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 		0, nil, "", "", nil) | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 		t.Errorf("MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`.", instanceType) | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// execute the object layer set to `nil` test.
 | 
					
						
							|  |  |  | 	// `ExecObjectLayerAPINilTest` manages the operation.
 | 
					
						
							|  |  |  | 	ExecObjectLayerAPINilTest(t, nilBucket, "", instanceType, apiRouter, nilReq) | 
					
						
							| 
									
										
										
										
											2016-07-01 14:49:59 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:04:01 +08:00
										 |  |  | // Wrapper for calling Get Bucket Policy HTTP handler tests for both Erasure multiple disks and single node setup.
 | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | func TestGetBucketPolicyHandler(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-06 17:02:42 +08:00
										 |  |  | 	ExecObjectLayerAPITest(t, testGetBucketPolicyHandler, []string{"PutBucketPolicy", "GetBucketPolicy"}) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // testGetBucketPolicyHandler - Test for end point which fetches the access policy json of the given bucket.
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:02:42 +08:00
										 |  |  | func testGetBucketPolicyHandler(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler, | 
					
						
							| 
									
										
										
										
											2017-11-01 02:54:32 +08:00
										 |  |  | 	credentials auth.Credentials, t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	// template for constructing HTTP request body for PUT bucket policy.
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 	bucketPolicyTemplate := `{"Version":"2012-10-17","Statement":[{"Action":["s3:GetBucketLocation","s3:ListBucket"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::%s"]},{"Action":["s3:GetObject"],"Effect":"Allow","Principal":{"AWS":["*"]},"Resource":["arn:aws:s3:::%s/this*"]}]}` | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Writing bucket policy before running test on GetBucketPolicy.
 | 
					
						
							|  |  |  | 	putTestPolicies := []struct { | 
					
						
							|  |  |  | 		bucketName string | 
					
						
							|  |  |  | 		accessKey  string | 
					
						
							|  |  |  | 		secretKey  string | 
					
						
							|  |  |  | 		// expected Response.
 | 
					
						
							|  |  |  | 		expectedRespStatus int | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 		{bucketName, credentials.AccessKey, credentials.SecretKey, http.StatusNoContent}, | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Iterating over the cases and writing the bucket policy.
 | 
					
						
							|  |  |  | 	// its required to write the policies first before running tests on GetBucketPolicy.
 | 
					
						
							|  |  |  | 	for i, testPolicy := range putTestPolicies { | 
					
						
							|  |  |  | 		// obtain the put bucket policy request body.
 | 
					
						
							|  |  |  | 		bucketPolicyStr := fmt.Sprintf(bucketPolicyTemplate, testPolicy.bucketName, testPolicy.bucketName) | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		recV4 := httptest.NewRecorder() | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV4, err := newTestSignedRequestV4(http.MethodPut, getPutPolicyURL("", testPolicy.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			int64(len(bucketPolicyStr)), bytes.NewReader([]byte(bucketPolicyStr)), testPolicy.accessKey, testPolicy.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for PutBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic ofthe handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		apiRouter.ServeHTTP(recV4, reqV4) | 
					
						
							|  |  |  | 		if recV4.Code != testPolicy.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testPolicy.expectedRespStatus, recV4.Code) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							|  |  |  | 		recV2 := httptest.NewRecorder() | 
					
						
							|  |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV2, err := newTestSignedRequestV2(http.MethodPut, getPutPolicyURL("", testPolicy.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			int64(len(bucketPolicyStr)), bytes.NewReader([]byte(bucketPolicyStr)), testPolicy.accessKey, testPolicy.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for PutBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic ofthe handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler.
 | 
					
						
							|  |  |  | 		apiRouter.ServeHTTP(recV2, reqV2) | 
					
						
							|  |  |  | 		if recV2.Code != testPolicy.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testPolicy.expectedRespStatus, recV2.Code) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// test cases with inputs and expected result for GetBucketPolicyHandler.
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		bucketName string | 
					
						
							|  |  |  | 		accessKey  string | 
					
						
							|  |  |  | 		secretKey  string | 
					
						
							|  |  |  | 		// expected output.
 | 
					
						
							|  |  |  | 		expectedBucketPolicy string | 
					
						
							|  |  |  | 		expectedRespStatus   int | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		// Test case - 1.
 | 
					
						
							|  |  |  | 		// Case which valid inputs, expected to return success status of 200OK.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:           bucketName, | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:            credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:            credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedBucketPolicy: bucketPolicyTemplate, | 
					
						
							|  |  |  | 			expectedRespStatus:   http.StatusOK, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 2.
 | 
					
						
							|  |  |  | 		// Case with non-existent bucket name.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:           "non-existent-bucket", | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:            credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:            credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedBucketPolicy: bucketPolicyTemplate, | 
					
						
							| 
									
										
										
										
											2016-11-15 07:45:00 +08:00
										 |  |  | 			expectedRespStatus:   http.StatusNotFound, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 3.
 | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 		// Case with non-existent bucket name.
 | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:           ".invalid-bucket-name", | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:            credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:            credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedBucketPolicy: "", | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 			expectedRespStatus:   http.StatusNotFound, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Iterating over the cases, fetching the policy and validating the response.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		// expected bucket policy json string.
 | 
					
						
							|  |  |  | 		expectedBucketPolicyStr := fmt.Sprintf(testCase.expectedBucketPolicy, testCase.bucketName, testCase.bucketName) | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		recV4 := httptest.NewRecorder() | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV4, err := newTestSignedRequestV4(http.MethodGet, getGetPolicyURL("", testCase.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			0, nil, testCase.accessKey, testCase.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for GetBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler, GetBucketPolicyHandler handles the request.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		apiRouter.ServeHTTP(recV4, reqV4) | 
					
						
							|  |  |  | 		// Assert the response code with the expected status.
 | 
					
						
							|  |  |  | 		if recV4.Code != testCase.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testCase.expectedRespStatus, recV4.Code) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// read the response body.
 | 
					
						
							|  |  |  | 		bucketPolicyReadBuf, err := ioutil.ReadAll(recV4.Body) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: %s: Failed parsing response body: <ERROR> %v", i+1, instanceType, err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if recV4.Code != testCase.expectedRespStatus { | 
					
						
							|  |  |  | 			// Verify whether the bucket policy fetched is same as the one inserted.
 | 
					
						
							| 
									
										
										
										
											2018-07-25 05:17:58 +08:00
										 |  |  | 			var expectedPolicy *policy.Policy | 
					
						
							|  |  |  | 			expectedPolicy, err = policy.ParseConfig(strings.NewReader(expectedBucketPolicyStr), testCase.bucketName) | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("unexpected error. %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-07-25 05:17:58 +08:00
										 |  |  | 			var gotPolicy *policy.Policy | 
					
						
							|  |  |  | 			gotPolicy, err = policy.ParseConfig(bytes.NewReader(bucketPolicyReadBuf), testCase.bucketName) | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("unexpected error. %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if !reflect.DeepEqual(expectedPolicy, gotPolicy) { | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 				t.Errorf("Test %d: %s: Bucket policy differs from expected value.", i+1, instanceType) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							|  |  |  | 		recV2 := httptest.NewRecorder() | 
					
						
							|  |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV2, err := newTestSignedRequestV2(http.MethodGet, getGetPolicyURL("", testCase.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			0, nil, testCase.accessKey, testCase.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for GetBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler, GetBucketPolicyHandler handles the request.
 | 
					
						
							|  |  |  | 		apiRouter.ServeHTTP(recV2, reqV2) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		// Assert the response code with the expected status.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		if recV2.Code != testCase.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testCase.expectedRespStatus, recV2.Code) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		// read the response body.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		bucketPolicyReadBuf, err = ioutil.ReadAll(recV2.Body) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: %s: Failed parsing response body: <ERROR> %v", i+1, instanceType, err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		if recV2.Code == http.StatusOK { | 
					
						
							|  |  |  | 			// Verify whether the bucket policy fetched is same as the one inserted.
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 			expectedPolicy, err := policy.ParseConfig(strings.NewReader(expectedBucketPolicyStr), testCase.bucketName) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("unexpected error. %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			gotPolicy, err := policy.ParseConfig(bytes.NewReader(bucketPolicyReadBuf), testCase.bucketName) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				t.Fatalf("unexpected error. %v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if !reflect.DeepEqual(expectedPolicy, gotPolicy) { | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 				t.Errorf("Test %d: %s: Bucket policy differs from expected value.", i+1, instanceType) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 	// Test for Anonymous/unsigned http request.
 | 
					
						
							|  |  |  | 	// Bucket policy related functions doesn't support anonymous requests, setting policies shouldn't make a difference.
 | 
					
						
							|  |  |  | 	// create unsigned HTTP request for PutBucketPolicyHandler.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 	anonReq, err := newTestRequest(http.MethodGet, getPutPolicyURL("", bucketName), 0, nil) | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 		t.Fatalf("MinIO %s: Failed to create an anonymous request for bucket \"%s\": <ERROR> %v", | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 			instanceType, bucketName, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 | 
					
						
							|  |  |  | 	// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 | 
					
						
							|  |  |  | 	// unsigned request goes through and its validated again.
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 	ExecObjectLayerAPIAnonTest(t, obj, "GetBucketPolicyHandler", bucketName, "", instanceType, apiRouter, anonReq, getAnonReadOnlyBucketPolicy(bucketName)) | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	// HTTP request for testing when `objectLayer` is set to `nil`.
 | 
					
						
							|  |  |  | 	// There is no need to use an existing bucket and valid input for creating the request
 | 
					
						
							|  |  |  | 	// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 | 
					
						
							|  |  |  | 	// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 | 
					
						
							|  |  |  | 	nilBucket := "dummy-bucket" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 	nilReq, err := newTestSignedRequestV4(http.MethodGet, getGetPolicyURL("", nilBucket), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 		0, nil, "", "", nil) | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 		t.Errorf("MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`.", instanceType) | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// execute the object layer set to `nil` test.
 | 
					
						
							|  |  |  | 	// `ExecObjectLayerAPINilTest` manages the operation.
 | 
					
						
							|  |  |  | 	ExecObjectLayerAPINilTest(t, nilBucket, "", instanceType, apiRouter, nilReq) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:04:01 +08:00
										 |  |  | // Wrapper for calling Delete Bucket Policy HTTP handler tests for both Erasure multiple disks and single node setup.
 | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | func TestDeleteBucketPolicyHandler(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2016-10-06 17:02:42 +08:00
										 |  |  | 	ExecObjectLayerAPITest(t, testDeleteBucketPolicyHandler, []string{"PutBucketPolicy", "DeleteBucketPolicy"}) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // testDeleteBucketPolicyHandler - Test for Delete bucket policy end point.
 | 
					
						
							| 
									
										
										
										
											2016-10-06 17:02:42 +08:00
										 |  |  | func testDeleteBucketPolicyHandler(obj ObjectLayer, instanceType, bucketName string, apiRouter http.Handler, | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | 	credentials auth.Credentials, t *testing.T, | 
					
						
							|  |  |  | ) { | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	// template for constructing HTTP request body for PUT bucket policy.
 | 
					
						
							|  |  |  | 	bucketPolicyTemplate := `{ | 
					
						
							|  |  |  |     "Version": "2012-10-17", | 
					
						
							|  |  |  |     "Statement": [ | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Action": [ | 
					
						
							|  |  |  |                 "s3:GetBucketLocation", | 
					
						
							|  |  |  |                 "s3:ListBucket" | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             "Effect": "Allow", | 
					
						
							|  |  |  |             "Principal": { | 
					
						
							|  |  |  |                 "AWS": [ | 
					
						
							|  |  |  |                     "*" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "Resource": [ | 
					
						
							|  |  |  |                 "arn:aws:s3:::%s" | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             "Action": [ | 
					
						
							|  |  |  |                 "s3:GetObject" | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             "Effect": "Allow", | 
					
						
							|  |  |  |             "Principal": { | 
					
						
							|  |  |  |                 "AWS": [ | 
					
						
							|  |  |  |                     "*" | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             "Resource": [ | 
					
						
							|  |  |  |                 "arn:aws:s3:::%s/this*" | 
					
						
							|  |  |  |             ] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     ] | 
					
						
							|  |  |  | }` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Writing bucket policy before running test on DeleteBucketPolicy.
 | 
					
						
							|  |  |  | 	putTestPolicies := []struct { | 
					
						
							|  |  |  | 		bucketName string | 
					
						
							|  |  |  | 		accessKey  string | 
					
						
							|  |  |  | 		secretKey  string | 
					
						
							|  |  |  | 		// expected Response.
 | 
					
						
							|  |  |  | 		expectedRespStatus int | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusNoContent, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Iterating over the cases and writing the bucket policy.
 | 
					
						
							|  |  |  | 	// its required to write the policies first before running tests on GetBucketPolicy.
 | 
					
						
							|  |  |  | 	for i, testPolicy := range putTestPolicies { | 
					
						
							|  |  |  | 		// obtain the put bucket policy request body.
 | 
					
						
							|  |  |  | 		bucketPolicyStr := fmt.Sprintf(bucketPolicyTemplate, testPolicy.bucketName, testPolicy.bucketName) | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		recV4 := httptest.NewRecorder() | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV4, err := newTestSignedRequestV4(http.MethodPut, getPutPolicyURL("", testPolicy.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			int64(len(bucketPolicyStr)), bytes.NewReader([]byte(bucketPolicyStr)), testPolicy.accessKey, testPolicy.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for PutBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		apiRouter.ServeHTTP(recV4, reqV4) | 
					
						
							|  |  |  | 		if recV4.Code != testPolicy.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testPolicy.expectedRespStatus, recV4.Code) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	// testcases with input and expected output for DeleteBucketPolicyHandler.
 | 
					
						
							|  |  |  | 	testCases := []struct { | 
					
						
							|  |  |  | 		bucketName string | 
					
						
							|  |  |  | 		accessKey  string | 
					
						
							|  |  |  | 		secretKey  string | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		// expected response.
 | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		expectedRespStatus int | 
					
						
							|  |  |  | 	}{ | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		// Test case - 1.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         bucketName, | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 			expectedRespStatus: http.StatusNoContent, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 2.
 | 
					
						
							|  |  |  | 		// Case with non-existent-bucket.
 | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         "non-existent-bucket", | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2016-11-15 07:45:00 +08:00
										 |  |  | 			expectedRespStatus: http.StatusNotFound, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 		// Test case - 3.
 | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 		// Case with non-existent-bucket.
 | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			bucketName:         ".invalid-bucket-name", | 
					
						
							| 
									
										
										
										
											2016-12-27 02:21:23 +08:00
										 |  |  | 			accessKey:          credentials.AccessKey, | 
					
						
							|  |  |  | 			secretKey:          credentials.SecretKey, | 
					
						
							| 
									
										
										
										
											2018-04-24 11:27:33 +08:00
										 |  |  | 			expectedRespStatus: http.StatusNotFound, | 
					
						
							| 
									
										
										
										
											2016-10-11 00:29:56 +08:00
										 |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// Iterating over the cases and deleting the bucket policy and then asserting response.
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		recV4 := httptest.NewRecorder() | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		// construct HTTP request for Delete bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV4, err := newTestSignedRequestV4(http.MethodDelete, getDeletePolicyURL("", testCase.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			0, nil, testCase.accessKey, testCase.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for GetBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler, DeleteBucketPolicyHandler  handles the request.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		apiRouter.ServeHTTP(recV4, reqV4) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		// Assert the response code with the expected status.
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		if recV4.Code != testCase.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testCase.expectedRespStatus, recV4.Code) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 	// Iterating over the cases and writing the bucket policy.
 | 
					
						
							|  |  |  | 	// its required to write the policies first before running tests on GetBucketPolicy.
 | 
					
						
							|  |  |  | 	for i, testPolicy := range putTestPolicies { | 
					
						
							|  |  |  | 		// obtain the put bucket policy request body.
 | 
					
						
							|  |  |  | 		bucketPolicyStr := fmt.Sprintf(bucketPolicyTemplate, testPolicy.bucketName, testPolicy.bucketName) | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							|  |  |  | 		recV2 := httptest.NewRecorder() | 
					
						
							|  |  |  | 		// construct HTTP request for PUT bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV2, err := newTestSignedRequestV2(http.MethodPut, getPutPolicyURL("", testPolicy.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			int64(len(bucketPolicyStr)), bytes.NewReader([]byte(bucketPolicyStr)), testPolicy.accessKey, testPolicy.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for PutBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler.
 | 
					
						
							|  |  |  | 		apiRouter.ServeHTTP(recV2, reqV2) | 
					
						
							|  |  |  | 		if recV2.Code != testPolicy.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testPolicy.expectedRespStatus, recV2.Code) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i, testCase := range testCases { | 
					
						
							|  |  |  | 		// initialize HTTP NewRecorder, this records any mutations to response writer inside the handler.
 | 
					
						
							|  |  |  | 		recV2 := httptest.NewRecorder() | 
					
						
							|  |  |  | 		// construct HTTP request for Delete bucket policy endpoint.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 		reqV2, err := newTestSignedRequestV2(http.MethodDelete, getDeletePolicyURL("", testCase.bucketName), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 			0, nil, testCase.accessKey, testCase.secretKey, nil) | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			t.Fatalf("Test %d: Failed to create HTTP request for GetBucketPolicyHandler: <ERROR> %v", i+1, err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		// Since `apiRouter` satisfies `http.Handler` it has a ServeHTTP to execute the logic of the handler.
 | 
					
						
							|  |  |  | 		// Call the ServeHTTP to execute the handler, DeleteBucketPolicyHandler  handles the request.
 | 
					
						
							|  |  |  | 		apiRouter.ServeHTTP(recV2, reqV2) | 
					
						
							|  |  |  | 		// Assert the response code with the expected status.
 | 
					
						
							|  |  |  | 		if recV2.Code != testCase.expectedRespStatus { | 
					
						
							|  |  |  | 			t.Fatalf("Case %d: Expected the response status to be `%d`, but instead found `%d`", i+1, testCase.expectedRespStatus, recV2.Code) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 	// Test for Anonymous/unsigned http request.
 | 
					
						
							|  |  |  | 	// Bucket policy related functions doesn't support anonymous requests, setting policies shouldn't make a difference.
 | 
					
						
							|  |  |  | 	// create unsigned HTTP request for PutBucketPolicyHandler.
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 	anonReq, err := newTestRequest(http.MethodDelete, getPutPolicyURL("", bucketName), 0, nil) | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 		t.Fatalf("MinIO %s: Failed to create an anonymous request for bucket \"%s\": <ERROR> %v", | 
					
						
							| 
									
										
										
										
											2016-10-08 16:04:26 +08:00
										 |  |  | 			instanceType, bucketName, err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// ExecObjectLayerAPIAnonTest - Calls the HTTP API handler using the anonymous request, validates the ErrAccessDeniedResponse,
 | 
					
						
							|  |  |  | 	// sets the bucket policy using the policy statement generated from `getWriteOnlyObjectStatement` so that the
 | 
					
						
							|  |  |  | 	// unsigned request goes through and its validated again.
 | 
					
						
							| 
									
										
										
										
											2018-04-25 06:53:30 +08:00
										 |  |  | 	ExecObjectLayerAPIAnonTest(t, obj, "DeleteBucketPolicyHandler", bucketName, "", instanceType, apiRouter, anonReq, getAnonWriteOnlyBucketPolicy(bucketName)) | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// HTTP request for testing when `objectLayer` is set to `nil`.
 | 
					
						
							|  |  |  | 	// There is no need to use an existing bucket and valid input for creating the request
 | 
					
						
							|  |  |  | 	// since the `objectLayer==nil`  check is performed before any other checks inside the handlers.
 | 
					
						
							|  |  |  | 	// The only aim is to generate an HTTP request in a way that the relevant/registered end point is evoked/called.
 | 
					
						
							|  |  |  | 	nilBucket := "dummy-bucket" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-21 03:52:49 +08:00
										 |  |  | 	nilReq, err := newTestSignedRequestV4(http.MethodDelete, getDeletePolicyURL("", nilBucket), | 
					
						
							| 
									
										
										
										
											2018-09-21 10:22:09 +08:00
										 |  |  | 		0, nil, "", "", nil) | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  | 		t.Errorf("MinIO %s: Failed to create HTTP request for testing the response when object Layer is set to `nil`.", instanceType) | 
					
						
							| 
									
										
										
										
											2016-10-07 04:34:33 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	// execute the object layer set to `nil` test.
 | 
					
						
							|  |  |  | 	// `ExecObjectLayerAPINilTest` manages the operation.
 | 
					
						
							|  |  |  | 	ExecObjectLayerAPINilTest(t, nilBucket, "", instanceType, apiRouter, nilReq) | 
					
						
							| 
									
										
										
										
											2016-07-04 13:35:30 +08:00
										 |  |  | } |