mirror of
https://github.com/minio/minio.git
synced 2025-11-07 04:42:56 -05:00
Add numeric/date policy conditions (#9233)
add new policy conditions - NumericEquals - NumericNotEquals - NumericLessThan - NumericLessThanEquals - NumericGreaterThan - NumericGreaterThanEquals - DateEquals - DateNotEquals - DateLessThan - DateLessThanEquals - DateGreaterThan - DateGreaterThanEquals
This commit is contained in:
@@ -89,8 +89,6 @@ const (
|
||||
// GetBucketLifecycleAction - GetBucketLifecycle Rest API action.
|
||||
GetBucketLifecycleAction = "s3:GetLifecycleConfiguration"
|
||||
|
||||
// BypassGovernanceModeAction - bypass governance mode for DeleteObject Rest API action.
|
||||
BypassGovernanceModeAction = "s3:BypassGovernanceMode"
|
||||
// BypassGovernanceRetentionAction - bypass governance retention for PutObjectRetention, PutObject and DeleteObject Rest API action.
|
||||
BypassGovernanceRetentionAction = "s3:BypassGovernanceRetention"
|
||||
// PutObjectRetentionAction - PutObjectRetention Rest API action.
|
||||
@@ -127,7 +125,6 @@ var supportedObjectActions = map[Action]struct{}{
|
||||
GetObjectAction: {},
|
||||
ListMultipartUploadPartsAction: {},
|
||||
PutObjectAction: {},
|
||||
BypassGovernanceModeAction: {},
|
||||
BypassGovernanceRetentionAction: {},
|
||||
PutObjectRetentionAction: {},
|
||||
GetObjectRetentionAction: {},
|
||||
@@ -172,7 +169,6 @@ var supportedActions = map[Action]struct{}{
|
||||
PutObjectLegalHoldAction: {},
|
||||
PutBucketObjectLockConfigurationAction: {},
|
||||
GetBucketObjectLockConfigurationAction: {},
|
||||
BypassGovernanceModeAction: {},
|
||||
BypassGovernanceRetentionAction: {},
|
||||
GetObjectTaggingAction: {},
|
||||
PutObjectTaggingAction: {},
|
||||
@@ -263,13 +259,31 @@ var actionConditionKeyMap = map[Action]condition.KeySet{
|
||||
condition.S3XAmzServerSideEncryptionCustomerAlgorithm,
|
||||
condition.S3XAmzMetadataDirective,
|
||||
condition.S3XAmzStorageClass,
|
||||
condition.S3ObjectLockRetainUntilDate,
|
||||
condition.S3ObjectLockMode,
|
||||
condition.S3ObjectLockLegalHold,
|
||||
}, condition.CommonKeys...)...),
|
||||
PutObjectRetentionAction: condition.NewKeySet(
|
||||
append([]condition.Key{
|
||||
condition.S3ObjectLockRemainingRetentionDays,
|
||||
condition.S3ObjectLockRetainUntilDate,
|
||||
condition.S3ObjectLockMode,
|
||||
condition.S3ObjectLockLegalHold,
|
||||
}, condition.CommonKeys...)...),
|
||||
|
||||
GetObjectRetentionAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
PutObjectLegalHoldAction: condition.NewKeySet(
|
||||
append([]condition.Key{
|
||||
condition.S3ObjectLockLegalHold,
|
||||
}, condition.CommonKeys...)...),
|
||||
GetObjectLegalHoldAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
BypassGovernanceRetentionAction: condition.NewKeySet(
|
||||
append([]condition.Key{
|
||||
condition.S3ObjectLockRemainingRetentionDays,
|
||||
condition.S3ObjectLockRetainUntilDate,
|
||||
condition.S3ObjectLockMode,
|
||||
condition.S3ObjectLockLegalHold,
|
||||
}, condition.CommonKeys...)...),
|
||||
PutObjectRetentionAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
GetObjectRetentionAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
BypassGovernanceModeAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
BypassGovernanceRetentionAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
PutObjectLegalHoldAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
GetObjectLegalHoldAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
GetBucketObjectLockConfigurationAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
PutBucketObjectLockConfigurationAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
PutObjectTaggingAction: condition.NewKeySet(condition.CommonKeys...),
|
||||
|
||||
@@ -111,6 +111,10 @@ func validateBinaryEqualsValues(n name, key Key, values set.StringSet) error {
|
||||
if s != "COPY" && s != "REPLACE" {
|
||||
return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzMetadataDirective, n)
|
||||
}
|
||||
case S3XAmzContentSha256:
|
||||
if s == "" {
|
||||
return fmt.Errorf("invalid empty value for '%v' for %v condition", S3XAmzContentSha256, n)
|
||||
}
|
||||
}
|
||||
values.Add(s)
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ func (f booleanFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return f.value == requestValue[0]
|
||||
}
|
||||
|
||||
|
||||
164
pkg/bucket/policy/condition/dateequalsfunc.go
Normal file
164
pkg/bucket/policy/condition/dateequalsfunc.go
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* MinIO Cloud Storage, (C) 2020 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package condition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
func toDateEqualsFuncString(n name, key Key, value time.Time) string {
|
||||
return fmt.Sprintf("%v:%v:%v", n, key, value.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
// dateEqualsFunc - String equals function. It checks whether value by Key in given
|
||||
// values map is in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is in values.
|
||||
type dateEqualsFunc struct {
|
||||
k Key
|
||||
value time.Time
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is in
|
||||
// condition values.
|
||||
func (f dateEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return f.value.Equal(t)
|
||||
}
|
||||
|
||||
// key() - returns condition key which is used by this condition function.
|
||||
func (f dateEqualsFunc) key() Key {
|
||||
return f.k
|
||||
}
|
||||
|
||||
// name() - returns "DateEquals" condition name.
|
||||
func (f dateEqualsFunc) name() name {
|
||||
return dateEquals
|
||||
}
|
||||
|
||||
func (f dateEqualsFunc) String() string {
|
||||
return toDateEqualsFuncString(dateEquals, f.k, f.value)
|
||||
}
|
||||
|
||||
// toMap - returns map representation of this function.
|
||||
func (f dateEqualsFunc) toMap() map[Key]ValueSet {
|
||||
if !f.k.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
values := NewValueSet()
|
||||
values.Add(NewStringValue(f.value.Format(time.RFC3339)))
|
||||
|
||||
return map[Key]ValueSet{
|
||||
f.k: values,
|
||||
}
|
||||
}
|
||||
|
||||
// dateNotEqualsFunc - String not equals function. It checks whether value by Key in
|
||||
// given values is NOT in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is NOT in values.
|
||||
type dateNotEqualsFunc struct {
|
||||
dateEqualsFunc
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is NOT in
|
||||
// condition values.
|
||||
func (f dateNotEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
return !f.dateEqualsFunc.evaluate(values)
|
||||
}
|
||||
|
||||
// name() - returns "DateNotEquals" condition name.
|
||||
func (f dateNotEqualsFunc) name() name {
|
||||
return dateNotEquals
|
||||
}
|
||||
|
||||
func (f dateNotEqualsFunc) String() string {
|
||||
return toDateEqualsFuncString(dateNotEquals, f.dateEqualsFunc.k, f.dateEqualsFunc.value)
|
||||
}
|
||||
|
||||
func valueToTime(n name, values ValueSet) (v time.Time, err error) {
|
||||
if len(values) != 1 {
|
||||
return v, fmt.Errorf("only one value is allowed for %s condition", n)
|
||||
}
|
||||
|
||||
for vs := range values {
|
||||
switch vs.GetType() {
|
||||
case reflect.String:
|
||||
s, err := vs.GetString()
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
if v, err = time.Parse(time.RFC3339, s); err != nil {
|
||||
return v, fmt.Errorf("value %s must be a time.Time string for %s condition: %w", vs, n, err)
|
||||
}
|
||||
default:
|
||||
return v, fmt.Errorf("value %s must be a time.Time for %s condition", vs, n)
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
|
||||
}
|
||||
|
||||
// newDateEqualsFunc - returns new DateEquals function.
|
||||
func newDateEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToTime(dateEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDateEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewDateEqualsFunc - returns new DateEquals function.
|
||||
func NewDateEqualsFunc(key Key, value time.Time) (Function, error) {
|
||||
return &dateEqualsFunc{key, value}, nil
|
||||
}
|
||||
|
||||
// newDateNotEqualsFunc - returns new DateNotEquals function.
|
||||
func newDateNotEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToTime(dateNotEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDateNotEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewDateNotEqualsFunc - returns new DateNotEquals function.
|
||||
func NewDateNotEqualsFunc(key Key, value time.Time) (Function, error) {
|
||||
return &dateNotEqualsFunc{dateEqualsFunc{key, value}}, nil
|
||||
}
|
||||
153
pkg/bucket/policy/condition/dategreaterthanfunc.go
Normal file
153
pkg/bucket/policy/condition/dategreaterthanfunc.go
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* MinIO Cloud Storage, (C) 2020 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package condition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func toDateGreaterThanFuncString(n name, key Key, value time.Time) string {
|
||||
return fmt.Sprintf("%v:%v:%v", n, key, value.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
// dateGreaterThanFunc - String equals function. It checks whether value by Key in given
|
||||
// values map is in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is in values.
|
||||
type dateGreaterThanFunc struct {
|
||||
k Key
|
||||
value time.Time
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is in
|
||||
// condition values.
|
||||
func (f dateGreaterThanFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return t.After(f.value)
|
||||
}
|
||||
|
||||
// key() - returns condition key which is used by this condition function.
|
||||
func (f dateGreaterThanFunc) key() Key {
|
||||
return f.k
|
||||
}
|
||||
|
||||
// name() - returns "DateGreaterThan" condition name.
|
||||
func (f dateGreaterThanFunc) name() name {
|
||||
return dateGreaterThan
|
||||
}
|
||||
|
||||
func (f dateGreaterThanFunc) String() string {
|
||||
return toDateGreaterThanFuncString(dateGreaterThan, f.k, f.value)
|
||||
}
|
||||
|
||||
// toMap - returns map representation of this function.
|
||||
func (f dateGreaterThanFunc) toMap() map[Key]ValueSet {
|
||||
if !f.k.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
values := NewValueSet()
|
||||
values.Add(NewStringValue(f.value.Format(time.RFC3339)))
|
||||
|
||||
return map[Key]ValueSet{
|
||||
f.k: values,
|
||||
}
|
||||
}
|
||||
|
||||
// dateNotEqualsFunc - String not equals function. It checks whether value by Key in
|
||||
// given values is NOT in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is NOT in values.
|
||||
type dateGreaterThanEqualsFunc struct {
|
||||
dateGreaterThanFunc
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is NOT in
|
||||
// condition values.
|
||||
func (f dateGreaterThanEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return t.After(f.value) || t.Equal(f.value)
|
||||
}
|
||||
|
||||
// name() - returns "DateNotEquals" condition name.
|
||||
func (f dateGreaterThanEqualsFunc) name() name {
|
||||
return dateGreaterThanEquals
|
||||
}
|
||||
|
||||
func (f dateGreaterThanEqualsFunc) String() string {
|
||||
return toDateGreaterThanFuncString(dateNotEquals, f.dateGreaterThanFunc.k, f.dateGreaterThanFunc.value)
|
||||
}
|
||||
|
||||
// newDateGreaterThanFunc - returns new DateGreaterThan function.
|
||||
func newDateGreaterThanFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToTime(dateGreaterThan, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDateGreaterThanFunc(key, v)
|
||||
}
|
||||
|
||||
// NewDateGreaterThanFunc - returns new DateGreaterThan function.
|
||||
func NewDateGreaterThanFunc(key Key, value time.Time) (Function, error) {
|
||||
return &dateGreaterThanFunc{key, value}, nil
|
||||
}
|
||||
|
||||
// newDateNotEqualsFunc - returns new DateNotEquals function.
|
||||
func newDateGreaterThanEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToTime(dateNotEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDateGreaterThanEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewDateGreaterThanEqualsFunc - returns new DateNotEquals function.
|
||||
func NewDateGreaterThanEqualsFunc(key Key, value time.Time) (Function, error) {
|
||||
return &dateGreaterThanEqualsFunc{dateGreaterThanFunc{key, value}}, nil
|
||||
}
|
||||
153
pkg/bucket/policy/condition/datelessthanfunc.go
Normal file
153
pkg/bucket/policy/condition/datelessthanfunc.go
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* MinIO Cloud Storage, (C) 2020 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package condition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
func toDateLessThanFuncString(n name, key Key, value time.Time) string {
|
||||
return fmt.Sprintf("%v:%v:%v", n, key, value.Format(time.RFC3339))
|
||||
}
|
||||
|
||||
// dateLessThanFunc - String equals function. It checks whether value by Key in given
|
||||
// values map is in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is in values.
|
||||
type dateLessThanFunc struct {
|
||||
k Key
|
||||
value time.Time
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is in
|
||||
// condition values.
|
||||
func (f dateLessThanFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return t.Before(f.value)
|
||||
}
|
||||
|
||||
// key() - returns condition key which is used by this condition function.
|
||||
func (f dateLessThanFunc) key() Key {
|
||||
return f.k
|
||||
}
|
||||
|
||||
// name() - returns "DateLessThan" condition name.
|
||||
func (f dateLessThanFunc) name() name {
|
||||
return dateLessThan
|
||||
}
|
||||
|
||||
func (f dateLessThanFunc) String() string {
|
||||
return toDateLessThanFuncString(dateLessThan, f.k, f.value)
|
||||
}
|
||||
|
||||
// toMap - returns map representation of this function.
|
||||
func (f dateLessThanFunc) toMap() map[Key]ValueSet {
|
||||
if !f.k.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
values := NewValueSet()
|
||||
values.Add(NewStringValue(f.value.Format(time.RFC3339)))
|
||||
|
||||
return map[Key]ValueSet{
|
||||
f.k: values,
|
||||
}
|
||||
}
|
||||
|
||||
// dateNotEqualsFunc - String not equals function. It checks whether value by Key in
|
||||
// given values is NOT in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is NOT in values.
|
||||
type dateLessThanEqualsFunc struct {
|
||||
dateLessThanFunc
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is NOT in
|
||||
// condition values.
|
||||
func (f dateLessThanEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
t, err := time.Parse(time.RFC3339, requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return t.Before(f.value) || t.Equal(f.value)
|
||||
}
|
||||
|
||||
// name() - returns "DateNotEquals" condition name.
|
||||
func (f dateLessThanEqualsFunc) name() name {
|
||||
return dateLessThanEquals
|
||||
}
|
||||
|
||||
func (f dateLessThanEqualsFunc) String() string {
|
||||
return toDateLessThanFuncString(dateNotEquals, f.dateLessThanFunc.k, f.dateLessThanFunc.value)
|
||||
}
|
||||
|
||||
// newDateLessThanFunc - returns new DateLessThan function.
|
||||
func newDateLessThanFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToTime(dateLessThan, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDateLessThanFunc(key, v)
|
||||
}
|
||||
|
||||
// NewDateLessThanFunc - returns new DateLessThan function.
|
||||
func NewDateLessThanFunc(key Key, value time.Time) (Function, error) {
|
||||
return &dateLessThanFunc{key, value}, nil
|
||||
}
|
||||
|
||||
// newDateNotEqualsFunc - returns new DateNotEquals function.
|
||||
func newDateLessThanEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToTime(dateNotEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewDateLessThanEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewDateLessThanEqualsFunc - returns new DateNotEquals function.
|
||||
func NewDateLessThanEqualsFunc(key Key, value time.Time) (Function, error) {
|
||||
return &dateLessThanEqualsFunc{dateLessThanFunc{key, value}}, nil
|
||||
}
|
||||
@@ -106,6 +106,18 @@ var conditionFuncMap = map[name]func(Key, ValueSet) (Function, error){
|
||||
notIPAddress: newNotIPAddressFunc,
|
||||
null: newNullFunc,
|
||||
boolean: newBooleanFunc,
|
||||
numericEquals: newNumericEqualsFunc,
|
||||
numericNotEquals: newNumericNotEqualsFunc,
|
||||
numericLessThan: newNumericLessThanFunc,
|
||||
numericLessThanEquals: newNumericLessThanEqualsFunc,
|
||||
numericGreaterThan: newNumericGreaterThanFunc,
|
||||
numericGreaterThanEquals: newNumericGreaterThanEqualsFunc,
|
||||
dateEquals: newDateEqualsFunc,
|
||||
dateNotEquals: newDateNotEqualsFunc,
|
||||
dateLessThan: newDateLessThanFunc,
|
||||
dateLessThanEquals: newDateLessThanEqualsFunc,
|
||||
dateGreaterThan: newDateGreaterThanFunc,
|
||||
dateGreaterThanEquals: newDateGreaterThanEqualsFunc,
|
||||
// Add new conditions here.
|
||||
}
|
||||
|
||||
|
||||
@@ -268,12 +268,7 @@ func TestFunctionsUnmarshalJSON(t *testing.T) {
|
||||
|
||||
case3Data := []byte(`{}`)
|
||||
|
||||
// Remove this test after supporting date conditions.
|
||||
case4Data := []byte(`{
|
||||
"DateEquals": { "aws:CurrentTime": "2013-06-30T00:00:00Z" }
|
||||
}`)
|
||||
|
||||
case5Data := []byte(`{
|
||||
"StringLike": {
|
||||
"s3:x-amz-metadata-directive": "REPL*"
|
||||
},
|
||||
@@ -336,10 +331,8 @@ func TestFunctionsUnmarshalJSON(t *testing.T) {
|
||||
{case2Data, NewFunctions(func6), false},
|
||||
// empty condition error.
|
||||
{case3Data, nil, true},
|
||||
// unsupported condition error.
|
||||
{case4Data, nil, true},
|
||||
// Success case multiple keys, same condition.
|
||||
{case5Data, NewFunctions(func1, func2_1, func2_2, func2_3, func3, func4, func5, func6, func7), false},
|
||||
{case4Data, NewFunctions(func1, func2_1, func2_2, func2_3, func3, func4, func5, func6, func7), false},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
|
||||
@@ -43,6 +43,9 @@ const (
|
||||
// PutObject API only.
|
||||
S3XAmzMetadataDirective Key = "s3:x-amz-metadata-directive"
|
||||
|
||||
// S3XAmzContentSha256 - set a static content-sha256 for all calls for a given action.
|
||||
S3XAmzContentSha256 = "s3:x-amz-content-sha256"
|
||||
|
||||
// S3XAmzStorageClass - key representing x-amz-storage-class HTTP header applicable to PutObject API
|
||||
// only.
|
||||
S3XAmzStorageClass Key = "s3:x-amz-storage-class"
|
||||
@@ -59,6 +62,24 @@ const (
|
||||
// S3MaxKeys - key representing max-keys query parameter of ListBucket API only.
|
||||
S3MaxKeys Key = "s3:max-keys"
|
||||
|
||||
// S3ObjectLockRemainingRetentionDays - key representing object-lock-remaining-retention-days
|
||||
// Enables enforcement of an object relative to the remaining retention days, you can set
|
||||
// minimum and maximum allowable retention periods for a bucket using a bucket policy.
|
||||
// This key are specific for s3:PutObjectRetention API.
|
||||
S3ObjectLockRemainingRetentionDays Key = "s3:object-lock-remaining-retention-days"
|
||||
|
||||
// S3ObjectLockMode - key representing object-lock-mode
|
||||
// Enables enforcement of the specified object retention mode
|
||||
S3ObjectLockMode Key = "s3:object-lock-mode"
|
||||
|
||||
// S3ObjectLockRetainUntilDate - key representing object-lock-retain-util-date
|
||||
// Enables enforcement of a specific retain-until-date
|
||||
S3ObjectLockRetainUntilDate Key = "s3:object-lock-retain-until-date"
|
||||
|
||||
// S3ObjectLockLegalHold - key representing object-local-legal-hold
|
||||
// Enables enforcement of the specified object legal hold status
|
||||
S3ObjectLockLegalHold Key = "s3:object-lock-legal-hold"
|
||||
|
||||
// AWSReferer - key representing Referer header of any API.
|
||||
AWSReferer Key = "aws:Referer"
|
||||
|
||||
@@ -94,10 +115,15 @@ var AllSupportedKeys = append([]Key{
|
||||
S3XAmzServerSideEncryptionCustomerAlgorithm,
|
||||
S3XAmzMetadataDirective,
|
||||
S3XAmzStorageClass,
|
||||
S3XAmzContentSha256,
|
||||
S3LocationConstraint,
|
||||
S3Prefix,
|
||||
S3Delimiter,
|
||||
S3MaxKeys,
|
||||
S3ObjectLockRemainingRetentionDays,
|
||||
S3ObjectLockMode,
|
||||
S3ObjectLockLegalHold,
|
||||
S3ObjectLockRetainUntilDate,
|
||||
AWSReferer,
|
||||
AWSSourceIP,
|
||||
AWSUserAgent,
|
||||
@@ -121,6 +147,7 @@ var CommonKeys = append([]Key{
|
||||
AWSPrincipalType,
|
||||
AWSUserID,
|
||||
AWSUsername,
|
||||
S3XAmzContentSha256,
|
||||
}, JWTKeys...)
|
||||
|
||||
func substFuncFromValues(values map[string][]string) func(string) string {
|
||||
|
||||
@@ -35,6 +35,18 @@ const (
|
||||
notIPAddress = "NotIpAddress"
|
||||
null = "Null"
|
||||
boolean = "Bool"
|
||||
numericEquals = "NumericEquals"
|
||||
numericNotEquals = "NumericNotEquals"
|
||||
numericLessThan = "NumericLessThan"
|
||||
numericLessThanEquals = "NumericLessThanEquals"
|
||||
numericGreaterThan = "NumericGreaterThan"
|
||||
numericGreaterThanEquals = "NumericGreaterThanEquals"
|
||||
dateEquals = "DateEquals"
|
||||
dateNotEquals = "DateNotEquals"
|
||||
dateLessThan = "DateLessThan"
|
||||
dateLessThanEquals = "DateLessThanEquals"
|
||||
dateGreaterThan = "DateGreaterThan"
|
||||
dateGreaterThanEquals = "DateGreaterThanEquals"
|
||||
)
|
||||
|
||||
var supportedConditions = []name{
|
||||
@@ -49,6 +61,18 @@ var supportedConditions = []name{
|
||||
notIPAddress,
|
||||
null,
|
||||
boolean,
|
||||
numericEquals,
|
||||
numericNotEquals,
|
||||
numericLessThan,
|
||||
numericLessThanEquals,
|
||||
numericGreaterThan,
|
||||
numericGreaterThanEquals,
|
||||
dateEquals,
|
||||
dateNotEquals,
|
||||
dateLessThan,
|
||||
dateLessThanEquals,
|
||||
dateGreaterThan,
|
||||
dateGreaterThanEquals,
|
||||
// Add new conditions here.
|
||||
}
|
||||
|
||||
|
||||
168
pkg/bucket/policy/condition/numericequalsfunc.go
Normal file
168
pkg/bucket/policy/condition/numericequalsfunc.go
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* MinIO Cloud Storage, (C) 2020 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package condition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func toNumericEqualsFuncString(n name, key Key, value int) string {
|
||||
return fmt.Sprintf("%v:%v:%v", n, key, value)
|
||||
}
|
||||
|
||||
// numericEqualsFunc - String equals function. It checks whether value by Key in given
|
||||
// values map is in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is in values.
|
||||
type numericEqualsFunc struct {
|
||||
k Key
|
||||
value int
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is in
|
||||
// condition values.
|
||||
func (f numericEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
rvInt, err := strconv.Atoi(requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return f.value == rvInt
|
||||
}
|
||||
|
||||
// key() - returns condition key which is used by this condition function.
|
||||
func (f numericEqualsFunc) key() Key {
|
||||
return f.k
|
||||
}
|
||||
|
||||
// name() - returns "NumericEquals" condition name.
|
||||
func (f numericEqualsFunc) name() name {
|
||||
return numericEquals
|
||||
}
|
||||
|
||||
func (f numericEqualsFunc) String() string {
|
||||
return toNumericEqualsFuncString(numericEquals, f.k, f.value)
|
||||
}
|
||||
|
||||
// toMap - returns map representation of this function.
|
||||
func (f numericEqualsFunc) toMap() map[Key]ValueSet {
|
||||
if !f.k.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
values := NewValueSet()
|
||||
values.Add(NewIntValue(f.value))
|
||||
|
||||
return map[Key]ValueSet{
|
||||
f.k: values,
|
||||
}
|
||||
}
|
||||
|
||||
// numericNotEqualsFunc - String not equals function. It checks whether value by Key in
|
||||
// given values is NOT in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is NOT in values.
|
||||
type numericNotEqualsFunc struct {
|
||||
numericEqualsFunc
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is NOT in
|
||||
// condition values.
|
||||
func (f numericNotEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
return !f.numericEqualsFunc.evaluate(values)
|
||||
}
|
||||
|
||||
// name() - returns "NumericNotEquals" condition name.
|
||||
func (f numericNotEqualsFunc) name() name {
|
||||
return numericNotEquals
|
||||
}
|
||||
|
||||
func (f numericNotEqualsFunc) String() string {
|
||||
return toNumericEqualsFuncString(numericNotEquals, f.numericEqualsFunc.k, f.numericEqualsFunc.value)
|
||||
}
|
||||
|
||||
func valueToInt(n name, values ValueSet) (v int, err error) {
|
||||
if len(values) != 1 {
|
||||
return -1, fmt.Errorf("only one value is allowed for %s condition", n)
|
||||
}
|
||||
|
||||
for vs := range values {
|
||||
switch vs.GetType() {
|
||||
case reflect.Int:
|
||||
if v, err = vs.GetInt(); err != nil {
|
||||
return -1, err
|
||||
}
|
||||
case reflect.String:
|
||||
s, err := vs.GetString()
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
if v, err = strconv.Atoi(s); err != nil {
|
||||
return -1, fmt.Errorf("value %s must be a int for %s condition: %w", vs, n, err)
|
||||
}
|
||||
default:
|
||||
return -1, fmt.Errorf("value %s must be a int for %s condition", vs, n)
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
|
||||
}
|
||||
|
||||
// newNumericEqualsFunc - returns new NumericEquals function.
|
||||
func newNumericEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToInt(numericEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewNumericEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewNumericEqualsFunc - returns new NumericEquals function.
|
||||
func NewNumericEqualsFunc(key Key, value int) (Function, error) {
|
||||
return &numericEqualsFunc{key, value}, nil
|
||||
}
|
||||
|
||||
// newNumericNotEqualsFunc - returns new NumericNotEquals function.
|
||||
func newNumericNotEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToInt(numericNotEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewNumericNotEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewNumericNotEqualsFunc - returns new NumericNotEquals function.
|
||||
func NewNumericNotEqualsFunc(key Key, value int) (Function, error) {
|
||||
return &numericNotEqualsFunc{numericEqualsFunc{key, value}}, nil
|
||||
}
|
||||
153
pkg/bucket/policy/condition/numericgreaterfunc.go
Normal file
153
pkg/bucket/policy/condition/numericgreaterfunc.go
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* MinIO Cloud Storage, (C) 2020 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package condition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func toNumericGreaterThanFuncString(n name, key Key, value int) string {
|
||||
return fmt.Sprintf("%v:%v:%v", n, key, value)
|
||||
}
|
||||
|
||||
// numericGreaterThanFunc - String equals function. It checks whether value by Key in given
|
||||
// values map is in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is in values.
|
||||
type numericGreaterThanFunc struct {
|
||||
k Key
|
||||
value int
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is in
|
||||
// condition values.
|
||||
func (f numericGreaterThanFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
rvInt, err := strconv.Atoi(requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return rvInt > f.value
|
||||
}
|
||||
|
||||
// key() - returns condition key which is used by this condition function.
|
||||
func (f numericGreaterThanFunc) key() Key {
|
||||
return f.k
|
||||
}
|
||||
|
||||
// name() - returns "NumericGreaterThan" condition name.
|
||||
func (f numericGreaterThanFunc) name() name {
|
||||
return numericGreaterThan
|
||||
}
|
||||
|
||||
func (f numericGreaterThanFunc) String() string {
|
||||
return toNumericGreaterThanFuncString(numericGreaterThan, f.k, f.value)
|
||||
}
|
||||
|
||||
// toMap - returns map representation of this function.
|
||||
func (f numericGreaterThanFunc) toMap() map[Key]ValueSet {
|
||||
if !f.k.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
values := NewValueSet()
|
||||
values.Add(NewIntValue(f.value))
|
||||
|
||||
return map[Key]ValueSet{
|
||||
f.k: values,
|
||||
}
|
||||
}
|
||||
|
||||
// numericGreaterThanEqualsFunc - String not equals function. It checks whether value by Key in
|
||||
// given values is NOT in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is NOT in values.
|
||||
type numericGreaterThanEqualsFunc struct {
|
||||
numericGreaterThanFunc
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is NOT in
|
||||
// condition values.
|
||||
func (f numericGreaterThanEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
rvInt, err := strconv.Atoi(requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return rvInt >= f.value
|
||||
}
|
||||
|
||||
// name() - returns "NumericGreaterThanEquals" condition name.
|
||||
func (f numericGreaterThanEqualsFunc) name() name {
|
||||
return numericGreaterThanEquals
|
||||
}
|
||||
|
||||
func (f numericGreaterThanEqualsFunc) String() string {
|
||||
return toNumericGreaterThanFuncString(numericGreaterThanEquals, f.numericGreaterThanFunc.k, f.numericGreaterThanFunc.value)
|
||||
}
|
||||
|
||||
// newNumericGreaterThanFunc - returns new NumericGreaterThan function.
|
||||
func newNumericGreaterThanFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToInt(numericGreaterThan, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewNumericGreaterThanFunc(key, v)
|
||||
}
|
||||
|
||||
// NewNumericGreaterThanFunc - returns new NumericGreaterThan function.
|
||||
func NewNumericGreaterThanFunc(key Key, value int) (Function, error) {
|
||||
return &numericGreaterThanFunc{key, value}, nil
|
||||
}
|
||||
|
||||
// newNumericGreaterThanEqualsFunc - returns new NumericGreaterThanEquals function.
|
||||
func newNumericGreaterThanEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToInt(numericGreaterThanEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewNumericGreaterThanEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewNumericGreaterThanEqualsFunc - returns new NumericGreaterThanEquals function.
|
||||
func NewNumericGreaterThanEqualsFunc(key Key, value int) (Function, error) {
|
||||
return &numericGreaterThanEqualsFunc{numericGreaterThanFunc{key, value}}, nil
|
||||
}
|
||||
153
pkg/bucket/policy/condition/numericlessfunc.go
Normal file
153
pkg/bucket/policy/condition/numericlessfunc.go
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* MinIO Cloud Storage, (C) 2020 MinIO, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package condition
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func toNumericLessThanFuncString(n name, key Key, value int) string {
|
||||
return fmt.Sprintf("%v:%v:%v", n, key, value)
|
||||
}
|
||||
|
||||
// numericLessThanFunc - String equals function. It checks whether value by Key in given
|
||||
// values map is in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is in values.
|
||||
type numericLessThanFunc struct {
|
||||
k Key
|
||||
value int
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is in
|
||||
// condition values.
|
||||
func (f numericLessThanFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
rvInt, err := strconv.Atoi(requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return rvInt < f.value
|
||||
}
|
||||
|
||||
// key() - returns condition key which is used by this condition function.
|
||||
func (f numericLessThanFunc) key() Key {
|
||||
return f.k
|
||||
}
|
||||
|
||||
// name() - returns "NumericLessThan" condition name.
|
||||
func (f numericLessThanFunc) name() name {
|
||||
return numericLessThan
|
||||
}
|
||||
|
||||
func (f numericLessThanFunc) String() string {
|
||||
return toNumericLessThanFuncString(numericLessThan, f.k, f.value)
|
||||
}
|
||||
|
||||
// toMap - returns map representation of this function.
|
||||
func (f numericLessThanFunc) toMap() map[Key]ValueSet {
|
||||
if !f.k.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
||||
values := NewValueSet()
|
||||
values.Add(NewIntValue(f.value))
|
||||
|
||||
return map[Key]ValueSet{
|
||||
f.k: values,
|
||||
}
|
||||
}
|
||||
|
||||
// numericLessThanEqualsFunc - String not equals function. It checks whether value by Key in
|
||||
// given values is NOT in condition values.
|
||||
// For example,
|
||||
// - if values = ["mybucket/foo"], at evaluate() it returns whether string
|
||||
// in value map for Key is NOT in values.
|
||||
type numericLessThanEqualsFunc struct {
|
||||
numericLessThanFunc
|
||||
}
|
||||
|
||||
// evaluate() - evaluates to check whether value by Key in given values is NOT in
|
||||
// condition values.
|
||||
func (f numericLessThanEqualsFunc) evaluate(values map[string][]string) bool {
|
||||
requestValue, ok := values[http.CanonicalHeaderKey(f.k.Name())]
|
||||
if !ok {
|
||||
requestValue = values[f.k.Name()]
|
||||
}
|
||||
|
||||
if len(requestValue) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
rvInt, err := strconv.Atoi(requestValue[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return rvInt <= f.value
|
||||
}
|
||||
|
||||
// name() - returns "NumericLessThanEquals" condition name.
|
||||
func (f numericLessThanEqualsFunc) name() name {
|
||||
return numericLessThanEquals
|
||||
}
|
||||
|
||||
func (f numericLessThanEqualsFunc) String() string {
|
||||
return toNumericLessThanFuncString(numericLessThanEquals, f.numericLessThanFunc.k, f.numericLessThanFunc.value)
|
||||
}
|
||||
|
||||
// newNumericLessThanFunc - returns new NumericLessThan function.
|
||||
func newNumericLessThanFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToInt(numericLessThan, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewNumericLessThanFunc(key, v)
|
||||
}
|
||||
|
||||
// NewNumericLessThanFunc - returns new NumericLessThan function.
|
||||
func NewNumericLessThanFunc(key Key, value int) (Function, error) {
|
||||
return &numericLessThanFunc{key, value}, nil
|
||||
}
|
||||
|
||||
// newNumericLessThanEqualsFunc - returns new NumericLessThanEquals function.
|
||||
func newNumericLessThanEqualsFunc(key Key, values ValueSet) (Function, error) {
|
||||
v, err := valueToInt(numericLessThanEquals, values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewNumericLessThanEqualsFunc(key, v)
|
||||
}
|
||||
|
||||
// NewNumericLessThanEqualsFunc - returns new NumericLessThanEquals function.
|
||||
func NewNumericLessThanEqualsFunc(key Key, value int) (Function, error) {
|
||||
return &numericLessThanEqualsFunc{numericLessThanFunc{key, value}}, nil
|
||||
}
|
||||
@@ -143,6 +143,10 @@ func validateStringEqualsValues(n name, key Key, values set.StringSet) error {
|
||||
if s != "COPY" && s != "REPLACE" {
|
||||
return fmt.Errorf("invalid value '%v' for '%v' for %v condition", s, S3XAmzMetadataDirective, n)
|
||||
}
|
||||
case S3XAmzContentSha256:
|
||||
if s == "" {
|
||||
return fmt.Errorf("invalid empty value for '%v' for %v condition", S3XAmzContentSha256, n)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user