forked from TrueCloudLab/frostfs-s3-gw
[#680] Drop GetContainer operation from policy converter
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
4d305d0d0f
commit
526ddc1243
2 changed files with 103 additions and 101 deletions
|
@ -1,7 +1,6 @@
|
|||
package iam
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -13,62 +12,62 @@ import (
|
|||
const PropertyKeyFilePath = "FilePath"
|
||||
|
||||
type nativeOperationInfo struct {
|
||||
operations []string
|
||||
needTreeWrite bool
|
||||
operations []string
|
||||
treeOperations []string
|
||||
}
|
||||
|
||||
var actionToNativeOpMap = map[string]nativeOperationInfo{
|
||||
s3common.S3ActionAbortMultipartUpload: {operations: []string{native.MethodGetContainer, native.MethodDeleteObject, native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}, needTreeWrite: true},
|
||||
s3common.S3ActionCreateBucket: {operations: []string{native.MethodGetContainer, native.MethodPutContainer, native.MethodSetContainerEACL}, needTreeWrite: true},
|
||||
s3common.S3ActionDeleteBucket: {operations: []string{native.MethodGetContainer, native.MethodDeleteContainer, native.MethodSearchObject, native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}, needTreeWrite: true},
|
||||
s3common.S3ActionDeleteBucketPolicy: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionDeleteObject: {operations: []string{native.MethodGetContainer, native.MethodDeleteObject, native.MethodPutObject, native.MethodHeadObject, native.MethodGetObject, native.MethodRangeObject}, needTreeWrite: true},
|
||||
s3common.S3ActionDeleteObjectTagging: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionDeleteObjectVersion: {operations: []string{native.MethodGetContainer, native.MethodDeleteObject, native.MethodPutObject, native.MethodHeadObject, native.MethodGetObject, native.MethodRangeObject}, needTreeWrite: true},
|
||||
s3common.S3ActionDeleteObjectVersionTagging: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionGetBucketACL: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetBucketCORS: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject}},
|
||||
s3common.S3ActionGetBucketLocation: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetBucketNotification: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject}}, // not supported
|
||||
s3common.S3ActionGetBucketObjectLockConfiguration: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetBucketPolicy: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetBucketPolicyStatus: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetBucketTagging: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetBucketVersioning: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetLifecycleConfiguration: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject}},
|
||||
s3common.S3ActionGetObject: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionGetObjectACL: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetObjectAttributes: {operations: []string{native.MethodGetContainer, native.MethodHeadObject}},
|
||||
s3common.S3ActionGetObjectLegalHold: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetObjectRetention: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetObjectTagging: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetObjectVersion: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionGetObjectVersionACL: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionGetObjectVersionAttributes: {operations: []string{native.MethodGetContainer, native.MethodHeadObject}},
|
||||
s3common.S3ActionGetObjectVersionTagging: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionListAllMyBuckets: {operations: []string{native.MethodListContainers, native.MethodGetContainer}},
|
||||
s3common.S3ActionListBucket: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionListBucketMultipartUploads: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionListBucketVersions: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionListMultipartUploadParts: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionPutBucketACL: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionPutBucketCORS: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodPutObject}, needTreeWrite: true},
|
||||
s3common.S3ActionPutBucketNotification: {operations: []string{native.MethodGetContainer, native.MethodHeadObject, native.MethodDeleteObject, native.MethodGetObject, native.MethodPutObject}, needTreeWrite: true}, // not supported
|
||||
s3common.S3ActionPutBucketObjectLockConfiguration: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionPutBucketPolicy: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionPutBucketTagging: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionPutBucketVersioning: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionPutLifecycleConfiguration: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodPutObject, native.MethodDeleteObject}, needTreeWrite: true},
|
||||
s3common.S3ActionPutObject: {operations: []string{native.MethodGetContainer, native.MethodPutObject, native.MethodGetObject, native.MethodHeadObject, native.MethodRangeObject}, needTreeWrite: true},
|
||||
s3common.S3ActionPutObjectACL: {operations: []string{native.MethodGetContainer}}, // not supported
|
||||
s3common.S3ActionPutObjectLegalHold: {operations: []string{native.MethodGetContainer, native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}, needTreeWrite: true},
|
||||
s3common.S3ActionPutObjectRetention: {operations: []string{native.MethodGetContainer, native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}, needTreeWrite: true},
|
||||
s3common.S3ActionPutObjectTagging: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionPutObjectVersionACL: {operations: []string{native.MethodGetContainer}}, // not supported
|
||||
s3common.S3ActionPutObjectVersionTagging: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionPatchObject: {operations: []string{native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodPatchObject, native.MethodPutObject, native.MethodRangeObject}, needTreeWrite: true},
|
||||
s3common.S3ActionPutBucketPublicAccessBlock: {operations: []string{native.MethodGetContainer}, needTreeWrite: true},
|
||||
s3common.S3ActionGetBucketPublicAccessBlock: {operations: []string{native.MethodGetContainer}},
|
||||
s3common.S3ActionAbortMultipartUpload: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodDeleteObject, native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionCreateBucket: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodPutContainer, native.MethodSetContainerEACL}},
|
||||
s3common.S3ActionDeleteBucket: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodDeleteContainer, native.MethodSearchObject, native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionDeleteBucketPolicy: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionDeleteObject: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodDeleteObject, native.MethodPutObject, native.MethodHeadObject, native.MethodGetObject, native.MethodRangeObject}},
|
||||
s3common.S3ActionDeleteObjectTagging: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionDeleteObjectVersion: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodDeleteObject, native.MethodPutObject, native.MethodHeadObject, native.MethodGetObject, native.MethodRangeObject}},
|
||||
s3common.S3ActionDeleteObjectVersionTagging: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionGetBucketACL: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetBucketCORS: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject}},
|
||||
s3common.S3ActionGetBucketLocation: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetBucketNotification: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject}}, // not supported
|
||||
s3common.S3ActionGetBucketObjectLockConfiguration: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetBucketPolicy: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetBucketPolicyStatus: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetBucketTagging: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetBucketVersioning: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetLifecycleConfiguration: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject}},
|
||||
s3common.S3ActionGetObject: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionGetObjectACL: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetObjectAttributes: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodHeadObject}},
|
||||
s3common.S3ActionGetObjectLegalHold: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetObjectRetention: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetObjectTagging: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetObjectVersion: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionGetObjectVersionACL: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionGetObjectVersionAttributes: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodHeadObject}},
|
||||
s3common.S3ActionGetObjectVersionTagging: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionListAllMyBuckets: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodListContainers}},
|
||||
s3common.S3ActionListBucket: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionListBucketMultipartUploads: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionListBucketVersions: {treeOperations: []string{native.MethodGetObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject}},
|
||||
s3common.S3ActionListMultipartUploadParts: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionPutBucketACL: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutBucketCORS: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutBucketNotification: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodHeadObject, native.MethodDeleteObject, native.MethodGetObject, native.MethodPutObject}}, // not supported
|
||||
s3common.S3ActionPutBucketObjectLockConfiguration: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutBucketPolicy: {treeOperations: []string{native.MethodGetObject}},
|
||||
s3common.S3ActionPutBucketTagging: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutBucketVersioning: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutLifecycleConfiguration: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject, native.MethodPutObject, native.MethodDeleteObject}},
|
||||
s3common.S3ActionPutObject: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodPutObject, native.MethodGetObject, native.MethodHeadObject, native.MethodRangeObject}},
|
||||
s3common.S3ActionPutObjectACL: {}, // not supported
|
||||
s3common.S3ActionPutObjectLegalHold: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutObjectRetention: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodHeadObject, native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutObjectTagging: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPutObjectVersionACL: {}, // not supported
|
||||
s3common.S3ActionPutObjectVersionTagging: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionPatchObject: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}, operations: []string{native.MethodGetObject, native.MethodHeadObject, native.MethodPatchObject, native.MethodPutObject, native.MethodRangeObject}},
|
||||
s3common.S3ActionPutBucketPublicAccessBlock: {treeOperations: []string{native.MethodGetObject, native.MethodPutObject}},
|
||||
s3common.S3ActionGetBucketPublicAccessBlock: {treeOperations: []string{native.MethodGetObject}},
|
||||
}
|
||||
|
||||
var containerNativeOperations = map[string]struct{}{
|
||||
|
@ -90,7 +89,7 @@ var objectNativeOperations = map[string]struct{}{
|
|||
native.MethodHashObject: {},
|
||||
}
|
||||
|
||||
var errConditionKeyNotApplicable = errors.New("condition key is not applicable")
|
||||
var treeNativeOperations = []string{native.MethodGetObject, native.MethodPutObject}
|
||||
|
||||
func ConvertToNativeChain(p s3common.Policy, resolver s3common.NativeResolver) (*chain.Chain, error) {
|
||||
if err := p.Validate(s3common.ResourceBasedPolicyType); err != nil {
|
||||
|
@ -109,37 +108,37 @@ func ConvertToNativeChain(p s3common.Policy, resolver s3common.NativeResolver) (
|
|||
}
|
||||
|
||||
action, actionInverted := statement.GetAction()
|
||||
nativeActions, treeWrite, err := formNativeActionNames(action)
|
||||
nativeActions, nativeTreeActions, err := formNativeActionNames(action)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ruleAction := chain.Actions{Inverted: actionInverted, Names: nativeActions}
|
||||
if len(ruleAction.Names) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
resource, resourceInverted := statement.GetResource()
|
||||
groupedResources, treeRes, err := formNativeResourceNamesAndConditions(resource, resolver, getActionTypes(nativeActions))
|
||||
groupedResources, treeRes, err := formNativeResourceNamesAndConditions(resource, resolver, getActionTypes(nativeActions, nativeTreeActions))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
groupedConditions, err := convertToNativeChainCondition(statement.Conditions, resolver)
|
||||
if err != nil {
|
||||
if errors.Is(err, errConditionKeyNotApplicable) {
|
||||
continue
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
splitConditions := s3common.SplitGroupedConditions(groupedConditions)
|
||||
|
||||
principals, principalCondFn, err := getNativePrincipalsAndConditionFunc(statement, resolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
engineChain.Rules = append(engineChain.Rules, getTreeRule(treeRes, principals, principalCondFn, treeWrite)...)
|
||||
if len(treeRes) != 0 {
|
||||
engineChain.Rules = append(engineChain.Rules, getTreeRule(treeRes, principals, principalCondFn, nativeTreeActions)...)
|
||||
}
|
||||
|
||||
if len(groupedResources) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
groupedConditions, err := convertToNativeChainCondition(statement.Conditions, resolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
splitConditions := s3common.SplitGroupedConditions(groupedConditions)
|
||||
|
||||
ruleAction := chain.Actions{Inverted: actionInverted, Names: nativeActions}
|
||||
for _, groupedResource := range groupedResources {
|
||||
for _, principal := range principals {
|
||||
for _, conditions := range splitConditions {
|
||||
|
@ -172,12 +171,7 @@ func ConvertToNativeChain(p s3common.Policy, resolver s3common.NativeResolver) (
|
|||
return &engineChain, nil
|
||||
}
|
||||
|
||||
func getTreeRule(resources []string, principals []string, principalCondFn s3common.FormPrincipalConditionFunc, needWrite bool) []chain.Rule {
|
||||
ops := []string{native.MethodGetObject}
|
||||
if needWrite {
|
||||
ops = append(ops, native.MethodPutObject)
|
||||
}
|
||||
|
||||
func getTreeRule(resources []string, principals []string, principalCondFn s3common.FormPrincipalConditionFunc, treeActions []string) []chain.Rule {
|
||||
treeCondition := chain.Condition{
|
||||
Op: chain.CondStringNotEquals,
|
||||
Kind: chain.KindResource,
|
||||
|
@ -197,7 +191,7 @@ func getTreeRule(resources []string, principals []string, principalCondFn s3comm
|
|||
if len(principalTreeConditions) == 0 {
|
||||
return []chain.Rule{{
|
||||
Status: chain.Allow,
|
||||
Actions: chain.Actions{Names: ops},
|
||||
Actions: chain.Actions{Names: treeActions},
|
||||
Resources: chain.Resources{Names: resources},
|
||||
Condition: []chain.Condition{treeCondition},
|
||||
}}
|
||||
|
@ -207,7 +201,7 @@ func getTreeRule(resources []string, principals []string, principalCondFn s3comm
|
|||
for i, condition := range principalTreeConditions {
|
||||
res[i] = chain.Rule{
|
||||
Status: chain.Allow,
|
||||
Actions: chain.Actions{Names: ops},
|
||||
Actions: chain.Actions{Names: treeActions},
|
||||
Resources: chain.Resources{Names: resources},
|
||||
Condition: []chain.Condition{treeCondition, condition},
|
||||
}
|
||||
|
@ -216,8 +210,8 @@ func getTreeRule(resources []string, principals []string, principalCondFn s3comm
|
|||
return res
|
||||
}
|
||||
|
||||
func getActionTypes(nativeActions []string) ActionTypes {
|
||||
var res ActionTypes
|
||||
func getActionTypes(nativeActions []string, treeActions []string) ActionTypes {
|
||||
res := ActionTypes{Tree: len(treeActions) != 0}
|
||||
for _, action := range nativeActions {
|
||||
if res.Object && res.Container {
|
||||
break
|
||||
|
@ -278,7 +272,8 @@ func convertToNativeChainCondition(c s3common.Conditions, resolver s3common.Nati
|
|||
for i := range gr.Conditions {
|
||||
switch {
|
||||
case gr.Conditions[i].Key == condKeyAWSMFAPresent:
|
||||
return s3common.GroupedConditions{}, errConditionKeyNotApplicable
|
||||
// MFA property exist only in S3 request (in AccessBox), so native protocol should not process such conditions.
|
||||
continue
|
||||
case gr.Conditions[i].Key == s3common.CondKeyAWSPrincipalARN:
|
||||
gr.Conditions[i].Key = native.PropertyKeyActorPublicKey
|
||||
val, err := formPrincipalKey(gr.Conditions[i].Value, resolver)
|
||||
|
@ -308,10 +303,11 @@ type GroupedResources struct {
|
|||
type ActionTypes struct {
|
||||
Object bool
|
||||
Container bool
|
||||
Tree bool
|
||||
}
|
||||
|
||||
func formNativeResourceNamesAndConditions(names []string, resolver s3common.NativeResolver, actionTypes ActionTypes) ([]GroupedResources, []string, error) {
|
||||
if !actionTypes.Object && !actionTypes.Container {
|
||||
if !actionTypes.Object && !actionTypes.Container && !actionTypes.Tree {
|
||||
return nil, nil, s3common.ErrActionsNotApplicable
|
||||
}
|
||||
|
||||
|
@ -356,7 +352,12 @@ func formNativeResourceNamesAndConditions(names []string, resolver s3common.Nati
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
treeResMap[fmt.Sprintf(native.ResourceFormatNamespaceContainerObjects, bktInfo.Namespace, bktInfo.Container)] = struct{}{}
|
||||
if actionTypes.Tree {
|
||||
treeResMap[fmt.Sprintf(native.ResourceFormatNamespaceContainerObjects, bktInfo.Namespace, bktInfo.Container)] = struct{}{}
|
||||
if !actionTypes.Object && !actionTypes.Container {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if obj == s3common.Wildcard && actionTypes.Object { // this corresponds to arn:aws:s3:::BUCKET/ or arn:aws:s3:::BUCKET/*
|
||||
combined[fmt.Sprintf(native.ResourceFormatNamespaceContainerObjects, bktInfo.Namespace, bktInfo.Container)] = struct{}{}
|
||||
|
@ -440,18 +441,18 @@ func formPrincipalKey(principal string, resolver s3common.NativeResolver) (strin
|
|||
return key, nil
|
||||
}
|
||||
|
||||
func formNativeActionNames(names []string) ([]string, bool, error) {
|
||||
func formNativeActionNames(names []string) ([]string, []string, error) {
|
||||
uniqueActions := make(map[string]struct{}, len(names))
|
||||
|
||||
var treeWrite bool
|
||||
var treeActions []string
|
||||
for _, action := range names {
|
||||
if action == s3common.Wildcard {
|
||||
return []string{s3common.Wildcard}, true, nil
|
||||
return []string{s3common.Wildcard}, treeNativeOperations, nil
|
||||
}
|
||||
|
||||
isIAM, err := s3common.ValidateAction(action)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if isIAM {
|
||||
|
@ -459,15 +460,16 @@ func formNativeActionNames(names []string) ([]string, bool, error) {
|
|||
}
|
||||
|
||||
if action[len(s3common.S3ActionPrefix):] == s3common.Wildcard {
|
||||
return []string{s3common.Wildcard}, true, nil
|
||||
return []string{s3common.Wildcard}, treeNativeOperations, nil
|
||||
}
|
||||
|
||||
nativeActions := actionToNativeOpMap[action]
|
||||
if nativeActions.needTreeWrite {
|
||||
treeWrite = true
|
||||
if len(nativeActions.operations) == 0 && len(nativeActions.treeOperations) == 0 {
|
||||
return nil, nil, s3common.ErrActionsNotApplicable
|
||||
}
|
||||
if len(nativeActions.operations) == 0 {
|
||||
return nil, false, s3common.ErrActionsNotApplicable
|
||||
|
||||
if len(nativeActions.treeOperations) > len(treeActions) {
|
||||
treeActions = nativeActions.treeOperations
|
||||
}
|
||||
|
||||
for _, nativeAction := range nativeActions.operations {
|
||||
|
@ -480,5 +482,5 @@ func formNativeActionNames(names []string) ([]string, bool, error) {
|
|||
res = append(res, key)
|
||||
}
|
||||
|
||||
return res, treeWrite, nil
|
||||
return res, treeActions, nil
|
||||
}
|
||||
|
|
|
@ -160,7 +160,7 @@ func TestConverters(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Status: chain.Allow,
|
||||
Actions: chain.Actions{Names: []string{native.MethodGetContainer, native.MethodPutObject,
|
||||
Actions: chain.Actions{Names: []string{native.MethodPutObject,
|
||||
native.MethodGetObject, native.MethodHeadObject, native.MethodRangeObject}},
|
||||
Resources: chain.Resources{Names: []string{
|
||||
fmt.Sprintf(native.ResourceFormatNamespaceContainerObjects, namespace, mockResolver.containers[bktName]),
|
||||
|
@ -257,7 +257,7 @@ func TestConverters(t *testing.T) {
|
|||
{
|
||||
Status: chain.Allow,
|
||||
Actions: chain.Actions{Names: []string{
|
||||
native.MethodGetContainer, native.MethodDeleteContainer,
|
||||
native.MethodDeleteContainer,
|
||||
native.MethodSearchObject, native.MethodHeadObject,
|
||||
native.MethodDeleteObject, native.MethodPutObject,
|
||||
native.MethodGetObject, native.MethodRangeObject,
|
||||
|
@ -284,7 +284,7 @@ func TestConverters(t *testing.T) {
|
|||
{
|
||||
Status: chain.Allow,
|
||||
Actions: chain.Actions{Names: []string{
|
||||
native.MethodGetContainer, native.MethodDeleteContainer,
|
||||
native.MethodDeleteContainer,
|
||||
native.MethodSearchObject, native.MethodHeadObject,
|
||||
native.MethodDeleteObject, native.MethodPutObject,
|
||||
native.MethodGetObject, native.MethodRangeObject,
|
||||
|
@ -421,8 +421,8 @@ func TestConverters(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Status: chain.Allow,
|
||||
Actions: chain.Actions{Names: []string{native.MethodGetContainer, native.MethodDeleteObject, native.MethodPutObject, native.MethodHeadObject, native.MethodGetObject, native.MethodRangeObject}},
|
||||
Resources: chain.Resources{Names: []string{native.ResourceFormatAllObjects, native.ResourceFormatAllContainers}},
|
||||
Actions: chain.Actions{Names: []string{native.MethodDeleteObject, native.MethodPutObject, native.MethodHeadObject, native.MethodGetObject, native.MethodRangeObject}},
|
||||
Resources: chain.Resources{Names: []string{native.ResourceFormatAllObjects}},
|
||||
Condition: []chain.Condition{{
|
||||
Op: chain.CondStringEquals,
|
||||
Kind: chain.KindRequest,
|
||||
|
@ -1752,7 +1752,7 @@ func TestFromActions(t *testing.T) {
|
|||
},
|
||||
{
|
||||
action: "s3:PutObject",
|
||||
res: []string{native.MethodGetContainer, native.MethodPutObject,
|
||||
res: []string{native.MethodPutObject,
|
||||
native.MethodGetObject, native.MethodHeadObject, native.MethodRangeObject},
|
||||
},
|
||||
{
|
||||
|
@ -2095,7 +2095,7 @@ func TestMFACondition(t *testing.T) {
|
|||
require.ElementsMatch(t, expectedConditions, s3Chain.Rules[0].Condition)
|
||||
|
||||
_, err = ConvertToNativeChain(p, newMockUserResolver(nil, nil, ""))
|
||||
require.ErrorIs(t, err, s3common.ErrActionsNotApplicable)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue