forked from TrueCloudLab/policy-engine
[#46] iam: Shrink rules for wildcard cases
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
8cc5173d73
commit
af388779a3
3 changed files with 81 additions and 19 deletions
|
@ -101,7 +101,12 @@ func ConvertToNativeChain(p Policy, resolver NativeResolver) (*chain.Chain, erro
|
||||||
for _, groupedResource := range groupedResources {
|
for _, groupedResource := range groupedResources {
|
||||||
for _, principal := range principals {
|
for _, principal := range principals {
|
||||||
for _, conditions := range splitConditions {
|
for _, conditions := range splitConditions {
|
||||||
ruleConditions := append([]chain.Condition{principalCondFn(principal)}, groupedResource.Conditions...)
|
var principalCondition []chain.Condition
|
||||||
|
if principal != Wildcard {
|
||||||
|
principalCondition = []chain.Condition{principalCondFn(principal)}
|
||||||
|
}
|
||||||
|
|
||||||
|
ruleConditions := append(principalCondition, groupedResource.Conditions...)
|
||||||
|
|
||||||
r := chain.Rule{
|
r := chain.Rule{
|
||||||
Status: status,
|
Status: status,
|
||||||
|
@ -220,13 +225,7 @@ func formNativeResourceNamesAndConditions(names []string, resolver NativeResolve
|
||||||
|
|
||||||
if resource == Wildcard {
|
if resource == Wildcard {
|
||||||
res = res[:0]
|
res = res[:0]
|
||||||
if actionTypes.Object {
|
return append(res, formWildcardNativeResource(actionTypes)), nil
|
||||||
res = append(res, GroupedResources{Names: []string{native.ResourceFormatAllObjects}})
|
|
||||||
}
|
|
||||||
if actionTypes.Container {
|
|
||||||
res = append(res, GroupedResources{Names: []string{native.ResourceFormatAllContainers}})
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !strings.HasPrefix(resource, s3ResourcePrefix) {
|
if !strings.HasPrefix(resource, s3ResourcePrefix) {
|
||||||
|
@ -237,13 +236,7 @@ func formNativeResourceNamesAndConditions(names []string, resolver NativeResolve
|
||||||
s3Resource := strings.TrimPrefix(resource, s3ResourcePrefix)
|
s3Resource := strings.TrimPrefix(resource, s3ResourcePrefix)
|
||||||
if s3Resource == Wildcard {
|
if s3Resource == Wildcard {
|
||||||
res = res[:0]
|
res = res[:0]
|
||||||
if actionTypes.Object {
|
return append(res, formWildcardNativeResource(actionTypes)), nil
|
||||||
res = append(res, GroupedResources{Names: []string{native.ResourceFormatAllObjects}})
|
|
||||||
}
|
|
||||||
if actionTypes.Container {
|
|
||||||
res = append(res, GroupedResources{Names: []string{native.ResourceFormatAllContainers}})
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if sepIndex := strings.Index(s3Resource, "/"); sepIndex < 0 {
|
if sepIndex := strings.Index(s3Resource, "/"); sepIndex < 0 {
|
||||||
|
@ -290,6 +283,18 @@ func formNativeResourceNamesAndConditions(names []string, resolver NativeResolve
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formWildcardNativeResource(actionTypes ActionTypes) GroupedResources {
|
||||||
|
groupedNames := make([]string, 0, 2)
|
||||||
|
if actionTypes.Object {
|
||||||
|
groupedNames = append(groupedNames, native.ResourceFormatAllObjects)
|
||||||
|
}
|
||||||
|
if actionTypes.Container {
|
||||||
|
groupedNames = append(groupedNames, native.ResourceFormatAllContainers)
|
||||||
|
}
|
||||||
|
|
||||||
|
return GroupedResources{Names: groupedNames}
|
||||||
|
}
|
||||||
|
|
||||||
func formNativePrincipal(principal []string, resolver NativeResolver) ([]string, error) {
|
func formNativePrincipal(principal []string, resolver NativeResolver) ([]string, error) {
|
||||||
res := make([]string, len(principal))
|
res := make([]string, len(principal))
|
||||||
|
|
||||||
|
|
|
@ -49,11 +49,16 @@ func ConvertToS3Chain(p Policy, resolver S3Resolver) (*chain.Chain, error) {
|
||||||
|
|
||||||
for _, principal := range principals {
|
for _, principal := range principals {
|
||||||
for _, conditions := range splitConditions {
|
for _, conditions := range splitConditions {
|
||||||
|
var principalCondition []chain.Condition
|
||||||
|
if principal != Wildcard {
|
||||||
|
principalCondition = []chain.Condition{principalCondFn(principal)}
|
||||||
|
}
|
||||||
|
|
||||||
r := chain.Rule{
|
r := chain.Rule{
|
||||||
Status: status,
|
Status: status,
|
||||||
Actions: ruleAction,
|
Actions: ruleAction,
|
||||||
Resources: ruleResource,
|
Resources: ruleResource,
|
||||||
Condition: append([]chain.Condition{principalCondFn(principal)}, conditions...),
|
Condition: append(principalCondition, conditions...),
|
||||||
}
|
}
|
||||||
engineChain.Rules = append(engineChain.Rules, r)
|
engineChain.Rules = append(engineChain.Rules, r)
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,6 +154,40 @@ 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",
|
||||||
|
@ -1190,11 +1224,29 @@ func TestWildcardConverters(t *testing.T) {
|
||||||
err := json.Unmarshal([]byte(policy), &p)
|
err := json.Unmarshal([]byte(policy), &p)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
_, err = ConvertToS3Chain(p, newMockUserResolver(nil, nil, ""))
|
s3Expected := &chain.Chain{
|
||||||
require.NoError(t, err)
|
Rules: []chain.Rule{{
|
||||||
|
Status: chain.Allow,
|
||||||
|
Actions: chain.Actions{Names: []string{Wildcard}},
|
||||||
|
Resources: chain.Resources{Names: []string{Wildcard}},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
_, err = ConvertToNativeChain(p, newMockUserResolver(nil, nil, ""))
|
s3Chain, err := ConvertToS3Chain(p, newMockUserResolver(nil, nil, ""))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, s3Expected, s3Chain)
|
||||||
|
|
||||||
|
nativeExpected := &chain.Chain{
|
||||||
|
Rules: []chain.Rule{{
|
||||||
|
Status: chain.Allow,
|
||||||
|
Actions: chain.Actions{Names: []string{Wildcard}},
|
||||||
|
Resources: chain.Resources{Names: []string{native.ResourceFormatAllObjects, native.ResourceFormatAllContainers}},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
|
||||||
|
nativeChain, err := ConvertToNativeChain(p, newMockUserResolver(nil, nil, ""))
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, nativeExpected, nativeChain)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestActionParsing(t *testing.T) {
|
func TestActionParsing(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue