2015-03-06 01:23:56 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
2018-01-08 18:31:38 +00:00
|
|
|
"context"
|
2015-03-06 01:23:56 +00:00
|
|
|
"fmt"
|
Backend plugin system (#2874)
* Add backend plugin changes
* Fix totp backend plugin tests
* Fix logical/plugin InvalidateKey test
* Fix plugin catalog CRUD test, fix NoopBackend
* Clean up commented code block
* Fix system backend mount test
* Set plugin_name to omitempty, fix handleMountTable config parsing
* Clean up comments, keep shim connections alive until cleanup
* Include pluginClient, disallow LookupPlugin call from within a plugin
* Add wrapper around backendPluginClient for proper cleanup
* Add logger shim tests
* Add logger, storage, and system shim tests
* Use pointer receivers for system view shim
* Use plugin name if no path is provided on mount
* Enable plugins for auth backends
* Add backend type attribute, move builtin/plugin/package
* Fix merge conflict
* Fix missing plugin name in mount config
* Add integration tests on enabling auth backend plugins
* Remove dependency cycle on mock-plugin
* Add passthrough backend plugin, use logical.BackendType to determine lease generation
* Remove vault package dependency on passthrough package
* Add basic impl test for passthrough plugin
* Incorporate feedback; set b.backend after shims creation on backendPluginServer
* Fix totp plugin test
* Add plugin backends docs
* Fix tests
* Fix builtin/plugin tests
* Remove flatten from PluginRunner fields
* Move mock plugin to logical/plugin, remove totp and passthrough plugins
* Move pluginMap into newPluginClient
* Do not create storage RPC connection on HandleRequest and HandleExistenceCheck
* Change shim logger's Fatal to no-op
* Change BackendType to uint32, match UX backend types
* Change framework.Backend Setup signature
* Add Setup func to logical.Backend interface
* Move OptionallyEnableMlock call into plugin.Serve, update docs and comments
* Remove commented var in plugin package
* RegisterLicense on logical.Backend interface (#3017)
* Add RegisterLicense to logical.Backend interface
* Update RegisterLicense to use callback func on framework.Backend
* Refactor framework.Backend.RegisterLicense
* plugin: Prevent plugin.SystemViewClient.ResponseWrapData from getting JWTs
* plugin: Revert BackendType to remove TypePassthrough and related references
* Fix typo in plugin backends docs
2017-07-20 17:28:40 +00:00
|
|
|
"io/ioutil"
|
2017-05-05 16:54:37 +00:00
|
|
|
"reflect"
|
2015-03-06 01:23:56 +00:00
|
|
|
"strings"
|
2015-04-29 02:17:45 +00:00
|
|
|
"sync"
|
2015-03-06 01:23:56 +00:00
|
|
|
"testing"
|
2015-09-02 19:56:58 +00:00
|
|
|
"time"
|
2015-03-15 21:53:41 +00:00
|
|
|
|
2015-12-16 17:56:20 +00:00
|
|
|
"github.com/hashicorp/go-uuid"
|
Backend plugin system (#2874)
* Add backend plugin changes
* Fix totp backend plugin tests
* Fix logical/plugin InvalidateKey test
* Fix plugin catalog CRUD test, fix NoopBackend
* Clean up commented code block
* Fix system backend mount test
* Set plugin_name to omitempty, fix handleMountTable config parsing
* Clean up comments, keep shim connections alive until cleanup
* Include pluginClient, disallow LookupPlugin call from within a plugin
* Add wrapper around backendPluginClient for proper cleanup
* Add logger shim tests
* Add logger, storage, and system shim tests
* Use pointer receivers for system view shim
* Use plugin name if no path is provided on mount
* Enable plugins for auth backends
* Add backend type attribute, move builtin/plugin/package
* Fix merge conflict
* Fix missing plugin name in mount config
* Add integration tests on enabling auth backend plugins
* Remove dependency cycle on mock-plugin
* Add passthrough backend plugin, use logical.BackendType to determine lease generation
* Remove vault package dependency on passthrough package
* Add basic impl test for passthrough plugin
* Incorporate feedback; set b.backend after shims creation on backendPluginServer
* Fix totp plugin test
* Add plugin backends docs
* Fix tests
* Fix builtin/plugin tests
* Remove flatten from PluginRunner fields
* Move mock plugin to logical/plugin, remove totp and passthrough plugins
* Move pluginMap into newPluginClient
* Do not create storage RPC connection on HandleRequest and HandleExistenceCheck
* Change shim logger's Fatal to no-op
* Change BackendType to uint32, match UX backend types
* Change framework.Backend Setup signature
* Add Setup func to logical.Backend interface
* Move OptionallyEnableMlock call into plugin.Serve, update docs and comments
* Remove commented var in plugin package
* RegisterLicense on logical.Backend interface (#3017)
* Add RegisterLicense to logical.Backend interface
* Update RegisterLicense to use callback func on framework.Backend
* Refactor framework.Backend.RegisterLicense
* plugin: Prevent plugin.SystemViewClient.ResponseWrapData from getting JWTs
* plugin: Revert BackendType to remove TypePassthrough and related references
* Fix typo in plugin backends docs
2017-07-20 17:28:40 +00:00
|
|
|
"github.com/hashicorp/vault/helper/logformat"
|
2015-03-15 21:53:41 +00:00
|
|
|
"github.com/hashicorp/vault/logical"
|
Backend plugin system (#2874)
* Add backend plugin changes
* Fix totp backend plugin tests
* Fix logical/plugin InvalidateKey test
* Fix plugin catalog CRUD test, fix NoopBackend
* Clean up commented code block
* Fix system backend mount test
* Set plugin_name to omitempty, fix handleMountTable config parsing
* Clean up comments, keep shim connections alive until cleanup
* Include pluginClient, disallow LookupPlugin call from within a plugin
* Add wrapper around backendPluginClient for proper cleanup
* Add logger shim tests
* Add logger, storage, and system shim tests
* Use pointer receivers for system view shim
* Use plugin name if no path is provided on mount
* Enable plugins for auth backends
* Add backend type attribute, move builtin/plugin/package
* Fix merge conflict
* Fix missing plugin name in mount config
* Add integration tests on enabling auth backend plugins
* Remove dependency cycle on mock-plugin
* Add passthrough backend plugin, use logical.BackendType to determine lease generation
* Remove vault package dependency on passthrough package
* Add basic impl test for passthrough plugin
* Incorporate feedback; set b.backend after shims creation on backendPluginServer
* Fix totp plugin test
* Add plugin backends docs
* Fix tests
* Fix builtin/plugin tests
* Remove flatten from PluginRunner fields
* Move mock plugin to logical/plugin, remove totp and passthrough plugins
* Move pluginMap into newPluginClient
* Do not create storage RPC connection on HandleRequest and HandleExistenceCheck
* Change shim logger's Fatal to no-op
* Change BackendType to uint32, match UX backend types
* Change framework.Backend Setup signature
* Add Setup func to logical.Backend interface
* Move OptionallyEnableMlock call into plugin.Serve, update docs and comments
* Remove commented var in plugin package
* RegisterLicense on logical.Backend interface (#3017)
* Add RegisterLicense to logical.Backend interface
* Update RegisterLicense to use callback func on framework.Backend
* Refactor framework.Backend.RegisterLicense
* plugin: Prevent plugin.SystemViewClient.ResponseWrapData from getting JWTs
* plugin: Revert BackendType to remove TypePassthrough and related references
* Fix typo in plugin backends docs
2017-07-20 17:28:40 +00:00
|
|
|
log "github.com/mgutz/logxi/v1"
|
2015-03-06 01:23:56 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type NoopBackend struct {
|
2015-04-29 02:17:45 +00:00
|
|
|
sync.Mutex
|
|
|
|
|
2018-01-18 17:19:18 +00:00
|
|
|
Root []string
|
|
|
|
Login []string
|
|
|
|
Paths []string
|
|
|
|
Requests []*logical.Request
|
|
|
|
Response *logical.Response
|
|
|
|
Invalidations []string
|
|
|
|
DefaultLeaseTTL time.Duration
|
|
|
|
MaxLeaseTTL time.Duration
|
2015-03-06 01:23:56 +00:00
|
|
|
}
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
func (n *NoopBackend) HandleRequest(ctx context.Context, req *logical.Request) (*logical.Response, error) {
|
2015-04-29 02:17:45 +00:00
|
|
|
n.Lock()
|
|
|
|
defer n.Unlock()
|
|
|
|
|
2015-03-31 03:55:01 +00:00
|
|
|
requestCopy := *req
|
2015-03-06 01:23:56 +00:00
|
|
|
n.Paths = append(n.Paths, req.Path)
|
2015-03-31 03:55:01 +00:00
|
|
|
n.Requests = append(n.Requests, &requestCopy)
|
2015-03-15 20:54:20 +00:00
|
|
|
if req.Storage == nil {
|
2015-03-06 01:23:56 +00:00
|
|
|
return nil, fmt.Errorf("missing view")
|
|
|
|
}
|
2015-03-31 03:55:01 +00:00
|
|
|
|
2015-03-16 20:58:22 +00:00
|
|
|
return n.Response, nil
|
2015-03-06 01:23:56 +00:00
|
|
|
}
|
|
|
|
|
2018-01-08 18:31:38 +00:00
|
|
|
func (n *NoopBackend) HandleExistenceCheck(ctx context.Context, req *logical.Request) (bool, bool, error) {
|
2016-01-12 20:09:16 +00:00
|
|
|
return false, false, nil
|
2016-01-07 20:10:05 +00:00
|
|
|
}
|
|
|
|
|
2015-03-31 00:46:18 +00:00
|
|
|
func (n *NoopBackend) SpecialPaths() *logical.Paths {
|
|
|
|
return &logical.Paths{
|
2015-03-31 01:07:05 +00:00
|
|
|
Root: n.Root,
|
|
|
|
Unauthenticated: n.Login,
|
2015-03-31 00:46:18 +00:00
|
|
|
}
|
2015-03-06 01:23:56 +00:00
|
|
|
}
|
|
|
|
|
2015-09-02 19:56:58 +00:00
|
|
|
func (n *NoopBackend) System() logical.SystemView {
|
2018-01-18 17:19:18 +00:00
|
|
|
defaultLeaseTTLVal := time.Hour * 24
|
|
|
|
maxLeaseTTLVal := time.Hour * 24 * 32
|
|
|
|
if n.DefaultLeaseTTL > 0 {
|
|
|
|
defaultLeaseTTLVal = n.DefaultLeaseTTL
|
|
|
|
}
|
|
|
|
|
|
|
|
if n.MaxLeaseTTL > 0 {
|
|
|
|
maxLeaseTTLVal = n.MaxLeaseTTL
|
|
|
|
}
|
|
|
|
|
2015-09-02 19:56:58 +00:00
|
|
|
return logical.StaticSystemView{
|
2018-01-18 17:19:18 +00:00
|
|
|
DefaultLeaseTTLVal: defaultLeaseTTLVal,
|
|
|
|
MaxLeaseTTLVal: maxLeaseTTLVal,
|
2015-09-02 19:56:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (n *NoopBackend) Cleanup(ctx context.Context) {
|
2015-09-10 14:11:37 +00:00
|
|
|
// noop
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (n *NoopBackend) InvalidateKey(ctx context.Context, k string) {
|
2017-02-24 15:45:29 +00:00
|
|
|
n.Invalidations = append(n.Invalidations, k)
|
2017-01-07 23:18:22 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (n *NoopBackend) Setup(ctx context.Context, config *logical.BackendConfig) error {
|
Backend plugin system (#2874)
* Add backend plugin changes
* Fix totp backend plugin tests
* Fix logical/plugin InvalidateKey test
* Fix plugin catalog CRUD test, fix NoopBackend
* Clean up commented code block
* Fix system backend mount test
* Set plugin_name to omitempty, fix handleMountTable config parsing
* Clean up comments, keep shim connections alive until cleanup
* Include pluginClient, disallow LookupPlugin call from within a plugin
* Add wrapper around backendPluginClient for proper cleanup
* Add logger shim tests
* Add logger, storage, and system shim tests
* Use pointer receivers for system view shim
* Use plugin name if no path is provided on mount
* Enable plugins for auth backends
* Add backend type attribute, move builtin/plugin/package
* Fix merge conflict
* Fix missing plugin name in mount config
* Add integration tests on enabling auth backend plugins
* Remove dependency cycle on mock-plugin
* Add passthrough backend plugin, use logical.BackendType to determine lease generation
* Remove vault package dependency on passthrough package
* Add basic impl test for passthrough plugin
* Incorporate feedback; set b.backend after shims creation on backendPluginServer
* Fix totp plugin test
* Add plugin backends docs
* Fix tests
* Fix builtin/plugin tests
* Remove flatten from PluginRunner fields
* Move mock plugin to logical/plugin, remove totp and passthrough plugins
* Move pluginMap into newPluginClient
* Do not create storage RPC connection on HandleRequest and HandleExistenceCheck
* Change shim logger's Fatal to no-op
* Change BackendType to uint32, match UX backend types
* Change framework.Backend Setup signature
* Add Setup func to logical.Backend interface
* Move OptionallyEnableMlock call into plugin.Serve, update docs and comments
* Remove commented var in plugin package
* RegisterLicense on logical.Backend interface (#3017)
* Add RegisterLicense to logical.Backend interface
* Update RegisterLicense to use callback func on framework.Backend
* Refactor framework.Backend.RegisterLicense
* plugin: Prevent plugin.SystemViewClient.ResponseWrapData from getting JWTs
* plugin: Revert BackendType to remove TypePassthrough and related references
* Fix typo in plugin backends docs
2017-07-20 17:28:40 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (n *NoopBackend) Logger() log.Logger {
|
|
|
|
return logformat.NewVaultLoggerWithWriter(ioutil.Discard, log.LevelOff)
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (n *NoopBackend) Initialize(ctx context.Context) error {
|
2017-01-13 21:12:27 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
Backend plugin system (#2874)
* Add backend plugin changes
* Fix totp backend plugin tests
* Fix logical/plugin InvalidateKey test
* Fix plugin catalog CRUD test, fix NoopBackend
* Clean up commented code block
* Fix system backend mount test
* Set plugin_name to omitempty, fix handleMountTable config parsing
* Clean up comments, keep shim connections alive until cleanup
* Include pluginClient, disallow LookupPlugin call from within a plugin
* Add wrapper around backendPluginClient for proper cleanup
* Add logger shim tests
* Add logger, storage, and system shim tests
* Use pointer receivers for system view shim
* Use plugin name if no path is provided on mount
* Enable plugins for auth backends
* Add backend type attribute, move builtin/plugin/package
* Fix merge conflict
* Fix missing plugin name in mount config
* Add integration tests on enabling auth backend plugins
* Remove dependency cycle on mock-plugin
* Add passthrough backend plugin, use logical.BackendType to determine lease generation
* Remove vault package dependency on passthrough package
* Add basic impl test for passthrough plugin
* Incorporate feedback; set b.backend after shims creation on backendPluginServer
* Fix totp plugin test
* Add plugin backends docs
* Fix tests
* Fix builtin/plugin tests
* Remove flatten from PluginRunner fields
* Move mock plugin to logical/plugin, remove totp and passthrough plugins
* Move pluginMap into newPluginClient
* Do not create storage RPC connection on HandleRequest and HandleExistenceCheck
* Change shim logger's Fatal to no-op
* Change BackendType to uint32, match UX backend types
* Change framework.Backend Setup signature
* Add Setup func to logical.Backend interface
* Move OptionallyEnableMlock call into plugin.Serve, update docs and comments
* Remove commented var in plugin package
* RegisterLicense on logical.Backend interface (#3017)
* Add RegisterLicense to logical.Backend interface
* Update RegisterLicense to use callback func on framework.Backend
* Refactor framework.Backend.RegisterLicense
* plugin: Prevent plugin.SystemViewClient.ResponseWrapData from getting JWTs
* plugin: Revert BackendType to remove TypePassthrough and related references
* Fix typo in plugin backends docs
2017-07-20 17:28:40 +00:00
|
|
|
func (n *NoopBackend) Type() logical.BackendType {
|
|
|
|
return logical.TypeLogical
|
|
|
|
}
|
|
|
|
|
2015-03-06 01:23:56 +00:00
|
|
|
func TestRouter_Mount(t *testing.T) {
|
|
|
|
r := NewRouter()
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, "logical/")
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-05-05 16:54:37 +00:00
|
|
|
|
|
|
|
mountEntry := &MountEntry{
|
2017-07-01 02:06:17 +00:00
|
|
|
Path: "prod/aws/",
|
|
|
|
UUID: meUUID,
|
|
|
|
Accessor: "awsaccessor",
|
2017-05-05 16:54:37 +00:00
|
|
|
}
|
|
|
|
|
2015-03-06 01:23:56 +00:00
|
|
|
n := &NoopBackend{}
|
2017-05-05 16:54:37 +00:00
|
|
|
err = r.Mount(n, "prod/aws/", mountEntry, view)
|
2015-03-06 01:23:56 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err = uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2017-05-05 16:54:37 +00:00
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
err = r.Mount(n, "prod/aws/", &MountEntry{UUID: meUUID}, view)
|
2015-03-06 01:23:56 +00:00
|
|
|
if !strings.Contains(err.Error(), "cannot mount under existing mount") {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2017-11-06 20:29:09 +00:00
|
|
|
meUUID, err = uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2015-03-12 00:56:01 +00:00
|
|
|
if path := r.MatchingMount("prod/aws/foo"); path != "prod/aws/" {
|
|
|
|
t.Fatalf("bad: %s", path)
|
|
|
|
}
|
|
|
|
|
2017-10-23 18:59:37 +00:00
|
|
|
if v := r.MatchingStorageByAPIPath("prod/aws/foo"); v.(*BarrierView) != view {
|
2017-05-02 03:34:10 +00:00
|
|
|
t.Fatalf("bad: %v", v)
|
2015-04-02 18:03:59 +00:00
|
|
|
}
|
|
|
|
|
2015-03-12 00:56:01 +00:00
|
|
|
if path := r.MatchingMount("stage/aws/foo"); path != "" {
|
|
|
|
t.Fatalf("bad: %s", path)
|
|
|
|
}
|
|
|
|
|
2017-10-23 18:59:37 +00:00
|
|
|
if v := r.MatchingStorageByAPIPath("stage/aws/foo"); v != nil {
|
2017-05-02 03:34:10 +00:00
|
|
|
t.Fatalf("bad: %v", v)
|
2015-04-02 18:03:59 +00:00
|
|
|
}
|
|
|
|
|
2017-06-17 03:54:19 +00:00
|
|
|
mountEntryFetched := r.MatchingMountByUUID(mountEntry.UUID)
|
2017-05-05 16:54:37 +00:00
|
|
|
if mountEntryFetched == nil || !reflect.DeepEqual(mountEntry, mountEntryFetched) {
|
2017-05-05 16:58:02 +00:00
|
|
|
t.Fatalf("failed to fetch mount entry using its ID; expected: %#v\n actual: %#v\n", mountEntry, mountEntryFetched)
|
2017-05-05 16:54:37 +00:00
|
|
|
}
|
|
|
|
|
2017-10-23 18:59:37 +00:00
|
|
|
mount, prefix, ok := r.MatchingStoragePrefixByStoragePath("logical/foo")
|
2017-01-07 23:18:22 +00:00
|
|
|
if !ok {
|
|
|
|
t.Fatalf("missing storage prefix")
|
|
|
|
}
|
|
|
|
if mount != "prod/aws/" || prefix != "logical/" {
|
|
|
|
t.Fatalf("Bad: %v - %v", mount, prefix)
|
|
|
|
}
|
|
|
|
|
2015-03-15 21:53:41 +00:00
|
|
|
req := &logical.Request{
|
2015-03-06 01:23:56 +00:00
|
|
|
Path: "prod/aws/foo",
|
|
|
|
}
|
2018-01-08 18:31:38 +00:00
|
|
|
resp, err := r.Route(context.Background(), req)
|
2015-03-06 01:23:56 +00:00
|
|
|
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)
|
|
|
|
}
|
2017-11-06 20:29:09 +00:00
|
|
|
|
|
|
|
subMountEntry := &MountEntry{
|
|
|
|
Path: "prod/",
|
|
|
|
UUID: meUUID,
|
|
|
|
Accessor: "prodaccessor",
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.MountConflict("prod/aws/") == "" {
|
|
|
|
t.Fatalf("bad: prod/aws/")
|
|
|
|
}
|
|
|
|
|
|
|
|
// No error is shown here because MountConflict is checked before Mount
|
|
|
|
err = r.Mount(n, "prod/", subMountEntry, view)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if r.MountConflict("prod/test") == "" {
|
|
|
|
t.Fatalf("bad: prod/test/")
|
|
|
|
}
|
2015-03-06 01:23:56 +00:00
|
|
|
}
|
|
|
|
|
2017-07-04 18:00:36 +00:00
|
|
|
func TestRouter_MountCredential(t *testing.T) {
|
|
|
|
r := NewRouter()
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, credentialBarrierPrefix)
|
|
|
|
|
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
mountEntry := &MountEntry{
|
|
|
|
Path: "aws",
|
|
|
|
UUID: meUUID,
|
|
|
|
Accessor: "awsaccessor",
|
|
|
|
}
|
|
|
|
|
|
|
|
n := &NoopBackend{}
|
|
|
|
err = r.Mount(n, "auth/aws/", mountEntry, view)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
meUUID, err = uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = r.Mount(n, "auth/aws/", &MountEntry{UUID: meUUID}, view)
|
|
|
|
if !strings.Contains(err.Error(), "cannot mount under existing mount") {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if path := r.MatchingMount("auth/aws/foo"); path != "auth/aws/" {
|
|
|
|
t.Fatalf("bad: %s", path)
|
|
|
|
}
|
|
|
|
|
2017-10-23 18:59:37 +00:00
|
|
|
if v := r.MatchingStorageByAPIPath("auth/aws/foo"); v.(*BarrierView) != view {
|
2017-07-04 18:00:36 +00:00
|
|
|
t.Fatalf("bad: %v", v)
|
|
|
|
}
|
|
|
|
|
|
|
|
if path := r.MatchingMount("auth/stage/aws/foo"); path != "" {
|
|
|
|
t.Fatalf("bad: %s", path)
|
|
|
|
}
|
|
|
|
|
2017-10-23 18:59:37 +00:00
|
|
|
if v := r.MatchingStorageByAPIPath("auth/stage/aws/foo"); v != nil {
|
2017-07-04 18:00:36 +00:00
|
|
|
t.Fatalf("bad: %v", v)
|
|
|
|
}
|
|
|
|
|
|
|
|
mountEntryFetched := r.MatchingMountByUUID(mountEntry.UUID)
|
|
|
|
if mountEntryFetched == nil || !reflect.DeepEqual(mountEntry, mountEntryFetched) {
|
|
|
|
t.Fatalf("failed to fetch mount entry using its ID; expected: %#v\n actual: %#v\n", mountEntry, mountEntryFetched)
|
|
|
|
}
|
|
|
|
|
2017-10-23 18:59:37 +00:00
|
|
|
mount, prefix, ok := r.MatchingStoragePrefixByStoragePath("auth/foo")
|
2017-07-04 18:00:36 +00:00
|
|
|
if !ok {
|
|
|
|
t.Fatalf("missing storage prefix")
|
|
|
|
}
|
|
|
|
if mount != "auth/aws" || prefix != credentialBarrierPrefix {
|
|
|
|
t.Fatalf("Bad: %v - %v", mount, prefix)
|
|
|
|
}
|
|
|
|
|
|
|
|
req := &logical.Request{
|
|
|
|
Path: "auth/aws/foo",
|
|
|
|
}
|
2018-01-08 18:31:38 +00:00
|
|
|
resp, err := r.Route(context.Background(), req)
|
2017-07-04 18:00:36 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-06 01:23:56 +00:00
|
|
|
func TestRouter_Unmount(t *testing.T) {
|
|
|
|
r := NewRouter()
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, "logical/")
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-03-06 01:23:56 +00:00
|
|
|
n := &NoopBackend{}
|
2017-07-01 02:06:17 +00:00
|
|
|
err = r.Mount(n, "prod/aws/", &MountEntry{Path: "prod/aws/", UUID: meUUID, Accessor: "awsaccessor"}, view)
|
2015-03-06 01:23:56 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
err = r.Unmount(context.Background(), "prod/aws/")
|
2015-03-06 01:23:56 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-03-15 21:53:41 +00:00
|
|
|
req := &logical.Request{
|
2015-03-06 01:23:56 +00:00
|
|
|
Path: "prod/aws/foo",
|
|
|
|
}
|
2018-01-08 18:31:38 +00:00
|
|
|
_, err = r.Route(context.Background(), req)
|
2015-06-19 21:04:32 +00:00
|
|
|
if !strings.Contains(err.Error(), "unsupported path") {
|
2015-03-06 01:23:56 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2017-01-07 23:18:22 +00:00
|
|
|
|
2017-10-23 18:59:37 +00:00
|
|
|
if _, _, ok := r.MatchingStoragePrefixByStoragePath("logical/foo"); ok {
|
2017-01-07 23:18:22 +00:00
|
|
|
t.Fatalf("should not have matching storage prefix")
|
|
|
|
}
|
2015-03-06 01:23:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestRouter_Remount(t *testing.T) {
|
|
|
|
r := NewRouter()
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, "logical/")
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-03-06 01:23:56 +00:00
|
|
|
n := &NoopBackend{}
|
2017-07-01 02:06:17 +00:00
|
|
|
me := &MountEntry{Path: "prod/aws/", UUID: meUUID, Accessor: "awsaccessor"}
|
2017-01-07 23:18:22 +00:00
|
|
|
err = r.Mount(n, "prod/aws/", me, view)
|
2015-03-06 01:23:56 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2017-01-07 23:18:22 +00:00
|
|
|
me.Path = "stage/aws/"
|
2015-03-06 01:23:56 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2015-03-15 21:53:41 +00:00
|
|
|
req := &logical.Request{
|
2015-03-06 01:23:56 +00:00
|
|
|
Path: "prod/aws/foo",
|
|
|
|
}
|
2018-01-08 18:31:38 +00:00
|
|
|
_, err = r.Route(context.Background(), req)
|
2015-06-19 21:04:32 +00:00
|
|
|
if !strings.Contains(err.Error(), "unsupported path") {
|
2015-03-06 01:23:56 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-03-15 21:53:41 +00:00
|
|
|
req = &logical.Request{
|
2015-03-06 01:23:56 +00:00
|
|
|
Path: "stage/aws/foo",
|
|
|
|
}
|
2018-01-08 18:31:38 +00:00
|
|
|
_, err = r.Route(context.Background(), req)
|
2015-03-06 01:23:56 +00:00
|
|
|
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)
|
|
|
|
}
|
2017-01-07 23:18:22 +00:00
|
|
|
|
|
|
|
// Check the resolve from storage still works
|
2017-10-23 18:59:37 +00:00
|
|
|
mount, prefix, _ := r.MatchingStoragePrefixByStoragePath("logical/foobar")
|
2017-01-07 23:18:22 +00:00
|
|
|
if mount != "stage/aws/" {
|
|
|
|
t.Fatalf("bad mount: %s", mount)
|
|
|
|
}
|
|
|
|
if prefix != "logical/" {
|
|
|
|
t.Fatalf("Bad prefix: %s", prefix)
|
|
|
|
}
|
2015-03-06 01:23:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestRouter_RootPath(t *testing.T) {
|
|
|
|
r := NewRouter()
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, "logical/")
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-03-06 01:23:56 +00:00
|
|
|
n := &NoopBackend{
|
|
|
|
Root: []string{
|
|
|
|
"root",
|
|
|
|
"policy/*",
|
|
|
|
},
|
|
|
|
}
|
2017-07-01 02:06:17 +00:00
|
|
|
err = r.Mount(n, "prod/aws/", &MountEntry{UUID: meUUID, Accessor: "awsaccessor"}, 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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-03-23 18:47:55 +00:00
|
|
|
|
|
|
|
func TestRouter_LoginPath(t *testing.T) {
|
|
|
|
r := NewRouter()
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, "auth/")
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-03-31 01:07:05 +00:00
|
|
|
n := &NoopBackend{
|
2015-03-23 18:47:55 +00:00
|
|
|
Login: []string{
|
|
|
|
"login",
|
|
|
|
"oauth/*",
|
|
|
|
},
|
|
|
|
}
|
2017-07-01 02:06:17 +00:00
|
|
|
err = r.Mount(n, "auth/foo/", &MountEntry{UUID: meUUID, Accessor: "authfooaccessor"}, view)
|
2015-03-23 18:47:55 +00:00
|
|
|
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/")
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-04-02 18:12:13 +00:00
|
|
|
n := &NoopBackend{}
|
2017-07-01 02:06:17 +00:00
|
|
|
err = r.Mount(n, "prod/aws/", &MountEntry{UUID: meUUID, Accessor: "awsaccessor"}, view)
|
2015-04-02 18:12:13 +00:00
|
|
|
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",
|
|
|
|
}
|
2018-01-08 18:31:38 +00:00
|
|
|
_, err = r.Route(context.Background(), req)
|
2015-06-19 21:04:32 +00:00
|
|
|
if err.Error() != "unsupported path" {
|
2015-04-02 18:12:13 +00:00
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rollback and Revoke should work
|
|
|
|
req.Operation = logical.RollbackOperation
|
2018-01-08 18:31:38 +00:00
|
|
|
_, err = r.Route(context.Background(), req)
|
2015-04-02 18:12:13 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req.Operation = logical.RevokeOperation
|
2018-01-08 18:31:38 +00:00
|
|
|
_, err = r.Route(context.Background(), req)
|
2015-04-02 18:12:13 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-02 19:01:53 +00:00
|
|
|
func TestRouter_Untaint(t *testing.T) {
|
|
|
|
r := NewRouter()
|
|
|
|
_, barrier, _ := mockBarrier(t)
|
|
|
|
view := NewBarrierView(barrier, "logical/")
|
|
|
|
|
2016-01-13 18:40:08 +00:00
|
|
|
meUUID, err := uuid.GenerateUUID()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
2015-04-02 19:01:53 +00:00
|
|
|
n := &NoopBackend{}
|
2017-07-01 02:06:17 +00:00
|
|
|
err = r.Mount(n, "prod/aws/", &MountEntry{UUID: meUUID, Accessor: "awsaccessor"}, view)
|
2015-04-02 19:01:53 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = r.Taint("prod/aws/")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = r.Untaint("prod/aws/")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
req := &logical.Request{
|
|
|
|
Operation: logical.ReadOperation,
|
|
|
|
Path: "prod/aws/foo",
|
|
|
|
}
|
2018-01-08 18:31:38 +00:00
|
|
|
_, err = r.Route(context.Background(), req)
|
2015-04-02 19:01:53 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-23 18:47:55 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|