storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/iam/policy/resourceset_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 iampolicy
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"reflect"
    23  	"testing"
    24  )
    25  
    26  func TestResourceSetBucketResourceExists(t *testing.T) {
    27  	testCases := []struct {
    28  		resourceSet    ResourceSet
    29  		expectedResult bool
    30  	}{
    31  		{NewResourceSet(NewResource("*", "")), true},
    32  		{NewResourceSet(NewResource("mybucket", "")), true},
    33  		{NewResourceSet(NewResource("mybucket*", "")), true},
    34  		{NewResourceSet(NewResource("mybucket?0", "")), true},
    35  		{NewResourceSet(NewResource("mybucket", "/2010/photos/*"), NewResource("mybucket", "")), true},
    36  		{NewResourceSet(NewResource("", "*")), false},
    37  		{NewResourceSet(NewResource("*", "*")), false},
    38  		{NewResourceSet(NewResource("mybucket", "*")), false},
    39  		{NewResourceSet(NewResource("mybucket*", "/myobject")), false},
    40  		{NewResourceSet(NewResource("mybucket?0", "/2010/photos/*")), false},
    41  	}
    42  
    43  	for i, testCase := range testCases {
    44  		result := testCase.resourceSet.bucketResourceExists()
    45  
    46  		if result != testCase.expectedResult {
    47  			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result)
    48  		}
    49  	}
    50  }
    51  
    52  func TestResourceSetObjectResourceExists(t *testing.T) {
    53  	testCases := []struct {
    54  		resourceSet    ResourceSet
    55  		expectedResult bool
    56  	}{
    57  		{NewResourceSet(NewResource("*", "")), true},
    58  		{NewResourceSet(NewResource("mybucket*", "")), true},
    59  		{NewResourceSet(NewResource("", "*")), true},
    60  		{NewResourceSet(NewResource("*", "*")), true},
    61  		{NewResourceSet(NewResource("mybucket", "*")), true},
    62  		{NewResourceSet(NewResource("mybucket*", "/myobject")), true},
    63  		{NewResourceSet(NewResource("mybucket?0", "/2010/photos/*")), true},
    64  		{NewResourceSet(NewResource("mybucket", ""), NewResource("mybucket", "/2910/photos/*")), true},
    65  		{NewResourceSet(NewResource("mybucket", "")), false},
    66  		{NewResourceSet(NewResource("mybucket?0", "")), false},
    67  	}
    68  
    69  	for i, testCase := range testCases {
    70  		result := testCase.resourceSet.objectResourceExists()
    71  
    72  		if result != testCase.expectedResult {
    73  			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result)
    74  		}
    75  	}
    76  }
    77  
    78  func TestResourceSetAdd(t *testing.T) {
    79  	testCases := []struct {
    80  		resourceSet    ResourceSet
    81  		resource       Resource
    82  		expectedResult ResourceSet
    83  	}{
    84  		{NewResourceSet(), NewResource("mybucket", "/myobject*"),
    85  			NewResourceSet(NewResource("mybucket", "/myobject*"))},
    86  		{NewResourceSet(NewResource("mybucket", "/myobject*")),
    87  			NewResource("mybucket", "/yourobject*"),
    88  			NewResourceSet(NewResource("mybucket", "/myobject*"),
    89  				NewResource("mybucket", "/yourobject*"))},
    90  		{NewResourceSet(NewResource("mybucket", "/myobject*")),
    91  			NewResource("mybucket", "/myobject*"),
    92  			NewResourceSet(NewResource("mybucket", "/myobject*"))},
    93  	}
    94  
    95  	for i, testCase := range testCases {
    96  		testCase.resourceSet.Add(testCase.resource)
    97  
    98  		if !reflect.DeepEqual(testCase.resourceSet, testCase.expectedResult) {
    99  			t.Fatalf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, testCase.resourceSet)
   100  		}
   101  	}
   102  }
   103  
   104  func TestResourceSetIntersection(t *testing.T) {
   105  	testCases := []struct {
   106  		set            ResourceSet
   107  		setToIntersect ResourceSet
   108  		expectedResult ResourceSet
   109  	}{
   110  		{NewResourceSet(), NewResourceSet(NewResource("mybucket", "/myobject*")), NewResourceSet()},
   111  		{NewResourceSet(NewResource("mybucket", "/myobject*")), NewResourceSet(), NewResourceSet()},
   112  		{NewResourceSet(NewResource("mybucket", "/myobject*")),
   113  			NewResourceSet(NewResource("mybucket", "/myobject*"), NewResource("mybucket", "/yourobject*")),
   114  			NewResourceSet(NewResource("mybucket", "/myobject*"))},
   115  	}
   116  
   117  	for i, testCase := range testCases {
   118  		result := testCase.set.Intersection(testCase.setToIntersect)
   119  
   120  		if !reflect.DeepEqual(result, testCase.expectedResult) {
   121  			t.Fatalf("case %v: expected: %v, got: %v\n", i+1, testCase.expectedResult, testCase.set)
   122  		}
   123  	}
   124  }
   125  
   126  func TestResourceSetMarshalJSON(t *testing.T) {
   127  	testCases := []struct {
   128  		resoruceSet    ResourceSet
   129  		expectedResult []byte
   130  		expectErr      bool
   131  	}{
   132  		{NewResourceSet(NewResource("mybucket", "/myobject*")),
   133  			[]byte(`["arn:aws:s3:::mybucket/myobject*"]`), false},
   134  		{NewResourceSet(NewResource("mybucket", "/photos/myobject*")),
   135  			[]byte(`["arn:aws:s3:::mybucket/photos/myobject*"]`), false},
   136  		{NewResourceSet(), nil, true},
   137  	}
   138  
   139  	for i, testCase := range testCases {
   140  		result, err := json.Marshal(testCase.resoruceSet)
   141  		expectErr := (err != nil)
   142  
   143  		if expectErr != testCase.expectErr {
   144  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   145  		}
   146  
   147  		if !testCase.expectErr {
   148  			if !reflect.DeepEqual(result, testCase.expectedResult) {
   149  				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, string(testCase.expectedResult), string(result))
   150  			}
   151  		}
   152  	}
   153  }
   154  
   155  func TestResourceSetMatch(t *testing.T) {
   156  	testCases := []struct {
   157  		resourceSet    ResourceSet
   158  		resource       string
   159  		expectedResult bool
   160  	}{
   161  		{NewResourceSet(NewResource("*", "")), "mybucket", true},
   162  		{NewResourceSet(NewResource("*", "")), "mybucket/myobject", true},
   163  		{NewResourceSet(NewResource("mybucket*", "")), "mybucket", true},
   164  		{NewResourceSet(NewResource("mybucket*", "")), "mybucket/myobject", true},
   165  		{NewResourceSet(NewResource("", "*")), "/myobject", true},
   166  		{NewResourceSet(NewResource("*", "*")), "mybucket/myobject", true},
   167  		{NewResourceSet(NewResource("mybucket", "*")), "mybucket/myobject", true},
   168  		{NewResourceSet(NewResource("mybucket*", "/myobject")), "mybucket/myobject", true},
   169  		{NewResourceSet(NewResource("mybucket*", "/myobject")), "mybucket100/myobject", true},
   170  		{NewResourceSet(NewResource("mybucket?0", "/2010/photos/*")), "mybucket20/2010/photos/1.jpg", true},
   171  		{NewResourceSet(NewResource("mybucket", "")), "mybucket", true},
   172  		{NewResourceSet(NewResource("mybucket?0", "")), "mybucket30", true},
   173  		{NewResourceSet(NewResource("mybucket?0", "/2010/photos/*"),
   174  			NewResource("mybucket", "/2010/photos/*")), "mybucket/2010/photos/1.jpg", true},
   175  		{NewResourceSet(NewResource("", "*")), "mybucket/myobject", false},
   176  		{NewResourceSet(NewResource("*", "*")), "mybucket", false},
   177  		{NewResourceSet(NewResource("mybucket", "*")), "mybucket10/myobject", false},
   178  		{NewResourceSet(NewResource("mybucket", "")), "mybucket/myobject", false},
   179  		{NewResourceSet(), "mybucket/myobject", false},
   180  	}
   181  
   182  	for i, testCase := range testCases {
   183  		testCase := testCase
   184  		t.Run(fmt.Sprintf("Test%d", i+1), func(t *testing.T) {
   185  			result := testCase.resourceSet.Match(testCase.resource, nil)
   186  			if result != testCase.expectedResult {
   187  				t.Errorf("case %v: expected: %v, got: %v", i+1, testCase.expectedResult, result)
   188  			}
   189  		})
   190  	}
   191  }
   192  
   193  func TestResourceSetUnmarshalJSON(t *testing.T) {
   194  	testCases := []struct {
   195  		data           []byte
   196  		expectedResult ResourceSet
   197  		expectErr      bool
   198  	}{
   199  		{[]byte(`"arn:aws:s3:::mybucket/myobject*"`),
   200  			NewResourceSet(NewResource("mybucket", "/myobject*")), false},
   201  		{[]byte(`"arn:aws:s3:::mybucket/photos/myobject*"`),
   202  			NewResourceSet(NewResource("mybucket", "/photos/myobject*")), false},
   203  		{[]byte(`"arn:aws:s3:::mybucket"`), NewResourceSet(NewResource("mybucket", "")), false},
   204  		{[]byte(`"mybucket/myobject*"`), nil, true},
   205  	}
   206  
   207  	for i, testCase := range testCases {
   208  		var result ResourceSet
   209  		err := json.Unmarshal(testCase.data, &result)
   210  		expectErr := (err != nil)
   211  
   212  		if expectErr != testCase.expectErr {
   213  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   214  		}
   215  
   216  		if !testCase.expectErr {
   217  			if !reflect.DeepEqual(result, testCase.expectedResult) {
   218  				t.Fatalf("case %v: result: expected: %v, got: %v", i+1, testCase.expectedResult, result)
   219  			}
   220  		}
   221  	}
   222  }
   223  
   224  func TestResourceSetValidate(t *testing.T) {
   225  	testCases := []struct {
   226  		resourceSet ResourceSet
   227  		expectErr   bool
   228  	}{
   229  		{NewResourceSet(NewResource("mybucket", "/myobject*")), false},
   230  		{NewResourceSet(NewResource("", "/myobject*")), false},
   231  		{NewResourceSet(NewResource("", "")), true},
   232  	}
   233  
   234  	for i, testCase := range testCases {
   235  		err := testCase.resourceSet.Validate()
   236  		expectErr := (err != nil)
   237  
   238  		if expectErr != testCase.expectErr {
   239  			t.Fatalf("case %v: error: expected: %v, got: %v", i+1, testCase.expectErr, expectErr)
   240  		}
   241  	}
   242  }