adding existence check for roles

This commit is contained in:
Chris Hoffman 2017-12-15 19:50:20 -05:00
parent b904d28d82
commit b08606b320
2 changed files with 45 additions and 14 deletions

View File

@ -63,7 +63,7 @@ func prepareTestContainer(t *testing.T) (cleanup func(), retAddress string, noma
t.Fatalf("err: %v", err) t.Fatalf("err: %v", err)
} }
nomadToken = aclbootstrap.SecretID nomadToken = aclbootstrap.SecretID
t.Log("[WARN] Generated Master token: %s", nomadToken) t.Logf("[WARN] Generated Master token: %s", nomadToken)
policy := &nomadapi.ACLPolicy{ policy := &nomadapi.ACLPolicy{
Name: "test", Name: "test",
Description: "test", Description: "test",
@ -211,7 +211,7 @@ func TestBackend_renew_revoke(t *testing.T) {
if err := mapstructure.Decode(resp.Data, &d); err != nil { if err := mapstructure.Decode(resp.Data, &d); err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Log("[WARN] Generated token: %s with accesor %s", d.Token, d.Accessor) t.Logf("[WARN] Generated token: %s with accesor %s", d.Token, d.Accessor)
// Build a client and verify that the credentials work // Build a client and verify that the credentials work
nomadapiConfig := nomadapi.DefaultConfig() nomadapiConfig := nomadapi.DefaultConfig()

View File

@ -1,6 +1,8 @@
package nomad package nomad
import ( import (
"errors"
"github.com/hashicorp/errwrap" "github.com/hashicorp/errwrap"
"github.com/hashicorp/vault/logical" "github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework" "github.com/hashicorp/vault/logical/framework"
@ -32,7 +34,6 @@ func pathRoles(b *backend) *framework.Path {
"global": &framework.FieldSchema{ "global": &framework.FieldSchema{
Type: framework.TypeBool, Type: framework.TypeBool,
Default: false,
Description: "Boolean value describing if the token should be global or not. Defaults to false.", Description: "Boolean value describing if the token should be global or not. Defaults to false.",
}, },
@ -48,13 +49,31 @@ Defaults to 'client'.`,
Callbacks: map[logical.Operation]framework.OperationFunc{ Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.pathRolesRead, logical.ReadOperation: b.pathRolesRead,
logical.CreateOperation: b.pathRolesWrite,
logical.UpdateOperation: b.pathRolesWrite, logical.UpdateOperation: b.pathRolesWrite,
logical.DeleteOperation: b.pathRolesDelete, logical.DeleteOperation: b.pathRolesDelete,
}, },
ExistenceCheck: b.rolesExistenceCheck,
} }
} }
// Establishes dichotomy of request operation between CreateOperation and UpdateOperation.
// Returning 'true' forces an UpdateOperation, CreateOperation otherwise.
func (b *backend) rolesExistenceCheck(req *logical.Request, d *framework.FieldData) (bool, error) {
name := d.Get("name").(string)
entry, err := b.Role(req.Storage, name)
if err != nil {
return false, err
}
return entry != nil, nil
}
func (b *backend) Role(storage logical.Storage, name string) (*roleConfig, error) { func (b *backend) Role(storage logical.Storage, name string) (*roleConfig, error) {
if name == "" {
return nil, errors.New("invalid role name")
}
entry, err := storage.Get("role/" + name) entry, err := storage.Get("role/" + name)
if err != nil { if err != nil {
return nil, errwrap.Wrapf("error retrieving role: {{err}}", err) return nil, errwrap.Wrapf("error retrieving role: {{err}}", err)
@ -105,19 +124,30 @@ func (b *backend) pathRolesRead(
func (b *backend) pathRolesWrite( func (b *backend) pathRolesWrite(
req *logical.Request, d *framework.FieldData) (*logical.Response, error) { req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
tokenType := d.Get("type").(string)
name := d.Get("name").(string) name := d.Get("name").(string)
global := d.Get("global").(bool)
policies := d.Get("policies").([]string)
switch tokenType { role, err := b.Role(req.Storage, name)
if err != nil {
return nil, err
}
if role == nil {
role = new(roleConfig)
}
policies, ok := d.GetOk("policies")
if ok {
role.Policies = policies.([]string)
}
role.TokenType = d.Get("type").(string)
switch role.TokenType {
case "client": case "client":
if len(policies) == 0 { if len(role.Policies) == 0 {
return logical.ErrorResponse( return logical.ErrorResponse(
"policies cannot be empty when using client tokens"), nil "policies cannot be empty when using client tokens"), nil
} }
case "management": case "management":
if len(policies) != 0 { if len(role.Policies) != 0 {
return logical.ErrorResponse( return logical.ErrorResponse(
"policies should be empty when using management tokens"), nil "policies should be empty when using management tokens"), nil
} }
@ -126,11 +156,12 @@ func (b *backend) pathRolesWrite(
`type must be "client" or "management"`), nil `type must be "client" or "management"`), nil
} }
entry, err := logical.StorageEntryJSON("role/"+name, roleConfig{ global, ok := d.GetOk("global")
Policies: policies, if ok {
TokenType: tokenType, role.Global = global.(bool)
Global: global, }
})
entry, err := logical.StorageEntryJSON("role/"+name, role)
if err != nil { if err != nil {
return nil, err return nil, err
} }