storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/condition/stringequalsfunc.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 condition 18 19 import ( 20 "fmt" 21 "net/http" 22 "sort" 23 24 "github.com/minio/minio-go/v7/pkg/s3utils" 25 "github.com/minio/minio-go/v7/pkg/set" 26 ) 27 28 func toStringEqualsFuncString(n name, key Key, values set.StringSet) string { 29 valueStrings := values.ToSlice() 30 sort.Strings(valueStrings) 31 32 return fmt.Sprintf("%v:%v:%v", n, key, valueStrings) 33 } 34 35 // stringEqualsFunc - String equals function. It checks whether value by Key in given 36 // values map is in condition values. 37 // For example, 38 // - if values = ["mybucket/foo"], at evaluate() it returns whether string 39 // in value map for Key is in values. 40 type stringEqualsFunc struct { 41 k Key 42 values set.StringSet 43 } 44 45 // evaluate() - evaluates to check whether value by Key in given values is in 46 // condition values. 47 func (f stringEqualsFunc) evaluate(values map[string][]string) bool { 48 requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())] 49 if !ok { 50 requestValue = values[f.k.Name()] 51 } 52 53 fvalues := f.values.ApplyFunc(substFuncFromValues(values)) 54 return !fvalues.Intersection(set.CreateStringSet(requestValue...)).IsEmpty() 55 } 56 57 // key() - returns condition key which is used by this condition function. 58 func (f stringEqualsFunc) key() Key { 59 return f.k 60 } 61 62 // name() - returns "StringEquals" condition name. 63 func (f stringEqualsFunc) name() name { 64 return stringEquals 65 } 66 67 func (f stringEqualsFunc) String() string { 68 return toStringEqualsFuncString(stringEquals, f.k, f.values) 69 } 70 71 // toMap - returns map representation of this function. 72 func (f stringEqualsFunc) toMap() map[Key]ValueSet { 73 if !f.k.IsValid() { 74 return nil 75 } 76 77 values := NewValueSet() 78 for _, value := range f.values.ToSlice() { 79 values.Add(NewStringValue(value)) 80 } 81 82 return map[Key]ValueSet{ 83 f.k: values, 84 } 85 } 86 87 // stringNotEqualsFunc - String not equals function. It checks whether value by Key in 88 // given values is NOT in condition values. 89 // For example, 90 // - if values = ["mybucket/foo"], at evaluate() it returns whether string 91 // in value map for Key is NOT in values. 92 type stringNotEqualsFunc struct { 93 stringEqualsFunc 94 } 95 96 // evaluate() - evaluates to check whether value by Key in given values is NOT in 97 // condition values. 98 func (f stringNotEqualsFunc) evaluate(values map[string][]string) bool { 99 return !f.stringEqualsFunc.evaluate(values) 100 } 101 102 // name() - returns "StringNotEquals" condition name. 103 func (f stringNotEqualsFunc) name() name { 104 return stringNotEquals 105 } 106 107 func (f stringNotEqualsFunc) String() string { 108 return toStringEqualsFuncString(stringNotEquals, f.stringEqualsFunc.k, f.stringEqualsFunc.values) 109 } 110 111 func valuesToStringSlice(n name, values ValueSet) ([]string, error) { 112 valueStrings := []string{} 113 114 for value := range values { 115 s, err := value.GetString() 116 if err != nil { 117 return nil, fmt.Errorf("value must be a string for %v condition", n) 118 } 119 120 valueStrings = append(valueStrings, s) 121 } 122 123 return valueStrings, nil 124 } 125 126 func validateStringEqualsValues(n name, key Key, values set.StringSet) error { 127 for _, s := range values.ToSlice() { 128 switch key { 129 case S3XAmzCopySource: 130 bucket, object := path2BucketAndObject(s) 131 if object == "" { 132 return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzCopySource, n) 133 } 134 if err := s3utils.CheckValidBucketName(bucket); err != nil { 135 return err 136 } 137 case S3XAmzServerSideEncryption, S3XAmzServerSideEncryptionCustomerAlgorithm: 138 if s != "AES256" { 139 return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzServerSideEncryption, n) 140 } 141 case S3XAmzMetadataDirective: 142 if s != "COPY" && s != "REPLACE" { 143 return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzMetadataDirective, n) 144 } 145 case S3XAmzContentSha256: 146 if s == "" { 147 return fmt.Errorf("invalid empty value for '%v' for %v condition", S3XAmzContentSha256, n) 148 } 149 } 150 } 151 152 return nil 153 } 154 155 // newStringEqualsFunc - returns new StringEquals function. 156 func newStringEqualsFunc(key Key, values ValueSet) (Function, error) { 157 valueStrings, err := valuesToStringSlice(stringEquals, values) 158 if err != nil { 159 return nil, err 160 } 161 162 return NewStringEqualsFunc(key, valueStrings...) 163 } 164 165 // NewStringEqualsFunc - returns new StringEquals function. 166 func NewStringEqualsFunc(key Key, values ...string) (Function, error) { 167 sset := set.CreateStringSet(values...) 168 if err := validateStringEqualsValues(stringEquals, key, sset); err != nil { 169 return nil, err 170 } 171 172 return &stringEqualsFunc{key, sset}, nil 173 } 174 175 // newStringNotEqualsFunc - returns new StringNotEquals function. 176 func newStringNotEqualsFunc(key Key, values ValueSet) (Function, error) { 177 valueStrings, err := valuesToStringSlice(stringNotEquals, values) 178 if err != nil { 179 return nil, err 180 } 181 182 return NewStringNotEqualsFunc(key, valueStrings...) 183 } 184 185 // NewStringNotEqualsFunc - returns new StringNotEquals function. 186 func NewStringNotEqualsFunc(key Key, values ...string) (Function, error) { 187 sset := set.CreateStringSet(values...) 188 if err := validateStringEqualsValues(stringNotEquals, key, sset); err != nil { 189 return nil, err 190 } 191 192 return &stringNotEqualsFunc{stringEqualsFunc{key, sset}}, nil 193 }