github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/postpolicyform_test.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package cmd 19 20 import ( 21 "bytes" 22 "encoding/base64" 23 "fmt" 24 "net/http" 25 "strings" 26 "testing" 27 28 minio "github.com/minio/minio-go/v7" 29 ) 30 31 func TestParsePostPolicyForm(t *testing.T) { 32 testCases := []struct { 33 policy string 34 success bool 35 }{ 36 // missing expiration, will fail. 37 { 38 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"]]}`, 39 success: false, 40 }, 41 // invalid json. 42 { 43 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"]]`, 44 success: false, 45 }, 46 // duplicate 'expiration' reject 47 { 48 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"]]}`, 49 }, 50 // duplicate '$bucket' reject 51 { 52 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"]]}`, 53 success: false, 54 }, 55 // duplicate conditions, reject 56 { 57 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"]]}`, 58 success: false, 59 }, 60 // no duplicates, shall be parsed properly. 61 { 62 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"]]}`, 63 success: true, 64 }, 65 } 66 67 for _, testCase := range testCases { 68 testCase := testCase 69 t.Run("", func(t *testing.T) { 70 _, err := parsePostPolicyForm(strings.NewReader(testCase.policy)) 71 if testCase.success && err != nil { 72 t.Errorf("Expected success but failed with %s", err) 73 } 74 if !testCase.success && err == nil { 75 t.Errorf("Expected failed but succeeded") 76 } 77 }) 78 } 79 } 80 81 // Test Post Policy parsing and checking conditions 82 func TestPostPolicyForm(t *testing.T) { 83 pp := minio.NewPostPolicy() 84 pp.SetBucket("testbucket") 85 pp.SetContentType("image/jpeg") 86 pp.SetUserMetadata("uuid", "14365123651274") 87 pp.SetKeyStartsWith("user/user1/filename") 88 pp.SetContentLengthRange(1048579, 10485760) 89 pp.SetSuccessStatusAction("201") 90 91 type testCase struct { 92 Bucket string 93 Key string 94 XAmzDate string 95 XAmzAlgorithm string 96 XAmzCredential string 97 XAmzMetaUUID string 98 ContentType string 99 SuccessActionStatus string 100 Policy string 101 Expired bool 102 expectedErr error 103 } 104 105 testCases := []testCase{ 106 // Everything is fine with this test 107 {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}, 108 // Expired policy document 109 {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")}, 110 // Different AMZ date 111 {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")}, 112 // Key which doesn't start with user/user1/filename 113 {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")}, 114 // Incorrect bucket name. 115 {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")}, 116 // Incorrect key name 117 {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")}, 118 // Incorrect date 119 {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")}, 120 // Incorrect ContentType 121 {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")}, 122 // Incorrect Metadata 123 {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]")}, 124 } 125 // Validate all the test cases. 126 for i, tt := range testCases { 127 formValues := make(http.Header) 128 formValues.Set("Bucket", tt.Bucket) 129 formValues.Set("Key", tt.Key) 130 formValues.Set("Content-Type", tt.ContentType) 131 formValues.Set("X-Amz-Date", tt.XAmzDate) 132 formValues.Set("X-Amz-Meta-Uuid", tt.XAmzMetaUUID) 133 formValues.Set("X-Amz-Algorithm", tt.XAmzAlgorithm) 134 formValues.Set("X-Amz-Credential", tt.XAmzCredential) 135 if tt.Expired { 136 // Expired already. 137 pp.SetExpires(UTCNow().AddDate(0, 0, -10)) 138 } else { 139 // Expires in 10 days. 140 pp.SetExpires(UTCNow().AddDate(0, 0, 10)) 141 } 142 143 formValues.Set("Policy", base64.StdEncoding.EncodeToString([]byte(pp.String()))) 144 formValues.Set("Success_action_status", tt.SuccessActionStatus) 145 policyBytes, err := base64.StdEncoding.DecodeString(base64.StdEncoding.EncodeToString([]byte(pp.String()))) 146 if err != nil { 147 t.Fatal(err) 148 } 149 150 postPolicyForm, err := parsePostPolicyForm(bytes.NewReader(policyBytes)) 151 if err != nil { 152 t.Fatal(err) 153 } 154 155 err = checkPostPolicy(formValues, postPolicyForm) 156 if err != nil && tt.expectedErr != nil && err.Error() != tt.expectedErr.Error() { 157 t.Fatalf("Test %d:, Expected %s, got %s", i+1, tt.expectedErr.Error(), err.Error()) 158 } 159 } 160 }