open-vault/vault/router_test.go

327 lines
6.2 KiB
Go
Raw Normal View History

2015-03-06 01:23:56 +00:00
package vault
import (
"fmt"
"strings"
"testing"
"github.com/hashicorp/vault/logical"
2015-03-06 01:23:56 +00:00
)
type NoopBackend struct {
Root []string
Login []string
Paths []string
Requests []*logical.Request
Response *logical.Response
2015-03-06 01:23:56 +00:00
}
func (n *NoopBackend) HandleRequest(req *logical.Request) (*logical.Response, error) {
requestCopy := *req
2015-03-06 01:23:56 +00:00
n.Paths = append(n.Paths, req.Path)
n.Requests = append(n.Requests, &requestCopy)
if req.Storage == nil {
2015-03-06 01:23:56 +00:00
return nil, fmt.Errorf("missing view")
}
return n.Response, nil
2015-03-06 01:23:56 +00:00
}
2015-03-31 00:46:18 +00:00
func (n *NoopBackend) SpecialPaths() *logical.Paths {
return &logical.Paths{
Root: n.Root,
Unauthenticated: n.Login,
2015-03-31 00:46:18 +00:00
}
2015-03-06 01:23:56 +00:00
}
func TestRouter_Mount(t *testing.T) {
r := NewRouter()
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "logical/")
n := &NoopBackend{}
2015-03-18 22:48:14 +00:00
err := r.Mount(n, "prod/aws/", view)
2015-03-06 01:23:56 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
2015-03-18 22:48:14 +00:00
err = r.Mount(n, "prod/aws/", view)
2015-03-06 01:23:56 +00:00
if !strings.Contains(err.Error(), "cannot mount under existing mount") {
t.Fatalf("err: %v", err)
}
if path := r.MatchingMount("prod/aws/foo"); path != "prod/aws/" {
t.Fatalf("bad: %s", path)
}
2015-04-02 18:03:59 +00:00
if v := r.MatchingView("prod/aws/foo"); v != view {
t.Fatalf("bad: %s", v)
}
if path := r.MatchingMount("stage/aws/foo"); path != "" {
t.Fatalf("bad: %s", path)
}
2015-04-02 18:03:59 +00:00
if v := r.MatchingView("stage/aws/foo"); v != nil {
t.Fatalf("bad: %s", v)
}
req := &logical.Request{
2015-03-06 01:23:56 +00:00
Path: "prod/aws/foo",
}
resp, err := r.Route(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
// Verify the path
if len(n.Paths) != 1 || n.Paths[0] != "foo" {
t.Fatalf("bad: %v", n.Paths)
}
}
func TestRouter_Unmount(t *testing.T) {
r := NewRouter()
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "logical/")
n := &NoopBackend{}
2015-03-18 22:48:14 +00:00
err := r.Mount(n, "prod/aws/", view)
2015-03-06 01:23:56 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
err = r.Unmount("prod/aws/")
if err != nil {
t.Fatalf("err: %v", err)
}
req := &logical.Request{
2015-03-06 01:23:56 +00:00
Path: "prod/aws/foo",
}
_, err = r.Route(req)
if !strings.Contains(err.Error(), "no handler for route") {
t.Fatalf("err: %v", err)
}
}
func TestRouter_Remount(t *testing.T) {
r := NewRouter()
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "logical/")
n := &NoopBackend{}
2015-03-18 22:48:14 +00:00
err := r.Mount(n, "prod/aws/", view)
2015-03-06 01:23:56 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
err = r.Remount("prod/aws/", "stage/aws/")
if err != nil {
t.Fatalf("err: %v", err)
}
err = r.Remount("prod/aws/", "stage/aws/")
if !strings.Contains(err.Error(), "no mount at") {
t.Fatalf("err: %v", err)
}
req := &logical.Request{
2015-03-06 01:23:56 +00:00
Path: "prod/aws/foo",
}
_, err = r.Route(req)
if !strings.Contains(err.Error(), "no handler for route") {
t.Fatalf("err: %v", err)
}
req = &logical.Request{
2015-03-06 01:23:56 +00:00
Path: "stage/aws/foo",
}
_, err = r.Route(req)
if err != nil {
t.Fatalf("err: %v", err)
}
// Verify the path
if len(n.Paths) != 1 || n.Paths[0] != "foo" {
t.Fatalf("bad: %v", n.Paths)
}
}
func TestRouter_RootPath(t *testing.T) {
r := NewRouter()
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "logical/")
n := &NoopBackend{
Root: []string{
"root",
"policy/*",
},
}
2015-03-18 22:48:14 +00:00
err := r.Mount(n, "prod/aws/", view)
2015-03-06 01:23:56 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
type tcase struct {
path string
expect bool
}
tcases := []tcase{
{"random", false},
{"prod/aws/foo", false},
{"prod/aws/root", true},
{"prod/aws/root-more", false},
{"prod/aws/policy", false},
{"prod/aws/policy/", true},
{"prod/aws/policy/ops", true},
}
for _, tc := range tcases {
out := r.RootPath(tc.path)
if out != tc.expect {
t.Fatalf("bad: path: %s expect: %v got %v", tc.path, tc.expect, out)
}
}
}
/*
func TestRouter_RouteLogin(t *testing.T) {
r := NewRouter()
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "auth/")
n := &NoopBackend{
Login: []string{"bar"},
}
err := r.Mount(n, "auth/foo/", view)
if err != nil {
t.Fatalf("err: %v", err)
}
if path := r.MatchingMount("auth/foo/bar"); path != "auth/foo/" {
t.Fatalf("bad: %s", path)
}
req := &logical.Request{
Path: "auth/foo/bar",
}
resp, err := r.RouteLogin(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
// Verify the path
if len(n.LPaths) != 1 || n.LPaths[0] != "bar" {
t.Fatalf("bad: %v", n.Paths)
}
}
*/
func TestRouter_LoginPath(t *testing.T) {
r := NewRouter()
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "auth/")
n := &NoopBackend{
Login: []string{
"login",
"oauth/*",
},
}
err := r.Mount(n, "auth/foo/", view)
if err != nil {
t.Fatalf("err: %v", err)
}
type tcase struct {
path string
expect bool
}
tcases := []tcase{
{"random", false},
{"auth/foo/bar", false},
{"auth/foo/login", true},
{"auth/foo/oauth", false},
{"auth/foo/oauth/redirect", true},
}
for _, tc := range tcases {
out := r.LoginPath(tc.path)
if out != tc.expect {
t.Fatalf("bad: path: %s expect: %v got %v", tc.path, tc.expect, out)
}
}
}
2015-04-02 18:12:13 +00:00
func TestRouter_Taint(t *testing.T) {
r := NewRouter()
_, barrier, _ := mockBarrier(t)
view := NewBarrierView(barrier, "logical/")
n := &NoopBackend{}
err := r.Mount(n, "prod/aws/", view)
if err != nil {
t.Fatalf("err: %v", err)
}
err = r.Taint("prod/aws/")
if err != nil {
t.Fatalf("err: %v", err)
}
req := &logical.Request{
Operation: logical.ReadOperation,
Path: "prod/aws/foo",
}
_, err = r.Route(req)
if err.Error() != "no handler for route 'prod/aws/foo'" {
t.Fatalf("err: %v", err)
}
// Rollback and Revoke should work
req.Operation = logical.RollbackOperation
_, err = r.Route(req)
if err != nil {
t.Fatalf("err: %v", err)
}
req.Operation = logical.RevokeOperation
_, err = r.Route(req)
if err != nil {
t.Fatalf("err: %v", err)
}
}
func TestPathsToRadix(t *testing.T) {
// Provide real paths
paths := []string{
"foo",
"foo/*",
"sub/bar*",
}
r := pathsToRadix(paths)
raw, ok := r.Get("foo")
if !ok || raw.(bool) != false {
t.Fatalf("bad: %v (foo)", raw)
}
raw, ok = r.Get("foo/")
if !ok || raw.(bool) != true {
t.Fatalf("bad: %v (foo/)", raw)
}
raw, ok = r.Get("sub/bar")
if !ok || raw.(bool) != true {
t.Fatalf("bad: %v (sub/bar)", raw)
}
}