vendorify
diff --git a/go/vendor/github.com/go-openapi/runtime/middleware/router.go b/go/vendor/github.com/go-openapi/runtime/middleware/router.go
new file mode 100644
index 0000000..73c8eeb
--- /dev/null
+++ b/go/vendor/github.com/go-openapi/runtime/middleware/router.go
@@ -0,0 +1,478 @@
+// Copyright 2015 go-swagger maintainers
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package middleware
+
+import (
+	"fmt"
+	"net/http"
+	fpath "path"
+	"regexp"
+	"strings"
+
+	"github.com/go-openapi/runtime/security"
+
+	"github.com/go-openapi/analysis"
+	"github.com/go-openapi/errors"
+	"github.com/go-openapi/loads"
+	"github.com/go-openapi/runtime"
+	"github.com/go-openapi/runtime/middleware/denco"
+	"github.com/go-openapi/spec"
+	"github.com/go-openapi/strfmt"
+)
+
+// RouteParam is a object to capture route params in a framework agnostic way.
+// implementations of the muxer should use these route params to communicate with the
+// swagger framework
+type RouteParam struct {
+	Name  string
+	Value string
+}
+
+// RouteParams the collection of route params
+type RouteParams []RouteParam
+
+// Get gets the value for the route param for the specified key
+func (r RouteParams) Get(name string) string {
+	vv, _, _ := r.GetOK(name)
+	if len(vv) > 0 {
+		return vv[len(vv)-1]
+	}
+	return ""
+}
+
+// GetOK gets the value but also returns booleans to indicate if a key or value
+// is present. This aids in validation and satisfies an interface in use there
+//
+// The returned values are: data, has key, has value
+func (r RouteParams) GetOK(name string) ([]string, bool, bool) {
+	for _, p := range r {
+		if p.Name == name {
+			return []string{p.Value}, true, p.Value != ""
+		}
+	}
+	return nil, false, false
+}
+
+// NewRouter creates a new context aware router middleware
+func NewRouter(ctx *Context, next http.Handler) http.Handler {
+	if ctx.router == nil {
+		ctx.router = DefaultRouter(ctx.spec, ctx.api)
+	}
+
+	return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
+		if _, rCtx, ok := ctx.RouteInfo(r); ok {
+			next.ServeHTTP(rw, rCtx)
+			return
+		}
+
+		// Not found, check if it exists in the other methods first
+		if others := ctx.AllowedMethods(r); len(others) > 0 {
+			ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.MethodNotAllowed(r.Method, others))
+			return
+		}
+
+		ctx.Respond(rw, r, ctx.analyzer.RequiredProduces(), nil, errors.NotFound("path %s was not found", r.URL.EscapedPath()))
+	})
+}
+
+// RoutableAPI represents an interface for things that can serve
+// as a provider of implementations for the swagger router
+type RoutableAPI interface {
+	HandlerFor(string, string) (http.Handler, bool)
+	ServeErrorFor(string) func(http.ResponseWriter, *http.Request, error)
+	ConsumersFor([]string) map[string]runtime.Consumer
+	ProducersFor([]string) map[string]runtime.Producer
+	AuthenticatorsFor(map[string]spec.SecurityScheme) map[string]runtime.Authenticator
+	Authorizer() runtime.Authorizer
+	Formats() strfmt.Registry
+	DefaultProduces() string
+	DefaultConsumes() string
+}
+
+// Router represents a swagger aware router
+type Router interface {
+	Lookup(method, path string) (*MatchedRoute, bool)
+	OtherMethods(method, path string) []string
+}
+
+type defaultRouteBuilder struct {
+	spec     *loads.Document
+	analyzer *analysis.Spec
+	api      RoutableAPI
+	records  map[string][]denco.Record
+}
+
+type defaultRouter struct {
+	spec    *loads.Document
+	routers map[string]*denco.Router
+}
+
+func newDefaultRouteBuilder(spec *loads.Document, api RoutableAPI) *defaultRouteBuilder {
+	return &defaultRouteBuilder{
+		spec:     spec,
+		analyzer: analysis.New(spec.Spec()),
+		api:      api,
+		records:  make(map[string][]denco.Record),
+	}
+}
+
+// DefaultRouter creates a default implemenation of the router
+func DefaultRouter(spec *loads.Document, api RoutableAPI) Router {
+	builder := newDefaultRouteBuilder(spec, api)
+	if spec != nil {
+		for method, paths := range builder.analyzer.Operations() {
+			for path, operation := range paths {
+				fp := fpath.Join(spec.BasePath(), path)
+				debugLog("adding route %s %s %q", method, fp, operation.ID)
+				builder.AddRoute(method, fp, operation)
+			}
+		}
+	}
+	return builder.Build()
+}
+
+// RouteAuthenticator is an authenticator that can compose several authenticators together.
+// It also knows when it contains an authenticator that allows for anonymous pass through.
+// Contains a group of 1 or more authenticators that have a logical AND relationship
+type RouteAuthenticator struct {
+	Authenticator  map[string]runtime.Authenticator
+	Schemes        []string
+	Scopes         map[string][]string
+	allScopes      []string
+	commonScopes   []string
+	allowAnonymous bool
+}
+
+func (ra *RouteAuthenticator) AllowsAnonymous() bool {
+	return ra.allowAnonymous
+}
+
+// AllScopes returns a list of unique scopes that is the combination
+// of all the scopes in the requirements
+func (ra *RouteAuthenticator) AllScopes() []string {
+	return ra.allScopes
+}
+
+// CommonScopes returns a list of unique scopes that are common in all the
+// scopes in the requirements
+func (ra *RouteAuthenticator) CommonScopes() []string {
+	return ra.commonScopes
+}
+
+// Authenticate Authenticator interface implementation
+func (ra *RouteAuthenticator) Authenticate(req *http.Request, route *MatchedRoute) (bool, interface{}, error) {
+	if ra.allowAnonymous {
+		route.Authenticator = ra
+		return true, nil, nil
+	}
+	// iterate in proper order
+	var lastResult interface{}
+	for _, scheme := range ra.Schemes {
+		if authenticator, ok := ra.Authenticator[scheme]; ok {
+			applies, princ, err := authenticator.Authenticate(&security.ScopedAuthRequest{
+				Request:        req,
+				RequiredScopes: ra.Scopes[scheme],
+			})
+			if !applies {
+				return false, nil, nil
+			}
+
+			if err != nil {
+				route.Authenticator = ra
+				return true, nil, err
+			}
+			lastResult = princ
+		}
+	}
+	route.Authenticator = ra
+	return true, lastResult, nil
+}
+
+func stringSliceUnion(slices ...[]string) []string {
+	unique := make(map[string]struct{})
+	var result []string
+	for _, slice := range slices {
+		for _, entry := range slice {
+			if _, ok := unique[entry]; ok {
+				continue
+			}
+			unique[entry] = struct{}{}
+			result = append(result, entry)
+		}
+	}
+	return result
+}
+
+func stringSliceIntersection(slices ...[]string) []string {
+	unique := make(map[string]int)
+	var intersection []string
+
+	total := len(slices)
+	var emptyCnt int
+	for _, slice := range slices {
+		if len(slice) == 0 {
+			emptyCnt++
+			continue
+		}
+
+		for _, entry := range slice {
+			unique[entry]++
+			if unique[entry] == total-emptyCnt { // this entry appeared in all the non-empty slices
+				intersection = append(intersection, entry)
+			}
+		}
+	}
+
+	return intersection
+}
+
+// RouteAuthenticators represents a group of authenticators that represent a logical OR
+type RouteAuthenticators []RouteAuthenticator
+
+// AllowsAnonymous returns true when there is an authenticator that means optional auth
+func (ras RouteAuthenticators) AllowsAnonymous() bool {
+	for _, ra := range ras {
+		if ra.AllowsAnonymous() {
+			return true
+		}
+	}
+	return false
+}
+
+// Authenticate method implemention so this collection can be used as authenticator
+func (ras RouteAuthenticators) Authenticate(req *http.Request, route *MatchedRoute) (bool, interface{}, error) {
+	var lastError error
+	var allowsAnon bool
+	var anonAuth RouteAuthenticator
+
+	for _, ra := range ras {
+		if ra.AllowsAnonymous() {
+			anonAuth = ra
+			allowsAnon = true
+			continue
+		}
+		applies, usr, err := ra.Authenticate(req, route)
+		if !applies || err != nil || usr == nil {
+			if err != nil {
+				lastError = err
+			}
+			continue
+		}
+		return applies, usr, nil
+	}
+
+	if allowsAnon && lastError == nil {
+		route.Authenticator = &anonAuth
+		return true, nil, lastError
+	}
+	return lastError != nil, nil, lastError
+}
+
+type routeEntry struct {
+	PathPattern    string
+	BasePath       string
+	Operation      *spec.Operation
+	Consumes       []string
+	Consumers      map[string]runtime.Consumer
+	Produces       []string
+	Producers      map[string]runtime.Producer
+	Parameters     map[string]spec.Parameter
+	Handler        http.Handler
+	Formats        strfmt.Registry
+	Binder         *untypedRequestBinder
+	Authenticators RouteAuthenticators
+	Authorizer     runtime.Authorizer
+}
+
+// MatchedRoute represents the route that was matched in this request
+type MatchedRoute struct {
+	routeEntry
+	Params        RouteParams
+	Consumer      runtime.Consumer
+	Producer      runtime.Producer
+	Authenticator *RouteAuthenticator
+}
+
+// HasAuth returns true when the route has a security requirement defined
+func (m *MatchedRoute) HasAuth() bool {
+	return len(m.Authenticators) > 0
+}
+
+// NeedsAuth returns true when the request still
+// needs to perform authentication
+func (m *MatchedRoute) NeedsAuth() bool {
+	return m.HasAuth() && m.Authenticator == nil
+}
+
+func (d *defaultRouter) Lookup(method, path string) (*MatchedRoute, bool) {
+	mth := strings.ToUpper(method)
+	debugLog("looking up route for %s %s", method, path)
+	if Debug {
+		if len(d.routers) == 0 {
+			debugLog("there are no known routers")
+		}
+		for meth := range d.routers {
+			debugLog("got a router for %s", meth)
+		}
+	}
+	if router, ok := d.routers[mth]; ok {
+		if m, rp, ok := router.Lookup(fpath.Clean(path)); ok && m != nil {
+			if entry, ok := m.(*routeEntry); ok {
+				debugLog("found a route for %s %s with %d parameters", method, path, len(entry.Parameters))
+				var params RouteParams
+				for _, p := range rp {
+					v, err := pathUnescape(p.Value)
+					if err != nil {
+						debugLog("failed to escape %q: %v", p.Value, err)
+						v = p.Value
+					}
+					// a workaround to handle fragment/composing parameters until they are supported in denco router
+					// check if this parameter is a fragment within a path segment
+					if xpos := strings.Index(entry.PathPattern, fmt.Sprintf("{%s}", p.Name)) + len(p.Name) + 2; xpos < len(entry.PathPattern) && entry.PathPattern[xpos] != '/' {
+						// extract fragment parameters
+						ep := strings.Split(entry.PathPattern[xpos:], "/")[0]
+						pnames, pvalues := decodeCompositParams(p.Name, v, ep, nil, nil)
+						for i, pname := range pnames {
+							params = append(params, RouteParam{Name: pname, Value: pvalues[i]})
+						}
+					} else {
+						// use the parameter directly
+						params = append(params, RouteParam{Name: p.Name, Value: v})
+					}
+				}
+				return &MatchedRoute{routeEntry: *entry, Params: params}, true
+			}
+		} else {
+			debugLog("couldn't find a route by path for %s %s", method, path)
+		}
+	} else {
+		debugLog("couldn't find a route by method for %s %s", method, path)
+	}
+	return nil, false
+}
+
+func (d *defaultRouter) OtherMethods(method, path string) []string {
+	mn := strings.ToUpper(method)
+	var methods []string
+	for k, v := range d.routers {
+		if k != mn {
+			if _, _, ok := v.Lookup(fpath.Clean(path)); ok {
+				methods = append(methods, k)
+				continue
+			}
+		}
+	}
+	return methods
+}
+
+// convert swagger parameters per path segment into a denco parameter as multiple parameters per segment are not supported in denco
+var pathConverter = regexp.MustCompile(`{(.+?)}([^/]*)`)
+
+func decodeCompositParams(name string, value string, pattern string, names []string, values []string) ([]string, []string) {
+	pleft := strings.Index(pattern, "{")
+	names = append(names, name)
+	if pleft < 0 {
+		if strings.HasSuffix(value, pattern) {
+			values = append(values, value[:len(value)-len(pattern)])
+		} else {
+			values = append(values, "")
+		}
+	} else {
+		toskip := pattern[:pleft]
+		pright := strings.Index(pattern, "}")
+		vright := strings.Index(value, toskip)
+		if vright >= 0 {
+			values = append(values, value[:vright])
+		} else {
+			values = append(values, "")
+			value = ""
+		}
+		return decodeCompositParams(pattern[pleft+1:pright], value[vright+len(toskip):], pattern[pright+1:], names, values)
+	}
+	return names, values
+}
+
+func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Operation) {
+	mn := strings.ToUpper(method)
+
+	bp := fpath.Clean(d.spec.BasePath())
+	if len(bp) > 0 && bp[len(bp)-1] == '/' {
+		bp = bp[:len(bp)-1]
+	}
+
+	debugLog("operation: %#v", *operation)
+	if handler, ok := d.api.HandlerFor(method, strings.TrimPrefix(path, bp)); ok {
+		consumes := d.analyzer.ConsumesFor(operation)
+		produces := d.analyzer.ProducesFor(operation)
+		parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp))
+
+		record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{
+			BasePath:       bp,
+			PathPattern:    path,
+			Operation:      operation,
+			Handler:        handler,
+			Consumes:       consumes,
+			Produces:       produces,
+			Consumers:      d.api.ConsumersFor(normalizeOffers(consumes)),
+			Producers:      d.api.ProducersFor(normalizeOffers(produces)),
+			Parameters:     parameters,
+			Formats:        d.api.Formats(),
+			Binder:         newUntypedRequestBinder(parameters, d.spec.Spec(), d.api.Formats()),
+			Authenticators: d.buildAuthenticators(operation),
+			Authorizer:     d.api.Authorizer(),
+		})
+		d.records[mn] = append(d.records[mn], record)
+	}
+}
+
+func (d *defaultRouteBuilder) buildAuthenticators(operation *spec.Operation) RouteAuthenticators {
+	requirements := d.analyzer.SecurityRequirementsFor(operation)
+	var auths []RouteAuthenticator
+	for _, reqs := range requirements {
+		var schemes []string
+		scopes := make(map[string][]string, len(reqs))
+		var scopeSlices [][]string
+		for _, req := range reqs {
+			schemes = append(schemes, req.Name)
+			scopes[req.Name] = req.Scopes
+			scopeSlices = append(scopeSlices, req.Scopes)
+		}
+
+		definitions := d.analyzer.SecurityDefinitionsForRequirements(reqs)
+		authenticators := d.api.AuthenticatorsFor(definitions)
+		auths = append(auths, RouteAuthenticator{
+			Authenticator:  authenticators,
+			Schemes:        schemes,
+			Scopes:         scopes,
+			allScopes:      stringSliceUnion(scopeSlices...),
+			commonScopes:   stringSliceIntersection(scopeSlices...),
+			allowAnonymous: len(reqs) == 1 && reqs[0].Name == "",
+		})
+	}
+	return auths
+}
+
+func (d *defaultRouteBuilder) Build() *defaultRouter {
+	routers := make(map[string]*denco.Router)
+	for method, records := range d.records {
+		router := denco.New()
+		_ = router.Build(records)
+		routers[method] = router
+	}
+	return &defaultRouter{
+		spec:    d.spec,
+		routers: routers,
+	}
+}