[#800] node: eACL -> APE converter

Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
Dmitrii Stepanov 2023-11-10 11:40:06 +03:00
parent 364f835b7e
commit fd9128d051
6 changed files with 749 additions and 30 deletions

View file

@ -6,6 +6,7 @@ import (
"strings"
policyengine "git.frostfs.info/TrueCloudLab/policy-engine"
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
"github.com/flynn-archive/go-shlex"
)
@ -65,7 +66,7 @@ func parseRuleLexemes(r *policyengine.Rule, lexemes []string) error {
return err
}
r.Action, err = parseAction(lexemes[1])
r.Actions, err = parseAction(lexemes[1])
if err != nil {
return err
}
@ -75,7 +76,7 @@ func parseRuleLexemes(r *policyengine.Rule, lexemes []string) error {
return err
}
r.Resource, err = parseResource(lexemes[len(lexemes)-1])
r.Resources, err = parseResource(lexemes[len(lexemes)-1])
return err
}
@ -100,41 +101,42 @@ func parseStatus(lexeme string) (policyengine.Status, error) {
}
}
func parseAction(lexeme string) ([]string, error) {
func parseAction(lexeme string) (policyengine.Actions, error) {
switch strings.ToLower(lexeme) {
case "object.put":
return []string{"native:PutObject"}, nil
return policyengine.Actions{Names: []string{nativeschema.MethodPutObject}}, nil
case "object.get":
return []string{"native:GetObject"}, nil
return policyengine.Actions{Names: []string{nativeschema.MethodGetObject}}, nil
case "object.head":
return []string{"native:HeadObject"}, nil
return policyengine.Actions{Names: []string{nativeschema.MethodHeadObject}}, nil
case "object.delete":
return []string{"native:DeleteObject"}, nil
return policyengine.Actions{Names: []string{nativeschema.MethodDeleteObject}}, nil
case "object.search":
return []string{"native:SearchObject"}, nil
return policyengine.Actions{Names: []string{nativeschema.MethodSearchObject}}, nil
case "object.range":
return []string{"native:RangeObject"}, nil
return policyengine.Actions{Names: []string{nativeschema.MethodRangeObject}}, nil
case "object.hash":
return []string{"native:HashObject"}, nil
return policyengine.Actions{Names: []string{nativeschema.MethodHashObject}}, nil
default:
}
return nil, fmt.Errorf("%w: %s", errUnknownOperation, lexeme)
return policyengine.Actions{}, fmt.Errorf("%w: %s", errUnknownOperation, lexeme)
}
func parseResource(lexeme string) ([]string, error) {
return []string{fmt.Sprintf("native:::object/%s", lexeme)}, nil
func parseResource(lexeme string) (policyengine.Resources, error) {
if lexeme == "*" {
return policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}}, nil
}
return policyengine.Resources{Names: []string{fmt.Sprintf(nativeschema.ResourceFormatRootContainerObjects, lexeme)}}, nil
}
const (
ObjectResource = "object.resource"
ObjectRequest = "object.request"
ObjectActor = "object.actor"
)
var typeToCondObject = map[string]policyengine.ObjectType{
ObjectResource: policyengine.ObjectResource,
ObjectRequest: policyengine.ObjectRequest,
ObjectActor: policyengine.ObjectActor,
}
func parseConditions(lexemes []string) ([]policyengine.Condition, error) {

View file

@ -4,6 +4,7 @@ import (
"testing"
policyengine "git.frostfs.info/TrueCloudLab/policy-engine"
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
"github.com/stretchr/testify/require"
)
@ -19,8 +20,8 @@ func TestParseAPERule(t *testing.T) {
rule: "allow Object.Put *",
expectRule: policyengine.Rule{
Status: policyengine.Allow,
Action: []string{"native:PutObject"},
Resource: []string{"native:::object/*"},
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}},
Condition: []policyengine.Condition{},
},
},
@ -29,8 +30,8 @@ func TestParseAPERule(t *testing.T) {
rule: "deny Object.Put *",
expectRule: policyengine.Rule{
Status: policyengine.AccessDenied,
Action: []string{"native:PutObject"},
Resource: []string{"native:::object/*"},
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}},
Condition: []policyengine.Condition{},
},
},
@ -39,8 +40,8 @@ func TestParseAPERule(t *testing.T) {
rule: "deny:QuotaLimitReached Object.Put *",
expectRule: policyengine.Rule{
Status: policyengine.QuotaLimitReached,
Action: []string{"native:PutObject"},
Resource: []string{"native:::object/*"},
Actions: policyengine.Actions{Names: []string{nativeschema.MethodPutObject}},
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}},
Condition: []policyengine.Condition{},
},
},
@ -48,9 +49,9 @@ func TestParseAPERule(t *testing.T) {
name: "Valid allow rule with conditions",
rule: "allow Object.Get Object.Resource:Department=HR Object.Request:Actor!=ownerA *",
expectRule: policyengine.Rule{
Status: policyengine.Allow,
Action: []string{"native:GetObject"},
Resource: []string{"native:::object/*"},
Status: policyengine.Allow,
Actions: policyengine.Actions{Names: []string{nativeschema.MethodGetObject}},
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}},
Condition: []policyengine.Condition{
{
Op: policyengine.CondStringEquals,
@ -71,9 +72,9 @@ func TestParseAPERule(t *testing.T) {
name: "Valid rule with conditions with action detail",
rule: "deny:QuotaLimitReached Object.Get Object.Resource:Department=HR Object.Request:Actor!=ownerA *",
expectRule: policyengine.Rule{
Status: policyengine.QuotaLimitReached,
Action: []string{"native:GetObject"},
Resource: []string{"native:::object/*"},
Status: policyengine.QuotaLimitReached,
Actions: policyengine.Actions{Names: []string{nativeschema.MethodGetObject}},
Resources: policyengine.Resources{Names: []string{nativeschema.ResourceFormatRootObjects}},
Condition: []policyengine.Condition{
{
Op: policyengine.CondStringEquals,