[#1501] cli: Move APE-chain parser methods to pkg/util
Signed-off-by: Airat Arifullin <a.arifullin@yadro.com>
This commit is contained in:
parent
ae31ef3602
commit
ffe9906266
6 changed files with 10 additions and 10 deletions
319
pkg/util/ape/parser_test.go
Normal file
319
pkg/util/ape/parser_test.go
Normal file
|
@ -0,0 +1,319 @@
|
|||
package ape
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestParseAPERule(t *testing.T) {
|
||||
tests := [...]struct {
|
||||
name string
|
||||
rule string
|
||||
expectErr error
|
||||
expectRule policyengine.Rule
|
||||
}{
|
||||
{
|
||||
name: "Valid allow rule for all objects",
|
||||
rule: "allow Object.Put *",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatAllObjects}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all objects in implicit root namespace",
|
||||
rule: "allow Object.Put /*",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all objects in explicit root namespace",
|
||||
rule: "allow Object.Put root/*",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all objects in root namespace and container",
|
||||
rule: "allow Object.Put /cid/*",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatRootContainerObjects, "cid"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for object in root namespace and container",
|
||||
rule: "allow Object.Put /cid/oid",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatRootContainerObject, "cid", "oid"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all objects in namespace",
|
||||
rule: "allow Object.Put ns/*",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatNamespaceObjects, "ns"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all objects in namespace and container",
|
||||
rule: "allow Object.Put ns/cid/*",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainerObjects, "ns", "cid"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for object in namespace and container",
|
||||
rule: "allow Object.Put ns/cid/oid",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainerObject, "ns", "cid", "oid"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid deny rule",
|
||||
rule: "deny Object.Put *",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.AccessDenied,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatAllObjects}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid deny rule with action detail",
|
||||
rule: "deny:QuotaLimitReached Object.Put *",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.QuotaLimitReached,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatAllObjects}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid allow rule with conditions",
|
||||
rule: "allow Object.Get ResourceCondition:Department=HR RequestCondition:Actor!=ownerA *",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodGetObject}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatAllObjects}},
|
||||
Condition: []policyengine.Condition{
|
||||
{
|
||||
Op: policyengine.CondStringEquals,
|
||||
Kind: policyengine.KindResource,
|
||||
Key: "Department",
|
||||
Value: "HR",
|
||||
},
|
||||
{
|
||||
Op: policyengine.CondStringNotEquals,
|
||||
Kind: policyengine.KindRequest,
|
||||
Key: "Actor",
|
||||
Value: "ownerA",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for object with conditions with action detail",
|
||||
rule: "deny:QuotaLimitReached Object.Get ResourceCondition:Department=HR RequestCondition:Actor!=ownerA *",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.QuotaLimitReached,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodGetObject}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatAllObjects}},
|
||||
Condition: []policyengine.Condition{
|
||||
{
|
||||
Op: policyengine.CondStringEquals,
|
||||
Kind: policyengine.KindResource,
|
||||
Key: "Department",
|
||||
Value: "HR",
|
||||
},
|
||||
{
|
||||
Op: policyengine.CondStringNotEquals,
|
||||
Kind: policyengine.KindRequest,
|
||||
Key: "Actor",
|
||||
Value: "ownerA",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with unknown status",
|
||||
rule: "permit Object.Put *",
|
||||
expectErr: errUnknownStatus,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with unknown action",
|
||||
rule: "allow Object.PutOut *",
|
||||
expectErr: errUnknownAction,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with unknown status detail",
|
||||
rule: "deny:UnknownActionDetail Object.Put *",
|
||||
expectErr: errUnknownStatusDetail,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with unknown condition binary operator",
|
||||
rule: "deny Object.Put ResourceCondition:Department<HR *",
|
||||
expectErr: errUnknownBinaryOperator,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with unknown condition object type",
|
||||
rule: "deny Object.Put ResourSeCondiDion:Department=HR *",
|
||||
expectErr: errUnknownCondObjectType,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with mixed types of actions",
|
||||
rule: "allow Object.Put Container.Put *",
|
||||
expectErr: errMixedTypesInRule,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with no actions",
|
||||
rule: "allow ResourceCondition:A=B *",
|
||||
expectErr: errNoActionsInRule,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with invalid resource for object nm/cnt/obj/err",
|
||||
rule: "allow Object.Put nm/cnt/obj/err",
|
||||
expectErr: errUnsupportedResourceFormat,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with invalid resource for container nm/cnt/err",
|
||||
rule: "allow Container.Put nm/cnt/err",
|
||||
expectErr: errUnsupportedResourceFormat,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with invalid resource for container /nm/cnt/err",
|
||||
rule: "allow Container.Put /nm/cnt/err",
|
||||
expectErr: errUnsupportedResourceFormat,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with invalid resource for container /nm/cnt/",
|
||||
rule: "allow Container.Put /nm/cnt/",
|
||||
expectErr: errUnsupportedResourceFormat,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with invalid resource for container /nm/cnt",
|
||||
rule: "allow Container.Put /nm/cnt",
|
||||
expectErr: errUnsupportedResourceFormat,
|
||||
},
|
||||
{
|
||||
name: "Invalid rule with invalid resource for container /nm/",
|
||||
rule: "allow Container.Put /nm/",
|
||||
expectErr: errUnsupportedResourceFormat,
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all containers",
|
||||
rule: "allow Container.Put *",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutContainer}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatAllContainers}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all containers in root namespace",
|
||||
rule: "allow Container.Put /*",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutContainer}},
|
||||
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootContainers}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for container in root namespace",
|
||||
rule: "allow Container.Put /cid",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutContainer}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatRootContainer, "cid"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for all container in namespace",
|
||||
rule: "allow Container.Put ns/*",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutContainer}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainers, "ns"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for container in namespace",
|
||||
rule: "allow Container.Put ns/cid",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutContainer}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
fmt.Sprintf(nativeschema.ResourceFormatNamespaceContainer, "ns", "cid"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid rule for container with conditions with action detail",
|
||||
rule: "allow Container.Get ResourceCondition:A=B Container.Put RequestCondition:C!=D " +
|
||||
"* /cnt_id",
|
||||
expectRule: policyengine.Rule{
|
||||
Status: policyengine.Allow,
|
||||
Actions: policyengine.Actions{Names: []string{nativeschema.MethodGetContainer, nativeschema.MethodPutContainer}},
|
||||
Resources: policyengine.Resources{Names: []string{
|
||||
nativeschema.ResourceFormatAllContainers,
|
||||
fmt.Sprintf(nativeschema.ResourceFormatRootContainer, "cnt_id"),
|
||||
}},
|
||||
Condition: []policyengine.Condition{
|
||||
{
|
||||
Op: policyengine.CondStringEquals,
|
||||
Kind: policyengine.KindResource,
|
||||
Key: "A",
|
||||
Value: "B",
|
||||
},
|
||||
{
|
||||
Op: policyengine.CondStringNotEquals,
|
||||
Kind: policyengine.KindRequest,
|
||||
Key: "C",
|
||||
Value: "D",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
r := new(policyengine.Rule)
|
||||
err := ParseAPERule(r, test.rule)
|
||||
require.ErrorIs(t, err, test.expectErr)
|
||||
if test.expectErr == nil {
|
||||
require.Equal(t, test.expectRule, *r)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue