package acl import ( "testing" ) func TestRootACL(t *testing.T) { if RootACL("allow") != AllowAll() { t.Fatalf("Bad root") } if RootACL("deny") != DenyAll() { t.Fatalf("Bad root") } if RootACL("manage") != ManageAll() { t.Fatalf("Bad root") } if RootACL("foo") != nil { t.Fatalf("bad root") } } func TestStaticACL(t *testing.T) { all := AllowAll() if _, ok := all.(*StaticACL); !ok { t.Fatalf("expected static") } none := DenyAll() if _, ok := none.(*StaticACL); !ok { t.Fatalf("expected static") } manage := ManageAll() if _, ok := manage.(*StaticACL); !ok { t.Fatalf("expected static") } if all.ACLList() { t.Fatalf("should not allow") } if all.ACLModify() { t.Fatalf("should not allow") } if !all.AgentRead("foobar") { t.Fatalf("should allow") } if !all.AgentWrite("foobar") { t.Fatalf("should allow") } if !all.EventRead("foobar") { t.Fatalf("should allow") } if !all.EventWrite("foobar") { t.Fatalf("should allow") } if !all.IntentionDefault() { t.Fatalf("should allow") } if !all.IntentionWrite("foobar") { t.Fatalf("should allow") } if !all.KeyRead("foobar") { t.Fatalf("should allow") } if !all.KeyWrite("foobar", nil) { t.Fatalf("should allow") } if !all.KeyringRead() { t.Fatalf("should allow") } if !all.KeyringWrite() { t.Fatalf("should allow") } if !all.NodeRead("foobar") { t.Fatalf("should allow") } if !all.NodeWrite("foobar", nil) { t.Fatalf("should allow") } if !all.OperatorRead() { t.Fatalf("should allow") } if !all.OperatorWrite() { t.Fatalf("should allow") } if !all.PreparedQueryRead("foobar") { t.Fatalf("should allow") } if !all.PreparedQueryWrite("foobar") { t.Fatalf("should allow") } if !all.ServiceRead("foobar") { t.Fatalf("should allow") } if !all.ServiceWrite("foobar", nil) { t.Fatalf("should allow") } if !all.SessionRead("foobar") { t.Fatalf("should allow") } if !all.SessionWrite("foobar") { t.Fatalf("should allow") } if all.Snapshot() { t.Fatalf("should not allow") } if none.ACLList() { t.Fatalf("should not allow") } if none.ACLModify() { t.Fatalf("should not allow") } if none.AgentRead("foobar") { t.Fatalf("should not allow") } if none.AgentWrite("foobar") { t.Fatalf("should not allow") } if none.EventRead("foobar") { t.Fatalf("should not allow") } if none.EventRead("") { t.Fatalf("should not allow") } if none.EventWrite("foobar") { t.Fatalf("should not allow") } if none.EventWrite("") { t.Fatalf("should not allow") } if none.IntentionDefault() { t.Fatalf("should not allow") } if none.IntentionWrite("foo") { t.Fatalf("should not allow") } if none.KeyRead("foobar") { t.Fatalf("should not allow") } if none.KeyWrite("foobar", nil) { t.Fatalf("should not allow") } if none.KeyringRead() { t.Fatalf("should now allow") } if none.KeyringWrite() { t.Fatalf("should not allow") } if none.NodeRead("foobar") { t.Fatalf("should not allow") } if none.NodeWrite("foobar", nil) { t.Fatalf("should not allow") } if none.OperatorRead() { t.Fatalf("should now allow") } if none.OperatorWrite() { t.Fatalf("should not allow") } if none.PreparedQueryRead("foobar") { t.Fatalf("should not allow") } if none.PreparedQueryWrite("foobar") { t.Fatalf("should not allow") } if none.ServiceRead("foobar") { t.Fatalf("should not allow") } if none.ServiceWrite("foobar", nil) { t.Fatalf("should not allow") } if none.SessionRead("foobar") { t.Fatalf("should not allow") } if none.SessionWrite("foobar") { t.Fatalf("should not allow") } if none.Snapshot() { t.Fatalf("should not allow") } if !manage.ACLList() { t.Fatalf("should allow") } if !manage.ACLModify() { t.Fatalf("should allow") } if !manage.AgentRead("foobar") { t.Fatalf("should allow") } if !manage.AgentWrite("foobar") { t.Fatalf("should allow") } if !manage.EventRead("foobar") { t.Fatalf("should allow") } if !manage.EventWrite("foobar") { t.Fatalf("should allow") } if !manage.IntentionDefault() { t.Fatalf("should allow") } if !manage.IntentionWrite("foobar") { t.Fatalf("should allow") } if !manage.KeyRead("foobar") { t.Fatalf("should allow") } if !manage.KeyWrite("foobar", nil) { t.Fatalf("should allow") } if !manage.KeyringRead() { t.Fatalf("should allow") } if !manage.KeyringWrite() { t.Fatalf("should allow") } if !manage.NodeRead("foobar") { t.Fatalf("should allow") } if !manage.NodeWrite("foobar", nil) { t.Fatalf("should allow") } if !manage.OperatorRead() { t.Fatalf("should allow") } if !manage.OperatorWrite() { t.Fatalf("should allow") } if !manage.PreparedQueryRead("foobar") { t.Fatalf("should allow") } if !manage.PreparedQueryWrite("foobar") { t.Fatalf("should allow") } if !manage.ServiceRead("foobar") { t.Fatalf("should allow") } if !manage.ServiceWrite("foobar", nil) { t.Fatalf("should allow") } if !manage.SessionRead("foobar") { t.Fatalf("should allow") } if !manage.SessionWrite("foobar") { t.Fatalf("should allow") } if !manage.Snapshot() { t.Fatalf("should allow") } } func TestPolicyACL(t *testing.T) { all := AllowAll() policy := &Policy{ Events: []*EventPolicy{ &EventPolicy{ Event: "", Policy: PolicyRead, }, &EventPolicy{ Event: "foo", Policy: PolicyWrite, }, &EventPolicy{ Event: "bar", Policy: PolicyDeny, }, }, Keys: []*KeyPolicy{ &KeyPolicy{ Prefix: "foo/", Policy: PolicyWrite, }, &KeyPolicy{ Prefix: "foo/priv/", Policy: PolicyDeny, }, &KeyPolicy{ Prefix: "bar/", Policy: PolicyDeny, }, &KeyPolicy{ Prefix: "zip/", Policy: PolicyRead, }, &KeyPolicy{ Prefix: "zap/", Policy: PolicyList, }, }, PreparedQueries: []*PreparedQueryPolicy{ &PreparedQueryPolicy{ Prefix: "", Policy: PolicyRead, }, &PreparedQueryPolicy{ Prefix: "foo", Policy: PolicyWrite, }, &PreparedQueryPolicy{ Prefix: "bar", Policy: PolicyDeny, }, &PreparedQueryPolicy{ Prefix: "zoo", Policy: PolicyWrite, }, }, Services: []*ServicePolicy{ &ServicePolicy{ Name: "", Policy: PolicyWrite, }, &ServicePolicy{ Name: "foo", Policy: PolicyRead, }, &ServicePolicy{ Name: "bar", Policy: PolicyDeny, }, &ServicePolicy{ Name: "barfoo", Policy: PolicyWrite, Intentions: PolicyWrite, }, &ServicePolicy{ Name: "intbaz", Policy: PolicyWrite, Intentions: PolicyDeny, }, }, } acl, err := New(all, policy, nil) if err != nil { t.Fatalf("err: %v", err) } type keycase struct { inp string read bool write bool writePrefix bool list bool } cases := []keycase{ {"other", true, true, true, true}, {"foo/test", true, true, true, true}, {"foo/priv/test", false, false, false, false}, {"bar/any", false, false, false, false}, {"zip/test", true, false, false, false}, {"foo/", true, true, false, true}, {"", true, true, false, true}, {"zap/test", true, false, false, true}, } for _, c := range cases { if c.read != acl.KeyRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.KeyWrite(c.inp, nil) { t.Fatalf("Write fail: %#v", c) } if c.writePrefix != acl.KeyWritePrefix(c.inp) { t.Fatalf("Write prefix fail: %#v", c) } } // Test the intentions type intentioncase struct { inp string read bool write bool } icases := []intentioncase{ {"other", true, false}, {"foo", true, false}, {"bar", false, false}, {"foobar", true, false}, {"barfo", false, false}, {"barfoo", true, true}, {"barfoo2", true, true}, {"intbaz", false, false}, } for _, c := range icases { if c.read != acl.IntentionRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.IntentionWrite(c.inp) { t.Fatalf("Write fail: %#v", c) } } // Test the services type servicecase struct { inp string read bool write bool } scases := []servicecase{ {"other", true, true}, {"foo", true, false}, {"bar", false, false}, {"foobar", true, false}, {"barfo", false, false}, {"barfoo", true, true}, {"barfoo2", true, true}, } for _, c := range scases { if c.read != acl.ServiceRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.ServiceWrite(c.inp, nil) { t.Fatalf("Write fail: %#v", c) } } // Test the events type eventcase struct { inp string read bool write bool } eventcases := []eventcase{ {"foo", true, true}, {"foobar", true, true}, {"bar", false, false}, {"barbaz", false, false}, {"baz", true, false}, } for _, c := range eventcases { if c.read != acl.EventRead(c.inp) { t.Fatalf("Event fail: %#v", c) } if c.write != acl.EventWrite(c.inp) { t.Fatalf("Event fail: %#v", c) } } // Test prepared queries type querycase struct { inp string read bool write bool } querycases := []querycase{ {"foo", true, true}, {"foobar", true, true}, {"bar", false, false}, {"barbaz", false, false}, {"baz", true, false}, {"nope", true, false}, {"zoo", true, true}, {"zookeeper", true, true}, } for _, c := range querycases { if c.read != acl.PreparedQueryRead(c.inp) { t.Fatalf("Prepared query fail: %#v", c) } if c.write != acl.PreparedQueryWrite(c.inp) { t.Fatalf("Prepared query fail: %#v", c) } } // Check default intentions bubble up if !acl.IntentionDefault() { t.Fatal("should allow") } } func TestPolicyACL_Parent(t *testing.T) { deny := DenyAll() policyRoot := &Policy{ Keys: []*KeyPolicy{ &KeyPolicy{ Prefix: "foo/", Policy: PolicyWrite, }, &KeyPolicy{ Prefix: "bar/", Policy: PolicyRead, }, }, PreparedQueries: []*PreparedQueryPolicy{ &PreparedQueryPolicy{ Prefix: "other", Policy: PolicyWrite, }, &PreparedQueryPolicy{ Prefix: "foo", Policy: PolicyRead, }, }, Services: []*ServicePolicy{ &ServicePolicy{ Name: "other", Policy: PolicyWrite, }, &ServicePolicy{ Name: "foo", Policy: PolicyRead, }, }, } root, err := New(deny, policyRoot, nil) if err != nil { t.Fatalf("err: %v", err) } policy := &Policy{ Keys: []*KeyPolicy{ &KeyPolicy{ Prefix: "foo/priv/", Policy: PolicyRead, }, &KeyPolicy{ Prefix: "bar/", Policy: PolicyDeny, }, &KeyPolicy{ Prefix: "zip/", Policy: PolicyRead, }, }, PreparedQueries: []*PreparedQueryPolicy{ &PreparedQueryPolicy{ Prefix: "bar", Policy: PolicyDeny, }, }, Services: []*ServicePolicy{ &ServicePolicy{ Name: "bar", Policy: PolicyDeny, }, }, } acl, err := New(root, policy, nil) if err != nil { t.Fatalf("err: %v", err) } type keycase struct { inp string read bool write bool writePrefix bool } cases := []keycase{ {"other", false, false, false}, {"foo/test", true, true, true}, {"foo/priv/test", true, false, false}, {"bar/any", false, false, false}, {"zip/test", true, false, false}, } for _, c := range cases { if c.read != acl.KeyRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.KeyWrite(c.inp, nil) { t.Fatalf("Write fail: %#v", c) } if c.writePrefix != acl.KeyWritePrefix(c.inp) { t.Fatalf("Write prefix fail: %#v", c) } } // Test the services type servicecase struct { inp string read bool write bool } scases := []servicecase{ {"fail", false, false}, {"other", true, true}, {"foo", true, false}, {"bar", false, false}, } for _, c := range scases { if c.read != acl.ServiceRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.ServiceWrite(c.inp, nil) { t.Fatalf("Write fail: %#v", c) } } // Test prepared queries type querycase struct { inp string read bool write bool } querycases := []querycase{ {"foo", true, false}, {"foobar", true, false}, {"bar", false, false}, {"barbaz", false, false}, {"baz", false, false}, {"nope", false, false}, } for _, c := range querycases { if c.read != acl.PreparedQueryRead(c.inp) { t.Fatalf("Prepared query fail: %#v", c) } if c.write != acl.PreparedQueryWrite(c.inp) { t.Fatalf("Prepared query fail: %#v", c) } } // Check some management functions that chain up if acl.ACLList() { t.Fatalf("should not allow") } if acl.ACLModify() { t.Fatalf("should not allow") } if acl.Snapshot() { t.Fatalf("should not allow") } // Check default intentions if acl.IntentionDefault() { t.Fatal("should not allow") } } func TestPolicyACL_Agent(t *testing.T) { deny := DenyAll() policyRoot := &Policy{ Agents: []*AgentPolicy{ &AgentPolicy{ Node: "root-nope", Policy: PolicyDeny, }, &AgentPolicy{ Node: "root-ro", Policy: PolicyRead, }, &AgentPolicy{ Node: "root-rw", Policy: PolicyWrite, }, &AgentPolicy{ Node: "override", Policy: PolicyDeny, }, }, } root, err := New(deny, policyRoot, nil) if err != nil { t.Fatalf("err: %v", err) } policy := &Policy{ Agents: []*AgentPolicy{ &AgentPolicy{ Node: "child-nope", Policy: PolicyDeny, }, &AgentPolicy{ Node: "child-ro", Policy: PolicyRead, }, &AgentPolicy{ Node: "child-rw", Policy: PolicyWrite, }, &AgentPolicy{ Node: "override", Policy: PolicyWrite, }, }, } acl, err := New(root, policy, nil) if err != nil { t.Fatalf("err: %v", err) } type agentcase struct { inp string read bool write bool } cases := []agentcase{ {"nope", false, false}, {"root-nope", false, false}, {"root-ro", true, false}, {"root-rw", true, true}, {"root-nope-prefix", false, false}, {"root-ro-prefix", true, false}, {"root-rw-prefix", true, true}, {"child-nope", false, false}, {"child-ro", true, false}, {"child-rw", true, true}, {"child-nope-prefix", false, false}, {"child-ro-prefix", true, false}, {"child-rw-prefix", true, true}, {"override", true, true}, } for _, c := range cases { if c.read != acl.AgentRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.AgentWrite(c.inp) { t.Fatalf("Write fail: %#v", c) } } } func TestPolicyACL_Keyring(t *testing.T) { type keyringcase struct { inp string read bool write bool } cases := []keyringcase{ {"", false, false}, {PolicyRead, true, false}, {PolicyWrite, true, true}, {PolicyDeny, false, false}, } for _, c := range cases { acl, err := New(DenyAll(), &Policy{Keyring: c.inp}, nil) if err != nil { t.Fatalf("bad: %s", err) } if acl.KeyringRead() != c.read { t.Fatalf("bad: %#v", c) } if acl.KeyringWrite() != c.write { t.Fatalf("bad: %#v", c) } } } func TestPolicyACL_Operator(t *testing.T) { type operatorcase struct { inp string read bool write bool } cases := []operatorcase{ {"", false, false}, {PolicyRead, true, false}, {PolicyWrite, true, true}, {PolicyDeny, false, false}, } for _, c := range cases { acl, err := New(DenyAll(), &Policy{Operator: c.inp}, nil) if err != nil { t.Fatalf("bad: %s", err) } if acl.OperatorRead() != c.read { t.Fatalf("bad: %#v", c) } if acl.OperatorWrite() != c.write { t.Fatalf("bad: %#v", c) } } } func TestPolicyACL_Node(t *testing.T) { deny := DenyAll() policyRoot := &Policy{ Nodes: []*NodePolicy{ &NodePolicy{ Name: "root-nope", Policy: PolicyDeny, }, &NodePolicy{ Name: "root-ro", Policy: PolicyRead, }, &NodePolicy{ Name: "root-rw", Policy: PolicyWrite, }, &NodePolicy{ Name: "override", Policy: PolicyDeny, }, }, } root, err := New(deny, policyRoot, nil) if err != nil { t.Fatalf("err: %v", err) } policy := &Policy{ Nodes: []*NodePolicy{ &NodePolicy{ Name: "child-nope", Policy: PolicyDeny, }, &NodePolicy{ Name: "child-ro", Policy: PolicyRead, }, &NodePolicy{ Name: "child-rw", Policy: PolicyWrite, }, &NodePolicy{ Name: "override", Policy: PolicyWrite, }, }, } acl, err := New(root, policy, nil) if err != nil { t.Fatalf("err: %v", err) } type nodecase struct { inp string read bool write bool } cases := []nodecase{ {"nope", false, false}, {"root-nope", false, false}, {"root-ro", true, false}, {"root-rw", true, true}, {"root-nope-prefix", false, false}, {"root-ro-prefix", true, false}, {"root-rw-prefix", true, true}, {"child-nope", false, false}, {"child-ro", true, false}, {"child-rw", true, true}, {"child-nope-prefix", false, false}, {"child-ro-prefix", true, false}, {"child-rw-prefix", true, true}, {"override", true, true}, } for _, c := range cases { if c.read != acl.NodeRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.NodeWrite(c.inp, nil) { t.Fatalf("Write fail: %#v", c) } } } func TestPolicyACL_Session(t *testing.T) { deny := DenyAll() policyRoot := &Policy{ Sessions: []*SessionPolicy{ &SessionPolicy{ Node: "root-nope", Policy: PolicyDeny, }, &SessionPolicy{ Node: "root-ro", Policy: PolicyRead, }, &SessionPolicy{ Node: "root-rw", Policy: PolicyWrite, }, &SessionPolicy{ Node: "override", Policy: PolicyDeny, }, }, } root, err := New(deny, policyRoot, nil) if err != nil { t.Fatalf("err: %v", err) } policy := &Policy{ Sessions: []*SessionPolicy{ &SessionPolicy{ Node: "child-nope", Policy: PolicyDeny, }, &SessionPolicy{ Node: "child-ro", Policy: PolicyRead, }, &SessionPolicy{ Node: "child-rw", Policy: PolicyWrite, }, &SessionPolicy{ Node: "override", Policy: PolicyWrite, }, }, } acl, err := New(root, policy, nil) if err != nil { t.Fatalf("err: %v", err) } type sessioncase struct { inp string read bool write bool } cases := []sessioncase{ {"nope", false, false}, {"root-nope", false, false}, {"root-ro", true, false}, {"root-rw", true, true}, {"root-nope-prefix", false, false}, {"root-ro-prefix", true, false}, {"root-rw-prefix", true, true}, {"child-nope", false, false}, {"child-ro", true, false}, {"child-rw", true, true}, {"child-nope-prefix", false, false}, {"child-ro-prefix", true, false}, {"child-rw-prefix", true, true}, {"override", true, true}, } for _, c := range cases { if c.read != acl.SessionRead(c.inp) { t.Fatalf("Read fail: %#v", c) } if c.write != acl.SessionWrite(c.inp) { t.Fatalf("Write fail: %#v", c) } } }