diff --git a/acl/policy.go b/acl/policy.go index 014ef51ac8..569570a9d0 100644 --- a/acl/policy.go +++ b/acl/policy.go @@ -2,20 +2,25 @@ package acl import ( "fmt" + "github.com/hashicorp/hcl" ) const ( - KeyPolicyDeny = "deny" - KeyPolicyRead = "read" - KeyPolicyWrite = "write" + KeyPolicyDeny = "deny" + KeyPolicyRead = "read" + KeyPolicyWrite = "write" + ServicePolicyDeny = "deny" + ServicePolicyRead = "read" + ServicePolicyWrite = "write" ) // Policy is used to represent the policy specified by // an ACL configuration. type Policy struct { - ID string `hcl:"-"` - Keys []*KeyPolicy `hcl:"key,expand"` + ID string `hcl:"-"` + Keys []*KeyPolicy `hcl:"key,expand"` + Services []*ServicePolicy `hcl:"service,expand"` } // KeyPolicy represents a policy for a key @@ -28,6 +33,16 @@ func (k *KeyPolicy) GoString() string { return fmt.Sprintf("%#v", *k) } +// ServicePolicy represents a policy for a service +type ServicePolicy struct { + Name string `hcl:",key"` + Policy string +} + +func (k *ServicePolicy) GoString() string { + return fmt.Sprintf("%#v", *k) +} + // Parse is used to parse the specified ACL rules into an // intermediary set of policies, before being compiled into // the ACL @@ -53,5 +68,17 @@ func Parse(rules string) (*Policy, error) { return nil, fmt.Errorf("Invalid key policy: %#v", kp) } } + + // Validate the service policy + for _, sp := range p.Services { + switch sp.Policy { + case ServicePolicyDeny: + case ServicePolicyRead: + case ServicePolicyWrite: + default: + return nil, fmt.Errorf("Invalid service policy: %#v", sp) + } + } + return p, nil } diff --git a/acl/policy_test.go b/acl/policy_test.go index 0fc75e0fa9..0c270e7d57 100644 --- a/acl/policy_test.go +++ b/acl/policy_test.go @@ -18,6 +18,12 @@ key "foo/bar/" { } key "foo/bar/baz" { policy = "deny" +} +service "" { + policy = "write" +} +service "foo" { + policy = "read" } ` exp := &Policy{ @@ -39,6 +45,16 @@ key "foo/bar/baz" { Policy: KeyPolicyDeny, }, }, + Services: []*ServicePolicy{ + &ServicePolicy{ + Name: "", + Policy: ServicePolicyWrite, + }, + &ServicePolicy{ + Name: "foo", + Policy: ServicePolicyRead, + }, + }, } out, err := Parse(inp) @@ -66,6 +82,14 @@ func TestParse_JSON(t *testing.T) { "foo/bar/baz": { "policy": "deny" } + }, + "service": { + "": { + "policy": "write" + }, + "foo": { + "policy": "read" + } } }` exp := &Policy{ @@ -87,6 +111,16 @@ func TestParse_JSON(t *testing.T) { Policy: KeyPolicyDeny, }, }, + Services: []*ServicePolicy{ + &ServicePolicy{ + Name: "", + Policy: ServicePolicyWrite, + }, + &ServicePolicy{ + Name: "foo", + Policy: ServicePolicyRead, + }, + }, } out, err := Parse(inp)