acl: Support ACL checks, adding new root policy

This commit is contained in:
Armon Dadgar 2014-08-12 15:09:01 -07:00
parent bac1527281
commit 02e71c70c5
2 changed files with 79 additions and 3 deletions

View File

@ -5,29 +5,47 @@ import (
) )
var ( var (
// allowAll is a singleton policy which allows all actions // allowAll is a singleton policy which allows all
// non-management actions
allowAll ACL allowAll ACL
// denyAll is a singleton policy which denies all actions // denyAll is a singleton policy which denies all actions
denyAll ACL denyAll ACL
// manageAll is a singleton policy which allows all
// actions, including management
manageAll ACL
) )
func init() { func init() {
// Setup the singletons // Setup the singletons
allowAll = &StaticACL{defaultAllow: true} allowAll = &StaticACL{
denyAll = &StaticACL{defaultAllow: false} allowManage: false,
defaultAllow: true,
}
denyAll = &StaticACL{
allowManage: false,
defaultAllow: false,
}
manageAll = &StaticACL{
allowManage: true,
defaultAllow: true,
}
} }
// ACL is the interface for policy enforcement. // ACL is the interface for policy enforcement.
type ACL interface { type ACL interface {
KeyRead(string) bool KeyRead(string) bool
KeyWrite(string) bool KeyWrite(string) bool
ACLList() bool
ACLModify() bool
} }
// StaticACL is used to implement a base ACL policy. It either // StaticACL is used to implement a base ACL policy. It either
// allows or denies all requests. This can be used as a parent // allows or denies all requests. This can be used as a parent
// ACL to act in a blacklist or whitelist mode. // ACL to act in a blacklist or whitelist mode.
type StaticACL struct { type StaticACL struct {
allowManage bool
defaultAllow bool defaultAllow bool
} }
@ -39,6 +57,14 @@ func (s *StaticACL) KeyWrite(string) bool {
return s.defaultAllow return s.defaultAllow
} }
func (s *StaticACL) ACLList() bool {
return s.allowManage
}
func (s *StaticACL) ACLModify() bool {
return s.allowManage
}
// AllowAll returns an ACL rule that allows all operations // AllowAll returns an ACL rule that allows all operations
func AllowAll() ACL { func AllowAll() ACL {
return allowAll return allowAll
@ -49,6 +75,11 @@ func DenyAll() ACL {
return denyAll return denyAll
} }
// ManageAll returns an ACL rule that can manage all resources
func ManageAll() ACL {
return manageAll
}
// RootACL returns a possible ACL if the ID matches a root policy // RootACL returns a possible ACL if the ID matches a root policy
func RootACL(id string) ACL { func RootACL(id string) ACL {
switch id { switch id {
@ -56,6 +87,8 @@ func RootACL(id string) ACL {
return allowAll return allowAll
case "deny": case "deny":
return denyAll return denyAll
case "manage":
return manageAll
default: default:
return nil return nil
} }
@ -122,3 +155,13 @@ func (p *PolicyACL) KeyWrite(key string) bool {
// No matching rule, use the parent. // No matching rule, use the parent.
return p.parent.KeyWrite(key) return p.parent.KeyWrite(key)
} }
// ACLList checks if listing of ACLs is allowed
func (p *PolicyACL) ACLList() bool {
return p.ACLList()
}
// ACLModify checks if modification of ACLs is allowed
func (p *PolicyACL) ACLModify() bool {
return p.ACLModify()
}

View File

@ -11,6 +11,9 @@ func TestRootACL(t *testing.T) {
if RootACL("deny") != DenyAll() { if RootACL("deny") != DenyAll() {
t.Fatalf("Bad root") t.Fatalf("Bad root")
} }
if RootACL("manage") != ManageAll() {
t.Fatalf("Bad root")
}
if RootACL("foo") != nil { if RootACL("foo") != nil {
t.Fatalf("bad root") t.Fatalf("bad root")
} }
@ -27,12 +30,23 @@ func TestStaticACL(t *testing.T) {
t.Fatalf("expected static") t.Fatalf("expected static")
} }
manage := ManageAll()
if _, ok := none.(*StaticACL); !ok {
t.Fatalf("expected static")
}
if !all.KeyRead("foobar") { if !all.KeyRead("foobar") {
t.Fatalf("should allow") t.Fatalf("should allow")
} }
if !all.KeyWrite("foobar") { if !all.KeyWrite("foobar") {
t.Fatalf("should allow") t.Fatalf("should allow")
} }
if all.ACLList() {
t.Fatalf("should not allow")
}
if all.ACLModify() {
t.Fatalf("should not allow")
}
if none.KeyRead("foobar") { if none.KeyRead("foobar") {
t.Fatalf("should not allow") t.Fatalf("should not allow")
@ -40,6 +54,25 @@ func TestStaticACL(t *testing.T) {
if none.KeyWrite("foobar") { if none.KeyWrite("foobar") {
t.Fatalf("should not allow") t.Fatalf("should not allow")
} }
if none.ACLList() {
t.Fatalf("should not noneow")
}
if none.ACLModify() {
t.Fatalf("should not noneow")
}
if !manage.KeyRead("foobar") {
t.Fatalf("should allow")
}
if !manage.KeyWrite("foobar") {
t.Fatalf("should allow")
}
if !manage.ACLList() {
t.Fatalf("should allow")
}
if !manage.ACLModify() {
t.Fatalf("should allow")
}
} }
func TestPolicyACL(t *testing.T) { func TestPolicyACL(t *testing.T) {