mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-04 04:28:08 +00:00 
			
		
		
		
	helper/backend: basic path routing (naive)
This commit is contained in:
		@@ -1,6 +1,9 @@
 | 
				
			|||||||
package backend
 | 
					package backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
						"sync"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/hashicorp/vault/vault"
 | 
						"github.com/hashicorp/vault/vault"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,7 +13,13 @@ import (
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// This is recommended over implementing vault.LogicalBackend directly.
 | 
					// This is recommended over implementing vault.LogicalBackend directly.
 | 
				
			||||||
type Backend struct {
 | 
					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
 | 
						Paths []*Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						once sync.Once
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Path is a single path that the backend responds to.
 | 
					// 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)
 | 
						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.
 | 
					// FieldSchema is a basic schema to describe the format of a path field.
 | 
				
			||||||
type FieldSchema struct {
 | 
					type FieldSchema struct {
 | 
				
			||||||
	Type    FieldType
 | 
						Type    FieldType
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,6 +5,51 @@ import (
 | 
				
			|||||||
	"testing"
 | 
						"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) {
 | 
					func TestFieldSchemaDefaultOrZero(t *testing.T) {
 | 
				
			||||||
	cases := map[string]struct {
 | 
						cases := map[string]struct {
 | 
				
			||||||
		Schema *FieldSchema
 | 
							Schema *FieldSchema
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user