helper/backend: one callback per operation

This commit is contained in:
Mitchell Hashimoto 2015-03-14 00:19:25 -07:00
parent 7f87d9ea6f
commit e8e55ef8b1
2 changed files with 68 additions and 13 deletions

View File

@ -47,11 +47,15 @@ type Path struct {
// trailing '*' to denote that it is a prefix, and not an exact match.
Root string
// Callback is what is called when this path is requested with
// a valid set of data.
Callback func(*vault.Request, *FieldData) (*vault.Response, error)
// Callbacks are the set of callbacks that are called for a given
// operation. If a callback for a specific operation is not present,
// then vault.ErrUnsupportedOperation is automatically generated.
Callbacks map[vault.Operation]OperationFunc
}
// OperationFunc is the callback called for an operation on a path.
type OperationFunc func(*vault.Request, *FieldData) (*vault.Response, error)
// vault.LogicalBackend impl.
func (b *Backend) HandleRequest(req *vault.Request) (*vault.Response, error) {
// Find the matching route
@ -70,8 +74,17 @@ func (b *Backend) HandleRequest(req *vault.Request) (*vault.Response, error) {
raw[k] = v
}
// Look up the callback for this operation
if path.Callbacks == nil {
return nil, vault.ErrUnsupportedOperation
}
callback, ok := path.Callbacks[req.Operation]
if !ok {
return nil, vault.ErrUnsupportedOperation
}
// Call the callback with the request and the data
return path.Callback(req, &FieldData{
return callback(req, &FieldData{
Raw: raw,
Schema: path.Fields,
})

View File

@ -55,14 +55,17 @@ func TestBackendHandleRequest(t *testing.T) {
Fields: map[string]*FieldSchema{
"value": &FieldSchema{Type: TypeInt},
},
Callback: callback,
Callbacks: map[vault.Operation]OperationFunc{
vault.ReadOperation: callback,
},
},
},
}
resp, err := b.HandleRequest(&vault.Request{
Path: "foo/bar",
Data: map[string]interface{}{"value": "42"},
Operation: vault.ReadOperation,
Path: "foo/bar",
Data: map[string]interface{}{"value": "42"},
})
if err != nil {
t.Fatalf("err: %s", err)
@ -88,20 +91,56 @@ func TestBackendHandleRequest_404(t *testing.T) {
Fields: map[string]*FieldSchema{
"value": &FieldSchema{Type: TypeInt},
},
Callback: callback,
Callbacks: map[vault.Operation]OperationFunc{
vault.ReadOperation: callback,
},
},
},
}
_, err := b.HandleRequest(&vault.Request{
Path: "foo/baz",
Data: map[string]interface{}{"value": "84"},
Operation: vault.ReadOperation,
Path: "foo/baz",
Data: map[string]interface{}{"value": "84"},
})
if err != vault.ErrUnsupportedPath {
t.Fatalf("err: %s", err)
}
}
func TestBackendHandleRequest_unsupportedOperation(t *testing.T) {
callback := func(req *vault.Request, data *FieldData) (*vault.Response, error) {
return &vault.Response{
Data: map[string]interface{}{
"value": data.Get("value"),
},
}, nil
}
b := &Backend{
Paths: []*Path{
&Path{
Pattern: `foo/bar`,
Fields: map[string]*FieldSchema{
"value": &FieldSchema{Type: TypeInt},
},
Callbacks: map[vault.Operation]OperationFunc{
vault.ReadOperation: callback,
},
},
},
}
_, err := b.HandleRequest(&vault.Request{
Operation: vault.WriteOperation,
Path: "foo/bar",
Data: map[string]interface{}{"value": "84"},
})
if err != vault.ErrUnsupportedOperation {
t.Fatalf("err: %s", err)
}
}
func TestBackendHandleRequest_urlPriority(t *testing.T) {
callback := func(req *vault.Request, data *FieldData) (*vault.Response, error) {
return &vault.Response{
@ -118,14 +157,17 @@ func TestBackendHandleRequest_urlPriority(t *testing.T) {
Fields: map[string]*FieldSchema{
"value": &FieldSchema{Type: TypeInt},
},
Callback: callback,
Callbacks: map[vault.Operation]OperationFunc{
vault.ReadOperation: callback,
},
},
},
}
resp, err := b.HandleRequest(&vault.Request{
Path: "foo/42",
Data: map[string]interface{}{"value": "84"},
Operation: vault.ReadOperation,
Path: "foo/42",
Data: map[string]interface{}{"value": "84"},
})
if err != nil {
t.Fatalf("err: %s", err)