storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/iam/policy/resourceset.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 "sort" 23 24 "github.com/minio/minio-go/v7/pkg/set" 25 ) 26 27 // ResourceSet - set of resources in policy statement. 28 type ResourceSet map[Resource]struct{} 29 30 // bucketResourceExists - checks if at least one bucket resource exists in the set. 31 func (resourceSet ResourceSet) bucketResourceExists() bool { 32 for resource := range resourceSet { 33 if resource.isBucketPattern() { 34 return true 35 } 36 } 37 38 return false 39 } 40 41 // objectResourceExists - checks if at least one object resource exists in the set. 42 func (resourceSet ResourceSet) objectResourceExists() bool { 43 for resource := range resourceSet { 44 if resource.isObjectPattern() { 45 return true 46 } 47 } 48 49 return false 50 } 51 52 // Add - adds resource to resource set. 53 func (resourceSet ResourceSet) Add(resource Resource) { 54 resourceSet[resource] = struct{}{} 55 } 56 57 // Equals - checks whether given resource set is equal to current resource set or not. 58 func (resourceSet ResourceSet) Equals(sresourceSet ResourceSet) bool { 59 // If length of set is not equal to length of given set, the 60 // set is not equal to given set. 61 if len(resourceSet) != len(sresourceSet) { 62 return false 63 } 64 65 // As both sets are equal in length, check each elements are equal. 66 for k := range resourceSet { 67 if _, ok := sresourceSet[k]; !ok { 68 return false 69 } 70 } 71 72 return true 73 } 74 75 // Intersection - returns resources available in both ResourceSet. 76 func (resourceSet ResourceSet) Intersection(sset ResourceSet) ResourceSet { 77 nset := NewResourceSet() 78 for k := range resourceSet { 79 if _, ok := sset[k]; ok { 80 nset.Add(k) 81 } 82 } 83 84 return nset 85 } 86 87 // MarshalJSON - encodes ResourceSet to JSON data. 88 func (resourceSet ResourceSet) MarshalJSON() ([]byte, error) { 89 if len(resourceSet) == 0 { 90 return nil, Errorf("empty resource set") 91 } 92 93 resources := []Resource{} 94 for resource := range resourceSet { 95 resources = append(resources, resource) 96 } 97 98 return json.Marshal(resources) 99 } 100 101 // Match - matches object name with anyone of resource pattern in resource set. 102 func (resourceSet ResourceSet) Match(resource string, conditionValues map[string][]string) bool { 103 for r := range resourceSet { 104 if r.Match(resource, conditionValues) { 105 return true 106 } 107 } 108 109 return false 110 } 111 112 func (resourceSet ResourceSet) String() string { 113 resources := []string{} 114 for resource := range resourceSet { 115 resources = append(resources, resource.String()) 116 } 117 sort.Strings(resources) 118 119 return fmt.Sprintf("%v", resources) 120 } 121 122 // UnmarshalJSON - decodes JSON data to ResourceSet. 123 func (resourceSet *ResourceSet) UnmarshalJSON(data []byte) error { 124 var sset set.StringSet 125 if err := json.Unmarshal(data, &sset); err != nil { 126 return err 127 } 128 129 *resourceSet = make(ResourceSet) 130 for _, s := range sset.ToSlice() { 131 resource, err := parseResource(s) 132 if err != nil { 133 return err 134 } 135 136 if _, found := (*resourceSet)[resource]; found { 137 return Errorf("duplicate resource '%v' found", s) 138 } 139 140 resourceSet.Add(resource) 141 } 142 143 return nil 144 } 145 146 // Validate - validates ResourceSet. 147 func (resourceSet ResourceSet) Validate() error { 148 for resource := range resourceSet { 149 if err := resource.Validate(); err != nil { 150 return err 151 } 152 } 153 154 return nil 155 } 156 157 // ToSlice - returns slice of resources from the resource set. 158 func (resourceSet ResourceSet) ToSlice() []Resource { 159 resources := []Resource{} 160 for resource := range resourceSet { 161 resources = append(resources, resource) 162 } 163 164 return resources 165 } 166 167 // Clone clones ResourceSet structure 168 func (resourceSet ResourceSet) Clone() ResourceSet { 169 return NewResourceSet(resourceSet.ToSlice()...) 170 } 171 172 // NewResourceSet - creates new resource set. 173 func NewResourceSet(resources ...Resource) ResourceSet { 174 resourceSet := make(ResourceSet) 175 for _, resource := range resources { 176 resourceSet.Add(resource) 177 } 178 179 return resourceSet 180 }