acl: Support for service policies

This commit is contained in:
Armon Dadgar 2014-11-30 20:18:16 -07:00
parent 4c410cf1f9
commit 3695f65292
2 changed files with 66 additions and 5 deletions

View File

@ -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
}

View File

@ -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)