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