storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/condition/binaryequalsfunc.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 "encoding/base64" 21 "fmt" 22 "net/http" 23 "sort" 24 25 "github.com/minio/minio-go/v7/pkg/s3utils" 26 "github.com/minio/minio-go/v7/pkg/set" 27 ) 28 29 func toBinaryEqualsFuncString(n name, key Key, values set.StringSet) string { 30 valueStrings := values.ToSlice() 31 sort.Strings(valueStrings) 32 33 return fmt.Sprintf("%v:%v:%v", n, key, valueStrings) 34 } 35 36 // binaryEqualsFunc - String equals function. It checks whether value by Key in given 37 // values map is in condition values. 38 // For example, 39 // - if values = ["mybucket/foo"], at evaluate() it returns whether string 40 // in value map for Key is in values. 41 type binaryEqualsFunc struct { 42 k Key 43 values set.StringSet 44 } 45 46 // evaluate() - evaluates to check whether value by Key in given values is in 47 // condition values. 48 func (f binaryEqualsFunc) evaluate(values map[string][]string) bool { 49 requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())] 50 if !ok { 51 requestValue = values[f.k.Name()] 52 } 53 54 fvalues := f.values.ApplyFunc(substFuncFromValues(values)) 55 return !fvalues.Intersection(set.CreateStringSet(requestValue...)).IsEmpty() 56 } 57 58 // key() - returns condition key which is used by this condition function. 59 func (f binaryEqualsFunc) key() Key { 60 return f.k 61 } 62 63 // name() - returns "BinaryEquals" condition name. 64 func (f binaryEqualsFunc) name() name { 65 return binaryEquals 66 } 67 68 func (f binaryEqualsFunc) String() string { 69 return toBinaryEqualsFuncString(binaryEquals, f.k, f.values) 70 } 71 72 // toMap - returns map representation of this function. 73 func (f binaryEqualsFunc) toMap() map[Key]ValueSet { 74 if !f.k.IsValid() { 75 return nil 76 } 77 78 values := NewValueSet() 79 for _, value := range f.values.ToSlice() { 80 values.Add(NewStringValue(base64.StdEncoding.EncodeToString([]byte(value)))) 81 } 82 83 return map[Key]ValueSet{ 84 f.k: values, 85 } 86 } 87 88 func validateBinaryEqualsValues(n name, key Key, values set.StringSet) error { 89 vslice := values.ToSlice() 90 for _, s := range vslice { 91 sbytes, err := base64.StdEncoding.DecodeString(s) 92 if err != nil { 93 return err 94 } 95 values.Remove(s) 96 s = string(sbytes) 97 switch key { 98 case S3XAmzCopySource: 99 bucket, object := path2BucketAndObject(s) 100 if object == "" { 101 return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzCopySource, n) 102 } 103 if err = s3utils.CheckValidBucketName(bucket); err != nil { 104 return err 105 } 106 case S3XAmzServerSideEncryption, S3XAmzServerSideEncryptionCustomerAlgorithm: 107 if s != "AES256" { 108 return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzServerSideEncryption, n) 109 } 110 case S3XAmzMetadataDirective: 111 if s != "COPY" && s != "REPLACE" { 112 return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzMetadataDirective, n) 113 } 114 case S3XAmzContentSha256: 115 if s == "" { 116 return fmt.Errorf("invalid empty value for '%v' for %v condition", S3XAmzContentSha256, n) 117 } 118 } 119 values.Add(s) 120 } 121 122 return nil 123 } 124 125 // newBinaryEqualsFunc - returns new BinaryEquals function. 126 func newBinaryEqualsFunc(key Key, values ValueSet) (Function, error) { 127 valueStrings, err := valuesToStringSlice(binaryEquals, values) 128 if err != nil { 129 return nil, err 130 } 131 132 return NewBinaryEqualsFunc(key, valueStrings...) 133 } 134 135 // NewBinaryEqualsFunc - returns new BinaryEquals function. 136 func NewBinaryEqualsFunc(key Key, values ...string) (Function, error) { 137 sset := set.CreateStringSet(values...) 138 if err := validateBinaryEqualsValues(binaryEquals, key, sset); err != nil { 139 return nil, err 140 } 141 142 return &binaryEqualsFunc{key, sset}, nil 143 }