From 10ebccba4507204f186f8fe4d2c4a07ddc154413 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 3 Mar 2018 16:14:33 -0800 Subject: [PATCH] acl: parsing intentions in service block --- acl/policy.go | 8 +++++ acl/policy_test.go | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/acl/policy.go b/acl/policy.go index b8fc498b6..0796a1aec 100644 --- a/acl/policy.go +++ b/acl/policy.go @@ -73,6 +73,11 @@ type ServicePolicy struct { Name string `hcl:",key"` Policy string Sentinel Sentinel + + // Intentions is the policy for intentions where this service is the + // destination. This may be empty, in which case the Policy determines + // the intentions policy. + Intentions string } func (s *ServicePolicy) GoString() string { @@ -197,6 +202,9 @@ func Parse(rules string, sentinel sentinel.Evaluator) (*Policy, error) { if !isPolicyValid(sp.Policy) { return nil, fmt.Errorf("Invalid service policy: %#v", sp) } + if sp.Intentions != "" && !isPolicyValid(sp.Intentions) { + return nil, fmt.Errorf("Invalid service intentions policy: %#v", sp) + } if err := isSentinelValid(sentinel, sp.Policy, sp.Sentinel); err != nil { return nil, fmt.Errorf("Invalid service Sentinel policy: %#v, got error:%v", sp, err) } diff --git a/acl/policy_test.go b/acl/policy_test.go index 37b8216f5..9d3ae8f69 100644 --- a/acl/policy_test.go +++ b/acl/policy_test.go @@ -6,6 +6,88 @@ import ( "testing" ) +func TestParse_table(t *testing.T) { + // Note that the table tests are newer than other tests. Many of the + // other aspects of policy parsing are tested in older tests below. New + // parsing tests should be added to this table as its easier to maintain. + cases := []struct { + Name string + Input string + Expected *Policy + Err string + }{ + { + "service no intentions", + ` +service "foo" { + policy = "write" +} + `, + &Policy{ + Services: []*ServicePolicy{ + { + Name: "foo", + Policy: "write", + }, + }, + }, + "", + }, + + { + "service intentions", + ` +service "foo" { + policy = "write" + intentions = "read" +} + `, + &Policy{ + Services: []*ServicePolicy{ + { + Name: "foo", + Policy: "write", + Intentions: "read", + }, + }, + }, + "", + }, + + { + "service intention: invalid value", + ` +service "foo" { + policy = "write" + intentions = "foo" +} + `, + nil, + "service intentions", + }, + } + + for _, tc := range cases { + t.Run(tc.Name, func(t *testing.T) { + actual, err := Parse(tc.Input, nil) + if (err != nil) != (tc.Err != "") { + t.Fatalf("err: %s", err) + } + if err != nil { + if !strings.Contains(err.Error(), tc.Err) { + t.Fatalf("err: %s", err) + } + + return + } + + if !reflect.DeepEqual(actual, tc.Expected) { + t.Fatalf("bad: %#v", actual) + } + }) + } +} + func TestACLPolicy_Parse_HCL(t *testing.T) { inp := ` agent "foo" {