diff --git a/command/capabilities_test.go b/command/capabilities_test.go index 198e0820dd..9c71fcf8a7 100644 --- a/command/capabilities_test.go +++ b/command/capabilities_test.go @@ -8,47 +8,37 @@ import ( "github.com/mitchellh/cli" ) -func TestCapabilities_Args(t *testing.T) { - core, _, _ := vault.TestCoreUnsealed(t) - ln, _ := http.TestServer(t, core) +func TestCapabilities_Basic(t *testing.T) { + core, _, token := vault.TestCoreUnsealed(t) + ln, addr := http.TestServer(t, core) defer ln.Close() - ui := new(cli.MockUi) c := &CapabilitiesCommand{ Meta: Meta{ - Ui: ui, + ClientToken: token, + Ui: ui, }, } - args := []string{} + var args []string + + args = []string{"-address", addr} if code := c.Run(args); code == 0 { t.Fatalf("expected failure due to no args") } - args = []string{"invalidtoken", "test"} + args = []string{"-address", addr, "testpath"} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + args = []string{"-address", addr, token, "test"} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + args = []string{"-address", addr, "invalidtoken", "test"} if code := c.Run(args); code == 0 { t.Fatalf("expected failure due to no invalid token") } - - /* - args = []string{"test"} - if code := c.Run(args); code != 0 { - t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) - } - - log.Printf("result1: %s\n", string(ui.OutputWriter.Bytes())) - if !strings.Contains(string(ui.OutputWriter.Bytes()), "This is a 'root' token.") { - t.Fatalf("bad: %s", ui.OutputWriter.String()) - } - - args = []string{string(key), "test"} - if code := c.Run(args); code != 0 { - t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) - } - - log.Printf("result2: %s\n", string(ui.OutputWriter.Bytes())) - if !strings.Contains(string(ui.OutputWriter.Bytes()), "This is a 'root' token.") { - t.Fatalf("bad: %s", ui.OutputWriter.String()) - } - */ } diff --git a/http/sys_capabilities_test.go b/http/sys_capabilities_test.go index d02cfda642..f192e2b0a6 100644 --- a/http/sys_capabilities_test.go +++ b/http/sys_capabilities_test.go @@ -1 +1,82 @@ package http + +import ( + "reflect" + "testing" + + "github.com/hashicorp/vault/vault" +) + +func TestSysCapabilities(t *testing.T) { + core, _, token := vault.TestCoreUnsealed(t) + ln, addr := TestServer(t, core) + defer ln.Close() + TestServerAuth(t, addr, token) + + // Send both token and path + resp := testHttpPost(t, token, addr+"/v1/sys/capabilities", map[string]interface{}{ + "token": token, + "path": "testpath", + }) + + var actual map[string][]string + testResponseStatus(t, resp, 200) + testResponseBody(t, resp, &actual) + + expected := map[string][]string{ + "capabilities": []string{"root"}, + } + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) + } + + // Send only path to capabilities-self + resp = testHttpPost(t, token, addr+"/v1/sys/capabilities-self", map[string]interface{}{ + "path": "testpath", + }) + testResponseStatus(t, resp, 200) + testResponseBody(t, resp, &actual) + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) + } + + // Testing for non-root tokens + + // Create a policy first + resp = testHttpPost(t, token, addr+"/v1/sys/policy/foo", map[string]interface{}{ + "rules": `path "testpath" {capabilities = ["read","sudo"]}`, + }) + testResponseStatus(t, resp, 204) + + // Create a token against the test policy + resp = testHttpPost(t, token, addr+"/v1/auth/token/create", map[string]interface{}{ + "policies": []string{"foo"}, + }) + + var tokenResp map[string]interface{} + testResponseStatus(t, resp, 200) + testResponseBody(t, resp, &tokenResp) + + // Check if desired policies are present in the token + auth := tokenResp["auth"].(map[string]interface{}) + actualPolicies := auth["policies"] + expectedPolicies := []interface{}{"default", "foo"} + if !reflect.DeepEqual(actualPolicies, expectedPolicies) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actualPolicies, expectedPolicies) + } + + // Check the capabilities with the created non-root token + resp = testHttpPost(t, token, addr+"/v1/sys/capabilities", map[string]interface{}{ + "token": auth["client_token"], + "path": "testpath", + }) + testResponseStatus(t, resp, 200) + testResponseBody(t, resp, &actual) + + expected = map[string][]string{ + "capabilities": []string{"sudo", "read"}, + } + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) + } +} diff --git a/vault/acl_test.go b/vault/acl_test.go index 41df6a2071..ac1ab4f7f9 100644 --- a/vault/acl_test.go +++ b/vault/acl_test.go @@ -1,11 +1,56 @@ package vault import ( + "reflect" "testing" "github.com/hashicorp/vault/logical" ) +func TestACL_Capabilities(t *testing.T) { + // Create the root policy ACL + policy := []*Policy{&Policy{Name: "root"}} + acl, err := NewACL(policy) + if err != nil { + t.Fatalf("err: %v", err) + } + + actual := acl.Capabilities("any/path") + expected := []string{"root"} + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) + } + + policies, err := Parse(aclPolicy) + if err != nil { + t.Fatalf("err: %v", err) + } + + acl, err = NewACL([]*Policy{policies}) + if err != nil { + t.Fatalf("err: %v", err) + } + + actual = acl.Capabilities("dev") + expected = []string{"deny"} + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: path:%s\ngot\n%#v\nexpected\n%#v\n", "deny", actual, expected) + } + + actual = acl.Capabilities("dev/") + expected = []string{"sudo", "read", "list", "update", "delete", "create"} + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: path:%s\ngot\n%#v\nexpected\n%#v\n", "dev/", actual, expected) + } + + actual = acl.Capabilities("stage/aws/test") + expected = []string{"sudo", "read", "list", "update"} + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: path:%s\ngot\n%#v\nexpected\n%#v\n", "stage/aws/test", actual, expected) + } + +} + func TestACL_Root(t *testing.T) { // Create the root policy ACL policy := []*Policy{&Policy{Name: "root"}} diff --git a/vault/capabilities_test.go b/vault/capabilities_test.go index f7e34c8a37..8367dc90bd 100644 --- a/vault/capabilities_test.go +++ b/vault/capabilities_test.go @@ -1 +1,45 @@ package vault + +import ( + "reflect" + "testing" +) + +func TestCapabilities_Basic(t *testing.T) { + c, _, token := TestCoreUnsealed(t) + + actual, err := c.Capabilities(token, "path") + if err != nil { + t.Fatalf("err: %s", err) + } + expected := []string{"root"} + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) + } + + // Create a policy + policy, _ := Parse(aclPolicy) + err = c.policyStore.SetPolicy(policy) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Create a token for the policy + ent := &TokenEntry{ + ID: "capabilitiestoken", + Path: "testpath", + Policies: []string{"dev"}, + } + if err := c.tokenStore.create(ent); err != nil { + t.Fatalf("err: %v", err) + } + + actual, err = c.Capabilities("capabilitiestoken", "foo/bar") + if err != nil { + t.Fatalf("err: %s", err) + } + expected = []string{"sudo", "read", "create"} + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected) + } +}