storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/condition/dateequalsfunc.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  	"time"
    24  )
    25  
    26  func toDateEqualsFuncString(n name, key Key, value time.Time) string {
    27  	return fmt.Sprintf("%v:%v:%v", n, key, value.Format(time.RFC3339))
    28  }
    29  
    30  // dateEqualsFunc - 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 dateEqualsFunc struct {
    36  	k     Key
    37  	value time.Time
    38  }
    39  
    40  // evaluate() - evaluates to check whether value by Key in given values is in
    41  // condition values.
    42  func (f dateEqualsFunc) 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  	t, err := time.Parse(time.RFC3339, requestValue[0])
    53  	if err != nil {
    54  		return false
    55  	}
    56  
    57  	return f.value.Equal(t)
    58  }
    59  
    60  // key() - returns condition key which is used by this condition function.
    61  func (f dateEqualsFunc) key() Key {
    62  	return f.k
    63  }
    64  
    65  // name() - returns "DateEquals" condition name.
    66  func (f dateEqualsFunc) name() name {
    67  	return dateEquals
    68  }
    69  
    70  func (f dateEqualsFunc) String() string {
    71  	return toDateEqualsFuncString(dateEquals, f.k, f.value)
    72  }
    73  
    74  // toMap - returns map representation of this function.
    75  func (f dateEqualsFunc) toMap() map[Key]ValueSet {
    76  	if !f.k.IsValid() {
    77  		return nil
    78  	}
    79  
    80  	values := NewValueSet()
    81  	values.Add(NewStringValue(f.value.Format(time.RFC3339)))
    82  
    83  	return map[Key]ValueSet{
    84  		f.k: values,
    85  	}
    86  }
    87  
    88  // dateNotEqualsFunc - 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 dateNotEqualsFunc struct {
    94  	dateEqualsFunc
    95  }
    96  
    97  // evaluate() - evaluates to check whether value by Key in given values is NOT in
    98  // condition values.
    99  func (f dateNotEqualsFunc) evaluate(values map[string][]string) bool {
   100  	return !f.dateEqualsFunc.evaluate(values)
   101  }
   102  
   103  // name() - returns "DateNotEquals" condition name.
   104  func (f dateNotEqualsFunc) name() name {
   105  	return dateNotEquals
   106  }
   107  
   108  func (f dateNotEqualsFunc) String() string {
   109  	return toDateEqualsFuncString(dateNotEquals, f.dateEqualsFunc.k, f.dateEqualsFunc.value)
   110  }
   111  
   112  func valueToTime(n name, values ValueSet) (v time.Time, err error) {
   113  	if len(values) != 1 {
   114  		return v, 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.String:
   120  			s, err := vs.GetString()
   121  			if err != nil {
   122  				return v, err
   123  			}
   124  			if v, err = time.Parse(time.RFC3339, s); err != nil {
   125  				return v, fmt.Errorf("value %s must be a time.Time string for %s condition: %w", vs, n, err)
   126  			}
   127  		default:
   128  			return v, fmt.Errorf("value %s must be a time.Time for %s condition", vs, n)
   129  		}
   130  	}
   131  
   132  	return v, nil
   133  
   134  }
   135  
   136  // newDateEqualsFunc - returns new DateEquals function.
   137  func newDateEqualsFunc(key Key, values ValueSet) (Function, error) {
   138  	v, err := valueToTime(dateEquals, values)
   139  	if err != nil {
   140  		return nil, err
   141  	}
   142  
   143  	return NewDateEqualsFunc(key, v)
   144  }
   145  
   146  // NewDateEqualsFunc - returns new DateEquals function.
   147  func NewDateEqualsFunc(key Key, value time.Time) (Function, error) {
   148  	return &dateEqualsFunc{key, value}, nil
   149  }
   150  
   151  // newDateNotEqualsFunc - returns new DateNotEquals function.
   152  func newDateNotEqualsFunc(key Key, values ValueSet) (Function, error) {
   153  	v, err := valueToTime(dateNotEquals, values)
   154  	if err != nil {
   155  		return nil, err
   156  	}
   157  
   158  	return NewDateNotEqualsFunc(key, v)
   159  }
   160  
   161  // NewDateNotEqualsFunc - returns new DateNotEquals function.
   162  func NewDateNotEqualsFunc(key Key, value time.Time) (Function, error) {
   163  	return &dateNotEqualsFunc{dateEqualsFunc{key, value}}, nil
   164  }