mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
helper/backend: basic path routing (naive)
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
package backend
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/vault/vault"
|
||||
)
|
||||
|
||||
@@ -10,7 +13,13 @@ import (
|
||||
//
|
||||
// This is recommended over implementing vault.LogicalBackend directly.
|
||||
type Backend struct {
|
||||
// Paths are the various routes that the backend responds to.
|
||||
// This cannot be modified after construction (i.e. dynamically changing
|
||||
// paths, including adding or removing, is not allowed once the
|
||||
// backend is in use).
|
||||
Paths []*Path
|
||||
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// Path is a single path that the backend responds to.
|
||||
@@ -42,6 +51,21 @@ type Path struct {
|
||||
Callback func(*vault.Request, *FieldData) (*vault.Response, error)
|
||||
}
|
||||
|
||||
func (b *Backend) Route(path string) *Path {
|
||||
regexps := make([]*regexp.Regexp, len(b.Paths))
|
||||
for i, p := range b.Paths {
|
||||
regexps[i] = regexp.MustCompile(p.Pattern)
|
||||
}
|
||||
|
||||
for i, re := range regexps {
|
||||
if re.MatchString(path) {
|
||||
return b.Paths[i]
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// FieldSchema is a basic schema to describe the format of a path field.
|
||||
type FieldSchema struct {
|
||||
Type FieldType
|
||||
|
||||
@@ -5,6 +5,51 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBackendRoute(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Patterns []string
|
||||
Path string
|
||||
Match string
|
||||
}{
|
||||
"no match": {
|
||||
[]string{"foo"},
|
||||
"bar",
|
||||
"",
|
||||
},
|
||||
|
||||
"exact": {
|
||||
[]string{"foo"},
|
||||
"foo",
|
||||
"foo",
|
||||
},
|
||||
|
||||
"regexp": {
|
||||
[]string{"fo+"},
|
||||
"foo",
|
||||
"fo+",
|
||||
},
|
||||
}
|
||||
|
||||
for n, tc := range cases {
|
||||
paths := make([]*Path, len(tc.Patterns))
|
||||
for i, pattern := range tc.Patterns {
|
||||
paths[i] = &Path{Pattern: pattern}
|
||||
}
|
||||
|
||||
b := &Backend{Paths: paths}
|
||||
result := b.Route(tc.Path)
|
||||
match := ""
|
||||
if result != nil {
|
||||
match = result.Pattern
|
||||
}
|
||||
|
||||
if match != tc.Match {
|
||||
t.Fatalf("bad: %s\n\nExpected: %s\nGot: %s",
|
||||
n, tc.Match, match)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldSchemaDefaultOrZero(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
Schema *FieldSchema
|
||||
|
||||
Reference in New Issue
Block a user