storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/postpolicyform_test.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2016 MinIO, Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package cmd
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/base64"
    22  	"fmt"
    23  	"net/http"
    24  	"strings"
    25  	"testing"
    26  
    27  	minio "github.com/minio/minio-go/v7"
    28  )
    29  
    30  func TestParsePostPolicyForm(t *testing.T) {
    31  	testCases := []struct {
    32  		policy  string
    33  		success bool
    34  	}{
    35  		// missing expiration, will fail.
    36  		{
    37  			policy:  `{"conditions":[["eq","$bucket","asdf"],["eq","$key","hello.txt"]],"conditions":[["eq","$success_action_status","201"],["eq","$Content-Type","plain/text"],["eq","$success_action_status","201"],["eq","$x-amz-algorithm","AWS4-HMAC-SHA256"],["eq","$x-amz-credential","Q3AM3UQ867SPQQA43P2F/20210315/us-east-1/s3/aws4_request"],["eq","$x-amz-date","20210315T091621Z"]]}`,
    38  			success: false,
    39  		},
    40  		// invalid json.
    41  		{
    42  			policy:  `{"conditions":[["eq","$bucket","asdf"],["eq","$key","hello.txt"]],"conditions":[["eq","$success_action_status","201"],["eq","$Content-Type","plain/text"],["eq","$success_action_status","201"],["eq","$x-amz-algorithm","AWS4-HMAC-SHA256"],["eq","$x-amz-credential","Q3AM3UQ867SPQQA43P2F/20210315/us-east-1/s3/aws4_request"],["eq","$x-amz-date","20210315T091621Z"]]`,
    43  			success: false,
    44  		},
    45  		// duplicate 'expiration' reject
    46  		{
    47  			policy: `{"expiration":"2021-03-22T09:16:21.310Z","expiration":"2021-03-22T09:16:21.310Z","conditions":[["eq","$bucket","evil"],["eq","$key","hello.txt"],["eq","$success_action_status","201"],["eq","$Content-Type","plain/text"],["eq","$success_action_status","201"],["eq","$x-amz-algorithm","AWS4-HMAC-SHA256"],["eq","$x-amz-credential","Q3AM3UQ867SPQQA43P2F/20210315/us-east-1/s3/aws4_request"],["eq","$x-amz-date","20210315T091621Z"]]}`,
    48  		},
    49  		// duplicate '$bucket' reject
    50  		{
    51  			policy:  `{"expiration":"2021-03-22T09:16:21.310Z","conditions":[["eq","$bucket","good"],["eq","$key","hello.txt"]],"conditions":[["eq","$bucket","evil"],["eq","$key","hello.txt"],["eq","$success_action_status","201"],["eq","$Content-Type","plain/text"],["eq","$success_action_status","201"],["eq","$x-amz-algorithm","AWS4-HMAC-SHA256"],["eq","$x-amz-credential","Q3AM3UQ867SPQQA43P2F/20210315/us-east-1/s3/aws4_request"],["eq","$x-amz-date","20210315T091621Z"]]}`,
    52  			success: false,
    53  		},
    54  		// duplicate conditions, reject
    55  		{
    56  			policy:  `{"expiration":"2021-03-22T09:16:21.310Z","conditions":[["eq","$bucket","asdf"],["eq","$key","hello.txt"]],"conditions":[["eq","$success_action_status","201"],["eq","$Content-Type","plain/text"],["eq","$success_action_status","201"],["eq","$x-amz-algorithm","AWS4-HMAC-SHA256"],["eq","$x-amz-credential","Q3AM3UQ867SPQQA43P2F/20210315/us-east-1/s3/aws4_request"],["eq","$x-amz-date","20210315T091621Z"]]}`,
    57  			success: false,
    58  		},
    59  		// no duplicates, shall be parsed properly.
    60  		{
    61  			policy:  `{"expiration":"2021-03-27T20:35:28.458Z","conditions":[["eq","$bucket","testbucket"],["eq","$key","wtf.txt"],["eq","$x-amz-date","20210320T203528Z"],["eq","$x-amz-algorithm","AWS4-HMAC-SHA256"],["eq","$x-amz-credential","Q3AM3UQ867SPQQA43P2F/20210320/us-east-1/s3/aws4_request"]]}`,
    62  			success: true,
    63  		},
    64  	}
    65  
    66  	for _, testCase := range testCases {
    67  		testCase := testCase
    68  		t.Run("", func(t *testing.T) {
    69  			_, err := parsePostPolicyForm(strings.NewReader(testCase.policy))
    70  			if testCase.success && err != nil {
    71  				t.Errorf("Expected success but failed with %s", err)
    72  			}
    73  			if !testCase.success && err == nil {
    74  				t.Errorf("Expected failed but succeeded")
    75  			}
    76  		})
    77  	}
    78  }
    79  
    80  // Test Post Policy parsing and checking conditions
    81  func TestPostPolicyForm(t *testing.T) {
    82  	pp := minio.NewPostPolicy()
    83  	pp.SetBucket("testbucket")
    84  	pp.SetContentType("image/jpeg")
    85  	pp.SetUserMetadata("uuid", "14365123651274")
    86  	pp.SetKeyStartsWith("user/user1/filename")
    87  	pp.SetContentLengthRange(1048579, 10485760)
    88  	pp.SetSuccessStatusAction("201")
    89  
    90  	type testCase struct {
    91  		Bucket              string
    92  		Key                 string
    93  		XAmzDate            string
    94  		XAmzAlgorithm       string
    95  		XAmzCredential      string
    96  		XAmzMetaUUID        string
    97  		ContentType         string
    98  		SuccessActionStatus string
    99  		Policy              string
   100  		Expired             bool
   101  		expectedErr         error
   102  	}
   103  
   104  	testCases := []testCase{
   105  		// Everything is fine with this test
   106  		{Bucket: "testbucket", Key: "user/user1/filename/${filename}/myfile.txt", XAmzMetaUUID: "14365123651274", SuccessActionStatus: "201", XAmzCredential: "KVGKMDUQ23TCZXTLTHLP/20160727/us-east-1/s3/aws4_request", XAmzDate: "20160727T000000Z", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", expectedErr: nil},
   107  		// Expired policy document
   108  		{Bucket: "testbucket", Key: "user/user1/filename/${filename}/myfile.txt", XAmzMetaUUID: "14365123651274", SuccessActionStatus: "201", XAmzCredential: "KVGKMDUQ23TCZXTLTHLP/20160727/us-east-1/s3/aws4_request", XAmzDate: "20160727T000000Z", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", Expired: true, expectedErr: fmt.Errorf("Invalid according to Policy: Policy expired")},
   109  		// Different AMZ date
   110  		{Bucket: "testbucket", Key: "user/user1/filename/${filename}/myfile.txt", XAmzMetaUUID: "14365123651274", XAmzDate: "2017T000000Z", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", expectedErr: fmt.Errorf("Invalid according to Policy: Policy Condition failed")},
   111  		// Key which doesn't start with user/user1/filename
   112  		{Bucket: "testbucket", Key: "myfile.txt", XAmzDate: "20160727T000000Z", XAmzMetaUUID: "14365123651274", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", expectedErr: fmt.Errorf("Invalid according to Policy: Policy Condition failed")},
   113  		// Incorrect bucket name.
   114  		{Bucket: "incorrect", Key: "user/user1/filename/myfile.txt", XAmzMetaUUID: "14365123651274", XAmzDate: "20160727T000000Z", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", expectedErr: fmt.Errorf("Invalid according to Policy: Policy Condition failed")},
   115  		// Incorrect key name
   116  		{Bucket: "testbucket", Key: "incorrect", XAmzDate: "20160727T000000Z", XAmzMetaUUID: "14365123651274", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", expectedErr: fmt.Errorf("Invalid according to Policy: Policy Condition failed")},
   117  		// Incorrect date
   118  		{Bucket: "testbucket", Key: "user/user1/filename/${filename}/myfile.txt", XAmzMetaUUID: "14365123651274", XAmzDate: "incorrect", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", expectedErr: fmt.Errorf("Invalid according to Policy: Policy Condition failed")},
   119  		// Incorrect ContentType
   120  		{Bucket: "testbucket", Key: "user/user1/filename/${filename}/myfile.txt", XAmzMetaUUID: "14365123651274", XAmzDate: "20160727T000000Z", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "incorrect", expectedErr: fmt.Errorf("Invalid according to Policy: Policy Condition failed")},
   121  		// Incorrect Metadata
   122  		{Bucket: "testbucket", Key: "user/user1/filename/${filename}/myfile.txt", XAmzMetaUUID: "151274", SuccessActionStatus: "201", XAmzCredential: "KVGKMDUQ23TCZXTLTHLP/20160727/us-east-1/s3/aws4_request", XAmzDate: "20160727T000000Z", XAmzAlgorithm: "AWS4-HMAC-SHA256", ContentType: "image/jpeg", expectedErr: fmt.Errorf("Invalid according to Policy: Policy Condition failed: [eq, $x-amz-meta-uuid, 14365123651274]")},
   123  	}
   124  	// Validate all the test cases.
   125  	for i, tt := range testCases {
   126  		formValues := make(http.Header)
   127  		formValues.Set("Bucket", tt.Bucket)
   128  		formValues.Set("Key", tt.Key)
   129  		formValues.Set("Content-Type", tt.ContentType)
   130  		formValues.Set("X-Amz-Date", tt.XAmzDate)
   131  		formValues.Set("X-Amz-Meta-Uuid", tt.XAmzMetaUUID)
   132  		formValues.Set("X-Amz-Algorithm", tt.XAmzAlgorithm)
   133  		formValues.Set("X-Amz-Credential", tt.XAmzCredential)
   134  		if tt.Expired {
   135  			// Expired already.
   136  			pp.SetExpires(UTCNow().AddDate(0, 0, -10))
   137  		} else {
   138  			// Expires in 10 days.
   139  			pp.SetExpires(UTCNow().AddDate(0, 0, 10))
   140  		}
   141  
   142  		formValues.Set("Policy", base64.StdEncoding.EncodeToString([]byte(pp.String())))
   143  		formValues.Set("Success_action_status", tt.SuccessActionStatus)
   144  		policyBytes, err := base64.StdEncoding.DecodeString(base64.StdEncoding.EncodeToString([]byte(pp.String())))
   145  		if err != nil {
   146  			t.Fatal(err)
   147  		}
   148  
   149  		postPolicyForm, err := parsePostPolicyForm(bytes.NewReader(policyBytes))
   150  		if err != nil {
   151  			t.Fatal(err)
   152  		}
   153  
   154  		err = checkPostPolicy(formValues, postPolicyForm)
   155  		if err != nil && tt.expectedErr != nil && err.Error() != tt.expectedErr.Error() {
   156  			t.Fatalf("Test %d:, Expected %s, got %s", i+1, tt.expectedErr.Error(), err.Error())
   157  		}
   158  	}
   159  }