storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/condition/numericequalsfunc.go (about)

     1  /*
     2   * MinIO Cloud Storage, (C) 2020 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  func toNumericEqualsFuncString(n name, key Key, value int) string {
    27  	return fmt.Sprintf("%v:%v:%v", n, key, value)
    28  }
    29  
    30  // numericEqualsFunc - String equals function. It checks whether value by Key in given
    31  // values map is in condition values.
    32  // For example,
    33  //   - if values = ["mybucket/foo"], at evaluate() it returns whether string
    34  //     in value map for Key is in values.
    35  type numericEqualsFunc struct {
    36  	k     Key
    37  	value int
    38  }
    39  
    40  // evaluate() - evaluates to check whether value by Key in given values is in
    41  // condition values.
    42  func (f numericEqualsFunc) evaluate(values map[string][]string) bool {
    43  	requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
    44  	if !ok {
    45  		requestValue = values[f.k.Name()]
    46  	}
    47  
    48  	if len(requestValue) == 0 {
    49  		return false
    50  	}
    51  
    52  	rvInt, err := strconv.Atoi(requestValue[0])
    53  	if err != nil {
    54  		return false
    55  	}
    56  
    57  	return f.value == rvInt
    58  }
    59  
    60  // key() - returns condition key which is used by this condition function.
    61  func (f numericEqualsFunc) key() Key {
    62  	return f.k
    63  }
    64  
    65  // name() - returns "NumericEquals" condition name.
    66  func (f numericEqualsFunc) name() name {
    67  	return numericEquals
    68  }
    69  
    70  func (f numericEqualsFunc) String() string {
    71  	return toNumericEqualsFuncString(numericEquals, f.k, f.value)
    72  }
    73  
    74  // toMap - returns map representation of this function.
    75  func (f numericEqualsFunc) toMap() map[Key]ValueSet {
    76  	if !f.k.IsValid() {
    77  		return nil
    78  	}
    79  
    80  	values := NewValueSet()
    81  	values.Add(NewIntValue(f.value))
    82  
    83  	return map[Key]ValueSet{
    84  		f.k: values,
    85  	}
    86  }
    87  
    88  // numericNotEqualsFunc - String not equals function. It checks whether value by Key in
    89  // given values is NOT in condition values.
    90  // For example,
    91  //   - if values = ["mybucket/foo"], at evaluate() it returns whether string
    92  //     in value map for Key is NOT in values.
    93  type numericNotEqualsFunc struct {
    94  	numericEqualsFunc
    95  }
    96  
    97  // evaluate() - evaluates to check whether value by Key in given values is NOT in
    98  // condition values.
    99  func (f numericNotEqualsFunc) evaluate(values map[string][]string) bool {
   100  	return !f.numericEqualsFunc.evaluate(values)
   101  }
   102  
   103  // name() - returns "NumericNotEquals" condition name.
   104  func (f numericNotEqualsFunc) name() name {
   105  	return numericNotEquals
   106  }
   107  
   108  func (f numericNotEqualsFunc) String() string {
   109  	return toNumericEqualsFuncString(numericNotEquals, f.numericEqualsFunc.k, f.numericEqualsFunc.value)
   110  }
   111  
   112  func valueToInt(n name, values ValueSet) (v int, err error) {
   113  	if len(values) != 1 {
   114  		return -1, fmt.Errorf("only one value is allowed for %s condition", n)
   115  	}
   116  
   117  	for vs := range values {
   118  		switch vs.GetType() {
   119  		case reflect.Int:
   120  			if v, err = vs.GetInt(); err != nil {
   121  				return -1, err
   122  			}
   123  		case reflect.String:
   124  			s, err := vs.GetString()
   125  			if err != nil {
   126  				return -1, err
   127  			}
   128  			if v, err = strconv.Atoi(s); err != nil {
   129  				return -1, fmt.Errorf("value %s must be a int for %s condition: %w", vs, n, err)
   130  			}
   131  		default:
   132  			return -1, fmt.Errorf("value %s must be a int for %s condition", vs, n)
   133  		}
   134  	}
   135  
   136  	return v, nil
   137  
   138  }
   139  
   140  // newNumericEqualsFunc - returns new NumericEquals function.
   141  func newNumericEqualsFunc(key Key, values ValueSet) (Function, error) {
   142  	v, err := valueToInt(numericEquals, values)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  
   147  	return NewNumericEqualsFunc(key, v)
   148  }
   149  
   150  // NewNumericEqualsFunc - returns new NumericEquals function.
   151  func NewNumericEqualsFunc(key Key, value int) (Function, error) {
   152  	return &numericEqualsFunc{key, value}, nil
   153  }
   154  
   155  // newNumericNotEqualsFunc - returns new NumericNotEquals function.
   156  func newNumericNotEqualsFunc(key Key, values ValueSet) (Function, error) {
   157  	v, err := valueToInt(numericNotEquals, values)
   158  	if err != nil {
   159  		return nil, err
   160  	}
   161  
   162  	return NewNumericNotEqualsFunc(key, v)
   163  }
   164  
   165  // NewNumericNotEqualsFunc - returns new NumericNotEquals function.
   166  func NewNumericNotEqualsFunc(key Key, value int) (Function, error) {
   167  	return &numericNotEqualsFunc{numericEqualsFunc{key, value}}, nil
   168  }