open-vault/vault/logical_system_test.go

684 lines
16 KiB
Go
Raw Normal View History

package vault
import (
"reflect"
"testing"
"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/logical"
)
func TestSystemBackend_RootPaths(t *testing.T) {
expected := []string{
2015-03-16 17:52:35 +00:00
"mounts/*",
"auth/*",
"remount",
2015-03-16 23:33:48 +00:00
"revoke-prefix/*",
2015-03-23 21:43:31 +00:00
"policy",
"policy/*",
"audit",
"audit/*",
2015-04-01 21:03:17 +00:00
"seal",
"raw/*",
}
b := testSystemBackend(t)
2015-03-31 00:46:18 +00:00
actual := b.SpecialPaths().Root
if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad: %#v", actual)
}
}
func TestSystemBackend_mounts(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.ReadOperation, "mounts")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp := map[string]interface{}{
"secret/": map[string]string{
"type": "generic",
"description": "generic secret storage",
},
"sys/": map[string]string{
"type": "system",
"description": "system endpoints used for control, policy and debugging",
},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
}
func TestSystemBackend_mount(t *testing.T) {
b := testSystemBackend(t)
2015-03-16 17:52:35 +00:00
req := logical.TestRequest(t, logical.WriteOperation, "mounts/prod/secret/")
req.Data["type"] = "generic"
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_mount_invalid(t *testing.T) {
b := testSystemBackend(t)
2015-03-16 17:52:35 +00:00
req := logical.TestRequest(t, logical.WriteOperation, "mounts/prod/secret/")
req.Data["type"] = "nope"
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
2015-03-15 23:25:38 +00:00
if resp.Data["error"] != "unknown backend type: nope" {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_unmount(t *testing.T) {
b := testSystemBackend(t)
2015-03-16 17:52:35 +00:00
req := logical.TestRequest(t, logical.DeleteOperation, "mounts/secret/")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_unmount_invalid(t *testing.T) {
b := testSystemBackend(t)
2015-03-16 17:52:35 +00:00
req := logical.TestRequest(t, logical.DeleteOperation, "mounts/foo/")
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "no matching mount" {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_remount(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.WriteOperation, "remount")
req.Data["from"] = "secret"
req.Data["to"] = "foo"
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_remount_invalid(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.WriteOperation, "remount")
req.Data["from"] = "unknown"
req.Data["to"] = "foo"
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "no matching mount at 'unknown/'" {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_remount_system(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.WriteOperation, "remount")
req.Data["from"] = "sys"
req.Data["to"] = "foo"
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "cannot remount 'sys/'" {
t.Fatalf("bad: %v", resp)
}
}
2015-03-16 23:11:55 +00:00
func TestSystemBackend_renew(t *testing.T) {
2015-03-24 18:37:07 +00:00
core, b, root := testCoreSystemBackend(t)
2015-03-16 23:11:55 +00:00
// Create a key with a lease
req := logical.TestRequest(t, logical.WriteOperation, "secret/foo")
req.Data["foo"] = "bar"
req.Data["lease"] = "1h"
2015-03-24 18:37:07 +00:00
req.ClientToken = root
2015-03-16 23:11:55 +00:00
resp, err := core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %#v", resp)
}
// Read a key with a VaultID
req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
2015-03-24 18:37:07 +00:00
req.ClientToken = root
2015-03-16 23:11:55 +00:00
resp, err = core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
if resp == nil || resp.Secret == nil || resp.Secret.VaultID == "" {
2015-03-16 23:11:55 +00:00
t.Fatalf("bad: %#v", resp)
}
// Attempt renew
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
req2 := logical.TestRequest(t, logical.WriteOperation, "renew/"+resp.Secret.VaultID)
2015-03-16 23:11:55 +00:00
req2.Data["increment"] = 100
resp2, err := b.HandleRequest(req2)
if err != nil {
t.Fatalf("err: %v", err)
}
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
if resp2.Secret.VaultID != resp.Secret.VaultID {
2015-03-16 23:11:55 +00:00
t.Fatalf("bad: %#v", resp)
}
if resp2.Data["foo"] != "bar" {
t.Fatalf("bad: %#v", resp)
}
}
2015-03-16 23:14:53 +00:00
func TestSystemBackend_renew_invalidID(t *testing.T) {
b := testSystemBackend(t)
// Attempt renew
req := logical.TestRequest(t, logical.WriteOperation, "renew/foobarbaz")
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "lease not found" {
t.Fatalf("bad: %v", resp)
}
}
2015-03-16 23:26:34 +00:00
func TestSystemBackend_revoke(t *testing.T) {
2015-03-24 18:37:07 +00:00
core, b, root := testCoreSystemBackend(t)
2015-03-16 23:26:34 +00:00
// Create a key with a lease
req := logical.TestRequest(t, logical.WriteOperation, "secret/foo")
req.Data["foo"] = "bar"
req.Data["lease"] = "1h"
2015-03-24 18:37:07 +00:00
req.ClientToken = root
2015-03-16 23:26:34 +00:00
resp, err := core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %#v", resp)
}
// Read a key with a VaultID
req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
2015-03-24 18:37:07 +00:00
req.ClientToken = root
2015-03-16 23:26:34 +00:00
resp, err = core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
if resp == nil || resp.Secret == nil || resp.Secret.VaultID == "" {
2015-03-16 23:26:34 +00:00
t.Fatalf("bad: %#v", resp)
}
2015-03-16 23:33:48 +00:00
// Attempt revoke
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
req2 := logical.TestRequest(t, logical.WriteOperation, "revoke/"+resp.Secret.VaultID)
2015-03-16 23:26:34 +00:00
resp2, err := b.HandleRequest(req2)
if err != nil {
t.Fatalf("err: %v %#v", err, resp2)
}
if resp2 != nil {
t.Fatalf("bad: %#v", resp)
}
2015-03-16 23:33:48 +00:00
// Attempt renew
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
req3 := logical.TestRequest(t, logical.WriteOperation, "renew/"+resp.Secret.VaultID)
2015-03-16 23:33:48 +00:00
resp3, err := b.HandleRequest(req3)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp3.Data["error"] != "lease not found" {
t.Fatalf("bad: %v", resp)
}
2015-03-16 23:26:34 +00:00
}
func TestSystemBackend_revoke_invalidID(t *testing.T) {
b := testSystemBackend(t)
// Attempt renew
req := logical.TestRequest(t, logical.WriteOperation, "revoke/foobarbaz")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
2015-03-16 23:33:48 +00:00
func TestSystemBackend_revokePrefix(t *testing.T) {
2015-03-24 18:37:07 +00:00
core, b, root := testCoreSystemBackend(t)
2015-03-16 23:33:48 +00:00
// Create a key with a lease
req := logical.TestRequest(t, logical.WriteOperation, "secret/foo")
req.Data["foo"] = "bar"
req.Data["lease"] = "1h"
2015-03-24 18:37:07 +00:00
req.ClientToken = root
2015-03-16 23:33:48 +00:00
resp, err := core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %#v", resp)
}
// Read a key with a VaultID
req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
2015-03-24 18:37:07 +00:00
req.ClientToken = root
2015-03-16 23:33:48 +00:00
resp, err = core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
if resp == nil || resp.Secret == nil || resp.Secret.VaultID == "" {
2015-03-16 23:33:48 +00:00
t.Fatalf("bad: %#v", resp)
}
// Attempt revoke
req2 := logical.TestRequest(t, logical.WriteOperation, "revoke-prefix/secret/")
resp2, err := b.HandleRequest(req2)
if err != nil {
t.Fatalf("err: %v %#v", err, resp2)
}
if resp2 != nil {
t.Fatalf("bad: %#v", resp)
}
// Attempt renew
vault: clean up VaultID duplications, make secret responses clearer /cc @armon - This is a reasonably major refactor that I think cleans up a lot of the logic with secrets in responses. The reason for the refactor is that while implementing Renew/Revoke in logical/framework I found the existing API to be really awkward to work with. Primarily, we needed a way to send down internal data for Vault core to store since not all the data you need to revoke a key is always sent down to the user (for example the user than AWS key belongs to). At first, I was doing this manually in logical/framework with req.Storage, but this is going to be such a common event that I think its something core should assist with. Additionally, I think the added context for secrets will be useful in the future when we have a Vault API for returning orphaned out keys: we can also return the internal data that might help an operator. So this leads me to this refactor. I've removed most of the fields in `logical.Response` and replaced it with a single `*Secret` pointer. If this is non-nil, then the response represents a secret. The Secret struct encapsulates all the lease info and such. It also has some fields on it that are only populated at _request_ time for Revoke/Renew operations. There is precedent for this sort of behavior in the Go stdlib where http.Request/http.Response have fields that differ based on client/server. I copied this style. All core unit tests pass. The APIs fail for obvious reasons but I'll fix that up in the next commit.
2015-03-19 22:11:42 +00:00
req3 := logical.TestRequest(t, logical.WriteOperation, "renew/"+resp.Secret.VaultID)
2015-03-16 23:33:48 +00:00
resp3, err := b.HandleRequest(req3)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp3.Data["error"] != "lease not found" {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_authTable(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.ReadOperation, "auth")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp := map[string]interface{}{
"token/": map[string]string{
"type": "token",
"description": "token based credentials",
},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
}
func TestSystemBackend_enableAuth(t *testing.T) {
2015-03-24 18:37:07 +00:00
c, b, _ := testCoreSystemBackend(t)
c.credentialBackends["noop"] = func(map[string]string) (logical.Backend, error) {
return &NoopBackend{}, nil
}
req := logical.TestRequest(t, logical.WriteOperation, "auth/foo")
req.Data["type"] = "noop"
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_enableAuth_invalid(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.WriteOperation, "auth/foo")
req.Data["type"] = "nope"
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "unknown backend type: nope" {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_disableAuth(t *testing.T) {
2015-03-24 18:37:07 +00:00
c, b, _ := testCoreSystemBackend(t)
c.credentialBackends["noop"] = func(map[string]string) (logical.Backend, error) {
return &NoopBackend{}, nil
}
// Register the backend
req := logical.TestRequest(t, logical.WriteOperation, "auth/foo")
req.Data["type"] = "noop"
b.HandleRequest(req)
// Deregister it
req = logical.TestRequest(t, logical.DeleteOperation, "auth/foo")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_disableAuth_invalid(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.DeleteOperation, "auth/foo")
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "no matching backend" {
t.Fatalf("bad: %v", resp)
}
}
2015-03-23 21:43:31 +00:00
func TestSystemBackend_policyList(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.ReadOperation, "policy")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp := map[string]interface{}{
"keys": []string{"root"},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
}
func TestSystemBackend_policyCRUD(t *testing.T) {
b := testSystemBackend(t)
// Create the policy
rules := `path "foo/" { policy = "read" }`
req := logical.TestRequest(t, logical.WriteOperation, "policy/foo")
req.Data["rules"] = rules
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v %#v", err, resp)
}
if resp != nil {
t.Fatalf("bad: %#v", resp)
}
// Read the policy
req = logical.TestRequest(t, logical.ReadOperation, "policy/foo")
resp, err = b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp := map[string]interface{}{
"name": "foo",
"rules": rules,
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
// List the policies
req = logical.TestRequest(t, logical.ReadOperation, "policy")
resp, err = b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp = map[string]interface{}{
"keys": []string{"foo", "root"},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
// Delete the policy
req = logical.TestRequest(t, logical.DeleteOperation, "policy/foo")
resp, err = b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %#v", resp)
}
// Read the policy (deleted)
req = logical.TestRequest(t, logical.ReadOperation, "policy/foo")
resp, err = b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %#v", resp)
}
// List the policies (deleted)
req = logical.TestRequest(t, logical.ReadOperation, "policy")
resp, err = b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp = map[string]interface{}{
"keys": []string{"root"},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
}
func TestSystemBackend_enableAudit(t *testing.T) {
c, b, _ := testCoreSystemBackend(t)
c.auditBackends["noop"] = func(map[string]string) (audit.Backend, error) {
return &NoopAudit{}, nil
}
req := logical.TestRequest(t, logical.WriteOperation, "audit/foo")
req.Data["type"] = "noop"
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_enableAudit_invalid(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.WriteOperation, "audit/foo")
req.Data["type"] = "nope"
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "unknown backend type: nope" {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_auditTable(t *testing.T) {
c, b, _ := testCoreSystemBackend(t)
c.auditBackends["noop"] = func(map[string]string) (audit.Backend, error) {
return &NoopAudit{}, nil
}
req := logical.TestRequest(t, logical.WriteOperation, "audit/foo")
req.Data["type"] = "noop"
req.Data["description"] = "testing"
req.Data["options"] = map[string]interface{}{
"foo": "bar",
}
b.HandleRequest(req)
req = logical.TestRequest(t, logical.ReadOperation, "audit")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
exp := map[string]interface{}{
"foo/": map[string]interface{}{
"type": "noop",
"description": "testing",
"options": map[string]string{
"foo": "bar",
},
},
}
if !reflect.DeepEqual(resp.Data, exp) {
t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
}
}
func TestSystemBackend_disableAudit(t *testing.T) {
c, b, _ := testCoreSystemBackend(t)
c.auditBackends["noop"] = func(map[string]string) (audit.Backend, error) {
return &NoopAudit{}, nil
}
req := logical.TestRequest(t, logical.WriteOperation, "audit/foo")
req.Data["type"] = "noop"
req.Data["description"] = "testing"
req.Data["options"] = map[string]interface{}{
"foo": "bar",
}
b.HandleRequest(req)
// Deregister it
req = logical.TestRequest(t, logical.DeleteOperation, "audit/foo")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_disableAudit_invalid(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.DeleteOperation, "audit/foo")
resp, err := b.HandleRequest(req)
if err != logical.ErrInvalidRequest {
t.Fatalf("err: %v", err)
}
if resp.Data["error"] != "no matching backend" {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_rawRead(t *testing.T) {
b := testSystemBackend(t)
req := logical.TestRequest(t, logical.ReadOperation, "raw/"+coreMountConfigPath)
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp.Data["value"].(string)[0] != '{' {
t.Fatalf("bad: %v", resp)
}
}
func TestSystemBackend_rawWrite(t *testing.T) {
c, b, _ := testCoreSystemBackend(t)
req := logical.TestRequest(t, logical.WriteOperation, "raw/sys/policy/test")
req.Data["value"] = `path "secret/" { policy = "read" }`
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
// Read the policy!
p, err := c.policy.GetPolicy("test")
if err != nil {
t.Fatalf("err: %v", err)
}
if p == nil || len(p.Paths) == 0 {
t.Fatalf("missing policy %#v", p)
}
if p.Paths[0].Prefix != "secret/" || p.Paths[0].Policy != PathPolicyRead {
t.Fatalf("Bad: %#v", p)
}
}
func TestSystemBackend_rawDelete(t *testing.T) {
c, b, _ := testCoreSystemBackend(t)
// set the policy!
p := &Policy{Name: "test"}
err := c.policy.SetPolicy(p)
if err != nil {
t.Fatalf("err: %v", err)
}
// Delete the policy
req := logical.TestRequest(t, logical.DeleteOperation, "raw/sys/policy/test")
resp, err := b.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
}
if resp != nil {
t.Fatalf("bad: %v", resp)
}
// Policy should be gone
2015-04-06 23:41:48 +00:00
c.policy.lru.Purge()
out, err := c.policy.GetPolicy("test")
if err != nil {
t.Fatalf("err: %v", err)
}
if out != nil {
t.Fatalf("policy should be gone")
}
}
2015-03-16 00:35:59 +00:00
func testSystemBackend(t *testing.T) logical.Backend {
2015-03-29 23:18:08 +00:00
c, _, _ := TestCoreUnsealed(t)
2015-03-16 00:35:59 +00:00
return NewSystemBackend(c)
}
2015-03-16 23:11:55 +00:00
2015-03-24 18:37:07 +00:00
func testCoreSystemBackend(t *testing.T) (*Core, logical.Backend, string) {
2015-03-29 23:18:08 +00:00
c, _, root := TestCoreUnsealed(t)
2015-03-24 18:37:07 +00:00
return c, NewSystemBackend(c), root
2015-03-16 23:11:55 +00:00
}