storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/bucket/policy/actionset.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 policy
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"sort"
    23  
    24  	"github.com/minio/minio-go/v7/pkg/set"
    25  )
    26  
    27  // ActionSet - set of actions.
    28  type ActionSet map[Action]struct{}
    29  
    30  // Add - add action to the set.
    31  func (actionSet ActionSet) Add(action Action) {
    32  	actionSet[action] = struct{}{}
    33  }
    34  
    35  // Contains - checks given action exists in the action set.
    36  func (actionSet ActionSet) Contains(action Action) bool {
    37  	_, found := actionSet[action]
    38  	return found
    39  }
    40  
    41  // Equals - checks whether given action set is equal to current action set or not.
    42  func (actionSet ActionSet) Equals(sactionSet ActionSet) bool {
    43  	// If length of set is not equal to length of given set, the
    44  	// set is not equal to given set.
    45  	if len(actionSet) != len(sactionSet) {
    46  		return false
    47  	}
    48  
    49  	// As both sets are equal in length, check each elements are equal.
    50  	for k := range actionSet {
    51  		if _, ok := sactionSet[k]; !ok {
    52  			return false
    53  		}
    54  	}
    55  
    56  	return true
    57  }
    58  
    59  // Intersection - returns actions available in both ActionSet.
    60  func (actionSet ActionSet) Intersection(sset ActionSet) ActionSet {
    61  	nset := NewActionSet()
    62  	for k := range actionSet {
    63  		if _, ok := sset[k]; ok {
    64  			nset.Add(k)
    65  		}
    66  	}
    67  
    68  	return nset
    69  }
    70  
    71  // MarshalJSON - encodes ActionSet to JSON data.
    72  func (actionSet ActionSet) MarshalJSON() ([]byte, error) {
    73  	if len(actionSet) == 0 {
    74  		return nil, Errorf("empty actions not allowed")
    75  	}
    76  
    77  	return json.Marshal(actionSet.ToSlice())
    78  }
    79  
    80  func (actionSet ActionSet) String() string {
    81  	actions := []string{}
    82  	for action := range actionSet {
    83  		actions = append(actions, string(action))
    84  	}
    85  	sort.Strings(actions)
    86  
    87  	return fmt.Sprintf("%v", actions)
    88  }
    89  
    90  // ToSlice - returns slice of actions from the action set.
    91  func (actionSet ActionSet) ToSlice() []Action {
    92  	actions := []Action{}
    93  	for action := range actionSet {
    94  		actions = append(actions, action)
    95  	}
    96  	return actions
    97  }
    98  
    99  // Clone clones ActionSet structure
   100  func (actionSet ActionSet) Clone() ActionSet {
   101  	return NewActionSet(actionSet.ToSlice()...)
   102  }
   103  
   104  // UnmarshalJSON - decodes JSON data to ActionSet.
   105  func (actionSet *ActionSet) UnmarshalJSON(data []byte) error {
   106  	var sset set.StringSet
   107  	if err := json.Unmarshal(data, &sset); err != nil {
   108  		return err
   109  	}
   110  
   111  	if len(sset) == 0 {
   112  		return Errorf("empty actions not allowed")
   113  	}
   114  
   115  	*actionSet = make(ActionSet)
   116  	for _, s := range sset.ToSlice() {
   117  		action, err := parseAction(s)
   118  		if err != nil {
   119  			return err
   120  		}
   121  
   122  		actionSet.Add(action)
   123  	}
   124  
   125  	return nil
   126  }
   127  
   128  // NewActionSet - creates new action set.
   129  func NewActionSet(actions ...Action) ActionSet {
   130  	actionSet := make(ActionSet)
   131  	for _, action := range actions {
   132  		actionSet.Add(action)
   133  	}
   134  
   135  	return actionSet
   136  }