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:
Anis Elleuch
2021-03-16 16:50:36 +01:00
committed by GitHub
parent 6160188bf3
commit fa94682e83
12 changed files with 279 additions and 31 deletions

View File

@@ -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{}{}

View File

@@ -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:]...)

View File

@@ -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)

View File

@@ -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{