mirror of https://github.com/minio/minio.git
169 lines
4.1 KiB
Go
169 lines
4.1 KiB
Go
|
/*
|
||
|
* Minio Cloud Storage, (C) 2018 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 (
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"sort"
|
||
|
)
|
||
|
|
||
|
// Function - condition function interface.
|
||
|
type Function interface {
|
||
|
// evaluate() - evaluates this condition function with given values.
|
||
|
evaluate(values map[string][]string) bool
|
||
|
|
||
|
// key() - returns condition key used in this function.
|
||
|
key() Key
|
||
|
|
||
|
// name() - returns condition name of this function.
|
||
|
name() name
|
||
|
|
||
|
// String() - returns string representation of function.
|
||
|
String() string
|
||
|
|
||
|
// toMap - returns map representation of this function.
|
||
|
toMap() map[Key]ValueSet
|
||
|
}
|
||
|
|
||
|
// Functions - list of functions.
|
||
|
type Functions []Function
|
||
|
|
||
|
// Evaluate - evaluates all functions with given values map. Each function is evaluated
|
||
|
// sequencely and next function is called only if current function succeeds.
|
||
|
func (functions Functions) Evaluate(values map[string][]string) bool {
|
||
|
for _, f := range functions {
|
||
|
if !f.evaluate(values) {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
// Keys - returns list of keys used in all functions.
|
||
|
func (functions Functions) Keys() KeySet {
|
||
|
keySet := NewKeySet()
|
||
|
|
||
|
for _, f := range functions {
|
||
|
keySet.Add(f.key())
|
||
|
}
|
||
|
|
||
|
return keySet
|
||
|
}
|
||
|
|
||
|
// MarshalJSON - encodes Functions to JSON data.
|
||
|
func (functions Functions) MarshalJSON() ([]byte, error) {
|
||
|
nm := make(map[name]map[Key]ValueSet)
|
||
|
|
||
|
for _, f := range functions {
|
||
|
nm[f.name()] = f.toMap()
|
||
|
}
|
||
|
|
||
|
return json.Marshal(nm)
|
||
|
}
|
||
|
|
||
|
func (functions Functions) String() string {
|
||
|
funcStrings := []string{}
|
||
|
for _, f := range functions {
|
||
|
s := fmt.Sprintf("%v", f)
|
||
|
funcStrings = append(funcStrings, s)
|
||
|
}
|
||
|
sort.Strings(funcStrings)
|
||
|
|
||
|
return fmt.Sprintf("%v", funcStrings)
|
||
|
}
|
||
|
|
||
|
// UnmarshalJSON - decodes JSON data to Functions.
|
||
|
func (functions *Functions) UnmarshalJSON(data []byte) error {
|
||
|
// As string kind, int kind then json.Unmarshaler is checked at
|
||
|
// https://github.com/golang/go/blob/master/src/encoding/json/decode.go#L618
|
||
|
// UnmarshalJSON() is not called for types extending string
|
||
|
// see https://play.golang.org/p/HrSsKksHvrS, better way to do is
|
||
|
// https://play.golang.org/p/y9ElWpBgVAB
|
||
|
//
|
||
|
// Due to this issue, name and Key types cannot be used as map keys below.
|
||
|
nm := make(map[string]map[string]ValueSet)
|
||
|
if err := json.Unmarshal(data, &nm); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if len(nm) == 0 {
|
||
|
return fmt.Errorf("condition must not be empty")
|
||
|
}
|
||
|
|
||
|
funcs := []Function{}
|
||
|
for nameString, args := range nm {
|
||
|
n, err := parseName(nameString)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
for keyString, values := range args {
|
||
|
key, err := parseKey(keyString)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
var f Function
|
||
|
switch n {
|
||
|
case stringEquals:
|
||
|
if f, err = newStringEqualsFunc(key, values); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
case stringNotEquals:
|
||
|
if f, err = newStringNotEqualsFunc(key, values); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
case stringLike:
|
||
|
if f, err = newStringLikeFunc(key, values); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
case stringNotLike:
|
||
|
if f, err = newStringNotLikeFunc(key, values); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
case ipAddress:
|
||
|
if f, err = newIPAddressFunc(key, values); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
case notIPAddress:
|
||
|
if f, err = newNotIPAddressFunc(key, values); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
case null:
|
||
|
if f, err = newNullFunc(key, values); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
default:
|
||
|
return fmt.Errorf("%v is not handled", n)
|
||
|
}
|
||
|
|
||
|
funcs = append(funcs, f)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
*functions = funcs
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// NewFunctions - returns new Functions with given function list.
|
||
|
func NewFunctions(functions ...Function) Functions {
|
||
|
return Functions(functions)
|
||
|
}
|