forked from TrueCloudLab/policy-engine
[#46] iam: Support more s3 to native actions mapping
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
af388779a3
commit
1cdb3e5a4a
2 changed files with 43 additions and 57 deletions
|
@ -10,15 +10,17 @@ import (
|
||||||
|
|
||||||
const PropertyKeyFilePath = "FilePath"
|
const PropertyKeyFilePath = "FilePath"
|
||||||
|
|
||||||
var actionToOpMap = map[string][]string{
|
var supportedActionToNativeOpMap = map[string][]string{
|
||||||
supportedS3ActionDeleteObject: {native.MethodDeleteObject},
|
supportedS3NativeActionDeleteObject: {native.MethodDeleteObject},
|
||||||
supportedS3ActionGetObject: {native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject},
|
supportedS3NativeActionGetObject: {native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject},
|
||||||
supportedS3ActionHeadObject: {native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject},
|
supportedS3NativeActionPutObject: {native.MethodPutObject},
|
||||||
supportedS3ActionPutObject: {native.MethodPutObject},
|
supportedS3NativeActionListBucket: {native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject},
|
||||||
supportedS3ActionListBucket: {native.MethodGetContainer, native.MethodGetObject, native.MethodHeadObject, native.MethodSearchObject, native.MethodRangeObject, native.MethodHashObject},
|
|
||||||
|
|
||||||
supportedS3ActionCreateBucket: {native.MethodPutContainer},
|
supportedS3NativeActionCreateBucket: {native.MethodPutContainer},
|
||||||
supportedS3ActionDeleteBucket: {native.MethodDeleteContainer},
|
supportedS3NativeActionDeleteBucket: {native.MethodDeleteContainer},
|
||||||
|
supportedS3NativeActionListAllMyBucket: {native.MethodListContainers},
|
||||||
|
supportedS3NativeActionPutBucketACL: {native.MethodSetContainerEACL},
|
||||||
|
supportedS3NativeActionGetBucketACL: {native.MethodGetContainerEACL},
|
||||||
}
|
}
|
||||||
|
|
||||||
var containerNativeOperations = map[string]struct{}{
|
var containerNativeOperations = map[string]struct{}{
|
||||||
|
@ -41,14 +43,16 @@ var objectNativeOperations = map[string]struct{}{
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
supportedS3ActionDeleteObject = "s3:DeleteObject"
|
supportedS3NativeActionDeleteObject = "s3:DeleteObject"
|
||||||
supportedS3ActionGetObject = "s3:GetObject"
|
supportedS3NativeActionGetObject = "s3:GetObject"
|
||||||
supportedS3ActionHeadObject = "s3:HeadObject"
|
supportedS3NativeActionPutObject = "s3:PutObject"
|
||||||
supportedS3ActionPutObject = "s3:PutObject"
|
supportedS3NativeActionListBucket = "s3:ListBucket"
|
||||||
supportedS3ActionListBucket = "s3:ListBucket"
|
|
||||||
|
|
||||||
supportedS3ActionCreateBucket = "s3:CreateBucket"
|
supportedS3NativeActionCreateBucket = "s3:CreateBucket"
|
||||||
supportedS3ActionDeleteBucket = "s3:DeleteBucket"
|
supportedS3NativeActionDeleteBucket = "s3:DeleteBucket"
|
||||||
|
supportedS3NativeActionListAllMyBucket = "s3:ListAllMyBuckets"
|
||||||
|
supportedS3NativeActionPutBucketACL = "s3:PutBucketAcl"
|
||||||
|
supportedS3NativeActionGetBucketACL = "s3:GetBucketAcl"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NativeResolver interface {
|
type NativeResolver interface {
|
||||||
|
@ -342,7 +346,7 @@ func formNativeActionNames(names []string) ([]string, error) {
|
||||||
return []string{Wildcard}, nil
|
return []string{Wildcard}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
res = append(res, actionToOpMap[action]...)
|
res = append(res, supportedActionToNativeOpMap[action]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
|
|
|
@ -154,40 +154,6 @@ func TestConverters(t *testing.T) {
|
||||||
require.Equal(t, expected, nativeChain)
|
require.Equal(t, expected, nativeChain)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("valid native policy with container resources", func(t *testing.T) {
|
|
||||||
p := Policy{
|
|
||||||
Version: "2012-10-17",
|
|
||||||
Statement: []Statement{{
|
|
||||||
Principal: map[PrincipalType][]string{
|
|
||||||
AWSPrincipalType: {principal},
|
|
||||||
},
|
|
||||||
Effect: AllowEffect,
|
|
||||||
Action: []string{"s3:PutObject"},
|
|
||||||
Resource: []string{resource},
|
|
||||||
}},
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := &chain.Chain{Rules: []chain.Rule{
|
|
||||||
{
|
|
||||||
Status: chain.Allow,
|
|
||||||
Actions: chain.Actions{Names: []string{native.MethodPutObject}},
|
|
||||||
Resources: chain.Resources{Names: []string{fmt.Sprintf(native.ResourceFormatNamespaceContainerObjects, namespace, mockResolver.containers[bktName])}},
|
|
||||||
Condition: []chain.Condition{
|
|
||||||
{
|
|
||||||
Op: chain.CondStringEquals,
|
|
||||||
Object: chain.ObjectRequest,
|
|
||||||
Key: native.PropertyKeyActorPublicKey,
|
|
||||||
Value: mockResolver.users[user],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
|
|
||||||
nativeChain, err := ConvertToNativeChain(p, mockResolver)
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, expected, nativeChain)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("valid inverted policy", func(t *testing.T) {
|
t.Run("valid inverted policy", func(t *testing.T) {
|
||||||
p := Policy{
|
p := Policy{
|
||||||
Version: "2012-10-17",
|
Version: "2012-10-17",
|
||||||
|
@ -222,7 +188,7 @@ func TestConverters(t *testing.T) {
|
||||||
require.Equal(t, expected, s3Chain)
|
require.Equal(t, expected, s3Chain)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("valid policy map get action", func(t *testing.T) {
|
t.Run("valid native policy map action", func(t *testing.T) {
|
||||||
p := Policy{
|
p := Policy{
|
||||||
Version: "2012-10-17",
|
Version: "2012-10-17",
|
||||||
Statement: []Statement{{
|
Statement: []Statement{{
|
||||||
|
@ -230,16 +196,19 @@ func TestConverters(t *testing.T) {
|
||||||
AWSPrincipalType: {principal},
|
AWSPrincipalType: {principal},
|
||||||
},
|
},
|
||||||
Effect: DenyEffect,
|
Effect: DenyEffect,
|
||||||
NotAction: []string{"s3:GetObject"},
|
Action: []string{"s3:DeleteObject", "s3:DeleteBucket"},
|
||||||
NotResource: []string{fmt.Sprintf(s3.ResourceFormatS3BucketObject, bktName, objName)},
|
Resource: []string{
|
||||||
|
fmt.Sprintf(s3.ResourceFormatS3BucketObject, bktName, objName),
|
||||||
|
fmt.Sprintf(s3.ResourceFormatS3Bucket, bktName),
|
||||||
|
},
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := &chain.Chain{Rules: []chain.Rule{
|
expected := &chain.Chain{Rules: []chain.Rule{
|
||||||
{
|
{
|
||||||
Status: chain.AccessDenied,
|
Status: chain.AccessDenied,
|
||||||
Actions: chain.Actions{Inverted: true, Names: actionToOpMap["s3:GetObject"]},
|
Actions: chain.Actions{Names: []string{native.MethodDeleteObject, native.MethodDeleteContainer}},
|
||||||
Resources: chain.Resources{Inverted: true, Names: []string{
|
Resources: chain.Resources{Names: []string{
|
||||||
fmt.Sprintf(native.ResourceFormatNamespaceContainerObjects, namespace, mockResolver.containers[bktName]),
|
fmt.Sprintf(native.ResourceFormatNamespaceContainerObjects, namespace, mockResolver.containers[bktName]),
|
||||||
}},
|
}},
|
||||||
Condition: []chain.Condition{
|
Condition: []chain.Condition{
|
||||||
|
@ -257,6 +226,19 @@ func TestConverters(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Status: chain.AccessDenied,
|
||||||
|
Actions: chain.Actions{Names: []string{native.MethodDeleteObject, native.MethodDeleteContainer}},
|
||||||
|
Resources: chain.Resources{Names: []string{
|
||||||
|
fmt.Sprintf(native.ResourceFormatNamespaceContainer, namespace, mockResolver.containers[bktName]),
|
||||||
|
}},
|
||||||
|
Condition: []chain.Condition{{
|
||||||
|
Op: chain.CondStringEquals,
|
||||||
|
Object: chain.ObjectRequest,
|
||||||
|
Key: native.PropertyKeyActorPublicKey,
|
||||||
|
Value: mockResolver.users[user],
|
||||||
|
}},
|
||||||
|
},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
nativeChain, err := ConvertToNativeChain(p, mockResolver)
|
nativeChain, err := ConvertToNativeChain(p, mockResolver)
|
||||||
|
@ -660,7 +642,7 @@ func TestComplexNativeConditions(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedStatus := chain.AccessDenied
|
expectedStatus := chain.AccessDenied
|
||||||
expectedActions := chain.Actions{Names: actionToOpMap["s3:"+action]}
|
expectedActions := chain.Actions{Names: supportedActionToNativeOpMap["s3:"+action]}
|
||||||
expectedResource1 := chain.Resources{Names: []string{nativeResource1}}
|
expectedResource1 := chain.Resources{Names: []string{nativeResource1}}
|
||||||
expectedResource23 := chain.Resources{Names: []string{nativeResource2, nativeResource3}}
|
expectedResource23 := chain.Resources{Names: []string{nativeResource2, nativeResource3}}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue