storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/condition/nullfunc.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  	"reflect"
    23  	"strconv"
    24  )
    25  
    26  // nullFunc - Null condition function. It checks whether Key is not present in given
    27  // values or not.
    28  // For example,
    29  //   1. if Key = S3XAmzCopySource and Value = true, at evaluate() it returns whether
    30  //      S3XAmzCopySource is NOT in given value map or not.
    31  //   2. if Key = S3XAmzCopySource and Value = false, at evaluate() it returns whether
    32  //      S3XAmzCopySource is in given value map or not.
    33  // https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition_operators.html#Conditions_Null
    34  type nullFunc struct {
    35  	k     Key
    36  	value bool
    37  }
    38  
    39  // evaluate() - evaluates to check whether Key is present in given values or not.
    40  // Depending on condition boolean value, this function returns true or false.
    41  func (f nullFunc) evaluate(values map[string][]string) bool {
    42  	requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
    43  	if !ok {
    44  		requestValue = values[f.k.Name()]
    45  	}
    46  
    47  	if f.value {
    48  		return len(requestValue) == 0
    49  	}
    50  
    51  	return len(requestValue) != 0
    52  }
    53  
    54  // key() - returns condition key which is used by this condition function.
    55  func (f nullFunc) key() Key {
    56  	return f.k
    57  }
    58  
    59  // name() - returns "Null" condition name.
    60  func (f nullFunc) name() name {
    61  	return null
    62  }
    63  
    64  func (f nullFunc) String() string {
    65  	return fmt.Sprintf("%v:%v:%v", null, f.k, f.value)
    66  }
    67  
    68  // toMap - returns map representation of this function.
    69  func (f nullFunc) toMap() map[Key]ValueSet {
    70  	if !f.k.IsValid() {
    71  		return nil
    72  	}
    73  
    74  	return map[Key]ValueSet{
    75  		f.k: NewValueSet(NewBoolValue(f.value)),
    76  	}
    77  }
    78  
    79  func newNullFunc(key Key, values ValueSet) (Function, error) {
    80  	if len(values) != 1 {
    81  		return nil, fmt.Errorf("only one value is allowed for Null condition")
    82  	}
    83  
    84  	var value bool
    85  	for v := range values {
    86  		switch v.GetType() {
    87  		case reflect.Bool:
    88  			value, _ = v.GetBool()
    89  		case reflect.String:
    90  			var err error
    91  			s, _ := v.GetString()
    92  			if value, err = strconv.ParseBool(s); err != nil {
    93  				return nil, fmt.Errorf("value must be a boolean string for Null condition")
    94  			}
    95  		default:
    96  			return nil, fmt.Errorf("value must be a boolean for Null condition")
    97  		}
    98  	}
    99  
   100  	return &nullFunc{key, value}, nil
   101  }
   102  
   103  // NewNullFunc - returns new Null function.
   104  func NewNullFunc(key Key, value bool) (Function, error) {
   105  	return &nullFunc{key, value}, nil
   106  }