storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/policy_test.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2018 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 "reflect" 21 "testing" 22 23 miniogopolicy "github.com/minio/minio-go/v7/pkg/policy" 24 "github.com/minio/minio-go/v7/pkg/set" 25 26 "storj.io/minio/pkg/bucket/policy" 27 "storj.io/minio/pkg/bucket/policy/condition" 28 ) 29 30 func TestPolicySysIsAllowed(t *testing.T) { 31 p := &policy.Policy{ 32 Version: policy.DefaultVersion, 33 Statements: []policy.Statement{ 34 policy.NewStatement( 35 policy.Allow, 36 policy.NewPrincipal("*"), 37 policy.NewActionSet(policy.GetBucketLocationAction), 38 policy.NewResourceSet(policy.NewResource("mybucket", "")), 39 condition.NewFunctions(), 40 ), 41 policy.NewStatement( 42 policy.Allow, 43 policy.NewPrincipal("*"), 44 policy.NewActionSet(policy.PutObjectAction), 45 policy.NewResourceSet(policy.NewResource("mybucket", "/myobject*")), 46 condition.NewFunctions(), 47 ), 48 }, 49 } 50 51 anonGetBucketLocationArgs := policy.Args{ 52 AccountName: "Q3AM3UQ867SPQQA43P2F", 53 Action: policy.GetBucketLocationAction, 54 BucketName: "mybucket", 55 ConditionValues: map[string][]string{}, 56 } 57 58 anonPutObjectActionArgs := policy.Args{ 59 AccountName: "Q3AM3UQ867SPQQA43P2F", 60 Action: policy.PutObjectAction, 61 BucketName: "mybucket", 62 ConditionValues: map[string][]string{ 63 "x-amz-copy-source": {"mybucket/myobject"}, 64 "SourceIp": {"192.168.1.10"}, 65 }, 66 ObjectName: "myobject", 67 } 68 69 anonGetObjectActionArgs := policy.Args{ 70 AccountName: "Q3AM3UQ867SPQQA43P2F", 71 Action: policy.GetObjectAction, 72 BucketName: "mybucket", 73 ConditionValues: map[string][]string{}, 74 ObjectName: "myobject", 75 } 76 77 getBucketLocationArgs := policy.Args{ 78 AccountName: "Q3AM3UQ867SPQQA43P2F", 79 Action: policy.GetBucketLocationAction, 80 BucketName: "mybucket", 81 ConditionValues: map[string][]string{}, 82 IsOwner: true, 83 } 84 85 putObjectActionArgs := policy.Args{ 86 AccountName: "Q3AM3UQ867SPQQA43P2F", 87 Action: policy.PutObjectAction, 88 BucketName: "mybucket", 89 ConditionValues: map[string][]string{ 90 "x-amz-copy-source": {"mybucket/myobject"}, 91 "SourceIp": {"192.168.1.10"}, 92 }, 93 IsOwner: true, 94 ObjectName: "myobject", 95 } 96 97 getObjectActionArgs := policy.Args{ 98 AccountName: "Q3AM3UQ867SPQQA43P2F", 99 Action: policy.GetObjectAction, 100 BucketName: "mybucket", 101 ConditionValues: map[string][]string{}, 102 IsOwner: true, 103 ObjectName: "myobject", 104 } 105 106 yourbucketAnonGetObjectActionArgs := policy.Args{ 107 AccountName: "Q3AM3UQ867SPQQA43P2F", 108 Action: policy.GetObjectAction, 109 BucketName: "yourbucket", 110 ConditionValues: map[string][]string{}, 111 ObjectName: "yourobject", 112 } 113 114 yourbucketGetObjectActionArgs := policy.Args{ 115 AccountName: "Q3AM3UQ867SPQQA43P2F", 116 Action: policy.GetObjectAction, 117 BucketName: "yourbucket", 118 ConditionValues: map[string][]string{}, 119 IsOwner: true, 120 ObjectName: "yourobject", 121 } 122 123 testCases := []struct { 124 args policy.Args 125 expectedResult bool 126 }{ 127 {anonGetBucketLocationArgs, true}, 128 {anonPutObjectActionArgs, true}, 129 {anonGetObjectActionArgs, false}, 130 {getBucketLocationArgs, true}, 131 {putObjectActionArgs, true}, 132 {getObjectActionArgs, true}, 133 {yourbucketAnonGetObjectActionArgs, false}, 134 {yourbucketGetObjectActionArgs, true}, 135 } 136 137 for i, testCase := range testCases { 138 result := p.IsAllowed(testCase.args) 139 140 if result != testCase.expectedResult { 141 t.Fatalf("case %v: expected: %v, got: %v\n", i+1, testCase.expectedResult, result) 142 } 143 } 144 } 145 146 func getReadOnlyStatement(bucketName, prefix string) []miniogopolicy.Statement { 147 return []miniogopolicy.Statement{ 148 { 149 Effect: string(policy.Allow), 150 Principal: miniogopolicy.User{AWS: set.CreateStringSet("*")}, 151 Resources: set.CreateStringSet(policy.NewResource(bucketName, "").String()), 152 Actions: set.CreateStringSet("s3:GetBucketLocation", "s3:ListBucket"), 153 }, 154 { 155 Effect: string(policy.Allow), 156 Principal: miniogopolicy.User{AWS: set.CreateStringSet("*")}, 157 Resources: set.CreateStringSet(policy.NewResource(bucketName, prefix).String()), 158 Actions: set.CreateStringSet("s3:GetObject"), 159 }, 160 } 161 } 162 163 func TestPolicyToBucketAccessPolicy(t *testing.T) { 164 case1Policy := &policy.Policy{ 165 Version: policy.DefaultVersion, 166 Statements: []policy.Statement{ 167 policy.NewStatement( 168 policy.Allow, 169 policy.NewPrincipal("*"), 170 policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction), 171 policy.NewResourceSet(policy.NewResource("mybucket", "")), 172 condition.NewFunctions(), 173 ), 174 policy.NewStatement( 175 policy.Allow, 176 policy.NewPrincipal("*"), 177 policy.NewActionSet(policy.GetObjectAction), 178 policy.NewResourceSet(policy.NewResource("mybucket", "/myobject*")), 179 condition.NewFunctions(), 180 ), 181 }, 182 } 183 184 case1Result := &miniogopolicy.BucketAccessPolicy{ 185 Version: policy.DefaultVersion, 186 Statements: getReadOnlyStatement("mybucket", "/myobject*"), 187 } 188 189 case2Policy := &policy.Policy{ 190 Version: policy.DefaultVersion, 191 Statements: []policy.Statement{}, 192 } 193 194 case2Result := &miniogopolicy.BucketAccessPolicy{ 195 Version: policy.DefaultVersion, 196 Statements: []miniogopolicy.Statement{}, 197 } 198 199 case3Policy := &policy.Policy{ 200 Version: "12-10-2012", 201 Statements: []policy.Statement{ 202 policy.NewStatement( 203 policy.Allow, 204 policy.NewPrincipal("*"), 205 policy.NewActionSet(policy.PutObjectAction), 206 policy.NewResourceSet(policy.NewResource("mybucket", "/myobject*")), 207 condition.NewFunctions(), 208 ), 209 }, 210 } 211 212 testCases := []struct { 213 bucketPolicy *policy.Policy 214 expectedResult *miniogopolicy.BucketAccessPolicy 215 expectErr bool 216 }{ 217 {case1Policy, case1Result, false}, 218 {case2Policy, case2Result, false}, 219 {case3Policy, nil, true}, 220 } 221 222 for i, testCase := range testCases { 223 result, err := PolicyToBucketAccessPolicy(testCase.bucketPolicy) 224 expectErr := (err != nil) 225 226 if expectErr != testCase.expectErr { 227 t.Fatalf("case %v: error: expected: %v, got: %v\n", i+1, testCase.expectErr, expectErr) 228 } 229 230 if !testCase.expectErr { 231 if !reflect.DeepEqual(result, testCase.expectedResult) { 232 t.Fatalf("case %v: result: expected: %+v, got: %+v\n", i+1, testCase.expectedResult, result) 233 } 234 } 235 } 236 } 237 238 func TestBucketAccessPolicyToPolicy(t *testing.T) { 239 case1PolicyInfo := &miniogopolicy.BucketAccessPolicy{ 240 Version: policy.DefaultVersion, 241 Statements: getReadOnlyStatement("mybucket", "/myobject*"), 242 } 243 244 case1Result := &policy.Policy{ 245 Version: policy.DefaultVersion, 246 Statements: []policy.Statement{ 247 policy.NewStatement( 248 policy.Allow, 249 policy.NewPrincipal("*"), 250 policy.NewActionSet(policy.GetBucketLocationAction, policy.ListBucketAction), 251 policy.NewResourceSet(policy.NewResource("mybucket", "")), 252 condition.NewFunctions(), 253 ), 254 policy.NewStatement( 255 policy.Allow, 256 policy.NewPrincipal("*"), 257 policy.NewActionSet(policy.GetObjectAction), 258 policy.NewResourceSet(policy.NewResource("mybucket", "/myobject*")), 259 condition.NewFunctions(), 260 ), 261 }, 262 } 263 264 case2PolicyInfo := &miniogopolicy.BucketAccessPolicy{ 265 Version: policy.DefaultVersion, 266 Statements: []miniogopolicy.Statement{}, 267 } 268 269 case2Result := &policy.Policy{ 270 Version: policy.DefaultVersion, 271 Statements: []policy.Statement{}, 272 } 273 274 case3PolicyInfo := &miniogopolicy.BucketAccessPolicy{ 275 Version: "12-10-2012", 276 Statements: getReadOnlyStatement("mybucket", "/myobject*"), 277 } 278 279 testCases := []struct { 280 policyInfo *miniogopolicy.BucketAccessPolicy 281 expectedResult *policy.Policy 282 expectErr bool 283 }{ 284 {case1PolicyInfo, case1Result, false}, 285 {case2PolicyInfo, case2Result, false}, 286 {case3PolicyInfo, nil, true}, 287 } 288 289 for i, testCase := range testCases { 290 result, err := BucketAccessPolicyToPolicy(testCase.policyInfo) 291 expectErr := (err != nil) 292 293 if expectErr != testCase.expectErr { 294 t.Fatalf("case %v: error: expected: %v, got: %v\n", i+1, testCase.expectErr, expectErr) 295 } 296 297 if !testCase.expectErr { 298 if !reflect.DeepEqual(result, testCase.expectedResult) { 299 t.Fatalf("case %v: result: expected: %+v, got: %+v\n", i+1, testCase.expectedResult, result) 300 } 301 } 302 } 303 }