mirror of
https://github.com/minio/minio.git
synced 2025-11-10 05:59:43 -05:00
policy: Add Merge API (#11793)
This commit adds a new API in pkg/bucket/policy package called Merge to merge multiple policies of a user or a group into one policy document.
This commit is contained in:
@@ -27,6 +27,11 @@ import (
|
||||
// ActionSet - set of actions.
|
||||
type ActionSet map[Action]struct{}
|
||||
|
||||
// Clone clones ActionSet structure
|
||||
func (actionSet ActionSet) Clone() ActionSet {
|
||||
return NewActionSet(actionSet.ToSlice()...)
|
||||
}
|
||||
|
||||
// Add - add action to the set.
|
||||
func (actionSet ActionSet) Add(action Action) {
|
||||
actionSet[action] = struct{}{}
|
||||
|
||||
@@ -151,23 +151,30 @@ func (iamp Policy) isValid() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Merge merges two policies documents and drop
|
||||
// duplicate statements if any.
|
||||
func (iamp Policy) Merge(input Policy) Policy {
|
||||
var mergedPolicy Policy
|
||||
if iamp.Version != "" {
|
||||
mergedPolicy.Version = iamp.Version
|
||||
} else {
|
||||
mergedPolicy.Version = input.Version
|
||||
}
|
||||
for _, st := range iamp.Statements {
|
||||
mergedPolicy.Statements = append(mergedPolicy.Statements, st.Clone())
|
||||
}
|
||||
for _, st := range input.Statements {
|
||||
mergedPolicy.Statements = append(mergedPolicy.Statements, st.Clone())
|
||||
}
|
||||
mergedPolicy.dropDuplicateStatements()
|
||||
return mergedPolicy
|
||||
}
|
||||
|
||||
func (iamp *Policy) dropDuplicateStatements() {
|
||||
redo:
|
||||
for i := range iamp.Statements {
|
||||
for j, statement := range iamp.Statements[i+1:] {
|
||||
if iamp.Statements[i].Effect != statement.Effect {
|
||||
continue
|
||||
}
|
||||
|
||||
if !iamp.Statements[i].Actions.Equals(statement.Actions) {
|
||||
continue
|
||||
}
|
||||
|
||||
if !iamp.Statements[i].Resources.Equals(statement.Resources) {
|
||||
continue
|
||||
}
|
||||
|
||||
if iamp.Statements[i].Conditions.String() != statement.Conditions.String() {
|
||||
if !iamp.Statements[i].Equals(statement) {
|
||||
continue
|
||||
}
|
||||
iamp.Statements = append(iamp.Statements[:j], iamp.Statements[j+1:]...)
|
||||
|
||||
@@ -154,6 +154,21 @@ func (resourceSet ResourceSet) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ToSlice - returns slice of resources from the resource set.
|
||||
func (resourceSet ResourceSet) ToSlice() []Resource {
|
||||
resources := []Resource{}
|
||||
for resource := range resourceSet {
|
||||
resources = append(resources, resource)
|
||||
}
|
||||
|
||||
return resources
|
||||
}
|
||||
|
||||
// Clone clones ResourceSet structure
|
||||
func (resourceSet ResourceSet) Clone() ResourceSet {
|
||||
return NewResourceSet(resourceSet.ToSlice()...)
|
||||
}
|
||||
|
||||
// NewResourceSet - creates new resource set.
|
||||
func NewResourceSet(resources ...Resource) ResourceSet {
|
||||
resourceSet := make(ResourceSet)
|
||||
|
||||
@@ -129,6 +129,29 @@ func (statement Statement) Validate() error {
|
||||
return statement.isValid()
|
||||
}
|
||||
|
||||
// Equals checks if two statements are equal
|
||||
func (statement Statement) Equals(st Statement) bool {
|
||||
if statement.Effect != st.Effect {
|
||||
return false
|
||||
}
|
||||
if !statement.Actions.Equals(st.Actions) {
|
||||
return false
|
||||
}
|
||||
if !statement.Resources.Equals(st.Resources) {
|
||||
return false
|
||||
}
|
||||
if !statement.Conditions.Equals(st.Conditions) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Clone clones Statement structure
|
||||
func (statement Statement) Clone() Statement {
|
||||
return NewStatement(statement.Effect, statement.Actions.Clone(),
|
||||
statement.Resources.Clone(), statement.Conditions.Clone())
|
||||
}
|
||||
|
||||
// NewStatement - creates new statement.
|
||||
func NewStatement(effect policy.Effect, actionSet ActionSet, resourceSet ResourceSet, conditions condition.Functions) Statement {
|
||||
return Statement{
|
||||
|
||||
Reference in New Issue
Block a user